From 6b70faf14111fa6ef2c0508e18245cf992b8296a Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 14 Nov 2017 21:42:14 -0800 Subject: [PATCH 001/491] Multiple login account support initial, needs a ton of work but can login and create account --- common/database.cpp | 35 ++++------- common/database.h | 9 ++- common/eqemu_config.cpp | 12 ++++ common/eqemu_config.h | 3 + world/client.cpp | 76 ++++++------------------ world/cliententry.cpp | 49 +++------------ world/cliententry.h | 7 +-- world/clientlist.cpp | 41 +------------ world/clientlist.h | 4 +- world/console.cpp | 53 +++++++++-------- world/login_server.cpp | 62 ++++--------------- world/login_server.h | 10 ++-- world/login_server_list.cpp | 22 +------ world/login_server_list.h | 4 +- world/net.cpp | 39 ++++++------ zone/client.h | 1 + zone/client_packet.cpp | 15 ++--- zone/command.cpp | 115 ++++++++++++++++++------------------ 18 files changed, 198 insertions(+), 359 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 62a8453d1..188c243e7 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -200,15 +200,15 @@ int16 Database::CheckStatus(uint32 account_id) { return status; } -uint32 Database::CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id) { +uint32 Database::CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id) { std::string query; if (password) - query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name,password,status, lsaccount_id); + query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();", name, password, status, loginserver, lsaccount_id); else - query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id); + query = StringFormat("INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, loginserver, lsaccount_id); - Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s' status: %i", name, status); + Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s:%s' status: %i", loginserver, name, status); auto results = QueryDatabase(query); if (!results.Success()) { @@ -223,9 +223,9 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta return results.LastInsertedID(); } -bool Database::DeleteAccount(const char* name) { - std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name); - Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name); +bool Database::DeleteAccount(const char *loginserver, const char* name) { + std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver); + Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s:%s'", loginserver, name); auto results = QueryDatabase(query); if (!results.Success()) { @@ -921,18 +921,6 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu return true; } -uint32 Database::GetMiniLoginAccount(char* ip) -{ - std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - auto row = results.begin(); - return atoi(row[0]); -} - // Get zone starting points from DB bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) { @@ -1194,9 +1182,10 @@ bool Database::AddToNameFilter(const char* name) { return true; } -uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* oStatus) { +uint32 Database::GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName, int16* oStatus) { uint32 account_id = 0; - std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID); + //iLoginServer is set by config so don't need to worry about escaping it. + std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i AND ls_id='%s'", iLSID, iLoginServer.c_str()); auto results = QueryDatabase(query); if (!results.Success()) { @@ -1431,9 +1420,9 @@ uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZo return charid; } -bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) { +bool Database::UpdateLiveChar(char* charname, uint32 account_id) { - std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id); + std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;", charname, account_id); auto results = QueryDatabase(query); if (!results.Success()){ diff --git a/common/database.h b/common/database.h index 6f3fd0642..6cdb9fddc 100644 --- a/common/database.h +++ b/common/database.h @@ -174,18 +174,17 @@ public: /* Account Related */ - bool DeleteAccount(const char* name); + bool DeleteAccount(const char *loginserver, const char* name); bool GetLiveChar(uint32 account_id, char* cname); bool SetAccountStatus(const char* name, int16 status); bool SetLocalPassword(uint32 accid, const char* password); - bool UpdateLiveChar(char* charname, uint32 lsaccount_id); + bool UpdateLiveChar(char* charname, uint32 account_id); int16 CheckStatus(uint32 account_id); uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0); - uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0); - uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); - uint32 GetMiniLoginAccount(char* ip); + uint32 CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id); + uint32 GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); uint8 GetAgreementFlag(uint32 acctid); void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); diff --git a/common/eqemu_config.cpp b/common/eqemu_config.cpp index 96980f834..15bc90302 100644 --- a/common/eqemu_config.cpp +++ b/common/eqemu_config.cpp @@ -70,6 +70,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele) if (text) { LoginLegacy = atoi(text) > 0 ? true : false; } + text = ParseTextBlock(sub_ele, "name", true); + if (text) { + LoginName = text; + } text = ParseTextBlock(sub_ele, "account", true); if (text) { LoginAccount = text; @@ -97,6 +101,10 @@ void EQEmuConfig::do_world(TiXmlElement *ele) if (text) { loginconfig->LoginLegacy = atoi(text) > 0 ? true : false; } + text = ParseTextBlock(sub_ele, "name", true); + if (text) { + loginconfig->LoginName = text; + } text = ParseTextBlock(sub_ele, "account", true); if (text) { loginconfig->LoginAccount = text; @@ -394,6 +402,9 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const if (var_name == "LoginLegacy") { return (itoa(LoginLegacy ? 1 : 0)); } + if (var_name == "LoginName") { + return LoginName; + } if (var_name == "Locked") { return (Locked ? "true" : "false"); } @@ -526,6 +537,7 @@ void EQEmuConfig::Dump() const std::cout << "LoginPassword = " << LoginPassword << std::endl; std::cout << "LoginPort = " << LoginPort << std::endl; std::cout << "LoginLegacy = " << LoginLegacy << std::endl; + std::cout << "LoginName = " << LoginName << std::endl; std::cout << "Locked = " << Locked << std::endl; std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl; std::cout << "WorldIP = " << WorldIP << std::endl; diff --git a/common/eqemu_config.h b/common/eqemu_config.h index 0f51f550f..da2479661 100644 --- a/common/eqemu_config.h +++ b/common/eqemu_config.h @@ -27,6 +27,7 @@ struct LoginConfig { std::string LoginPassword; uint16 LoginPort; bool LoginLegacy; + std::string LoginName; }; class EQEmuConfig : public XMLParser @@ -44,6 +45,7 @@ class EQEmuConfig : public XMLParser std::string LoginPassword; uint16 LoginPort; bool LoginLegacy; + std::string LoginName; uint32 LoginCount; LinkedList loginlist; bool Locked; @@ -134,6 +136,7 @@ class EQEmuConfig : public XMLParser LoginHost = "login.eqemulator.net"; LoginPort = 5998; LoginLegacy = false; + LoginName = "eqemu"; // World Locked = false; WorldTCPPort = 9000; diff --git a/world/client.cpp b/world/client.cpp index aaf7d4c9c..6625712f0 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -395,7 +395,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { if (app->size != sizeof(LoginInfo_Struct)) { return false; } - + LoginInfo_Struct *li=(LoginInfo_Struct *)app->pBuffer; // Quagmire - max len for name is 18, pass 15 @@ -405,60 +405,25 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { strn0cpy(password, (char*)&(li->login_info[strlen(name)+1]), 15); if (strlen(password) <= 1) { - // TODO: Find out how to tell the client wrong username/password - Log(Logs::Detail, Logs::World_Server,"Login without a password"); + Log(Logs::Detail, Logs::World_Server, "Login without a password"); return false; } - is_player_zoning=(li->zoning==1); + is_player_zoning = (li->zoning == 1); -#ifdef IPBASED_AUTH_HACK - struct in_addr tmpip; - tmpip.s_addr = ip; -#endif - uint32 id=0; - bool minilogin = loginserverlist.MiniLogin(); - if(minilogin){ - struct in_addr miniip; - miniip.s_addr = ip; - id = database.GetMiniLoginAccount(inet_ntoa(miniip)); - } - else if(strncasecmp(name, "LS#", 3) == 0) - id=atoi(&name[3]); - else if(database.GetAccountIDByName(name)){ - int16 status = 0; - uint32 lsid = 0; - id = database.GetAccountIDByName(name, &status, &lsid); - } - else - id=atoi(name); - if (loginserverlist.Connected() == false && !is_player_zoning) { - Log(Logs::General, Logs::World_Server,"Error: Login server login while not connected to login server."); + uint32 id = atoi(name); + + if (id == 0) { + Log(Logs::General, Logs::World_Server, "Login ID is 0, disconnecting."); return false; } - if (((cle = client_list.CheckAuth(name, password)) || (cle = client_list.CheckAuth(id, password)))) - { - if (cle->AccountID() == 0 || (!minilogin && cle->LSID()==0)) { - Log(Logs::General, Logs::World_Server,"ID is 0. Is this server connected to minilogin?"); - if (!minilogin) { - Log(Logs::General, Logs::World_Server, "If so you forget the minilogin variable..."); - } - else { - Log(Logs::General, Logs::World_Server, "Could not find a minilogin account, verify ip address logging into minilogin is the same that is in your account table."); - } - return false; - } - if(minilogin){ - cle->SetOnline(); - WorldConfig::DisableStats(); - Log(Logs::General, Logs::World_Server, "MiniLogin Account #%d",cle->AccountID()); - } - else if (!is_player_zoning) { + if (cle = client_list.CheckAuth(id, password)) { + if (!is_player_zoning) { // Track who is in and who is out of the game char *inout= (char *) ""; - if (cle->GetOnline() == CLE_Status_Never){ + if (cle->GetOnline() == CLE_Status_Never) { // Desktop -> Char Select inout = (char *) "In"; } @@ -466,7 +431,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { // Game -> Char Select inout=(char *) "Out"; } - + // Always at Char select at this point. // Either from a fresh client launch or coming back from the game. // Exiting the game entirely does not come through here. @@ -480,10 +445,10 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { else { cle->SetOnline(); } - + const WorldConfig *Config=WorldConfig::get(); - - if(Config->UpdateStats){ + + if(Config->UpdateStats) { auto pack = new ServerPacket; pack->opcode = ServerOP_LSPlayerJoinWorld; pack->size = sizeof(ServerLSPlayerJoinWorld_Struct); @@ -495,10 +460,10 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { loginserverlist.SendPacket(pack); safe_delete(pack); } - + if (!is_player_zoning) SendGuildList(); - + SendLogServer(); SendApproveWorld(); SendEnterWorld(cle->name()); @@ -509,18 +474,13 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { database.LoginIP(cle->AccountID(), long2ip(GetIP()).c_str()); } + cle->SetIP(GetIP()); + return true; } else { - // TODO: Find out how to tell the client wrong username/password Log(Logs::Detail, Logs::World_Server,"Bad/Expired session key '%s'",name); return false; } - - if (!cle) - return true; - - cle->SetIP(GetIP()); - return true; } bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) diff --git a/world/cliententry.cpp b/world/cliententry.cpp index be8916676..9949de55c 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -31,7 +31,7 @@ extern LoginServerList loginserverlist; extern ClientList client_list; extern volatile bool RunLoops; -ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) +ClientListEntry::ClientListEntry(const char* iLoginServer, uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) : id(in_id) { ClearVars(true); @@ -39,9 +39,10 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginN pIP = ip; pLSID = iLSID; if(iLSID > 0) - paccountid = database.GetAccountIDFromLSID(iLSID, paccountname, &padmin); + paccountid = database.GetAccountIDFromLSID(iLoginServer, iLSID, paccountname, &padmin); strn0cpy(plsname, iLoginName, sizeof(plsname)); strn0cpy(plskey, iLoginKey, sizeof(plskey)); + strn0cpy(pLoginServer, iLoginServer, sizeof(pLoginServer)); pworldadmin = iWorldAdmin; plocal=(local==1); @@ -52,27 +53,6 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char* iLoginN memset(pLFGComments, 0, 64); } -ClientListEntry::ClientListEntry(uint32 in_id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin) -: id(in_id) -{ - ClearVars(true); - - pIP = 0; - pLSID = 0; - pworldadmin = 0; - - paccountid = iAccID; - strn0cpy(paccountname, iAccName, sizeof(paccountname)); - pMD5Pass = iMD5Pass; - padmin = iAdmin; - - pinstance = 0; - pLFGFromLevel = 0; - pLFGToLevel = 0; - pLFGMatchFilter = false; - memset(pLFGComments, 0, 64); -} - ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) : id(in_id) { @@ -278,12 +258,12 @@ bool ClientListEntry::CheckStale() { } bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { - if (strncmp(plskey, iKey,10) == 0) { - if (paccountid == 0 && LSID()>0) { + if (strncmp(plskey, iKey, 10) == 0) { + if (paccountid == 0 && LSID() > 0) { int16 tmpStatus = WorldConfig::get()->DefaultStatus; - paccountid = database.CreateAccount(plsname, 0, tmpStatus, LSID()); + paccountid = database.CreateAccount(plsname, 0, tmpStatus, pLoginServer, LSID()); if (!paccountid) { - Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s', duplicate name?" ,plsname); + Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s:%s', duplicate name?", pLoginServer, plsname); return false; } strn0cpy(paccountname, plsname, sizeof(paccountname)); @@ -298,21 +278,6 @@ bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { return false; } -bool ClientListEntry::CheckAuth(const char* iName, MD5& iMD5Password) { - if (LSAccountID() == 0 && strcmp(paccountname, iName) == 0 && pMD5Pass == iMD5Password) - return true; - return false; -} - -bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) { - if (pIP==ip && strncmp(plskey, iKey,10) == 0){ - paccountid = id; - database.GetAccountFromID(id,paccountname,&padmin); - return true; - } - return false; -} - void ClientListEntry::ProcessTellQueue() { if (!Server()) diff --git a/world/cliententry.h b/world/cliententry.h index 24a837ae9..365552a0a 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -21,8 +21,7 @@ struct ServerClientList_Struct; class ClientListEntry { public: - ClientListEntry(uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); - ClientListEntry(uint32 id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin = 0); + ClientListEntry(const char* iLoginServer, uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline); ~ClientListEntry(); bool CheckStale(); @@ -30,8 +29,6 @@ public: void LSUpdate(ZoneServer* zoneserver); void LSZoneChange(ZoneToZone_Struct* ztz); bool CheckAuth(uint32 iLSID, const char* key); - bool CheckAuth(const char* iName, MD5& iMD5Password); - bool CheckAuth(uint32 id, const char* key, uint32 ip); void SetOnline(ZoneServer* iZS, int8 iOnline); void SetOnline(int8 iOnline = CLE_Status_Online); void SetChar(uint32 iCharID, const char* iCharName); @@ -45,6 +42,7 @@ public: void Camp(ZoneServer* iZS = 0); // Login Server stuff + inline const char* LoginServer() const { return pLoginServer; } inline uint32 LSID() const { return pLSID; } inline uint32 LSAccountID() const { return pLSID; } inline const char* LSName() const { return plsname; } @@ -97,6 +95,7 @@ private: uint8 stale; // Login Server stuff + char pLoginServer[64]; //Loginserver we came from. uint32 pLSID; char plsname[32]; char plskey[16]; diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 3f1c3f50c..06fa2f405 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -349,8 +349,8 @@ void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnect } -void ClientList::CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) { - auto tmp = new ClientListEntry(GetNextCLEID(), iLSID, iLoginName, iLoginKey, iWorldAdmin, ip, local); +void ClientList::CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) { + auto tmp = new ClientListEntry(iLoginServer, GetNextCLEID(), iLSID, iLoginName, iLoginKey, iWorldAdmin, ip, local); clientlist.Append(tmp); } @@ -410,18 +410,6 @@ void ClientList::CLEKeepAlive(uint32 numupdates, uint32* wid) { } } - -ClientListEntry* ClientList::CheckAuth(uint32 id, const char* iKey, uint32 ip ) { - LinkedListIterator iterator(clientlist); - - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->CheckAuth(id, iKey, ip)) - return iterator.GetData(); - iterator.Advance(); - } - return 0; -} ClientListEntry* ClientList::CheckAuth(uint32 iLSID, const char* iKey) { LinkedListIterator iterator(clientlist); @@ -434,31 +422,6 @@ ClientListEntry* ClientList::CheckAuth(uint32 iLSID, const char* iKey) { return 0; } -ClientListEntry* ClientList::CheckAuth(const char* iName, const char* iPassword) { - LinkedListIterator iterator(clientlist); - MD5 tmpMD5(iPassword); - - iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->CheckAuth(iName, tmpMD5)) - return iterator.GetData(); - iterator.Advance(); - } - int16 tmpadmin; - - //Log.LogDebugType(Logs::Detail, Logs::World_Server,"Login with '%s' and '%s'", iName, iPassword); - - uint32 accid = database.CheckLogin(iName, iPassword, &tmpadmin); - if (accid) { - uint32 lsid = 0; - database.GetAccountIDByName(iName, &tmpadmin, &lsid); - auto tmp = new ClientListEntry(GetNextCLEID(), lsid, iName, tmpMD5, tmpadmin, 0, 0); - clientlist.Append(tmp); - return tmp; - } - return 0; -} - void ClientList::SendOnlineGuildMembers(uint32 FromID, uint32 GuildID) { int PacketLength = 8; diff --git a/world/clientlist.h b/world/clientlist.h index 4cee08a7f..361218241 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -51,8 +51,6 @@ public: void ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* scl); void CLERemoveZSRef(ZoneServer* iZS); ClientListEntry* CheckAuth(uint32 iLSID, const char* iKey); - ClientListEntry* CheckAuth(const char* iName, const char* iPassword); - ClientListEntry* CheckAuth(uint32 id, const char* iKey, uint32 ip); ClientListEntry* FindCharacter(const char* name); ClientListEntry* FindCLEByAccountID(uint32 iAccID); ClientListEntry* FindCLEByCharacterID(uint32 iCharID); @@ -63,7 +61,7 @@ public: void EnforceSessionLimit(uint32 iLSAccountID); void CLCheckStale(); void CLEKeepAlive(uint32 numupdates, uint32* wid); - void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); + void CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); void UpdateClientGuild(uint32 char_id, uint32 guild_id); int GetClientCount(); diff --git a/world/console.cpp b/world/console.cpp index 8326737c2..5237e9b0d 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -15,17 +15,18 @@ extern ZSList zoneserver_list; extern LoginServerList loginserverlist; struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string& username, const std::string& password) { + //TODO REIMPLEMENT struct EQ::Net::ConsoleLoginStatus ret; - ret.account_id = database.CheckLogin(username.c_str(), password.c_str()); - if (ret.account_id == 0) { - return ret; - } - - char account_name[64]; - database.GetAccountName(ret.account_id, account_name); - - ret.account_name = account_name; - ret.status = database.CheckStatus(ret.account_id); + //ret.account_id = database.CheckLogin(username.c_str(), password.c_str()); + //if (ret.account_id == 0) { + // return ret; + //} + // + //char account_name[64]; + //database.GetAccountName(ret.account_id, account_name); + // + //ret.account_name = account_name; + //ret.status = database.CheckStatus(ret.account_id); return ret; } @@ -379,21 +380,23 @@ void ConsoleFlag(EQ::Net::ConsoleServerConnection* connection, const std::string } void ConsoleSetPass(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector& args) { - if (args.size() != 2) { - connection->SendLine("Format: setpass accountname password"); - } - else { - int16 tmpstatus = 0; - uint32 tmpid = database.GetAccountIDByName(args[0].c_str(), &tmpstatus); - if (!tmpid) - connection->SendLine("Error: Account not found"); - else if (tmpstatus > connection->Admin()) - connection->SendLine("Cannot change password: Account's status is higher than yours"); - else if (database.SetLocalPassword(tmpid, args[1].c_str())) - connection->SendLine("Password changed."); - else - connection->SendLine("Error changing password."); - } + //TODO: REIMPLEMENT + + //if (args.size() != 2) { + // connection->SendLine("Format: setpass accountname password"); + //} + //else { + // int16 tmpstatus = 0; + // uint32 tmpid = database.GetAccountIDByName(args[0].c_str(), &tmpstatus); + // if (!tmpid) + // connection->SendLine("Error: Account not found"); + // else if (tmpstatus > connection->Admin()) + // connection->SendLine("Cannot change password: Account's status is higher than yours"); + // else if (database.SetLocalPassword(tmpid, args[1].c_str())) + // connection->SendLine("Password changed."); + // else + // connection->SendLine("Error changing password."); + //} } void ConsoleVersion(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector& args) { diff --git a/world/login_server.cpp b/world/login_server.cpp index 97c9f5214..fe3c33e28 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -41,14 +41,15 @@ extern uint32 numzones; extern uint32 numplayers; extern volatile bool RunLoops; -LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy) +LoginServer::LoginServer(const char *Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy) { strn0cpy(LoginServerAddress, iAddress, 256); LoginServerPort = iPort; - strn0cpy(LoginAccount, Account, 31); - strn0cpy(LoginPassword, Password, 31); + LoginAccount = Account; + LoginPassword = Password; CanAccountUpdate = false; IsLegacy = legacy; + LoginName = Name; Connect(); } @@ -60,7 +61,7 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); - uint32 id = database.GetAccountIDFromLSID(utwr->lsaccountid); + uint32 id = database.GetAccountIDFromLSID(LoginName, utwr->lsaccountid); int16 status = database.CheckStatus(id); auto outpack = new ServerPacket; @@ -110,7 +111,7 @@ void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) { client_list.EnforceSessionLimit(slsca.lsaccount_id); } - client_list.CLEAdd(slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); + client_list.CLEAdd(LoginName.c_str(), slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); } catch (std::exception &ex) { LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); @@ -154,19 +155,6 @@ void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) { } bool LoginServer::Connect() { - std::string tmp; - if (database.GetVariable("loginType", tmp) && strcasecmp(tmp.c_str(), "MinILogin") == 0) { - minilogin = true; - Log(Logs::Detail, Logs::World_Server, "Setting World to MiniLogin Server type"); - } - else - minilogin = false; - - if (minilogin && WorldConfig::get()->WorldAddress.length() == 0) { - Log(Logs::Detail, Logs::World_Server, "**** For minilogin to work, you need to set the
element in the section."); - return false; - } - char errbuf[1024]; if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) { Log(Logs::Detail, Logs::World_Server, "Unable to resolve '%s' to an IP.", LoginServerAddress); @@ -183,10 +171,7 @@ bool LoginServer::Connect() { legacy_client->OnConnect([this](EQ::Net::ServertalkLegacyClient *client) { if (client) { Log(Logs::Detail, Logs::World_Server, "Connected to Legacy Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - if (minilogin) - SendInfo(); - else - SendNewInfo(); + SendInfo(); SendStatus(); zoneserver_list.SendLSZones(); @@ -212,10 +197,7 @@ bool LoginServer::Connect() { client->OnConnect([this](EQ::Net::ServertalkClient *client) { if (client) { Log(Logs::Detail, Logs::World_Server, "Connected to Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - if (minilogin) - SendInfo(); - else - SendNewInfo(); + SendInfo(); SendStatus(); zoneserver_list.SendLSZones(); @@ -238,28 +220,10 @@ bool LoginServer::Connect() { return true; } + void LoginServer::SendInfo() { const WorldConfig *Config = WorldConfig::get(); - auto pack = new ServerPacket; - pack->opcode = ServerOP_LSInfo; - pack->size = sizeof(ServerLSInfo_Struct); - pack->pBuffer = new uchar[pack->size]; - memset(pack->pBuffer, 0, pack->size); - ServerLSInfo_Struct* lsi = (ServerLSInfo_Struct*)pack->pBuffer; - strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION); - strcpy(lsi->serverversion, LOGIN_VERSION); - strcpy(lsi->name, Config->LongName.c_str()); - strcpy(lsi->account, LoginAccount); - strcpy(lsi->password, LoginPassword); - strcpy(lsi->address, Config->WorldAddress.c_str()); - SendPacket(pack); - delete pack; -} - -void LoginServer::SendNewInfo() { - const WorldConfig *Config = WorldConfig::get(); - auto pack = new ServerPacket; pack->opcode = ServerOP_NewLSInfo; pack->size = sizeof(ServerNewLSInfo_Struct); @@ -270,8 +234,8 @@ void LoginServer::SendNewInfo() { strcpy(lsi->serverversion, LOGIN_VERSION); strcpy(lsi->name, Config->LongName.c_str()); strcpy(lsi->shortname, Config->ShortName.c_str()); - strcpy(lsi->account, LoginAccount); - strcpy(lsi->password, LoginPassword); + strn0cpy(lsi->account, LoginAccount.c_str(), 30); + strn0cpy(lsi->password, LoginPassword.c_str(), 30); if (Config->WorldAddress.length()) strcpy(lsi->remote_address, Config->WorldAddress.c_str()); if (Config->LocalAddress.length()) @@ -310,8 +274,8 @@ void LoginServer::SendAccountUpdate(ServerPacket* pack) { ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *)pack->pBuffer; if (CanUpdate()) { Log(Logs::Detail, Logs::World_Server, "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d", LoginServerAddress, LoginServerPort); - strn0cpy(s->worldaccount, LoginAccount, 30); - strn0cpy(s->worldpassword, LoginPassword, 30); + strn0cpy(s->worldaccount, LoginAccount.c_str(), 30); + strn0cpy(s->worldpassword, LoginPassword.c_str(), 30); SendPacket(pack); } } diff --git a/world/login_server.h b/world/login_server.h index 33fdac18c..0063f40a4 100644 --- a/world/login_server.h +++ b/world/login_server.h @@ -31,19 +31,17 @@ class LoginServer{ public: - LoginServer(const char*, uint16, const char*, const char*, bool legacy); + LoginServer(const char *, const char*, uint16, const char*, const char*, bool legacy); ~LoginServer(); bool Connect(); void SendInfo(); - void SendNewInfo(); void SendStatus(); void SendPacket(ServerPacket* pack) { if (IsLegacy) legacy_client->SendPacket(pack); else client->SendPacket(pack); } void SendAccountUpdate(ServerPacket* pack); bool Connected() { return IsLegacy ? legacy_client->Connected() : client->Connected(); } - bool MiniLogin() { return minilogin; } bool CanUpdate() { return CanAccountUpdate; } private: @@ -54,16 +52,16 @@ private: void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p); - bool minilogin; std::unique_ptr client; std::unique_ptr legacy_client; std::unique_ptr statusupdate_timer; char LoginServerAddress[256]; uint32 LoginServerIP; uint16 LoginServerPort; - char LoginAccount[32]; - char LoginPassword[32]; + std::string LoginAccount; + std::string LoginPassword; bool CanAccountUpdate; bool IsLegacy; + std::string LoginName; }; #endif diff --git a/world/login_server_list.cpp b/world/login_server_list.cpp index 92d67fb82..1b9eecee3 100644 --- a/world/login_server_list.cpp +++ b/world/login_server_list.cpp @@ -49,9 +49,9 @@ LoginServerList::LoginServerList() { LoginServerList::~LoginServerList() { } -void LoginServerList::Add(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy) +void LoginServerList::Add(const char* Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy) { - auto loginserver = new LoginServer(iAddress, iPort, Account, Password, Legacy); + auto loginserver = new LoginServer(Name, iAddress, iPort, Account, Password, Legacy); m_list.push_back(std::unique_ptr(loginserver)); } @@ -63,14 +63,6 @@ bool LoginServerList::SendInfo() { return true; } -bool LoginServerList::SendNewInfo() { - for (auto &iter : m_list) { - (*iter).SendNewInfo(); - } - - return true; -} - bool LoginServerList::SendStatus() { for (auto &iter : m_list) { (*iter).SendStatus(); @@ -118,16 +110,6 @@ bool LoginServerList::AllConnected() { return true; } -bool LoginServerList::MiniLogin() { - for (auto &iter : m_list) { - if ((*iter).MiniLogin()) { - return true; - } - } - - return false; -} - bool LoginServerList::CanUpdate() { for (auto &iter : m_list) { if ((*iter).CanUpdate()) { diff --git a/world/login_server_list.h b/world/login_server_list.h index 56806f704..26a0a4b53 100644 --- a/world/login_server_list.h +++ b/world/login_server_list.h @@ -15,17 +15,15 @@ public: LoginServerList(); ~LoginServerList(); - void Add(const char*, uint16, const char*, const char*, bool); + void Add(const char*, const char*, uint16, const char*, const char*, bool); bool SendInfo(); - bool SendNewInfo(); bool SendStatus(); bool SendPacket(ServerPacket *pack); bool SendAccountUpdate(ServerPacket *pack); bool Connected(); bool AllConnected(); - bool MiniLogin(); bool CanUpdate(); size_t GetServerCount() const { return m_list.size(); } diff --git a/world/net.cpp b/world/net.cpp index b6e7babcc..3b7f7b79f 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -157,7 +157,7 @@ int main(int argc, char** argv) { // add login server config to list if (Config->LoginCount == 0) { if (Config->LoginHost.length()) { - loginserverlist.Add(Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy); + loginserverlist.Add(Config->LoginName.c_str(), Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy); Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", Config->LoginHost.c_str(), Config->LoginPort); } } @@ -166,7 +166,7 @@ int main(int argc, char** argv) { LinkedListIterator iterator(loginlist); iterator.Reset(); while (iterator.MoreElements()) { - loginserverlist.Add(iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(), + loginserverlist.Add(iterator.GetData()->LoginName.c_str(), iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(), iterator.GetData()->LoginLegacy); Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort); iterator.Advance(); @@ -213,23 +213,24 @@ int main(int argc, char** argv) { } } else if (strcasecmp(argv[1], "adduser") == 0) { - if (argc == 5) { - if (Seperator::IsNumber(argv[4])) { - if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) { - if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0) { - std::cerr << "database.CreateAccount failed." << std::endl; - return 1; - } - else { - std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl; - return 0; - } - } - } - } - std::cout << "Usage: world adduser username password flag" << std::endl; - std::cout << "flag = 0, 1 or 2" << std::endl; - return 0; + //TODO: REIMPLEMENT + //if (argc == 5) { + // if (Seperator::IsNumber(argv[4])) { + // if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) { + // if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0) { + // std::cerr << "database.CreateAccount failed." << std::endl; + // return 1; + // } + // else { + // std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl; + // return 0; + // } + // } + // } + //} + //std::cout << "Usage: world adduser username password flag" << std::endl; + //std::cout << "flag = 0, 1 or 2" << std::endl; + //return 0; } else if (strcasecmp(argv[1], "flag") == 0) { if (argc == 4) { diff --git a/zone/client.h b/zone/client.h index 88622fcff..925f214b7 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1405,6 +1405,7 @@ private: uint32 WID; uint32 account_id; char account_name[30]; + char loginserver[64]; uint32 lsaccountid; char lskey[30]; int16 admin; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8efe55f2b..3e1b812ce 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1283,16 +1283,17 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) database.LoadCharacterFactionValues(cid, factionvalues); /* Load Character Account Data: Temp until I move */ - query = StringFormat("SELECT `status`, `name`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme`, `time_creation` FROM `account` WHERE `id` = %u", this->AccountID()); + query = StringFormat("SELECT `status`, `name`, `ls_id`, `lsaccount_id`, `gmspeed`, `revoked`, `hideme`, `time_creation` FROM `account` WHERE `id` = %u", this->AccountID()); auto results = database.QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { admin = atoi(row[0]); - strncpy(account_name, row[1], 30); - lsaccountid = atoi(row[2]); - gmspeed = atoi(row[3]); - revoked = atoi(row[4]); - gm_hide_me = atoi(row[5]); - account_creation = atoul(row[6]); + strn0cpy(account_name, row[1], sizeof(account_name)); + strn0cpy(loginserver, row[2], sizeof(loginserver)); + lsaccountid = atoi(row[3]); + gmspeed = atoi(row[4]); + revoked = atoi(row[5]); + gm_hide_me = atoi(row[6]); + account_creation = atoul(row[7]); } /* Load Character Data */ diff --git a/zone/command.cpp b/zone/command.cpp index a65f9005e..9ca19a3b9 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1957,31 +1957,33 @@ void command_shutdown(Client *c, const Seperator *sep) void command_delacct(Client *c, const Seperator *sep) { - if(sep->arg[1][0] == 0) - c->Message(0, "Format: #delacct accountname"); - else - if (database.DeleteAccount(sep->arg[1])) - c->Message(0, "The account was deleted."); - else - c->Message(0, "Unable to delete account."); + //TODO: REIMPLEMENT +// if(sep->arg[1][0] == 0) +// c->Message(0, "Format: #delacct accountname"); +// else +// if (database.DeleteAccount(sep->arg[1])) +// c->Message(0, "The account was deleted."); +// else +// c->Message(0, "Unable to delete account."); } void command_setpass(Client *c, const Seperator *sep) { - if(sep->argnum != 2) - c->Message(0, "Format: #setpass accountname password"); - else { - int16 tmpstatus = 0; - uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus); - if (!tmpid) - c->Message(0, "Error: Account not found"); - else if (tmpstatus > c->Admin()) - c->Message(0, "Cannot change password: Account's status is higher than yours"); - else if (database.SetLocalPassword(tmpid, sep->arg[2])) - c->Message(0, "Password changed."); - else - c->Message(0, "Error changing password."); - } + //TODO: REIMPLEMENT + //if(sep->argnum != 2) + // c->Message(0, "Format: #setpass accountname password"); + //else { + // int16 tmpstatus = 0; + // uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus); + // if (!tmpid) + // c->Message(0, "Error: Account not found"); + // else if (tmpstatus > c->Admin()) + // c->Message(0, "Cannot change password: Account's status is higher than yours"); + // else if (database.SetLocalPassword(tmpid, sep->arg[2])) + // c->Message(0, "Password changed."); + // else + // c->Message(0, "Error changing password."); + //} } void command_setlsinfo(Client *c, const Seperator *sep) @@ -4414,41 +4416,42 @@ void command_uptime(Client *c, const Seperator *sep) void command_flag(Client *c, const Seperator *sep) { - if(sep->arg[2][0] == 0) { - if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { - c->UpdateAdmin(); - c->Message(0, "Refreshed your admin flag from DB."); - } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { - c->GetTarget()->CastToClient()->UpdateAdmin(); - c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); - c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); - } - } - else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) - c->Message(0, "Usage: #flag [status] [acctname]"); - - else if (c->Admin() < commandChangeFlags) { -//this check makes banning players by less than this level -//impossible, but i'll leave it in anyways - c->Message(0, "You may only refresh your own flag, doing so now."); - c->UpdateAdmin(); - } - else { - if (atoi(sep->arg[1]) > c->Admin()) - c->Message(0, "You cannot set people's status to higher than your own"); - else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) - c->Message(0, "You have too low of status to suspend/ban"); - else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) - c->Message(0, "Unable to set GM Flag."); - else { - c->Message(0, "Set GM Flag on account."); - auto pack = new ServerPacket(ServerOP_FlagUpdate, 6); - *((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]); - *((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]); - worldserver.SendPacket(pack); - delete pack; - } - } + //TODO: REIMPLEMENT +// if(sep->arg[2][0] == 0) { +// if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { +// c->UpdateAdmin(); +// c->Message(0, "Refreshed your admin flag from DB."); +// } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { +// c->GetTarget()->CastToClient()->UpdateAdmin(); +// c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); +// c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); +// } +// } +// else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) +// c->Message(0, "Usage: #flag [status] [acctname]"); +// +// else if (c->Admin() < commandChangeFlags) { +////this check makes banning players by less than this level +////impossible, but i'll leave it in anyways +// c->Message(0, "You may only refresh your own flag, doing so now."); +// c->UpdateAdmin(); +// } +// else { +// if (atoi(sep->arg[1]) > c->Admin()) +// c->Message(0, "You cannot set people's status to higher than your own"); +// else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) +// c->Message(0, "You have too low of status to suspend/ban"); +// else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) +// c->Message(0, "Unable to set GM Flag."); +// else { +// c->Message(0, "Set GM Flag on account."); +// auto pack = new ServerPacket(ServerOP_FlagUpdate, 6); +// *((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]); +// *((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]); +// worldserver.SendPacket(pack); +// delete pack; +// } +// } } void command_time(Client *c, const Seperator *sep) From 5bbeec626cba64bc7dd50e69f37f228c8d8e59bd Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 10 Dec 2017 23:35:25 -0800 Subject: [PATCH 002/491] Heavy wip on login changes to get it to actually work like we want --- common/database.cpp | 12 ++-- common/database.h | 4 +- common/eqemu_config.cpp | 12 ---- common/eqemu_config.h | 3 - common/servertalk.h | 46 ++++++++++++-- loginserver/CMakeLists.txt | 2 - loginserver/client.cpp | 59 +++++++++--------- loginserver/client.h | 1 + loginserver/database.h | 5 +- loginserver/database_mysql.cpp | 13 +++- loginserver/database_mysql.h | 4 +- loginserver/database_postgresql.cpp | 2 +- loginserver/database_postgresql.h | 2 +- loginserver/login_server.h | 1 - loginserver/main.cpp | 11 ---- loginserver/server_manager.cpp | 6 +- loginserver/world_server.cpp | 94 ++++++++++++++++++++++++++++- loginserver/world_server.h | 1 + world/cliententry.cpp | 13 ++-- world/cliententry.h | 2 +- world/clientlist.cpp | 4 +- world/clientlist.h | 2 +- world/console.cpp | 78 +++++++++++++++--------- world/login_server.cpp | 84 +++++++++++++++++++++++--- world/login_server.h | 5 +- world/login_server_list.cpp | 4 +- world/login_server_list.h | 2 +- world/net.cpp | 4 +- 28 files changed, 338 insertions(+), 138 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 188c243e7..8926ed4de 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -86,7 +86,7 @@ Database::~Database() Return the account id or zero if no account matches. Zero will also be returned if there is a database error. */ -uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) { +uint32 Database::CheckLogin(const char* name, const char* password, const char *loginserver, int16* oStatus) { if(strlen(name) >= 50 || strlen(password) >= 50) return(0); @@ -97,9 +97,10 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat DoEscapeString(tmpUN, name, strlen(name)); DoEscapeString(tmpPW, password, strlen(password)); - std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND password is not null " + std::string query = StringFormat("SELECT id, status FROM account WHERE name='%s' AND ls_id='%s' AND password is not null " "and length(password) > 0 and (password='%s' or password=MD5('%s'))", - tmpUN, tmpPW, tmpPW); + tmpUN, EscapeString(loginserver).c_str(), tmpPW, tmpPW); + auto results = QueryDatabase(query); if (!results.Success()) @@ -788,11 +789,12 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) { return atoi(row[0]); } -uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* lsid) { +uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver, int16* status, uint32* lsid) { if (!isAlphaNumeric(accname)) return 0; - std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' LIMIT 1", accname); + std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1", + EscapeString(accname).c_str(), EscapeString(loginserver).c_str()); auto results = QueryDatabase(query); if (!results.Success()) { diff --git a/common/database.h b/common/database.h index 6cdb9fddc..471e59a31 100644 --- a/common/database.h +++ b/common/database.h @@ -127,7 +127,7 @@ public: uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0); uint32 GetAccountIDByChar(uint32 char_id); - uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0); + uint32 GetAccountIDByName(const char* accname, const char *loginserver, int16* status = 0, uint32* lsid = 0); uint32 GetCharacterID(const char *name); uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0); uint32 GetGuildIDByCharID(uint32 char_id); @@ -182,7 +182,7 @@ public: int16 CheckStatus(uint32 account_id); - uint32 CheckLogin(const char* name, const char* password, 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 GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); uint8 GetAgreementFlag(uint32 acctid); diff --git a/common/eqemu_config.cpp b/common/eqemu_config.cpp index 15bc90302..96980f834 100644 --- a/common/eqemu_config.cpp +++ b/common/eqemu_config.cpp @@ -70,10 +70,6 @@ void EQEmuConfig::do_world(TiXmlElement *ele) if (text) { LoginLegacy = atoi(text) > 0 ? true : false; } - text = ParseTextBlock(sub_ele, "name", true); - if (text) { - LoginName = text; - } text = ParseTextBlock(sub_ele, "account", true); if (text) { LoginAccount = text; @@ -101,10 +97,6 @@ void EQEmuConfig::do_world(TiXmlElement *ele) if (text) { loginconfig->LoginLegacy = atoi(text) > 0 ? true : false; } - text = ParseTextBlock(sub_ele, "name", true); - if (text) { - loginconfig->LoginName = text; - } text = ParseTextBlock(sub_ele, "account", true); if (text) { loginconfig->LoginAccount = text; @@ -402,9 +394,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const if (var_name == "LoginLegacy") { return (itoa(LoginLegacy ? 1 : 0)); } - if (var_name == "LoginName") { - return LoginName; - } if (var_name == "Locked") { return (Locked ? "true" : "false"); } @@ -537,7 +526,6 @@ void EQEmuConfig::Dump() const std::cout << "LoginPassword = " << LoginPassword << std::endl; std::cout << "LoginPort = " << LoginPort << std::endl; std::cout << "LoginLegacy = " << LoginLegacy << std::endl; - std::cout << "LoginName = " << LoginName << std::endl; std::cout << "Locked = " << Locked << std::endl; std::cout << "WorldTCPPort = " << WorldTCPPort << std::endl; std::cout << "WorldIP = " << WorldIP << std::endl; diff --git a/common/eqemu_config.h b/common/eqemu_config.h index da2479661..0f51f550f 100644 --- a/common/eqemu_config.h +++ b/common/eqemu_config.h @@ -27,7 +27,6 @@ struct LoginConfig { std::string LoginPassword; uint16 LoginPort; bool LoginLegacy; - std::string LoginName; }; class EQEmuConfig : public XMLParser @@ -45,7 +44,6 @@ class EQEmuConfig : public XMLParser std::string LoginPassword; uint16 LoginPort; bool LoginLegacy; - std::string LoginName; uint32 LoginCount; LinkedList loginlist; bool Locked; @@ -136,7 +134,6 @@ class EQEmuConfig : public XMLParser LoginHost = "login.eqemulator.net"; LoginPort = 5998; LoginLegacy = false; - LoginName = "eqemu"; // World Locked = false; WorldTCPPort = 9000; diff --git a/common/servertalk.h b/common/servertalk.h index f5965cd74..5bd2692f9 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -142,14 +142,15 @@ #define ServerOP_ClientVersionSummary 0x0215 #define ServerOP_LSInfo 0x1000 #define ServerOP_LSStatus 0x1001 -#define ServerOP_LSClientAuth 0x1002 +#define ServerOP_LSClientAuthLeg 0x1002 #define ServerOP_LSFatalError 0x1003 #define ServerOP_SystemwideMessage 0x1005 #define ServerOP_ListWorlds 0x1006 #define ServerOP_PeerConnect 0x1007 #define ServerOP_NewLSInfo 0x1008 #define ServerOP_LSRemoteAddr 0x1009 -#define ServerOP_LSAccountUpdate 0x100A +#define ServerOP_LSAccountUpdate 0x100A +#define ServerOP_LSClientAuth 0x100B #define ServerOP_EncapPacket 0x2007 // Packet within a packet #define ServerOP_WorldListUpdate 0x2008 @@ -169,8 +170,10 @@ #define ServerOP_LSPlayerJoinWorld 0x3007 #define ServerOP_LSPlayerZoneChange 0x3008 -#define ServerOP_UsertoWorldReq 0xAB00 -#define ServerOP_UsertoWorldResp 0xAB01 +#define ServerOP_UsertoWorldReqLeg 0xAB00 +#define ServerOP_UsertoWorldRespLeg 0xAB01 +#define ServerOP_UsertoWorldReq 0xAB02 +#define ServerOP_UsertoWorldResp 0xAB03 #define ServerOP_LauncherConnectInfo 0x3000 #define ServerOP_LauncherZoneRequest 0x3001 @@ -512,6 +515,23 @@ struct ServerLSPlayerZoneChange_Struct { }; struct ClientAuth_Struct { + uint32 lsaccount_id; // ID# in login server's db + char lsname[64]; + char name[30]; // username in login server's db + char key[30]; // the Key the client will present + uint8 lsadmin; // login server admin level + int16 worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it + uint32 ip; + uint8 local; // 1 if the client is from the local network + + template + void serialize(Archive &ar) + { + ar(lsaccount_id, lsname, name, key, lsadmin, worldadmin, ip, local); + } +}; + +struct ClientAuthLegacy_Struct { uint32 lsaccount_id; // ID# in login server's db char name[30]; // username in login server's db char key[30]; // the Key the client will present @@ -651,12 +671,29 @@ struct ServerSyncWorldList_Struct { bool placeholder; }; +struct UsertoWorldRequestLegacy_Struct { + uint32 lsaccountid; + uint32 worldid; + uint32 FromID; + uint32 ToID; + char IPAddr[64]; +}; + struct UsertoWorldRequest_Struct { uint32 lsaccountid; uint32 worldid; uint32 FromID; uint32 ToID; char IPAddr[64]; + char login[64]; +}; + +struct UsertoWorldResponseLegacy_Struct { + uint32 lsaccountid; + uint32 worldid; + int8 response; // -3) World Full, -2) Banned, -1) Suspended, 0) Denied, 1) Allowed + uint32 FromID; + uint32 ToID; }; struct UsertoWorldResponse_Struct { @@ -665,6 +702,7 @@ struct UsertoWorldResponse_Struct { int8 response; // -3) World Full, -2) Banned, -1) Suspended, 0) Denied, 1) Allowed uint32 FromID; uint32 ToID; + char login[64]; }; // generic struct to be used for alot of simple zone->world questions diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index df06e7572..1561aa537 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -5,7 +5,6 @@ SET(eqlogin_sources client_manager.cpp config.cpp database_mysql.cpp - database_postgresql.cpp encryption.cpp main.cpp server_manager.cpp @@ -18,7 +17,6 @@ SET(eqlogin_headers config.h database.h database_mysql.h - database_postgresql.h encryption.h login_server.h login_structures.h diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 602967e38..ea2951d5f 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -219,37 +219,38 @@ void Client::Handle_Login(const char* data, unsigned int size) bool result = false; if (outbuffer[0] == 0 && outbuffer[1] == 0) { - if (server.options.IsTokenLoginAllowed()) { - cred = (&outbuffer[2 + user.length()]); - result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, user); - } + //if (server.options.IsTokenLoginAllowed()) { + // cred = (&outbuffer[2 + user.length()]); + // result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, user); + //} } else { - if (server.options.IsPasswordLoginAllowed()) { - cred = (&outbuffer[1 + user.length()]); - if (server.db->GetLoginDataFromAccountName(user, db_account_password_hash, db_account_id) == false) { - /* If we have auto_create_accounts enabled in the login.ini, we will process the creation of an account on our own*/ - if ( - server.options.CanAutoCreateAccounts() && - server.db->CreateLoginData(user, eqcrypt_hash(user, cred, mode), db_account_id) == true - ) { - LogF(Logs::General, Logs::Error, "User {0} does not exist in the database, so we created it...", user); - result = true; - } - else { - LogF(Logs::General, Logs::Error, "Error logging in, user {0} does not exist in the database.", user); - result = false; - } - } - else { - if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { - result = true; - } - else { - result = false; - } - } - } + //if (server.options.IsPasswordLoginAllowed()) { + // result = false; + // //cred = (&outbuffer[1 + user.length()]); + // //if (server.db->GetLoginDataFromAccountName(user, db_account_password_hash, db_account_id) == false) { + // // /* If we have auto_create_accounts enabled in the login.ini, we will process the creation of an account on our own*/ + // // if ( + // // server.options.CanAutoCreateAccounts() && + // // server.db->CreateLoginData(user, eqcrypt_hash(user, cred, mode), db_account_id) == true + // // ) { + // // LogF(Logs::General, Logs::Error, "User {0} does not exist in the database, so we created it...", user); + // // result = true; + // // } + // // else { + // // LogF(Logs::General, Logs::Error, "Error logging in, user {0} does not exist in the database.", user); + // // result = false; + // // } + // //} + // //else { + // // if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { + // // result = true; + // // } + // // else { + // // result = false; + // // } + // //} + //} } /* Login Accepted */ diff --git a/loginserver/client.h b/loginserver/client.h index b9bfe0494..35ba3a1f0 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -129,6 +129,7 @@ private: std::string account_name; unsigned int account_id; + std::string loginserver_name; unsigned int play_server_id; unsigned int play_sequence_id; std::string key; diff --git a/loginserver/database.h b/loginserver/database.h index 5dd7f7037..26eb45623 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -21,7 +21,6 @@ #include #define EQEMU_MYSQL_ENABLED -//#define EQEMU_POSTGRESQL_ENABLED /** * Base database class, intended to be extended. @@ -42,9 +41,9 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id) { return false; } + virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver) { return false; } - virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &user) { return false; } + virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; } virtual bool CreateLoginData(const std::string &name, const std::string &password, unsigned int &id) { return false; } diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index b40c77a0f..6e1b2cf12 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -59,7 +59,7 @@ DatabaseMySQL::~DatabaseMySQL() } } -bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id) +bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver) { if (!database) { @@ -96,7 +96,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &p return false; } -bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &user) +bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { if (!database) { @@ -120,6 +120,7 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const s bool found_username = false; bool found_login_id = false; + bool found_login_server_name = false; if (res) { while ((row = mysql_fetch_row(res)) != nullptr) @@ -135,12 +136,18 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const s found_login_id = true; continue; } + + if (strcmp(row[2], "login_server_name") == 0) { + db_loginserver = row[3]; + found_login_server_name = true; + continue; + } } mysql_free_result(res); } - return found_username && found_login_id; + return found_username && found_login_id && found_login_server_name; } bool DatabaseMySQL::CreateLoginData(const std::string &name, const std::string &password, unsigned int &id) diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index fc791b229..6edf0f1ce 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -57,9 +57,9 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id); + virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver); - virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &user); + virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user); virtual bool CreateLoginData(const std::string &name, const std::string &password, unsigned int &id); diff --git a/loginserver/database_postgresql.cpp b/loginserver/database_postgresql.cpp index 4b6242e63..e67e47467 100644 --- a/loginserver/database_postgresql.cpp +++ b/loginserver/database_postgresql.cpp @@ -53,7 +53,7 @@ DatabasePostgreSQL::~DatabasePostgreSQL() } } -bool DatabasePostgreSQL::GetLoginDataFromAccountName(string name, string &password, unsigned int &id) +bool DatabasePostgreSQL::GetLoginDataFromAccountName(string name, string &password, unsigned int &id, std::string &loginserver) { if(!db) { diff --git a/loginserver/database_postgresql.h b/loginserver/database_postgresql.h index 0cd5c3ee8..9d195920e 100644 --- a/loginserver/database_postgresql.h +++ b/loginserver/database_postgresql.h @@ -57,7 +57,7 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id); + virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver); /** * Retrieves the world registration from the long and short names provided. diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 7760b7efb..a5d780ebb 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -21,7 +21,6 @@ #include "config.h" #include "database.h" #include "database_mysql.h" -#include "database_postgresql.h" #include "encryption.h" #include "options.h" #include "server_manager.h" diff --git a/loginserver/main.cpp b/loginserver/main.cpp index a77ec395f..7fd047903 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -116,17 +116,6 @@ int main() server.config->GetVariable("database", "db")); #endif } - else if (server.config->GetVariable("database", "subsystem").compare("PostgreSQL") == 0) { -#ifdef EQEMU_POSTGRESQL_ENABLED - Log(Logs::General, Logs::Login_Server, "PostgreSQL Database Init."); - server.db = (Database*)new DatabasePostgreSQL( - server.config->GetVariable("database", "user"), - server.config->GetVariable("database", "password"), - server.config->GetVariable("database", "host"), - server.config->GetVariable("database", "port"), - server.config->GetVariable("database", "db")); -#endif - } /* Make sure our database got created okay, otherwise cleanup and exit. */ if (!server.db) { diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 550dba806..0a059ec93 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -213,11 +213,11 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int while (iter != world_servers.end()) { if ((*iter)->GetRuntimeID() == server_id) { EQ::Net::DynamicPacket outapp; - outapp.Resize(sizeof(UsertoWorldRequest_Struct)); - UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data(); + outapp.Resize(sizeof(UsertoWorldRequestLegacy_Struct)); + UsertoWorldRequestLegacy_Struct *utwr = (UsertoWorldRequestLegacy_Struct*)outapp.Data(); utwr->worldid = server_id; utwr->lsaccountid = client_account_id; - (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp); + (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReqLeg, outapp); found = true; if (server.options.IsDumpInPacketsOn()) { diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 55fc03b7b..02254f223 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -39,6 +39,7 @@ WorldServer::WorldServer(std::shared_ptr c) c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2)); c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage(ServerOP_UsertoWorldRespLeg, std::bind(&WorldServer::ProcessUsertoWorldRespLeg, this, std::placeholders::_1, std::placeholders::_2)); c->OnMessage(ServerOP_UsertoWorldResp, std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2)); c->OnMessage(ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); } @@ -116,6 +117,93 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) Handle_LSStatus(ls_status); } +void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p) +{ + if (server.options.IsWorldTraceOn()) + { + Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + } + + if (server.options.IsDumpInPacketsOn()) + { + DumpPacket(opcode, p); + } + + if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) + { + Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " + "but was too small. Discarded to avoid buffer overrun."); + return; + } + + //I don't use world trace for this and here is why: + //Because this is a part of the client login procedure it makes tracking client errors + //While keeping world server spam with multiple servers connected almost impossible. + if (server.options.IsTraceOn()) + { + Log(Logs::General, Logs::Netcode, "User-To-World Response received."); + } + + UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct*)p.Data(); + Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); + Client *c = server.client_manager->GetClient(utwr->lsaccountid); + if (c) + { + Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); + EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); + PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; + per->Sequence = c->GetPlaySequence(); + per->ServerNumber = c->GetPlayServerID(); + Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); + + Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + + if (utwr->response > 0) + { + per->Allowed = 1; + SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); + } + + switch (utwr->response) + { + case 1: + per->Message = 101; + break; + case 0: + per->Message = 326; + break; + case -1: + per->Message = 337; + break; + case -2: + per->Message = 338; + break; + case -3: + per->Message = 303; + break; + } + + if (server.options.IsTraceOn()) + { + Log(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", + per->Allowed, per->Sequence, per->ServerNumber, per->Message); + Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + } + + if (server.options.IsDumpOutPacketsOn()) + { + DumpPacket(outapp); + } + + c->SendPlayResponse(outapp); + delete outapp; + } + else + { + Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); + } +} + void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p) { if (server.options.IsWorldTraceOn()) @@ -501,7 +589,7 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id) { EQ::Net::DynamicPacket outapp; - ClientAuth_Struct client_auth; + ClientAuthLegacy_Struct client_auth; client_auth.lsaccount_id = account_id; strncpy(client_auth.name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); @@ -523,10 +611,10 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin } outapp.PutSerialize(0, client_auth); - connection->Send(ServerOP_LSClientAuth, outapp); + connection->Send(ServerOP_LSClientAuthLeg, outapp); if (server.options.IsDumpInPacketsOn()) { - DumpPacket(ServerOP_LSClientAuth, outapp); + DumpPacket(ServerOP_LSClientAuthLeg, outapp); } } diff --git a/loginserver/world_server.h b/loginserver/world_server.h index bce7b27eb..83c42d27f 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -133,6 +133,7 @@ private: */ void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); + void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p); void ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p); diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 9949de55c..cb0234ad8 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -31,18 +31,21 @@ extern LoginServerList loginserverlist; extern ClientList client_list; extern volatile bool RunLoops; -ClientListEntry::ClientListEntry(const char* iLoginServer, uint32 in_id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) +ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char *iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) : id(in_id) { ClearVars(true); pIP = ip; pLSID = iLSID; - if(iLSID > 0) - paccountid = database.GetAccountIDFromLSID(iLoginServer, iLSID, paccountname, &padmin); + if (iLSID > 0) { + + paccountid = database.GetAccountIDFromLSID(iLoginServerName, iLSID, paccountname, &padmin); + } + strn0cpy(plsname, iLoginName, sizeof(plsname)); strn0cpy(plskey, iLoginKey, sizeof(plskey)); - strn0cpy(pLoginServer, iLoginServer, sizeof(pLoginServer)); + strn0cpy(pLoginServer, iLoginServerName, sizeof(pLoginServer)); pworldadmin = iWorldAdmin; plocal=(local==1); @@ -258,7 +261,7 @@ bool ClientListEntry::CheckStale() { } bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { - if (strncmp(plskey, iKey, 10) == 0) { + if (pLSID == iLSID && strncmp(plskey, iKey, 10) == 0) { if (paccountid == 0 && LSID() > 0) { int16 tmpStatus = WorldConfig::get()->DefaultStatus; paccountid = database.CreateAccount(plsname, 0, tmpStatus, pLoginServer, LSID()); diff --git a/world/cliententry.h b/world/cliententry.h index 365552a0a..ca2f5e07d 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -21,7 +21,7 @@ struct ServerClientList_Struct; class ClientListEntry { public: - ClientListEntry(const char* iLoginServer, uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); + ClientListEntry(uint32 id, uint32 iLSID, const char *iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline); ~ClientListEntry(); bool CheckStale(); diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 06fa2f405..14aeb5766 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -349,8 +349,8 @@ void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnect } -void ClientList::CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) { - auto tmp = new ClientListEntry(iLoginServer, GetNextCLEID(), iLSID, iLoginName, iLoginKey, iWorldAdmin, ip, local); +void ClientList::CLEAdd(uint32 iLSID, const char *iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) { + auto tmp = new ClientListEntry(GetNextCLEID(), iLSID, iLoginServerName, iLoginName, iLoginKey, iWorldAdmin, ip, local); clientlist.Append(tmp); } diff --git a/world/clientlist.h b/world/clientlist.h index 361218241..be6bd5042 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -61,7 +61,7 @@ public: void EnforceSessionLimit(uint32 iLSAccountID); void CLCheckStale(); void CLEKeepAlive(uint32 numupdates, uint32* wid); - void CLEAdd(const char* iLoginServer, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); + void CLEAdd(uint32 iLSID, const char* iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); void UpdateClientGuild(uint32 char_id, uint32 guild_id); int GetClientCount(); diff --git a/world/console.cpp b/world/console.cpp index 5237e9b0d..ab7097244 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -15,18 +15,30 @@ extern ZSList zoneserver_list; extern LoginServerList loginserverlist; struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string& username, const std::string& password) { - //TODO REIMPLEMENT struct EQ::Net::ConsoleLoginStatus ret; - //ret.account_id = database.CheckLogin(username.c_str(), password.c_str()); - //if (ret.account_id == 0) { - // return ret; - //} - // - //char account_name[64]; - //database.GetAccountName(ret.account_id, account_name); - // - //ret.account_name = account_name; - //ret.status = database.CheckStatus(ret.account_id); + std::string prefix = "eqemu"; + std::string raw_user = ""; + + auto split = SplitString(username, ':'); + if (split.size() == 2) { + prefix = split[0]; + raw_user = split[1]; + } + else { + raw_user = split[0]; + } + + ret.account_id = database.CheckLogin(raw_user.c_str(), password.c_str(), prefix.c_str()); + + if (ret.account_id == 0) { + return ret; + } + + char account_name[64]; + database.GetAccountName(ret.account_id, account_name); + + ret.account_name = account_name; + ret.status = database.CheckStatus(ret.account_id); return ret; } @@ -380,23 +392,33 @@ void ConsoleFlag(EQ::Net::ConsoleServerConnection* connection, const std::string } void ConsoleSetPass(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector& args) { - //TODO: REIMPLEMENT - - //if (args.size() != 2) { - // connection->SendLine("Format: setpass accountname password"); - //} - //else { - // int16 tmpstatus = 0; - // uint32 tmpid = database.GetAccountIDByName(args[0].c_str(), &tmpstatus); - // if (!tmpid) - // connection->SendLine("Error: Account not found"); - // else if (tmpstatus > connection->Admin()) - // connection->SendLine("Cannot change password: Account's status is higher than yours"); - // else if (database.SetLocalPassword(tmpid, args[1].c_str())) - // connection->SendLine("Password changed."); - // else - // connection->SendLine("Error changing password."); - //} + if (args.size() != 2) { + connection->SendLine("Format: setpass accountname password"); + } + else { + std::string prefix = "eqemu"; + std::string raw_user = ""; + + auto split = SplitString(args[0], ':'); + if (split.size() == 2) { + prefix = split[0]; + raw_user = split[1]; + } + else { + raw_user = split[0]; + } + + int16 tmpstatus = 0; + uint32 tmpid = database.GetAccountIDByName(raw_user.c_str(), prefix.c_str(), &tmpstatus); + if (!tmpid) + connection->SendLine("Error: Account not found"); + else if (tmpstatus > connection->Admin()) + connection->SendLine("Cannot change password: Account's status is higher than yours"); + else if (database.SetLocalPassword(tmpid, args[1].c_str())) + connection->SendLine("Password changed."); + else + connection->SendLine("Error changing password."); + } } void ConsoleVersion(EQ::Net::ConsoleServerConnection* connection, const std::string& command, const std::vector& args) { diff --git a/world/login_server.cpp b/world/login_server.cpp index fe3c33e28..b01e9d933 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -41,7 +41,7 @@ extern uint32 numzones; extern uint32 numplayers; extern volatile bool RunLoops; -LoginServer::LoginServer(const char *Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy) +LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy) { strn0cpy(LoginServerAddress, iAddress, 256); LoginServerPort = iPort; @@ -49,27 +49,26 @@ LoginServer::LoginServer(const char *Name, const char* iAddress, uint16 iPort, c LoginPassword = Password; CanAccountUpdate = false; IsLegacy = legacy; - LoginName = Name; Connect(); } LoginServer::~LoginServer() { } -void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p) { const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); - UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); - uint32 id = database.GetAccountIDFromLSID(LoginName, utwr->lsaccountid); + UsertoWorldRequestLegacy_Struct* utwr = (UsertoWorldRequestLegacy_Struct*)p.Data(); + uint32 id = database.GetAccountIDFromLSID("eqemu", utwr->lsaccountid); int16 status = database.CheckStatus(id); auto outpack = new ServerPacket; - outpack->opcode = ServerOP_UsertoWorldResp; - outpack->size = sizeof(UsertoWorldResponse_Struct); + outpack->opcode = ServerOP_UsertoWorldRespLeg; + outpack->size = sizeof(UsertoWorldResponseLegacy_Struct); outpack->pBuffer = new uchar[outpack->size]; memset(outpack->pBuffer, 0, outpack->size); - UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer; + UsertoWorldResponseLegacy_Struct* utwrs = (UsertoWorldResponseLegacy_Struct*)outpack->pBuffer; utwrs->lsaccountid = utwr->lsaccountid; utwrs->ToID = utwr->FromID; @@ -98,6 +97,69 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { delete outpack; } +void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); + uint32 id = database.GetAccountIDFromLSID(utwr->login, utwr->lsaccountid); + int16 status = database.CheckStatus(id); + + auto outpack = new ServerPacket; + outpack->opcode = ServerOP_UsertoWorldResp; + outpack->size = sizeof(UsertoWorldResponse_Struct); + outpack->pBuffer = new uchar[outpack->size]; + memset(outpack->pBuffer, 0, outpack->size); + UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer; + utwrs->lsaccountid = utwr->lsaccountid; + utwrs->ToID = utwr->FromID; + strn0cpy(utwrs->login, utwr->login, 64); + + if (Config->Locked == true) + { + if ((status == 0 || status < 100) && (status != -2 || status != -1)) + utwrs->response = 0; + if (status >= 100) + utwrs->response = 1; + } + else { + utwrs->response = 1; + } + + int32 x = Config->MaxClients; + if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80) + utwrs->response = -3; + + if (status == -1) + utwrs->response = -1; + if (status == -2) + utwrs->response = -2; + + utwrs->worldid = utwr->worldid; + SendPacket(outpack); + delete outpack; +} + +void LoginServer::ProcessLSClientAuthLeg(uint16_t opcode, EQ::Net::Packet &p) { + const WorldConfig *Config = WorldConfig::get(); + Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + + try { + auto slsca = p.GetSerialize(0); + + if (RuleI(World, AccountSessionLimit) >= 0) { + // Enforce the limit on the number of characters on the same account that can be + // online at the same time. + client_list.EnforceSessionLimit(slsca.lsaccount_id); + } + + client_list.CLEAdd(slsca.lsaccount_id, "eqemu", slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); + } + catch (std::exception &ex) { + LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); + } +} + void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) { const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); @@ -111,7 +173,7 @@ void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) { client_list.EnforceSessionLimit(slsca.lsaccount_id); } - client_list.CLEAdd(LoginName.c_str(), slsca.lsaccount_id, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); + client_list.CLEAdd(slsca.lsaccount_id, slsca.lsname, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); } catch (std::exception &ex) { LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); @@ -184,7 +246,9 @@ bool LoginServer::Connect() { } }); + legacy_client->OnMessage(ServerOP_UsertoWorldReqLeg, std::bind(&LoginServer::ProcessUsertoWorldReqLeg, this, std::placeholders::_1, std::placeholders::_2)); legacy_client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2)); + legacy_client->OnMessage(ServerOP_LSClientAuthLeg, std::bind(&LoginServer::ProcessLSClientAuthLeg, this, std::placeholders::_1, std::placeholders::_2)); legacy_client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2)); legacy_client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2)); legacy_client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2)); @@ -210,7 +274,9 @@ bool LoginServer::Connect() { } }); + client->OnMessage(ServerOP_UsertoWorldReqLeg, std::bind(&LoginServer::ProcessUsertoWorldReqLeg, this, std::placeholders::_1, std::placeholders::_2)); client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2)); + client->OnMessage(ServerOP_LSClientAuthLeg, std::bind(&LoginServer::ProcessLSClientAuthLeg, this, std::placeholders::_1, std::placeholders::_2)); client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2)); client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2)); client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2)); diff --git a/world/login_server.h b/world/login_server.h index 0063f40a4..3bcc8dedf 100644 --- a/world/login_server.h +++ b/world/login_server.h @@ -31,7 +31,7 @@ class LoginServer{ public: - LoginServer(const char *, const char*, uint16, const char*, const char*, bool legacy); + LoginServer(const char*, uint16, const char*, const char*, bool legacy); ~LoginServer(); bool Connect(); @@ -45,8 +45,10 @@ public: bool CanUpdate() { return CanAccountUpdate; } private: + void ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p); void ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSClientAuthLeg(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p); void ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p); @@ -62,6 +64,5 @@ private: std::string LoginPassword; bool CanAccountUpdate; bool IsLegacy; - std::string LoginName; }; #endif diff --git a/world/login_server_list.cpp b/world/login_server_list.cpp index 1b9eecee3..fb273cbe8 100644 --- a/world/login_server_list.cpp +++ b/world/login_server_list.cpp @@ -49,9 +49,9 @@ LoginServerList::LoginServerList() { LoginServerList::~LoginServerList() { } -void LoginServerList::Add(const char* Name, const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy) +void LoginServerList::Add(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool Legacy) { - auto loginserver = new LoginServer(Name, iAddress, iPort, Account, Password, Legacy); + auto loginserver = new LoginServer(iAddress, iPort, Account, Password, Legacy); m_list.push_back(std::unique_ptr(loginserver)); } diff --git a/world/login_server_list.h b/world/login_server_list.h index 26a0a4b53..d1b29a8cf 100644 --- a/world/login_server_list.h +++ b/world/login_server_list.h @@ -15,7 +15,7 @@ public: LoginServerList(); ~LoginServerList(); - void Add(const char*, const char*, uint16, const char*, const char*, bool); + void Add(const char*, uint16, const char*, const char*, bool); bool SendInfo(); bool SendStatus(); diff --git a/world/net.cpp b/world/net.cpp index 3b7f7b79f..2c04b9d10 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -157,7 +157,7 @@ int main(int argc, char** argv) { // add login server config to list if (Config->LoginCount == 0) { if (Config->LoginHost.length()) { - loginserverlist.Add(Config->LoginName.c_str(), Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy); + loginserverlist.Add(Config->LoginHost.c_str(), Config->LoginPort, Config->LoginAccount.c_str(), Config->LoginPassword.c_str(), Config->LoginLegacy); Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", Config->LoginHost.c_str(), Config->LoginPort); } } @@ -166,7 +166,7 @@ int main(int argc, char** argv) { LinkedListIterator iterator(loginlist); iterator.Reset(); while (iterator.MoreElements()) { - loginserverlist.Add(iterator.GetData()->LoginName.c_str(), iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(), + loginserverlist.Add(iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort, iterator.GetData()->LoginAccount.c_str(), iterator.GetData()->LoginPassword.c_str(), iterator.GetData()->LoginLegacy); Log(Logs::General, Logs::World_Server, "Added loginserver %s:%i", iterator.GetData()->LoginHost.c_str(), iterator.GetData()->LoginPort); iterator.Advance(); From 569a907e43348fcb5bce8efc7ea3a20e0b72191f Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 11 Dec 2017 18:38:04 -0800 Subject: [PATCH 003/491] Changes to make it actually sorta work --- loginserver/client.cpp | 83 ++++++++++++++++------------------ loginserver/client.h | 5 ++ loginserver/client_manager.cpp | 19 +++----- loginserver/client_manager.h | 4 +- loginserver/database.h | 2 +- loginserver/database_mysql.cpp | 6 ++- loginserver/database_mysql.h | 2 +- loginserver/server_manager.cpp | 9 ++-- loginserver/server_manager.h | 2 +- loginserver/world_server.cpp | 17 +++---- loginserver/world_server.h | 2 +- 11 files changed, 75 insertions(+), 76 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index ea2951d5f..52b050495 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "login_structures.h" #include "../common/misc_functions.h" #include "../common/eqemu_logsys.h" +#include "../common/string_util.h" extern LoginServer server; @@ -194,6 +195,7 @@ void Client::Handle_Login(const char* data, unsigned int size) char *login_packet_buffer = nullptr; unsigned int db_account_id = 0; + std::string db_loginserver = "eqemu"; std::string db_account_password_hash; std::string outbuffer; @@ -219,54 +221,49 @@ void Client::Handle_Login(const char* data, unsigned int size) bool result = false; if (outbuffer[0] == 0 && outbuffer[1] == 0) { - //if (server.options.IsTokenLoginAllowed()) { - // cred = (&outbuffer[2 + user.length()]); - // result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, user); - //} + if (server.options.IsTokenLoginAllowed()) { + cred = (&outbuffer[2 + user.length()]); + result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, db_loginserver, user); + } } else { - //if (server.options.IsPasswordLoginAllowed()) { - // result = false; - // //cred = (&outbuffer[1 + user.length()]); - // //if (server.db->GetLoginDataFromAccountName(user, db_account_password_hash, db_account_id) == false) { - // // /* If we have auto_create_accounts enabled in the login.ini, we will process the creation of an account on our own*/ - // // if ( - // // server.options.CanAutoCreateAccounts() && - // // server.db->CreateLoginData(user, eqcrypt_hash(user, cred, mode), db_account_id) == true - // // ) { - // // LogF(Logs::General, Logs::Error, "User {0} does not exist in the database, so we created it...", user); - // // result = true; - // // } - // // else { - // // LogF(Logs::General, Logs::Error, "Error logging in, user {0} does not exist in the database.", user); - // // result = false; - // // } - // //} - // //else { - // // if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { - // // result = true; - // // } - // // else { - // // result = false; - // // } - // //} - //} + if (server.options.IsPasswordLoginAllowed()) { + cred = (&outbuffer[1 + user.length()]); + auto components = SplitString(user, '.'); + if (components.size() == 2) { + db_loginserver = components[0]; + user = components[1]; + } + + if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == false) { + + } + else { + if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { + result = true; + } + else { + result = false; + } + } + } } /* Login Accepted */ if (result) { - server.client_manager->RemoveExistingClient(db_account_id); - + server.client_manager->RemoveExistingClient(db_account_id, db_loginserver); + in_addr in; in.s_addr = connection->GetRemoteIP(); - + server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); GenerateKey(); - + account_id = db_account_id; account_name = user; - + loginserver_name = db_loginserver; + EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data; LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer; @@ -275,10 +272,10 @@ void Client::Handle_Login(const char* data, unsigned int size) login_accepted->unknown3 = llrs->unknown3; login_accepted->unknown4 = llrs->unknown4; login_accepted->unknown5 = llrs->unknown5; - + LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct; memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct)); - + login_failed_attempts->failed_attempts = 0; login_failed_attempts->message = 0x01; login_failed_attempts->lsid = db_account_id; @@ -298,22 +295,22 @@ void Client::Handle_Login(const char* data, unsigned int size) login_failed_attempts->unknown11[0] = 0x63; login_failed_attempts->unknown12[0] = 0x01; memcpy(login_failed_attempts->key, key.c_str(), key.size()); - + char encrypted_buffer[80] = { 0 }; auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1); if (rc == nullptr) { LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block"); } - + memcpy(login_accepted->encrypt, encrypted_buffer, 80); - + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } - + connection->QueuePacket(outapp); delete outapp; - + status = cs_logged_in; } else { @@ -358,7 +355,7 @@ void Client::Handle_Play(const char* data) this->play_server_id = (unsigned int)play->ServerNumber; play_sequence_id = sequence_in; play_server_id = server_id_in; - server.server_manager->SendUserToWorldRequest(server_id_in, account_id); + server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name); } void Client::SendServerListPacket(uint32 seq) diff --git a/loginserver/client.h b/loginserver/client.h index 35ba3a1f0..bd8547d9a 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -96,6 +96,11 @@ public: */ unsigned int GetAccountID() const { return account_id; } + /** + * Gets the loginserver name of this client. + */ + std::string GetLoginServerName() const { return loginserver_name; } + /** * Gets the account name of this client. */ diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 04de69e53..569f8c27d 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -124,12 +124,12 @@ void ClientManager::ProcessDisconnect() } } -void ClientManager::RemoveExistingClient(unsigned int account_id) +void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver) { auto iter = clients.begin(); while (iter != clients.end()) { - if ((*iter)->GetAccountID() == account_id) + if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { Log(Logs::General, Logs::Login_Server, "Client attempting to log in and existing client already logged in, removing existing client."); delete (*iter); @@ -142,24 +142,17 @@ void ClientManager::RemoveExistingClient(unsigned int account_id) } } -Client *ClientManager::GetClient(unsigned int account_id) +Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver) { - Client *cur = nullptr; - int count = 0; auto iter = clients.begin(); while (iter != clients.end()) { - if ((*iter)->GetAccountID() == account_id) + if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { - cur = (*iter); - count++; + return (*iter); } ++iter; } - if (count > 1) - { - Log(Logs::General, Logs::Error, "More than one client with a given account_id existed in the client list."); - } - return cur; + return nullptr; } diff --git a/loginserver/client_manager.h b/loginserver/client_manager.h index 7e05737a2..08b1f1b98 100644 --- a/loginserver/client_manager.h +++ b/loginserver/client_manager.h @@ -48,12 +48,12 @@ public: /** * Removes a client with a certain account id. */ - void RemoveExistingClient(unsigned int account_id); + void RemoveExistingClient(unsigned int account_id, const std::string &loginserver); /** * Gets a client (if exists) by their account id. */ - Client *GetClient(unsigned int account_id); + Client *GetClient(unsigned int account_id, const std::string &loginserver); private: /** diff --git a/loginserver/database.h b/loginserver/database.h index 26eb45623..5edfbcbde 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -41,7 +41,7 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver) { return false; } + virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) { return false; } virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; } diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 6e1b2cf12..913468245 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -59,7 +59,7 @@ DatabaseMySQL::~DatabaseMySQL() } } -bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver) +bool DatabaseMySQL::GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) { if (!database) { @@ -70,7 +70,9 @@ bool DatabaseMySQL::GetLoginDataFromAccountName(std::string name, std::string &p MYSQL_ROW row; std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() << " WHERE AccountName = '"; - query << name; + query << EscapeString(name); + query << "' AND AccountLoginserver='"; + query << EscapeString(loginserver); query << "'"; if (mysql_query(database, query.str().c_str()) != 0) diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 6edf0f1ce..42eb9b304 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -57,7 +57,7 @@ public: * Needed for client login procedure. * Returns true if the record was found, false otherwise. */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver); + virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id); virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 0a059ec93..4be55ac98 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -206,18 +206,19 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq return outapp; } -void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id) +void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver) { auto iter = world_servers.begin(); bool found = false; while (iter != world_servers.end()) { if ((*iter)->GetRuntimeID() == server_id) { EQ::Net::DynamicPacket outapp; - outapp.Resize(sizeof(UsertoWorldRequestLegacy_Struct)); - UsertoWorldRequestLegacy_Struct *utwr = (UsertoWorldRequestLegacy_Struct*)outapp.Data(); + outapp.Resize(sizeof(UsertoWorldRequest_Struct)); + UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data(); utwr->worldid = server_id; utwr->lsaccountid = client_account_id; - (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReqLeg, outapp); + strncpy(utwr->login, &client_loginserver[0], 64); + (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp); found = true; if (server.options.IsDumpInPacketsOn()) { diff --git a/loginserver/server_manager.h b/loginserver/server_manager.h index f9a1f66e1..220f40be3 100644 --- a/loginserver/server_manager.h +++ b/loginserver/server_manager.h @@ -45,7 +45,7 @@ public: /** * Sends a request to world to see if the client is banned or suspended. */ - void SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id); + void SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver); /** * Creates a server list packet for the client. diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 02254f223..5561b1964 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -146,7 +146,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct*)p.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); - Client *c = server.client_manager->GetClient(utwr->lsaccountid); + Client *c = server.client_manager->GetClient(utwr->lsaccountid, "eqemu"); if (c) { Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); @@ -161,7 +161,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack if (utwr->response > 0) { per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); + SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName()); } switch (utwr->response) @@ -233,7 +233,7 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); - Client *c = server.client_manager->GetClient(utwr->lsaccountid); + Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); if (c) { Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); @@ -248,7 +248,7 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet if (utwr->response > 0) { per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID()); + SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName()); } switch (utwr->response) @@ -586,16 +586,17 @@ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) server_status = s->status; } -void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id) +void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name) { EQ::Net::DynamicPacket outapp; - ClientAuthLegacy_Struct client_auth; + ClientAuth_Struct client_auth; client_auth.lsaccount_id = account_id; strncpy(client_auth.name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); client_auth.lsadmin = 0; client_auth.worldadmin = 0; client_auth.ip = inet_addr(ip.c_str()); + strncpy(client_auth.lsname, &loginserver_name[0], 64); std::string client_address(ip); std::string world_address(connection->Handle()->RemoteIP()); @@ -611,10 +612,10 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin } outapp.PutSerialize(0, client_auth); - connection->Send(ServerOP_LSClientAuthLeg, outapp); + connection->Send(ServerOP_LSClientAuth, outapp); if (server.options.IsDumpInPacketsOn()) { - DumpPacket(ServerOP_LSClientAuthLeg, outapp); + DumpPacket(ServerOP_LSClientAuth, outapp); } } diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 83c42d27f..9e295a5fd 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -124,7 +124,7 @@ public: /** * Informs world that there is a client incoming with the following data. */ - void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id); + void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name); private: From 3ee573089073899a5271f9eb5e4dce0b9acd1384 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 14 Dec 2017 18:41:10 -0800 Subject: [PATCH 004/491] Auto link ls accounts plus auto-create --- loginserver/client.cpp | 352 +++++++++++++++++++++++++-------- loginserver/client.h | 48 ++++- loginserver/database.h | 4 +- loginserver/database_mysql.cpp | 63 +++++- loginserver/database_mysql.h | 6 +- loginserver/main.cpp | 19 ++ loginserver/options.h | 12 ++ 7 files changed, 410 insertions(+), 94 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 52b050495..3e7c282b9 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -17,10 +17,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "client.h" #include "login_server.h" -#include "login_structures.h" #include "../common/misc_functions.h" #include "../common/eqemu_logsys.h" #include "../common/string_util.h" +#include "encryption.h" extern LoginServer server; @@ -192,6 +192,11 @@ void Client::Handle_Login(const char* data, unsigned int size) return; } + if (size < sizeof(LoginLoginRequest_Struct)) { + Log(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a buffer overflow, discarding.", size); + return; + } + char *login_packet_buffer = nullptr; unsigned int db_account_id = 0; @@ -219,6 +224,8 @@ void Client::Handle_Login(const char* data, unsigned int size) return; } + memcpy(&llrs, data, sizeof(LoginLoginRequest_Struct)); + bool result = false; if (outbuffer[0] == 0 && outbuffer[1] == 0) { if (server.options.IsTokenLoginAllowed()) { @@ -236,7 +243,9 @@ void Client::Handle_Login(const char* data, unsigned int size) } if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == false) { - + status = cs_creating_account; + AttemptLoginAccountCreation(user, cred, db_loginserver); + return; } else { if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { @@ -251,87 +260,10 @@ void Client::Handle_Login(const char* data, unsigned int size) /* Login Accepted */ if (result) { - - server.client_manager->RemoveExistingClient(db_account_id, db_loginserver); - - in_addr in; - in.s_addr = connection->GetRemoteIP(); - - server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); - GenerateKey(); - - account_id = db_account_id; - account_name = user; - loginserver_name = db_loginserver; - - EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); - const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data; - LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer; - login_accepted->unknown1 = llrs->unknown1; - login_accepted->unknown2 = llrs->unknown2; - login_accepted->unknown3 = llrs->unknown3; - login_accepted->unknown4 = llrs->unknown4; - login_accepted->unknown5 = llrs->unknown5; - - LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct; - memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct)); - - login_failed_attempts->failed_attempts = 0; - login_failed_attempts->message = 0x01; - login_failed_attempts->lsid = db_account_id; - login_failed_attempts->unknown3[3] = 0x03; - login_failed_attempts->unknown4[3] = 0x02; - login_failed_attempts->unknown5[0] = 0xe7; - login_failed_attempts->unknown5[1] = 0x03; - login_failed_attempts->unknown6[0] = 0xff; - login_failed_attempts->unknown6[1] = 0xff; - login_failed_attempts->unknown6[2] = 0xff; - login_failed_attempts->unknown6[3] = 0xff; - login_failed_attempts->unknown7[0] = 0xa0; - login_failed_attempts->unknown7[1] = 0x05; - login_failed_attempts->unknown8[3] = 0x02; - login_failed_attempts->unknown9[0] = 0xff; - login_failed_attempts->unknown9[1] = 0x03; - login_failed_attempts->unknown11[0] = 0x63; - login_failed_attempts->unknown12[0] = 0x01; - memcpy(login_failed_attempts->key, key.c_str(), key.size()); - - char encrypted_buffer[80] = { 0 }; - auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1); - if (rc == nullptr) { - LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block"); - } - - memcpy(login_accepted->encrypt, encrypted_buffer, 80); - - if (server.options.IsDumpOutPacketsOn()) { - DumpPacket(outapp); - } - - connection->QueuePacket(outapp); - delete outapp; - - status = cs_logged_in; + DoSuccessfulLogin(user, db_account_id, db_loginserver); } else { - EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); - const LoginLoginRequest_Struct* llrs = (const LoginLoginRequest_Struct *)data; - LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp->pBuffer; - llas->unknown1 = llrs->unknown1; - llas->unknown2 = llrs->unknown2; - llas->unknown3 = llrs->unknown3; - llas->unknown4 = llrs->unknown4; - llas->unknown5 = llrs->unknown5; - memcpy(llas->unknown6, FailedLoginResponseData, sizeof(FailedLoginResponseData)); - - if (server.options.IsDumpOutPacketsOn()) { - DumpPacket(outapp); - } - - connection->QueuePacket(outapp); - delete outapp; - - status = cs_failed_to_login; + DoFailedLogin(); } } @@ -400,3 +332,261 @@ void Client::GenerateKey() count++; } } + +void Client::AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver) +{ + if (loginserver == "eqemu") { + if (!server.options.CanAutoCreateAccounts()) { + DoFailedLogin(); + return; + } + + if (server.options.GetEQEmuLoginServerAddress().length() == 0) { + DoFailedLogin(); + return; + } + + auto addr_components = SplitString(server.options.GetEQEmuLoginServerAddress(), ':'); + if (addr_components.size() != 2) { + DoFailedLogin(); + return; + } + + stored_user = user; + stored_pass = pass; + + auto address = addr_components[0]; + auto port = std::stoi(addr_components[1]); + EQ::Net::DNSLookup(address, port, false, [=](const std::string &addr) { + if (addr.empty()) { + DoFailedLogin(); + return; + } + + login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager()); + login_connection_manager->OnNewConnection(std::bind(&Client::LoginOnNewConnection, this, std::placeholders::_1)); + login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + login_connection_manager->OnPacketRecv(std::bind(&Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); + + login_connection_manager->Connect(addr, port); + }); + } + else { + if (!server.options.CanAutoCreateAccounts()) { + DoFailedLogin(); + return; + } + + CreateLocalAccount(user, pass); + } +} + +void Client::DoFailedLogin() +{ + stored_user.clear(); + stored_pass.clear(); + + EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); + LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp.pBuffer; + llas->unknown1 = llrs.unknown1; + llas->unknown2 = llrs.unknown2; + llas->unknown3 = llrs.unknown3; + llas->unknown4 = llrs.unknown4; + llas->unknown5 = llrs.unknown5; + memcpy(llas->unknown6, FailedLoginResponseData, sizeof(FailedLoginResponseData)); + + if (server.options.IsDumpOutPacketsOn()) { + DumpPacket(&outapp); + } + + connection->QueuePacket(&outapp); + status = cs_failed_to_login; +} + +void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver) +{ + stored_user.clear(); + stored_pass.clear(); + + server.client_manager->RemoveExistingClient(db_account_id, db_loginserver); + + in_addr in; + in.s_addr = connection->GetRemoteIP(); + + server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); + GenerateKey(); + + account_id = db_account_id; + account_name = user; + loginserver_name = db_loginserver; + + EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); + LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer; + login_accepted->unknown1 = llrs.unknown1; + login_accepted->unknown2 = llrs.unknown2; + login_accepted->unknown3 = llrs.unknown3; + login_accepted->unknown4 = llrs.unknown4; + login_accepted->unknown5 = llrs.unknown5; + + LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct; + memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct)); + + login_failed_attempts->failed_attempts = 0; + login_failed_attempts->message = 0x01; + login_failed_attempts->lsid = db_account_id; + login_failed_attempts->unknown3[3] = 0x03; + login_failed_attempts->unknown4[3] = 0x02; + login_failed_attempts->unknown5[0] = 0xe7; + login_failed_attempts->unknown5[1] = 0x03; + login_failed_attempts->unknown6[0] = 0xff; + login_failed_attempts->unknown6[1] = 0xff; + login_failed_attempts->unknown6[2] = 0xff; + login_failed_attempts->unknown6[3] = 0xff; + login_failed_attempts->unknown7[0] = 0xa0; + login_failed_attempts->unknown7[1] = 0x05; + login_failed_attempts->unknown8[3] = 0x02; + login_failed_attempts->unknown9[0] = 0xff; + login_failed_attempts->unknown9[1] = 0x03; + login_failed_attempts->unknown11[0] = 0x63; + login_failed_attempts->unknown12[0] = 0x01; + memcpy(login_failed_attempts->key, key.c_str(), key.size()); + + char encrypted_buffer[80] = { 0 }; + auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1); + if (rc == nullptr) { + LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block"); + } + + memcpy(login_accepted->encrypt, encrypted_buffer, 80); + + if (server.options.IsDumpOutPacketsOn()) { + DumpPacket(outapp); + } + + connection->QueuePacket(outapp); + delete outapp; + + status = cs_logged_in; +} + +void Client::CreateLocalAccount(const std::string &user, const std::string &pass) +{ + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(user, pass, mode); + + unsigned int db_id = 0; + std::string db_login = server.options.GetDefaultLoginServerName(); + if (!server.db->CreateLoginData(user, hash, db_login, db_id)) { + DoFailedLogin(); + } + else { + DoSuccessfulLogin(user, db_id, db_login); + } +} + +void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id) +{ + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(user, pass, mode); + + if (!server.db->CreateLoginDataWithID(user, hash, "eqemu", id)) { + DoFailedLogin(); + } + else { + DoSuccessfulLogin(user, id, "eqemu"); + } +} + +void Client::LoginOnNewConnection(std::shared_ptr connection) +{ + login_connection = connection; +} + +void Client::LoginOnStatusChange(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) +{ + if (to == EQ::Net::StatusConnected) { + LoginSendSessionReady(); + } + + if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) { + DoFailedLogin(); + } +} + +void Client::LoginOnStatusChangeIgnored(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) +{ +} + +void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet & p) +{ + auto opcode = p.GetUInt16(0); + switch (opcode) { + case 0x0017: //OP_ChatMessage + LoginSendLogin(); + break; + case 0x0018: + LoginProcessLoginResponse(p); + break; + } +} + +void Client::LoginSendSessionReady() +{ + EQ::Net::DynamicPacket p; + p.PutUInt16(0, 1); //OP_SessionReady + p.PutUInt32(2, 2); + + login_connection->QueuePacket(p); +} + +void Client::LoginSendLogin() +{ + size_t buffer_len = stored_user.length() + stored_pass.length() + 2; + std::unique_ptr buffer(new char[buffer_len]); + + strcpy(&buffer[0], stored_user.c_str()); + strcpy(&buffer[stored_user.length() + 1], stored_pass.c_str()); + + size_t encrypted_len = buffer_len; + + if (encrypted_len % 8 > 0) { + encrypted_len = ((encrypted_len / 8) + 1) * 8; + } + + EQ::Net::DynamicPacket p; + p.Resize(12 + encrypted_len); + p.PutUInt16(0, 2); //OP_Login + p.PutUInt32(2, 3); + + eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true); + + login_connection->QueuePacket(p); +} + +void Client::LoginProcessLoginResponse(const EQ::Net::Packet & p) +{ + auto encrypt_size = p.Length() - 12; + if (encrypt_size % 8 > 0) { + encrypt_size = (encrypt_size / 8) * 8; + } + + std::unique_ptr decrypted(new char[encrypt_size]); + + eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false); + + EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); + auto response_error = sp.GetUInt16(1); + + login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChangeIgnored, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + + if (response_error > 101) { + DoFailedLogin(); + login_connection->Close(); + } + else { + auto m_dbid = sp.GetUInt32(8); + + CreateEQEmuAccount(stored_user, stored_pass, m_dbid); + login_connection->Close(); + } +} diff --git a/loginserver/client.h b/loginserver/client.h index bd8547d9a..0271ec545 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -21,9 +21,13 @@ #include "../common/global_define.h" #include "../common/opcodemgr.h" #include "../common/random.h" +#include "../common/eq_stream_intf.h" +#include "../common/net/dns.h" +#include "../common/net/daybreak_connection.h" + +#include "login_structures.h" #include -#include "../common/eq_stream_intf.h" enum LSClientVersion { @@ -35,6 +39,7 @@ enum LSClientStatus { cs_not_sent_session_ready, cs_waiting_for_login, + cs_creating_account, cs_failed_to_login, cs_logged_in }; @@ -126,8 +131,33 @@ public: */ std::shared_ptr GetConnection() { return connection; } - EQEmu::Random random; + /** + * Attempts to create a login account + */ + void AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver); + + /** + * Does a failed login + */ + void DoFailedLogin(); + + /** + * Does a successful login + */ + void DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver); + + /** + * Creates a local account + */ + void CreateLocalAccount(const std::string &user, const std::string &pass); + + /** + * Creates an eqemu account + */ + void CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id); + private: + EQEmu::Random random; std::shared_ptr connection; LSClientVersion version; LSClientStatus status; @@ -138,6 +168,20 @@ private: unsigned int play_server_id; unsigned int play_sequence_id; std::string key; + + std::unique_ptr login_connection_manager; + std::shared_ptr login_connection; + LoginLoginRequest_Struct llrs; + + std::string stored_user; + std::string stored_pass; + void LoginOnNewConnection(std::shared_ptr connection); + void LoginOnStatusChange(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); + void LoginOnStatusChangeIgnored(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); + void LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p); + void LoginSendSessionReady(); + void LoginSendLogin(); + void LoginProcessLoginResponse(const EQ::Net::Packet &p); }; #endif diff --git a/loginserver/database.h b/loginserver/database.h index 5edfbcbde..0025cd476 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -45,7 +45,9 @@ public: virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; } - virtual bool CreateLoginData(const std::string &name, const std::string &password, unsigned int &id) { return false; } + virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) { return false; } + + virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id) { return false; } /** * Retrieves the world registration from the long and short names provided. diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 913468245..9781ec4df 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -152,30 +152,75 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const s return found_username && found_login_id && found_login_server_name; } -bool DatabaseMySQL::CreateLoginData(const std::string &name, const std::string &password, unsigned int &id) +unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) +{ + if (!database) + { + return false; + } + + MYSQL_RES *res; + MYSQL_ROW row; + std::stringstream query(std::stringstream::in | std::stringstream::out); + query << "SELECT MAX(LoginServerID) + 1 FROM " << server.options.GetAccountTable() << " WHERE AccountLoginServer='"; + query << EscapeString(loginserver) << "'"; + + if (mysql_query(database, query.str().c_str()) != 0) + { + Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); + return 0; + } + + res = mysql_use_result(database); + + if (res) + { + while ((row = mysql_fetch_row(res)) != nullptr) + { + if (row[0] == nullptr) { + mysql_free_result(res); + return 1; + } + + auto ret = atol(row[0]); + mysql_free_result(res); + return ret; + } + + mysql_free_result(res); + } + + return 1; +} + +bool DatabaseMySQL::CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) +{ + return CreateLoginDataWithID(name, password, loginserver, GetFreeID(loginserver)); +} + +bool DatabaseMySQL::CreateLoginDataWithID(const std::string & name, const std::string & password, const std::string & loginserver, unsigned int id) { if (!database) { return false; } + if (id == 0) { + return false; + } + MYSQL_RES *result; MYSQL_ROW row; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "INSERT INTO " << server.options.GetAccountTable() << " (AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; - query << " VALUES('" << name << "', '" << password << "', 'local_creation', NOW(), '127.0.0.1'); "; + query << "INSERT INTO " << server.options.GetAccountTable() << " (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; + query << " VALUES(" << id << ", '" << EscapeString(loginserver) << "', '" << EscapeString(name) << "', '" << EscapeString(password) << "', 'local_creation', NOW(), '127.0.0.1'); "; if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } - else { - id = mysql_insert_id(database); - return true; - } - Log(Logs::General, Logs::Error, "Mysql query returned no result: %s", query.str().c_str()); - return false; + return true; } bool DatabaseMySQL::GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 42eb9b304..41eac0eb5 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -61,7 +61,11 @@ public: virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user); - virtual bool CreateLoginData(const std::string &name, const std::string &password, unsigned int &id); + virtual unsigned int GetFreeID(const std::string &loginserver); + + virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id); + + virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id); /** * Retrieves the world registration from the long and short names provided. diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 7fd047903..17cc179e5 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -71,12 +71,31 @@ int main() if (server.config->GetVariable("security", "allow_token_login").compare("TRUE") == 0) server.options.AllowTokenLogin(true); + auto eqemu_loginserver_addr = server.config->GetVariable("options", "eqemu_loginserver_address"); + if (eqemu_loginserver_addr.size() > 0) { + server.options.EQEmuLoginServerAddress(eqemu_loginserver_addr); + } + else { + server.options.EQEmuLoginServerAddress("login.eqemulator.net:5999"); + } + + auto default_loginserver_name = server.config->GetVariable("options", "default_loginserver_name"); + if (default_loginserver_name.size() > 0) { + server.options.DefaultLoginServerName(default_loginserver_name); + } + else { + server.options.DefaultLoginServerName("peq"); + } + if (server.config->GetVariable("security", "allow_password_login").compare("FALSE") == 0) server.options.AllowPasswordLogin(false); if (server.config->GetVariable("options", "auto_create_accounts").compare("TRUE") == 0) server.options.AutoCreateAccounts(true); + if (server.config->GetVariable("options", "auto_link_accounts").compare("TRUE") == 0) + server.options.AutoLinkAccounts(true); + std::string mode = server.config->GetVariable("security", "mode"); if (mode.size() > 0) server.options.EncryptionMode(atoi(mode.c_str())); diff --git a/loginserver/options.h b/loginserver/options.h index f215e443b..a89d3f760 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -169,6 +169,15 @@ public: inline void AutoCreateAccounts(bool b) { auto_create_accounts = b; } inline bool CanAutoCreateAccounts() const { return auto_create_accounts; } + inline void AutoLinkAccounts(bool b) { auto_link_accounts = b; } + inline bool CanAutoLinkAccounts() const { return auto_link_accounts; } + + inline void EQEmuLoginServerAddress(std::string v) { eqemu_loginserver_address = v; } + inline std::string GetEQEmuLoginServerAddress() const { return eqemu_loginserver_address; } + + inline void DefaultLoginServerName(std::string v) { default_loginserver_name = v; } + inline std::string GetDefaultLoginServerName() const { return default_loginserver_name; } + private: bool allow_unregistered; bool trace; @@ -179,12 +188,15 @@ private: bool allow_token_login; bool allow_password_login; bool auto_create_accounts; + bool auto_link_accounts; int encryption_mode; std::string local_network; std::string account_table; std::string world_registration_table; std::string world_admin_registration_table; std::string world_server_type_table; + std::string eqemu_loginserver_address; + std::string default_loginserver_name; }; #endif From 7a778c549fa58e00457f38351397ee874b0c7252 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 16 Dec 2017 23:08:21 -0800 Subject: [PATCH 005/491] convert login.ini to login.json, stole jumber's idea about auto-updating old passwords (wip still) --- common/json_config.cpp | 1 + common/json_config.h | 2 +- loginserver/CMakeLists.txt | 2 - loginserver/client.cpp | 35 +++++++++- loginserver/client_manager.cpp | 12 ++-- loginserver/database.h | 2 + loginserver/database_mysql.cpp | 19 ++++++ loginserver/database_mysql.h | 2 + loginserver/encryption.cpp | 16 ++--- loginserver/login_server.h | 6 +- loginserver/main.cpp | 115 +++++++++------------------------ loginserver/options.h | 4 ++ loginserver/server_manager.cpp | 2 +- world/console.cpp | 4 +- 14 files changed, 110 insertions(+), 112 deletions(-) diff --git a/common/json_config.cpp b/common/json_config.cpp index d677fc452..c9599b99d 100644 --- a/common/json_config.cpp +++ b/common/json_config.cpp @@ -3,6 +3,7 @@ EQ::JsonConfigFile::JsonConfigFile() { + } EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value) diff --git a/common/json_config.h b/common/json_config.h index 279fb64d9..ba1051970 100644 --- a/common/json_config.h +++ b/common/json_config.h @@ -7,6 +7,7 @@ namespace EQ class JsonConfigFile { public: + JsonConfigFile(); JsonConfigFile(const Json::Value &value); ~JsonConfigFile(); @@ -19,7 +20,6 @@ namespace EQ Json::Value& RawHandle() { return m_root; } private: - JsonConfigFile(); Json::Value m_root; }; diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 1561aa537..3af0c7e66 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -3,7 +3,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(eqlogin_sources client.cpp client_manager.cpp - config.cpp database_mysql.cpp encryption.cpp main.cpp @@ -14,7 +13,6 @@ SET(eqlogin_sources SET(eqlogin_headers client.h client_manager.h - config.h database.h database_mysql.h encryption.h diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 3e7c282b9..0db9c1600 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -251,8 +251,37 @@ void Client::Handle_Login(const char* data, unsigned int size) if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { result = true; } - else { - result = false; + else + { + if (server.options.IsUpdatingInsecurePasswords()) { + auto len = db_account_password_hash.length(); + int start = 0; + int end = 0; + switch (len) { + case 32: + start = 1; + end = 4; + break; + case 40: + start = 5; + end = 8; + break; + case 128: + start = 9; + end = 12; + break; + } + + if (start != 0) { + for (int i = start; i <= end; ++i) { + if (eqcrypt_verify_hash(user, cred, db_account_password_hash, i)) { + result = true; + server.db->UpdateLoginHash(user, db_loginserver, eqcrypt_hash(user, cred, mode)); + break; + } + } + } + } } } } @@ -336,7 +365,7 @@ void Client::GenerateKey() void Client::AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver) { if (loginserver == "eqemu") { - if (!server.options.CanAutoCreateAccounts()) { + if (!server.options.CanAutoLinkAccounts()) { DoFailedLogin(); return; } diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 569f8c27d..532f65032 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -25,14 +25,14 @@ extern bool run_server; ClientManager::ClientManager() { - int titanium_port = atoi(server.config->GetVariable("Titanium", "port").c_str()); + int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); EQ::Net::EQStreamManagerOptions titanium_opts(titanium_port, false, false); titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); titanium_ops = new RegularOpcodeManager; - if (!titanium_ops->LoadOpcodes(server.config->GetVariable("Titanium", "opcodes").c_str())) + if (!titanium_ops->LoadOpcodes(server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str())) { Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for Titanium file %s.", - server.config->GetVariable("Titanium", "opcodes").c_str()); + server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str()); run_server = false; } @@ -43,14 +43,14 @@ ClientManager::ClientManager() clients.push_back(c); }); - int sod_port = atoi(server.config->GetVariable("SoD", "port").c_str()); + int sod_port = server.config.GetVariableInt("SoD", "port", 5999); EQ::Net::EQStreamManagerOptions sod_opts(sod_port, false, false); sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; - if (!sod_ops->LoadOpcodes(server.config->GetVariable("SoD", "opcodes").c_str())) + if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) { Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for SoD file %s.", - server.config->GetVariable("SoD", "opcodes").c_str()); + server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str()); run_server = false; } diff --git a/loginserver/database.h b/loginserver/database.h index 0025cd476..00a76b099 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -49,6 +49,8 @@ public: virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id) { return false; } + virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { } + /** * Retrieves the world registration from the long and short names provided. * Needed for world login procedure. diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 9781ec4df..0787110a9 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -223,6 +223,25 @@ bool DatabaseMySQL::CreateLoginDataWithID(const std::string & name, const std::s return true; } +void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) +{ + if (!database) + { + return; + } + + auto query = fmt::format("UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", + server.options.GetAccountTable(), + hash, + EscapeString(name), + EscapeString(loginserver)); + + if (mysql_query(database, query.c_str()) != 0) + { + Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.c_str()); + } +} + bool DatabaseMySQL::GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) { diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 41eac0eb5..60e8290cf 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -67,6 +67,8 @@ public: virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id); + virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + /** * Retrieves the world registration from the long and short names provided. * Needed for world login procedure. diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index c8e688e5f..bdbab2fbf 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -74,27 +74,25 @@ std::string eqcrypt_sha512(const std::string &msg) { std::string eqcrypt_argon2(const std::string &msg) { - std::string ret; - ret.resize(crypto_pwhash_STRBYTES); + char buffer[crypto_pwhash_STRBYTES]; - if (crypto_pwhash_str(&ret[0], &msg[0], msg.length(), crypto_pwhash_OPSLIMIT_SENSITIVE, crypto_pwhash_MEMLIMIT_SENSITIVE) != 0) { + if (crypto_pwhash_str(&buffer[0], &msg[0], msg.length(), crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE) != 0) { return ""; } - return ret; + return buffer; } std::string eqcrypt_scrypt(const std::string &msg) { - std::string ret; - ret.resize(crypto_pwhash_scryptsalsa208sha256_STRBYTES); + char buffer[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; - if (crypto_pwhash_scryptsalsa208sha256_str(&ret[0], &msg[0], msg.length(), - crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE) != 0) { + if (crypto_pwhash_scryptsalsa208sha256_str(&buffer[0], &msg[0], msg.length(), + crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { return ""; } - return ret; + return buffer; } #endif diff --git a/loginserver/login_server.h b/loginserver/login_server.h index a5d780ebb..111565dbb 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -18,7 +18,7 @@ #ifndef EQEMU_LOGINSERVER_H #define EQEMU_LOGINSERVER_H -#include "config.h" +#include "../common/json_config.h" #include "database.h" #include "database_mysql.h" #include "encryption.h" @@ -33,9 +33,9 @@ struct LoginServer { public: - LoginServer() : config(nullptr), db(nullptr), server_manager(nullptr) { } + LoginServer() : db(nullptr), server_manager(nullptr) { } - Config *config; + EQ::JsonConfigFile config; Database *db; Options options; ServerManager *server_manager; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 17cc179e5..b2603056a 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -48,99 +48,51 @@ int main() Log(Logs::General, Logs::Login_Server, "Logging System Init."); - /* Parse out login.ini */ - server.config = new Config(); + server.config = EQ::JsonConfigFile::Load("login.json"); Log(Logs::General, Logs::Login_Server, "Config System Init."); - server.config->Parse("login.ini"); - if (server.config->GetVariable("options", "unregistered_allowed").compare("FALSE") == 0) - server.options.AllowUnregistered(false); + server.options.Trace(server.config.GetVariableBool("general", "trace", false)); + server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); + server.options.DumpInPackets(server.config.GetVariableBool("general", "dump_packets_in", false)); + server.options.DumpOutPackets(server.config.GetVariableBool("general", "dump_packets_out", false)); + server.options.LocalNetwork(server.config.GetVariableString("general", "local_network", "192.168.1.")); + server.options.RejectDuplicateServers(server.config.GetVariableBool("general", "reject_duplicate_servers", false)); + server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); + server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", true)); + server.options.EQEmuLoginServerAddress(server.config.GetVariableString("general", "eqemu_loginserver_address", "login.eqemulator.net:5999")); + server.options.DefaultLoginServerName(server.config.GetVariableString("general", "default_loginserver_name", "peq")); - if (server.config->GetVariable("options", "trace").compare("TRUE") == 0) - server.options.Trace(true); +#ifdef ENABLE_SECURITY + server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13)); +#else + server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6)); +#endif + server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true)); + server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false)); + server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true)); + server.options.UpdateInsecurePasswords(server.config.GetVariableBool("security", "update_insecure_passwords", true)); - if (server.config->GetVariable("options", "world_trace").compare("TRUE") == 0) - server.options.WorldTrace(true); - - if (server.config->GetVariable("options", "dump_packets_in").compare("TRUE") == 0) - server.options.DumpInPackets(true); - - if (server.config->GetVariable("options", "dump_packets_out").compare("TRUE") == 0) - server.options.DumpOutPackets(true); - - if (server.config->GetVariable("security", "allow_token_login").compare("TRUE") == 0) - server.options.AllowTokenLogin(true); - - auto eqemu_loginserver_addr = server.config->GetVariable("options", "eqemu_loginserver_address"); - if (eqemu_loginserver_addr.size() > 0) { - server.options.EQEmuLoginServerAddress(eqemu_loginserver_addr); - } - else { - server.options.EQEmuLoginServerAddress("login.eqemulator.net:5999"); - } - - auto default_loginserver_name = server.config->GetVariable("options", "default_loginserver_name"); - if (default_loginserver_name.size() > 0) { - server.options.DefaultLoginServerName(default_loginserver_name); - } - else { - server.options.DefaultLoginServerName("peq"); - } - - if (server.config->GetVariable("security", "allow_password_login").compare("FALSE") == 0) - server.options.AllowPasswordLogin(false); - - if (server.config->GetVariable("options", "auto_create_accounts").compare("TRUE") == 0) - server.options.AutoCreateAccounts(true); - - if (server.config->GetVariable("options", "auto_link_accounts").compare("TRUE") == 0) - server.options.AutoLinkAccounts(true); - - std::string mode = server.config->GetVariable("security", "mode"); - if (mode.size() > 0) - server.options.EncryptionMode(atoi(mode.c_str())); - - std::string local_network = server.config->GetVariable("options", "local_network"); - if (local_network.size() > 0) - server.options.LocalNetwork(local_network); - - if (server.config->GetVariable("options", "reject_duplicate_servers").compare("TRUE") == 0) - server.options.RejectDuplicateServers(true); - - local_network = server.config->GetVariable("schema", "account_table"); - if (local_network.size() > 0) - server.options.AccountTable(local_network); - - local_network = server.config->GetVariable("schema", "world_registration_table"); - if (local_network.size() > 0) - server.options.WorldRegistrationTable(local_network); - - local_network = server.config->GetVariable("schema", "world_admin_registration_table"); - if (local_network.size() > 0) - server.options.WorldAdminRegistrationTable(local_network); - - local_network = server.config->GetVariable("schema", "world_server_type_table"); - if (local_network.size() > 0) - server.options.WorldServerTypeTable(local_network); + server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); + server.options.WorldRegistrationTable(server.config.GetVariableString("schema", "account_table", "tblWorldServerRegistration")); + server.options.WorldAdminRegistrationTable(server.config.GetVariableString("schema", "account_table", "tblServerAdminRegistration")); + server.options.WorldServerTypeTable(server.config.GetVariableString("schema", "account_table", "tblServerListType")); /* Create database connection */ - if (server.config->GetVariable("database", "subsystem").compare("MySQL") == 0) { + if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) { #ifdef EQEMU_MYSQL_ENABLED Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); server.db = (Database*)new DatabaseMySQL( - server.config->GetVariable("database", "user"), - server.config->GetVariable("database", "password"), - server.config->GetVariable("database", "host"), - server.config->GetVariable("database", "port"), - server.config->GetVariable("database", "db")); + server.config.GetVariableString("database", "user", "root"), + server.config.GetVariableString("database", "password", ""), + server.config.GetVariableString("database", "host", "localhost"), + server.config.GetVariableString("database", "port", "3306"), + server.config.GetVariableString("database", "db", "peq")); #endif } /* Make sure our database got created okay, otherwise cleanup and exit. */ if (!server.db) { Log(Logs::General, Logs::Error, "Database Initialization Failure."); - Log(Logs::General, Logs::Login_Server, "Config System Shutdown."); - delete server.config; Log(Logs::General, Logs::Login_Server, "Log System Shutdown."); return 1; } @@ -151,11 +103,8 @@ int main() if (!server.server_manager) { //We can't run without a server manager, cleanup and exit. Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); - Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); delete server.db; - Log(Logs::General, Logs::Login_Server, "Config System Shutdown."); - delete server.config; return 1; } @@ -170,8 +119,6 @@ int main() Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); delete server.db; - Log(Logs::General, Logs::Login_Server, "Config System Shutdown."); - delete server.config; return 1; } @@ -199,7 +146,5 @@ int main() Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); delete server.db; - Log(Logs::General, Logs::Login_Server, "Config System Shutdown."); - delete server.config; return 0; } diff --git a/loginserver/options.h b/loginserver/options.h index a89d3f760..067c911ec 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -178,6 +178,9 @@ public: inline void DefaultLoginServerName(std::string v) { default_loginserver_name = v; } inline std::string GetDefaultLoginServerName() const { return default_loginserver_name; } + inline void UpdateInsecurePasswords(bool b) { update_insecure_passwords = b; } + inline bool IsUpdatingInsecurePasswords() const { return update_insecure_passwords; } + private: bool allow_unregistered; bool trace; @@ -189,6 +192,7 @@ private: bool allow_password_login; bool auto_create_accounts; bool auto_link_accounts; + bool update_insecure_passwords; int encryption_mode; std::string local_network; std::string account_table; diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 4be55ac98..94c7705fc 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -27,7 +27,7 @@ extern bool run_server; ServerManager::ServerManager() { - int listen_port = atoi(server.config->GetVariable("options", "listen_port").c_str()); + int listen_port = server.config.GetVariableInt("general", "listen_port", 5998); server_connection.reset(new EQ::Net::ServertalkServer()); EQ::Net::ServertalkServerOptions opts; diff --git a/world/console.cpp b/world/console.cpp index ab7097244..8342b2e3c 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -19,7 +19,7 @@ struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string& username, const std::string prefix = "eqemu"; std::string raw_user = ""; - auto split = SplitString(username, ':'); + auto split = SplitString(username, '.'); if (split.size() == 2) { prefix = split[0]; raw_user = split[1]; @@ -399,7 +399,7 @@ void ConsoleSetPass(EQ::Net::ConsoleServerConnection* connection, const std::str std::string prefix = "eqemu"; std::string raw_user = ""; - auto split = SplitString(args[0], ':'); + auto split = SplitString(args[0], '.'); if (split.size() == 2) { prefix = split[0]; raw_user = split[1]; From 0ec53eff5243ecf85512d60155350bad01a43ba3 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 24 Dec 2017 23:21:17 -0800 Subject: [PATCH 006/491] Reimplement some functions --- common/database.cpp | 2 +- common/database.h | 2 +- common/string_util.cpp | 13 ++++ common/string_util.h | 1 + loginserver/client.cpp | 84 +++++++++++++----------- loginserver/client.h | 5 ++ loginserver/encryption.cpp | 30 +++++---- loginserver/encryption.h | 18 ++++++ world/console.cpp | 18 +----- world/net.cpp | 40 ++++++------ zone/command.cpp | 128 ++++++++++++++++++++----------------- 11 files changed, 195 insertions(+), 146 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 8926ed4de..160a6a7ff 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -224,7 +224,7 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta return results.LastInsertedID(); } -bool Database::DeleteAccount(const char *loginserver, const char* name) { +bool Database::DeleteAccount(const char* name, const char *loginserver) { std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver); Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s:%s'", loginserver, name); diff --git a/common/database.h b/common/database.h index 471e59a31..b32739f9d 100644 --- a/common/database.h +++ b/common/database.h @@ -174,7 +174,7 @@ public: /* Account Related */ - bool DeleteAccount(const char *loginserver, const char* name); + bool DeleteAccount(const char *name, const char* loginserver); bool GetLiveChar(uint32 account_id, char* cname); bool SetAccountStatus(const char* name, int16 status); bool SetLocalPassword(uint32 accid, const char* password); diff --git a/common/string_util.cpp b/common/string_util.cpp index 3e9986b48..74d5ea0c7 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -196,6 +196,19 @@ void find_replace(std::string& string_subject, const std::string& search_string, } } +void ParseAccountString(const std::string &s, std::string &account, std::string &loginserver) +{ + auto split = SplitString(s, '.'); + if (split.size() == 2) { + loginserver = split[0]; + account = split[1]; + } + else if(split.size() == 1) { + loginserver = "eqemu"; + account = split[0]; + } +} + //Const char based // normal strncpy doesnt put a null term on copied strings, this one does diff --git a/common/string_util.h b/common/string_util.h index 0db8ff2c9..636a7e352 100644 --- a/common/string_util.h +++ b/common/string_util.h @@ -34,6 +34,7 @@ void ToLowerString(std::string &s); void ToUpperString(std::string &s); std::string JoinString(const std::vector& ar, const std::string &delim); void find_replace(std::string& string_subject, const std::string& search_string, const std::string& replace_string); +void ParseAccountString(const std::string &s, std::string &account, std::string &loginserver); //const char based diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 0db9c1600..aae1e9f3e 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -180,8 +180,6 @@ void Client::Handle_SessionReady(const char* data, unsigned int size) void Client::Handle_Login(const char* data, unsigned int size) { - auto mode = server.options.GetEncryptionMode(); - if (status != cs_waiting_for_login) { Log(Logs::General, Logs::Error, "Login received after already having logged in."); return; @@ -241,6 +239,8 @@ void Client::Handle_Login(const char* data, unsigned int size) db_loginserver = components[0]; user = components[1]; } + + ParseAccountString(user, user, db_loginserver); if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == false) { status = cs_creating_account; @@ -248,41 +248,7 @@ void Client::Handle_Login(const char* data, unsigned int size) return; } else { - if (eqcrypt_verify_hash(user, cred, db_account_password_hash, mode)) { - result = true; - } - else - { - if (server.options.IsUpdatingInsecurePasswords()) { - auto len = db_account_password_hash.length(); - int start = 0; - int end = 0; - switch (len) { - case 32: - start = 1; - end = 4; - break; - case 40: - start = 5; - end = 8; - break; - case 128: - start = 9; - end = 12; - break; - } - - if (start != 0) { - for (int i = start; i <= end; ++i) { - if (eqcrypt_verify_hash(user, cred, db_account_password_hash, i)) { - result = true; - server.db->UpdateLoginHash(user, db_loginserver, eqcrypt_hash(user, cred, mode)); - break; - } - } - } - } - } + result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); } } } @@ -432,6 +398,50 @@ void Client::DoFailedLogin() status = cs_failed_to_login; } +bool Client::VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash) +{ + auto mode = server.options.GetEncryptionMode(); + if (eqcrypt_verify_hash(user, cred, hash, mode)) { + return true; + } + else { + if (server.options.IsUpdatingInsecurePasswords()) { + if (mode < EncryptionModeArgon2) { + mode = EncryptionModeArgon2; + } + + if (hash.length() == 32) { //md5 is insecure + for (int i = EncryptionModeMD5; i <= EncryptionModeMD5Triple; ++i) { + if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + return true; + } + } + } + else if (hash.length() == 40) { //sha1 is insecure + for (int i = EncryptionModeSHA; i <= EncryptionModeSHATriple; ++i) { + if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + return true; + } + } + } + else if (hash.length() == 128) { //sha2-512 is insecure + for (int i = EncryptionModeSHA512; i <= EncryptionModeSHA512Triple; ++i) { + if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + return true; + } + } + } + //argon2 is still secure + //scrypt is still secure + } + } + + return false; +} + void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver) { stored_user.clear(); diff --git a/loginserver/client.h b/loginserver/client.h index 0271ec545..8225dc90a 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -141,6 +141,11 @@ public: */ void DoFailedLogin(); + /** + * Verifies a login hash, will also attempt to update a login hash if needed. + */ + bool VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash); + /** * Does a successful login */ diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index bdbab2fbf..43d6ae694 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -7,6 +7,8 @@ #include #endif +#include "encryption.h" + const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc) { DES_key_schedule k; DES_cblock v; @@ -100,34 +102,34 @@ std::string eqcrypt_scrypt(const std::string &msg) std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) { switch (mode) { - case 1: + case EncryptionModeMD5: return eqcrypt_md5(password); - case 2: + case EncryptionModeMD5PassUser: return eqcrypt_md5(password + ":" + username); - case 3: + case EncryptionModeMD5UserPass: return eqcrypt_md5(username + ":" + password); - case 4: + case EncryptionModeMD5Triple: return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); - case 5: + case EncryptionModeSHA: return eqcrypt_sha1(password); - case 6: + case EncryptionModeSHAPassUser: return eqcrypt_sha1(password + ":" + username); - case 7: + case EncryptionModeSHAUserPass: return eqcrypt_sha1(username + ":" + password); - case 8: + case EncryptionModeSHATriple: return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); - case 9: + case EncryptionModeSHA512: return eqcrypt_sha512(password); - case 10: + case EncryptionModeSHA512PassUser: return eqcrypt_sha512(password + ":" + username); - case 11: + case EncryptionModeSHA512UserPass: return eqcrypt_sha512(username + ":" + password); - case 12: + case EncryptionModeSHA512Triple: return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); #ifdef ENABLE_SECURITY - case 13: + case EncryptionModeArgon2: return eqcrypt_argon2(password); - case 14: + case EncryptionModeSCrypt: return eqcrypt_scrypt(password); #endif //todo bcrypt? pbkdf2? diff --git a/loginserver/encryption.h b/loginserver/encryption.h index fe27ce28a..3ec9c2743 100644 --- a/loginserver/encryption.h +++ b/loginserver/encryption.h @@ -2,6 +2,24 @@ #include +enum EncryptionMode +{ + EncryptionModeMD5 = 1, + EncryptionModeMD5PassUser = 2, + EncryptionModeMD5UserPass = 3, + EncryptionModeMD5Triple = 4, + EncryptionModeSHA = 5, + EncryptionModeSHAPassUser = 6, + EncryptionModeSHAUserPass = 7, + EncryptionModeSHATriple = 8, + EncryptionModeSHA512 = 9, + EncryptionModeSHA512PassUser = 10, + EncryptionModeSHA512UserPass = 11, + EncryptionModeSHA512Triple = 12, + EncryptionModeArgon2 = 13, + EncryptionModeSCrypt = 14 +}; + const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc); std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode); bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode); diff --git a/world/console.cpp b/world/console.cpp index 8342b2e3c..9debd7e9b 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -19,14 +19,7 @@ struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string& username, const std::string prefix = "eqemu"; std::string raw_user = ""; - auto split = SplitString(username, '.'); - if (split.size() == 2) { - prefix = split[0]; - raw_user = split[1]; - } - else { - raw_user = split[0]; - } + ParseAccountString(username, raw_user, prefix); ret.account_id = database.CheckLogin(raw_user.c_str(), password.c_str(), prefix.c_str()); @@ -399,14 +392,7 @@ void ConsoleSetPass(EQ::Net::ConsoleServerConnection* connection, const std::str std::string prefix = "eqemu"; std::string raw_user = ""; - auto split = SplitString(args[0], '.'); - if (split.size() == 2) { - prefix = split[0]; - raw_user = split[1]; - } - else { - raw_user = split[0]; - } + ParseAccountString(args[0], raw_user, prefix); int16 tmpstatus = 0; uint32 tmpid = database.GetAccountIDByName(raw_user.c_str(), prefix.c_str(), &tmpstatus); diff --git a/world/net.cpp b/world/net.cpp index 2c04b9d10..c0ab16ecc 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -213,24 +213,28 @@ int main(int argc, char** argv) { } } else if (strcasecmp(argv[1], "adduser") == 0) { - //TODO: REIMPLEMENT - //if (argc == 5) { - // if (Seperator::IsNumber(argv[4])) { - // if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) { - // if (database.CreateAccount(argv[2], argv[3], atoi(argv[4])) == 0) { - // std::cerr << "database.CreateAccount failed." << std::endl; - // return 1; - // } - // else { - // std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl; - // return 0; - // } - // } - // } - //} - //std::cout << "Usage: world adduser username password flag" << std::endl; - //std::cout << "flag = 0, 1 or 2" << std::endl; - //return 0; + if (argc == 5) { + if (Seperator::IsNumber(argv[4])) { + if (atoi(argv[4]) >= 0 && atoi(argv[4]) <= 255) { + std::string user; + std::string loginserver; + + ParseAccountString(argv[2], user, loginserver); + + if (database.CreateAccount(argv[2], argv[3], atoi(argv[4]), loginserver.c_str(), 0) == 0) { + std::cerr << "database.CreateAccount failed." << std::endl; + return 1; + } + else { + std::cout << "Account created: Username='" << argv[2] << "', Password='" << argv[3] << "', status=" << argv[4] << std::endl; + return 0; + } + } + } + } + std::cout << "Usage: world adduser username password flag" << std::endl; + std::cout << "flag = 0, 1 or 2" << std::endl; + return 0; } else if (strcasecmp(argv[1], "flag") == 0) { if (argc == 4) { diff --git a/zone/command.cpp b/zone/command.cpp index 9ca19a3b9..164e0f750 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1957,33 +1957,40 @@ void command_shutdown(Client *c, const Seperator *sep) void command_delacct(Client *c, const Seperator *sep) { - //TODO: REIMPLEMENT -// if(sep->arg[1][0] == 0) -// c->Message(0, "Format: #delacct accountname"); -// else -// if (database.DeleteAccount(sep->arg[1])) -// c->Message(0, "The account was deleted."); -// else -// c->Message(0, "Unable to delete account."); + if (sep->arg[1][0] == 0) + c->Message(0, "Format: #delacct accountname"); + else { + std::string user; + std::string loginserver; + ParseAccountString(sep->arg[1], user, loginserver); + + if (database.DeleteAccount(user.c_str(), loginserver.c_str())) + c->Message(0, "The account was deleted."); + else + c->Message(0, "Unable to delete account."); + } } void command_setpass(Client *c, const Seperator *sep) { - //TODO: REIMPLEMENT - //if(sep->argnum != 2) - // c->Message(0, "Format: #setpass accountname password"); - //else { - // int16 tmpstatus = 0; - // uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus); - // if (!tmpid) - // c->Message(0, "Error: Account not found"); - // else if (tmpstatus > c->Admin()) - // c->Message(0, "Cannot change password: Account's status is higher than yours"); - // else if (database.SetLocalPassword(tmpid, sep->arg[2])) - // c->Message(0, "Password changed."); - // else - // c->Message(0, "Error changing password."); - //} + if(sep->argnum != 2) + c->Message(0, "Format: #setpass accountname password"); + else { + std::string user; + std::string loginserver; + ParseAccountString(sep->arg[1], user, loginserver); + + int16 tmpstatus = 0; + uint32 tmpid = database.GetAccountIDByName(user.c_str(), loginserver.c_str(), &tmpstatus); + if (!tmpid) + c->Message(0, "Error: Account not found"); + else if (tmpstatus > c->Admin()) + c->Message(0, "Cannot change password: Account's status is higher than yours"); + else if (database.SetLocalPassword(tmpid, sep->arg[2])) + c->Message(0, "Password changed."); + else + c->Message(0, "Error changing password."); + } } void command_setlsinfo(Client *c, const Seperator *sep) @@ -4416,42 +4423,45 @@ void command_uptime(Client *c, const Seperator *sep) void command_flag(Client *c, const Seperator *sep) { - //TODO: REIMPLEMENT -// if(sep->arg[2][0] == 0) { -// if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { -// c->UpdateAdmin(); -// c->Message(0, "Refreshed your admin flag from DB."); -// } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { -// c->GetTarget()->CastToClient()->UpdateAdmin(); -// c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); -// c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); -// } -// } -// else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) -// c->Message(0, "Usage: #flag [status] [acctname]"); -// -// else if (c->Admin() < commandChangeFlags) { -////this check makes banning players by less than this level -////impossible, but i'll leave it in anyways -// c->Message(0, "You may only refresh your own flag, doing so now."); -// c->UpdateAdmin(); -// } -// else { -// if (atoi(sep->arg[1]) > c->Admin()) -// c->Message(0, "You cannot set people's status to higher than your own"); -// else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) -// c->Message(0, "You have too low of status to suspend/ban"); -// else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) -// c->Message(0, "Unable to set GM Flag."); -// else { -// c->Message(0, "Set GM Flag on account."); -// auto pack = new ServerPacket(ServerOP_FlagUpdate, 6); -// *((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]); -// *((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]); -// worldserver.SendPacket(pack); -// delete pack; -// } -// } + if(sep->arg[2][0] == 0) { + if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { + c->UpdateAdmin(); + c->Message(0, "Refreshed your admin flag from DB."); + } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { + c->GetTarget()->CastToClient()->UpdateAdmin(); + c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); + c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); + } + } + else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) + c->Message(0, "Usage: #flag [status] [acctname]"); + + else if (c->Admin() < commandChangeFlags) { + //this check makes banning players by less than this level + //impossible, but i'll leave it in anyways + c->Message(0, "You may only refresh your own flag, doing so now."); + c->UpdateAdmin(); + } + else { + if (atoi(sep->arg[1]) > c->Admin()) + c->Message(0, "You cannot set people's status to higher than your own"); + else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) + c->Message(0, "You have too low of status to suspend/ban"); + else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) + c->Message(0, "Unable to set GM Flag."); + else { + c->Message(0, "Set GM Flag on account."); + + std::string user; + std::string loginserver; + ParseAccountString(sep->argplus[2], user, loginserver); + + ServerPacket pack(ServerOP_FlagUpdate, 6); + *((uint32*) pack.pBuffer) = database.GetAccountIDByName(user.c_str(), loginserver.c_str()); + *((int16*) &pack.pBuffer[4]) = atoi(sep->arg[1]); + worldserver.SendPacket(&pack); + } + } } void command_time(Client *c, const Seperator *sep) From cc0034fd3c30b963b7b20561dfd91eb87ee59c1d Mon Sep 17 00:00:00 2001 From: KimLS Date: Sun, 24 Dec 2017 23:31:13 -0800 Subject: [PATCH 007/491] SQL files --- utils/sql/db_update_manifest.txt | 1 + .../git/optional/2017_12_25_LoginServer.sql | 21 +++++++++++++++++++ .../git/required/2017_12_25_AccountTable.sql | 11 ++++++++++ 3 files changed, 33 insertions(+) create mode 100644 utils/sql/git/optional/2017_12_25_LoginServer.sql create mode 100644 utils/sql/git/required/2017_12_25_AccountTable.sql diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 11dd1b315..498bf3deb 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -370,6 +370,7 @@ 9114|2017_07_22_aura.sql|SHOW TABLES LIKE 'auras'|empty| 9115|2017_10_28_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'triggered_number'|empty| 9116|2017_12_16_GroundSpawn_Respawn_Timer.sql|SHOW COLUMNS FROM `ground_spawns` WHERE Field = 'respawn_timer' AND Type = 'int(11) unsigned'|empty| +9117|2017_12_25_AccountTable.sql|SHOW COLUMNS FROM `ground_spawns` WHERE Field = 'ls_id' AND Type = 'varchar(64)'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/optional/2017_12_25_LoginServer.sql b/utils/sql/git/optional/2017_12_25_LoginServer.sql new file mode 100644 index 000000000..3853e5c21 --- /dev/null +++ b/utils/sql/git/optional/2017_12_25_LoginServer.sql @@ -0,0 +1,21 @@ +ALTER TABLE `tblloginserveraccounts` + ADD COLUMN `AccountLoginserver` VARCHAR(64) NULL AFTER `LastIPAddress`; + +ALTER TABLE `tblloginserveraccounts` + CHANGE COLUMN `AccountLoginserver` `AccountLoginserver` VARCHAR(64) NOT NULL DEFAULT 'eqemu' AFTER `LoginServerID`, + DROP PRIMARY KEY, + ADD PRIMARY KEY (`LoginServerID`, `AccountLoginserver`); + +ALTER TABLE `tblloginserveraccounts` + ADD UNIQUE INDEX `AccountLoginserver_AccountName` (`AccountLoginserver`, `AccountName`); + +ALTER TABLE `tblloginserveraccounts` + ALTER `LoginServerID` DROP DEFAULT; +ALTER TABLE `tblloginserveraccounts` + CHANGE COLUMN `LoginServerID` `LoginServerID` INT(10) UNSIGNED NOT NULL FIRST; + +ALTER TABLE `tblloginserveraccounts` + ALTER `AccountPassword` DROP DEFAULT; +ALTER TABLE `tblloginserveraccounts` + CHANGE COLUMN `AccountPassword` `AccountPassword` TEXT NOT NULL AFTER `AccountName`; + \ No newline at end of file diff --git a/utils/sql/git/required/2017_12_25_AccountTable.sql b/utils/sql/git/required/2017_12_25_AccountTable.sql new file mode 100644 index 000000000..e4393d29d --- /dev/null +++ b/utils/sql/git/required/2017_12_25_AccountTable.sql @@ -0,0 +1,11 @@ +ALTER TABLE `account` + DROP INDEX `name`, + DROP INDEX `lsaccount_id`; + +ALTER TABLE `account` + ADD COLUMN `ls_id` VARCHAR(64) NULL DEFAULT 'eqemu' AFTER `status`; + +ALTER TABLE `account` + ADD UNIQUE INDEX `name_ls_id` (`name`, `ls_id`), + ADD UNIQUE INDEX `ls_id_lsaccount_id` (`ls_id`, `lsaccount_id`); + \ No newline at end of file From f16faae964051e0161173abe824896a6d1a0ac27 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 20 Jan 2018 21:26:52 -0800 Subject: [PATCH 008/491] Fix for bug in config reading tables --- loginserver/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loginserver/main.cpp b/loginserver/main.cpp index b2603056a..85f2bde4a 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -73,9 +73,9 @@ int main() server.options.UpdateInsecurePasswords(server.config.GetVariableBool("security", "update_insecure_passwords", true)); server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); - server.options.WorldRegistrationTable(server.config.GetVariableString("schema", "account_table", "tblWorldServerRegistration")); - server.options.WorldAdminRegistrationTable(server.config.GetVariableString("schema", "account_table", "tblServerAdminRegistration")); - server.options.WorldServerTypeTable(server.config.GetVariableString("schema", "account_table", "tblServerListType")); + server.options.WorldRegistrationTable(server.config.GetVariableString("schema", "world_registration_table", "tblWorldServerRegistration")); + server.options.WorldAdminRegistrationTable(server.config.GetVariableString("schema", "world_admin_registration_table", "tblServerAdminRegistration")); + server.options.WorldServerTypeTable(server.config.GetVariableString("schema", "world_server_type_table", "tblServerListType")); /* Create database connection */ if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) { From a73bf221ed9f97f58fd0d175a1364222be0de49b Mon Sep 17 00:00:00 2001 From: hg <4683435+hgtw@users.noreply.github.com> Date: Thu, 13 Sep 2018 19:25:05 -0400 Subject: [PATCH 009/491] Make SPA 112 affect fizzle rate not effective caster level Per dev quote, SPA 112 "Modifies casting skills of the affected entity by BaseEffect for the purposes of determining whether or not a fizzle occurs when casting spells." Fixes issues caused by having a spell with this effect on caster such as wrong target debuff durations and buff refreshes not taking hold. --- zone/bonuses.cpp | 20 +++++++++++++++++--- zone/common.h | 1 + zone/lua_stat_bonuses.cpp | 6 ++++++ zone/lua_stat_bonuses.h | 1 + zone/spells.cpp | 2 ++ 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/zone/bonuses.cpp b/zone/bonuses.cpp index b6de679d1..7965e016e 100644 --- a/zone/bonuses.cpp +++ b/zone/bonuses.cpp @@ -1217,8 +1217,12 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon) break; } - case SE_CastingLevel2: case SE_CastingLevel: { + newbon->adjusted_casting_skill += base1; + break; + } + + case SE_CastingLevel2: { newbon->effective_casting_level += base1; break; } @@ -1917,8 +1921,13 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne break; } - case SE_CastingLevel2: case SE_CastingLevel: // Brilliance of Ro + { + new_bonus->adjusted_casting_skill += effect_value; + break; + } + + case SE_CastingLevel2: { new_bonus->effective_casting_level += effect_value; break; @@ -3867,8 +3876,13 @@ void Mob::NegateSpellsBonuses(uint16 spell_id) aabonuses.Corrup = effect_value; break; - case SE_CastingLevel2: case SE_CastingLevel: // Brilliance of Ro + spellbonuses.adjusted_casting_skill = effect_value; + aabonuses.adjusted_casting_skill = effect_value; + itembonuses.adjusted_casting_skill = effect_value; + break; + + case SE_CastingLevel2: spellbonuses.effective_casting_level = effect_value; aabonuses.effective_casting_level = effect_value; itembonuses.effective_casting_level = effect_value; diff --git a/zone/common.h b/zone/common.h index df6b22637..9db776e4b 100644 --- a/zone/common.h +++ b/zone/common.h @@ -354,6 +354,7 @@ struct StatBonuses { int32 skillmod[EQEmu::skills::HIGHEST_SKILL + 1]; int32 skillmodmax[EQEmu::skills::HIGHEST_SKILL + 1]; int effective_casting_level; + int adjusted_casting_skill; // SPA 112 for fizzles int reflect_chance; // chance to reflect incoming spell uint32 singingMod; uint32 Amplification; // stacks with singingMod diff --git a/zone/lua_stat_bonuses.cpp b/zone/lua_stat_bonuses.cpp index e1fb329cc..282aaad38 100644 --- a/zone/lua_stat_bonuses.cpp +++ b/zone/lua_stat_bonuses.cpp @@ -333,6 +333,11 @@ int Lua_StatBonuses::Geteffective_casting_level() const { return self->effective_casting_level; } +int Lua_StatBonuses::Getadjusted_casting_skill() const { + Lua_Safe_Call_Int(); + return self->adjusted_casting_skill; +} + int Lua_StatBonuses::Getreflect_chance() const { Lua_Safe_Call_Int(); return self->reflect_chance; @@ -1347,6 +1352,7 @@ luabind::scope lua_register_stat_bonuses() { .def("skillmod", &Lua_StatBonuses::Getskillmod) .def("skillmodmax", &Lua_StatBonuses::Getskillmodmax) .def("effective_casting_level", &Lua_StatBonuses::Geteffective_casting_level) + .def("adjusted_casting_skill", &Lua_StatBonuses::Getadjusted_casting_skill) .def("reflect_chance", &Lua_StatBonuses::Getreflect_chance) .def("singingMod", &Lua_StatBonuses::GetsingingMod) .def("Amplification", &Lua_StatBonuses::GetAmplification) diff --git a/zone/lua_stat_bonuses.h b/zone/lua_stat_bonuses.h index 9ad04d681..c65c589a4 100644 --- a/zone/lua_stat_bonuses.h +++ b/zone/lua_stat_bonuses.h @@ -91,6 +91,7 @@ public: int32 Getskillmod(int idx) const; int32 Getskillmodmax(int idx) const; int Geteffective_casting_level() const; + int Getadjusted_casting_skill() const; int Getreflect_chance() const; uint32 GetsingingMod() const; uint32 GetAmplification() const; diff --git a/zone/spells.cpp b/zone/spells.cpp index 60591b7b1..990b26d60 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -752,6 +752,8 @@ bool Client::CheckFizzle(uint16 spell_id) act_skill = GetSkill(spells[spell_id].skill); act_skill += GetLevel(); // maximum of whatever the client can cheat + act_skill += itembonuses.adjusted_casting_skill + spellbonuses.adjusted_casting_skill + aabonuses.adjusted_casting_skill; + Log(Logs::Detail, Logs::Spells, "Adjusted casting skill: %d+%d+%d+%d+%d=%d", GetSkill(spells[spell_id].skill), GetLevel(), itembonuses.adjusted_casting_skill, spellbonuses.adjusted_casting_skill, aabonuses.adjusted_casting_skill, act_skill); //spell specialization float specialize = GetSpecializeSkillValue(spell_id); From 44f85f140cab8ddf8eb398377204d7bfe9db617d Mon Sep 17 00:00:00 2001 From: Xackery Xtal Date: Mon, 21 Jan 2019 20:29:12 -0800 Subject: [PATCH 010/491] Added Spells:CharmDisablesSpecialAbilities --- common/ruletypes.h | 1 + zone/npc.cpp | 5 +++++ zone/npc.h | 1 + 3 files changed, 7 insertions(+) diff --git a/common/ruletypes.h b/common/ruletypes.h index 623260af4..7076eda69 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -365,6 +365,7 @@ RULE_INT(Spells, CharismaEffectiveness, 10) // Deterimes how much resist modific RULE_INT(Spells, CharismaEffectivenessCap, 255) // Deterimes how much resist modification charisma applies to charm/pacify checks. Default 10 CHA = -1 resist mod. RULE_BOOL(Spells, CharismaCharmDuration, false) // Allow CHA resist mod to extend charm duration. RULE_INT(Spells, CharmBreakCheckChance, 25) //Determines chance for a charm break check to occur each buff tick. +RULE_BOOL(Spells, CharmDisablesSpecialAbilities, false) //When charm is cast on an NPC, strip their special abilities RULE_INT(Spells, MaxCastTimeReduction, 50) //Max percent your spell cast time can be reduced by spell haste RULE_INT(Spells, RootBreakFromSpells, 55) //Chance for root to break when cast on. RULE_INT(Spells, DeathSaveCharismaMod, 3) //Determines how much charisma effects chance of death save firing. diff --git a/zone/npc.cpp b/zone/npc.cpp index 8de819e0c..ad7bbd74d 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -208,6 +208,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi default_accuracy_rating = npc_type_data->accuracy_rating; default_avoidance_rating = npc_type_data->avoidance_rating; default_atk = npc_type_data->ATK; + strn0cpy(default_special_abilities, npc_type_data->special_abilities, 512); // used for when getting charmed, if 0, doesn't swap charm_ac = npc_type_data->charm_ac; @@ -2840,6 +2841,8 @@ void NPC::ModifyStatsOnCharm(bool bRemoved) base_damage = round((default_max_dmg - default_min_dmg) / 1.9); min_damage = default_min_dmg - round(base_damage / 10.0); } + if (RuleB(Spells, CharmDisablesSpecialAbilities)) + ProcessSpecialAbilities(default_special_abilities); } else { if (charm_ac) AC = charm_ac; @@ -2855,6 +2858,8 @@ void NPC::ModifyStatsOnCharm(bool bRemoved) base_damage = round((charm_max_dmg - charm_min_dmg) / 1.9); min_damage = charm_min_dmg - round(base_damage / 10.0); } + if (RuleB(Spells, CharmDisablesSpecialAbilities)) + ClearSpecialAbilities(); } // the rest of the stats aren't cached, so lets just do these two instead of full CalcBonuses() SetAttackTimer(); diff --git a/zone/npc.h b/zone/npc.h index b9e0458e6..ec60f80d2 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -538,6 +538,7 @@ protected: int default_accuracy_rating; int default_avoidance_rating; int default_atk; + char default_special_abilities[512]; // when charmed, switch to these int charm_ac; From 26eb4fb6e099d44e61926ba358fddc13b1110841 Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:06:32 -0600 Subject: [PATCH 011/491] Swapped luabind for non-boost fork https://github.com/decimad/luabind-deboostified --- CMakeLists.txt | 8 +- libs/luabind/CMakeLists.txt | 87 +- libs/luabind/CMakeSettings.json | 54 + libs/luabind/luabind/adopt_policy.hpp | 189 ++- libs/luabind/luabind/back_reference.hpp | 132 +- libs/luabind/luabind/back_reference_fwd.hpp | 10 +- libs/luabind/luabind/class.hpp | 899 ++++------- libs/luabind/luabind/class_info.hpp | 9 +- libs/luabind/luabind/config.hpp | 63 +- libs/luabind/luabind/container_policy.hpp | 179 +-- libs/luabind/luabind/copy_policy.hpp | 71 +- libs/luabind/luabind/dependency_policy.hpp | 124 +- libs/luabind/luabind/detail/call.hpp | 790 ++++++---- libs/luabind/luabind/detail/call_function.hpp | 558 ++----- libs/luabind/luabind/detail/call_member.hpp | 360 +---- .../luabind/detail/call_operator_iterate.hpp | 66 - .../{object_call.hpp => call_shared.hpp} | 61 +- libs/luabind/luabind/detail/call_traits.hpp | 113 ++ libs/luabind/luabind/detail/class_cache.hpp | 89 -- .../luabind/luabind/detail/class_registry.hpp | 72 +- libs/luabind/luabind/detail/class_rep.hpp | 319 ++-- libs/luabind/luabind/detail/compute_score.hpp | 73 - libs/luabind/luabind/detail/constructor.hpp | 132 +- .../conversion_policies/conversion_base.hpp | 81 + .../conversion_policies.hpp | 89 ++ .../conversion_policies/enum_converter.hpp | 82 + .../function_converter.hpp | 95 ++ .../lua_proxy_converter.hpp | 73 + .../conversion_policies/native_converter.hpp | 302 ++++ .../conversion_policies/pointer_converter.hpp | 143 ++ .../reference_converter.hpp | 124 ++ .../conversion_policies/value_converter.hpp | 79 + .../luabind/detail/conversion_storage.hpp | 48 +- .../luabind/luabind/detail/convert_to_lua.hpp | 92 -- libs/luabind/luabind/detail/crtp_iterator.hpp | 58 + libs/luabind/luabind/detail/debug.hpp | 34 +- libs/luabind/luabind/detail/decorate_type.hpp | 230 +-- .../luabind/detail/deduce_signature.hpp | 112 +- libs/luabind/luabind/detail/enum_maker.hpp | 20 +- .../luabind/detail/format_signature.hpp | 205 ++- .../luabind/detail/garbage_collector.hpp | 37 +- .../luabind/detail/has_get_pointer.hpp | 107 -- libs/luabind/luabind/detail/inheritance.hpp | 245 +-- .../luabind/detail/instance_holder.hpp | 228 +-- .../luabind/detail/is_indirect_const.hpp | 70 - .../luabind/detail/link_compatibility.hpp | 42 +- libs/luabind/luabind/detail/make_instance.hpp | 208 ++- libs/luabind/luabind/detail/meta.hpp | 581 +++++++ libs/luabind/luabind/detail/object.hpp | 386 +++++ libs/luabind/luabind/detail/object_funs.hpp | 224 --- libs/luabind/luabind/detail/object_rep.hpp | 180 +-- libs/luabind/luabind/detail/operator_id.hpp | 88 +- libs/luabind/luabind/detail/other.hpp | 95 +- libs/luabind/luabind/detail/pcall.hpp | 14 +- libs/luabind/luabind/detail/policy.hpp | 1057 ++----------- libs/luabind/luabind/detail/primitives.hpp | 74 +- libs/luabind/luabind/detail/property.hpp | 38 +- .../{calc_arity.hpp => push_to_lua.hpp} | 66 +- libs/luabind/luabind/detail/ref.hpp | 127 +- .../luabind/detail/signature_match.hpp | 32 - libs/luabind/luabind/detail/stack_utils.hpp | 38 +- libs/luabind/luabind/detail/type_traits.hpp | 189 +++ libs/luabind/luabind/detail/typetraits.hpp | 190 --- .../luabind/luabind/discard_result_policy.hpp | 57 +- libs/luabind/luabind/error.hpp | 29 +- ...ntee_typeid.hpp => error_callback_fun.hpp} | 30 +- libs/luabind/luabind/exception_handler.hpp | 125 +- libs/luabind/luabind/from_stack.hpp | 20 +- libs/luabind/luabind/function.hpp | 67 +- ..._sizeof.hpp => function_introspection.hpp} | 54 +- libs/luabind/luabind/get_main_thread.hpp | 4 +- libs/luabind/luabind/handle.hpp | 180 ++- libs/luabind/luabind/iterator_policy.hpp | 165 +- libs/luabind/luabind/lua_argument_proxy.hpp | 71 + libs/luabind/luabind/lua_include.hpp | 4 +- libs/luabind/luabind/lua_index_proxy.hpp | 137 ++ libs/luabind/luabind/lua_iterator_proxy.hpp | 230 +++ .../most_derived.hpp => lua_proxy.hpp} | 42 +- libs/luabind/luabind/lua_proxy_interface.hpp | 306 ++++ .../{get_pointer.hpp => lua_state_fwd.hpp} | 25 +- libs/luabind/luabind/luabind.hpp | 2 + libs/luabind/luabind/make_function.hpp | 172 +- libs/luabind/luabind/nil.hpp | 11 +- libs/luabind/luabind/no_dependency.hpp | 28 + libs/luabind/luabind/object.hpp | 1392 +---------------- libs/luabind/luabind/open.hpp | 2 + libs/luabind/luabind/operator.hpp | 315 ++-- libs/luabind/luabind/out_value_policy.hpp | 462 +++--- libs/luabind/luabind/pointer_traits.hpp | 148 ++ libs/luabind/luabind/raw_policy.hpp | 78 +- .../luabind/return_reference_to_policy.hpp | 73 +- libs/luabind/luabind/scope.hpp | 118 +- .../{lua502.hpp => set_package_preload.hpp} | 60 +- libs/luabind/luabind/shared_ptr_converter.hpp | 118 +- libs/luabind/luabind/tag_function.hpp | 111 +- libs/luabind/luabind/typeid.hpp | 75 +- libs/luabind/luabind/value_wrapper.hpp | 168 -- libs/luabind/luabind/version.hpp | 1 + libs/luabind/luabind/weak_ref.hpp | 32 +- libs/luabind/luabind/wrapper_base.hpp | 153 +- libs/luabind/luabind/yield_policy.hpp | 38 +- libs/luabind/src/CMakeLists.txt | 182 +++ libs/luabind/src/class.cpp | 559 ++++--- libs/luabind/src/class_info.cpp | 145 +- libs/luabind/src/class_registry.cpp | 190 +-- libs/luabind/src/class_rep.cpp | 193 +-- libs/luabind/src/create_class.cpp | 202 +-- libs/luabind/src/error.cpp | 29 +- libs/luabind/src/exception_handler.cpp | 145 +- libs/luabind/src/function.cpp | 214 +-- libs/luabind/src/function_introspection.cpp | 117 ++ libs/luabind/src/headertest.cpp | 1 + libs/luabind/src/inheritance.cpp | 361 ++--- libs/luabind/src/link_compatibility.cpp | 15 +- libs/luabind/src/object_rep.cpp | 477 +++--- libs/luabind/src/open.cpp | 230 ++- .../detail/yes_no.hpp => src/operator.cpp} | 18 +- libs/luabind/src/pcall.cpp | 56 +- libs/luabind/src/scope.cpp | 300 ++-- libs/luabind/src/set_package_preload.cpp | 60 + libs/luabind/src/stack_content_by_name.cpp | 21 +- libs/luabind/src/weak_ref.cpp | 217 +-- libs/luabind/src/wrapper_base.cpp | 42 +- 123 files changed, 9408 insertions(+), 10110 deletions(-) create mode 100644 libs/luabind/CMakeSettings.json delete mode 100644 libs/luabind/luabind/detail/call_operator_iterate.hpp rename libs/luabind/luabind/detail/{object_call.hpp => call_shared.hpp} (51%) create mode 100644 libs/luabind/luabind/detail/call_traits.hpp delete mode 100644 libs/luabind/luabind/detail/class_cache.hpp delete mode 100644 libs/luabind/luabind/detail/compute_score.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/function_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/native_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp create mode 100644 libs/luabind/luabind/detail/conversion_policies/value_converter.hpp delete mode 100644 libs/luabind/luabind/detail/convert_to_lua.hpp create mode 100644 libs/luabind/luabind/detail/crtp_iterator.hpp delete mode 100644 libs/luabind/luabind/detail/has_get_pointer.hpp delete mode 100644 libs/luabind/luabind/detail/is_indirect_const.hpp create mode 100644 libs/luabind/luabind/detail/meta.hpp create mode 100644 libs/luabind/luabind/detail/object.hpp delete mode 100644 libs/luabind/luabind/detail/object_funs.hpp rename libs/luabind/luabind/detail/{calc_arity.hpp => push_to_lua.hpp} (53%) create mode 100644 libs/luabind/luabind/detail/type_traits.hpp delete mode 100644 libs/luabind/luabind/detail/typetraits.hpp rename libs/luabind/luabind/{detail/pointee_typeid.hpp => error_callback_fun.hpp} (63%) rename libs/luabind/luabind/{detail/pointee_sizeof.hpp => function_introspection.hpp} (57%) create mode 100644 libs/luabind/luabind/lua_argument_proxy.hpp create mode 100644 libs/luabind/luabind/lua_index_proxy.hpp create mode 100644 libs/luabind/luabind/lua_iterator_proxy.hpp rename libs/luabind/luabind/{detail/most_derived.hpp => lua_proxy.hpp} (64%) create mode 100644 libs/luabind/luabind/lua_proxy_interface.hpp rename libs/luabind/luabind/{get_pointer.hpp => lua_state_fwd.hpp} (77%) create mode 100644 libs/luabind/luabind/no_dependency.hpp create mode 100644 libs/luabind/luabind/pointer_traits.hpp rename libs/luabind/luabind/{lua502.hpp => set_package_preload.hpp} (56%) delete mode 100644 libs/luabind/luabind/value_wrapper.hpp create mode 100644 libs/luabind/src/CMakeLists.txt create mode 100644 libs/luabind/src/function_introspection.cpp create mode 100644 libs/luabind/src/headertest.cpp rename libs/luabind/{luabind/detail/yes_no.hpp => src/operator.cpp} (81%) create mode 100644 libs/luabind/src/set_package_preload.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ad551966..0fe7680e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,13 +323,7 @@ ENDIF() IF(EQEMU_BUILD_LUA) FIND_PACKAGE(EQLua51 REQUIRED) - SET(Boost_USE_STATIC_LIBS OFF) - SET(Boost_USE_MULTITHREADED ON) - SET(Boost_USE_STATIC_RUNTIME OFF) - SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost") - - FIND_PACKAGE(Boost REQUIRED) - INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}") + INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}") INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind") OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON) diff --git a/libs/luabind/CMakeLists.txt b/libs/luabind/CMakeLists.txt index de3b60c61..48a120400 100644 --- a/libs/luabind/CMakeLists.txt +++ b/libs/luabind/CMakeLists.txt @@ -1,38 +1,61 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +# Build for LuaBind +# Ryan Pavlik +# http://academic.cleardefinition.com/ +# Iowa State University HCI Graduate Program/VRAC -SET(lb_sources - src/class.cpp - src/class_info.cpp - src/class_registry.cpp - src/class_rep.cpp - src/create_class.cpp - src/error.cpp - src/exception_handler.cpp - src/function.cpp - src/inheritance.cpp - src/link_compatibility.cpp - src/object_rep.cpp - src/open.cpp - src/pcall.cpp - src/scope.cpp - src/stack_content_by_name.cpp - src/weak_ref.cpp - src/wrapper_base.cpp +cmake_minimum_required(VERSION 3.0) +project(LuaBind) + +set(CPACK_PACKAGE_VERSION_MAJOR "0") +set(CPACK_PACKAGE_VERSION_MINOR "9") +set(CPACK_PACKAGE_VERSION_PATCH "1") +set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +if(NOT LUA_FOUND AND NOT LUA51_FOUND) + find_package(Lua51 REQUIRED) + set(LUA_INCLUDE_DIRS "${LUA_INCLUDE_DIR}") +endif() + +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + # We are the top-level project + include(CTest) + option(LUABIND_INSTALL "Install the LuaBind library and headers" ON) + option(LUABIND_BUILD_DOCS "Build documentation files" OFF) + option(LUABIND_BUILD_SHARED "Build luabind as a shared library?" OFF) +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # Requiring C++11 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif() + +if(MSVC) + # Requiring C++11 +# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++11") +# set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /std:c++11") +endif() + +set(BUILD_SHARED_LIBS ${LUABIND_BUILD_SHARED}) +if(BUILD_SHARED_LIBS) + add_definitions(-DLUABIND_DYNAMIC_LINK) +endif() + +include_directories( + "${CMAKE_CURRENT_SOURCE_DIR}" + ${LUA_INCLUDE_DIRS} ) -SET(lb_headers +add_subdirectory(src) -) +if(BUILD_TESTING) + add_subdirectory(test) +endif() -ADD_LIBRARY(luabind ${lb_sources} ${lb_headers}) +if(LUABIND_BUILD_DOCS) + add_subdirectory(doc) +endif() - -IF(UNIX) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS -Wno-deprecated-declarations) -ENDIF(UNIX) - -IF(MSVC) - set_source_files_properties(${lb_sources} PROPERTY COMPILE_FLAGS " /W0 " ) -ENDIF(MSVC) - -SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) diff --git a/libs/luabind/CMakeSettings.json b/libs/luabind/CMakeSettings.json new file mode 100644 index 000000000..d85358021 --- /dev/null +++ b/libs/luabind/CMakeSettings.json @@ -0,0 +1,54 @@ +{ + "configurations": [ + { + "name": "x32-debug", + "generator": "Visual Studio 15 2017", + "buildRoot": "${projectDir}/temp/x32-debug", + "cmakeCommandArgs": "", + "configurationType": "Debug", + "variables": [ + { + "name": "LUA_INCLUDE_DIR", + "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src" + }, + { + "name": "LUA_LIBRARIES", + "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib" + }, + { + "name": "LUABIND_INSTALL", + "value": "ON" + }, + { + "name": "CMAKE_INSTALL_PREFIX", + "value": "${projectDir}/build/debug" + } + ] + }, + { + "name": "x32-release", + "generator": "Visual Studio 15 2017", + "buildRoot": "${projectDir}/temp/x32-release", + "cmakeCommandArgs": "", + "configurationType": "Release", + "variables": [ + { + "name": "LUA_INCLUDE_DIR", + "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src" + }, + { + "name": "LUA_LIBRARIES", + "value": "C:/gitprojects/LuaJIT-2.1.0-beta3/src/lua51.lib" + }, + { + "name": "LUABIND_INSTALL", + "value": "ON" + }, + { + "name": "CMAKE_INSTALL_PREFIX", + "value": "${projectDir}/build/release" + } + ] + } + ] +} diff --git a/libs/luabind/luabind/adopt_policy.hpp b/libs/luabind/luabind/adopt_policy.hpp index 5e81b948b..3f4751cc3 100644 --- a/libs/luabind/luabind/adopt_policy.hpp +++ b/libs/luabind/luabind/adopt_policy.hpp @@ -28,114 +28,111 @@ #include #include #include -#include -#include -namespace luabind { namespace detail -{ - template - void adjust_backref_ownership(T* ptr, mpl::true_) - { - if (wrap_base* p = dynamic_cast(ptr)) - { - wrapped_self_t& wrapper = wrap_access::ref(*p); - wrapper.get(wrapper.state()); - wrapper.m_strong_ref.set(wrapper.state()); - } - } +namespace luabind { + namespace detail { - inline void adjust_backref_ownership(void*, mpl::false_) - {} - - template - struct adopt_pointer : pointer_converter - { - typedef adopt_pointer type; - - int const consumed_args(...) - { - return 1; - } - - template - T* apply(lua_State* L, by_pointer, int index) + template + void adjust_backref_ownership(T* ptr, std::true_type) { - T* ptr = pointer_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - - object_rep* obj = static_cast( - lua_touserdata(L, index)); - obj->release(); - - adjust_backref_ownership(ptr, boost::is_polymorphic()); - - return ptr; - } - - template - int match(lua_State* L, by_pointer, int index) - { - return pointer_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template<> - struct adopt_pointer - { - typedef adopt_pointer type; - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) + if(wrap_base* p = dynamic_cast(ptr)) { - lua_pushnil(L); - return; + wrapped_self_t& wrapper = wrap_access::ref(*p); + wrapper.get(wrapper.state()); + wrapper.m_strong_ref.set(wrapper.state()); + } + } + + inline void adjust_backref_ownership(void*, std::false_type) + {} + + template + struct adopt_pointer : pointer_converter + { + using type = adopt_pointer; + + enum { consumed_args = 1 }; + + template + T* to_cpp(lua_State* L, by_pointer, int index) + { + T* ptr = pointer_converter::to_cpp(L, decorate_type_t(), index); + + object_rep* obj = static_cast(lua_touserdata(L, index)); + obj->release(); + + adjust_backref_ownership(ptr, std::is_polymorphic()); + + return ptr; } - // if there is a back_reference, then the - // ownership will be removed from the - // back reference and put on the lua stack. - if (luabind::move_back_reference(L, ptr)) - return; + template + int match(lua_State* L, by_pointer, int index) + { + return pointer_converter::match(L, decorate_type_t(), index); + } - make_instance(L, std::auto_ptr(ptr)); - } - }; - - template -// struct adopt_policy : converter_policy_tag - struct adopt_policy : conversion_policy - { -// BOOST_STATIC_CONSTANT(int, index = N); - - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_pointers {}; - - template - struct apply - { - typedef luabind::detail::is_nonconst_pointer is_nonconst_p; - typedef typename boost::mpl::if_, only_accepts_nonconst_pointers>::type type; + template + void converter_postcall(lua_State*, T, int) {} }; - }; -}} + template + struct pointer_or_default + { + using type = Pointer; + }; + + template + struct pointer_or_default + { + using type = std::unique_ptr; + }; + + template + struct adopt_pointer + { + using type = adopt_pointer; + + template + void to_lua(lua_State* L, T* ptr) + { + if(ptr == 0) + { + lua_pushnil(L); + return; + } + + // if there is a back_reference, then the + // ownership will be removed from the + // back reference and put on the lua stack. + if(luabind::move_back_reference(L, ptr)) + return; + + using pointer_type = typename pointer_or_default::type; + + make_pointer_instance(L, pointer_type(ptr)); + } + }; + + template + struct adopt_policy_impl + { + template + struct specialize + { + static_assert(detail::is_nonconst_pointer::value, "Adopt policy only accepts non-const pointers"); + using type = adopt_pointer; + }; + }; + + } +} namespace luabind { - template - detail::policy_cons, detail::null_type> - adopt(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + // Caution: if we use the aliased type "policy_list" here, MSVC crashes. + template + using adopt_policy = meta::type_list>>; } #endif // LUABIND_ADOPT_POLICY_HPP_INCLUDE diff --git a/libs/luabind/luabind/back_reference.hpp b/libs/luabind/luabind/back_reference.hpp index 5027618fb..1635c047f 100644 --- a/libs/luabind/luabind/back_reference.hpp +++ b/libs/luabind/luabind/back_reference.hpp @@ -23,88 +23,86 @@ #ifndef LUABIND_BACK_REFERENCE_040510_HPP #define LUABIND_BACK_REFERENCE_040510_HPP -#include +#include +#include +#include + +#if !defined(LUABIND_NO_RTTI) && !defined(LUABIND_WRAPPER_BASE_HPP_INCLUDED) #include -#include -#include -#include -#include -#include +#endif + +#include namespace luabind { + struct wrap_base; -namespace detail -{ - namespace mpl = boost::mpl; - - template - wrap_base const* get_back_reference_aux0(T const* p, mpl::true_) - { - return dynamic_cast(p); - } + namespace detail + { + template + wrap_base const* get_back_reference_aux0(T const* p, std::true_type) + { + return dynamic_cast(p); + } - template - wrap_base const* get_back_reference_aux0(T const*, mpl::false_) - { - return 0; - } + template + wrap_base const* get_back_reference_aux0(T const*, std::false_type) + { + return 0; + } - template - wrap_base const* get_back_reference_aux1(T const* p) - { - return get_back_reference_aux0(p, boost::is_polymorphic()); - } + template + wrap_base const* get_back_reference_aux1(T const* p) + { + return get_back_reference_aux0(p, std::is_polymorphic()); + } - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::true_) - { - return get_back_reference_aux1(get_pointer(x)); - } + template + wrap_base const* get_back_reference_aux2(T const& x, std::true_type) + { + return get_back_reference_aux1(get_pointer(x)); + } - template - wrap_base const* get_back_reference_aux2(T const& x, mpl::false_) - { - return get_back_reference_aux1(&x); - } + template + wrap_base const* get_back_reference_aux2(T const& x, std::false_type) + { + return get_back_reference_aux1(&x); + } - template - wrap_base const* get_back_reference(T const& x) - { - return detail::get_back_reference_aux2( - x - , has_get_pointer() - ); - } - -} // namespace detail + template + wrap_base const* get_back_reference(T const& x) + { + return detail::get_back_reference_aux2(x, has_get_pointer()); + } -template -bool get_back_reference(lua_State* L, T const& x) -{ + } // namespace detail + + template + bool get_back_reference(lua_State* L, T const& x) + { #ifndef LUABIND_NO_RTTI - if (wrap_base const* w = detail::get_back_reference(x)) - { - detail::wrap_access::ref(*w).get(L); - return true; - } + if(wrap_base const* w = detail::get_back_reference(x)) + { + detail::wrap_access::ref(*w).get(L); + return true; + } #endif - return false; -} + return false; + } -template -bool move_back_reference(lua_State* L, T const& x) -{ + template + bool move_back_reference(lua_State* L, T const& x) + { #ifndef LUABIND_NO_RTTI - if (wrap_base* w = const_cast(detail::get_back_reference(x))) - { - assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); - detail::wrap_access::ref(*w).get(L); - detail::wrap_access::ref(*w).m_strong_ref.reset(); - return true; - } + if(wrap_base* w = const_cast(detail::get_back_reference(x))) + { + assert(detail::wrap_access::ref(*w).m_strong_ref.is_valid()); + detail::wrap_access::ref(*w).get(L); + detail::wrap_access::ref(*w).m_strong_ref.reset(); + return true; + } #endif - return false; -} + return false; + } } // namespace luabind diff --git a/libs/luabind/luabind/back_reference_fwd.hpp b/libs/luabind/luabind/back_reference_fwd.hpp index ffe141dba..85cb4478e 100644 --- a/libs/luabind/luabind/back_reference_fwd.hpp +++ b/libs/luabind/luabind/back_reference_fwd.hpp @@ -23,13 +23,15 @@ #ifndef LUABIND_BACK_REFERENCE_FWD_040510_HPP #define LUABIND_BACK_REFERENCE_FWD_040510_HPP +#include + namespace luabind { -template -bool get_back_reference(lua_State* L, T const& x); + template + bool get_back_reference(lua_State* L, T const& x); -template -bool move_back_reference(lua_State* L, T const& x); + template + bool move_back_reference(lua_State* L, T const& x); } // namespace luabind diff --git a/libs/luabind/luabind/class.hpp b/libs/luabind/luabind/class.hpp index 10fb8e03d..320c8065f 100644 --- a/libs/luabind/luabind/class.hpp +++ b/libs/luabind/luabind/class.hpp @@ -52,7 +52,7 @@ TODO: ------------------------------------------------------ - finish smart pointer support + finish smart pointer support * the adopt policy should not be able to adopt pointers to held_types. This must be prohibited. * name_of_type must recognize holder_types and not return "custom" @@ -64,7 +64,7 @@ support the __concat metamethod. This is a bit tricky, since it cannot be treated as a normal operator. It is a binary operator but we want to use the __tostring implementation for both arguments. - + */ #include @@ -75,42 +75,27 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include #include -#include +#include // -> object.hpp #include -#include -#include -#include -#include +#include // -> object.hpp #include #include -#include +#include #include -#include #include -#include +#include #include #include #include -#include #include #include +#include +#include #include +#include // to remove the 'this' used in initialization list-warning #ifdef _MSC_VER @@ -118,17 +103,8 @@ #pragma warning(disable: 4355) #endif -namespace boost -{ - - template class shared_ptr; - -} // namespace boost - -namespace luabind -{ - namespace detail - { +namespace luabind { + namespace detail { struct unspecified {}; template struct operator_; @@ -136,96 +112,86 @@ namespace luabind struct you_need_to_define_a_get_const_holder_function_for_your_smart_ptr {}; } - template + template < typename... BaseClasses > + struct bases { }; + + using no_bases = bases< >; + using default_holder = null_type; + + namespace detail { + + template < typename T > + struct make_bases { + using type = bases< T >; + }; + + template< typename... Bases > + struct make_bases< bases< Bases... > > { + using type = bases< Bases... >; + }; + } + + template< typename T > + using make_bases = typename detail::make_bases< T >::type; + + template< typename... Args > + struct constructor + {}; + + // helper for overloaded methods, only need to provide argument types (IntelliSense bug squiggles the code, but it does compile!) + template< typename... Args > + struct meth { + template< typename Class, typename Ret > + static auto use_nonconst(Ret(Class::*fn)(Args...)) -> decltype(fn) + { + return fn; + } + + template< typename Class, typename Ret > + static auto use_const(Ret(Class::*fn)(Args...) const) -> decltype(fn) + { + return fn; + } + + template< typename Class, typename Ret > + static auto use_auto(Ret(Class::*fn)(Args...) const) -> decltype(fn) + { + return fn; + } + + template< typename Class, typename Ret > + static auto use_auto(Ret(Class::*fn)(Args...)) -> decltype(fn) + { + return fn; + } + }; + + // TODO: Could specialize for certain base classes to make the interface "type safe". + template struct class_; // TODO: this function will only be invoked if the user hasn't defined a correct overload // maybe we should have a static assert in here? inline detail::you_need_to_define_a_get_const_holder_function_for_your_smart_ptr* - get_const_holder(...) + get_const_holder(...) { return 0; } template - boost::shared_ptr* get_const_holder(boost::shared_ptr*) + std::shared_ptr* get_const_holder(std::shared_ptr*) { return 0; } - template < - BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT( - LUABIND_MAX_BASES, class A, detail::null_type) - > - struct bases - {}; - typedef bases no_bases; - - namespace detail - { - template - struct is_bases - : mpl::false_ - {}; - - template - struct is_bases > - : mpl::true_ - {}; - - template - struct is_unspecified - : mpl::apply1 - {}; - - template - struct is_unspecified - : mpl::true_ - {}; - - template - struct is_unspecified_mfn - { - template - struct apply - : is_unspecified - {}; - }; - - template - struct get_predicate - { - typedef mpl::protect > type; - }; - - template - struct result_or_default - { - typedef Result type; - }; - - template - struct result_or_default - { - typedef Default type; - }; - - template - struct extract_parameter - { - typedef typename get_predicate::type pred; - typedef typename boost::mpl::find_if::type iterator; - typedef typename result_or_default< - typename iterator::type, DefaultValue - >::type type; - }; + namespace detail { // prints the types of the values on the stack, in the // range [start_index, lua_gettop()] LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - + struct LUABIND_API create_class { static int stage1(lua_State* L); @@ -252,7 +218,7 @@ namespace luabind private: template void operator,(U const&) const; void operator=(static_scope const&); - + T& self; }; @@ -261,7 +227,7 @@ namespace luabind struct LUABIND_API class_base : scope { public: - class_base(char const* name); + class_base(char const* name); struct base_desc { @@ -270,10 +236,10 @@ namespace luabind }; void init( - type_id const& type, class_id id - , type_id const& wrapped_type, class_id wrapper_id); + type_id const& type, class_id id + , type_id const& wrapped_type, class_id wrapper_id); - void add_base(type_id const& base, cast_function cast); + void add_base(type_id const& base, cast_function cast); void add_member(registration* member); void add_default_member(registration* member); @@ -283,15 +249,15 @@ namespace luabind void add_static_constant(const char* name, int val); void add_inner_scope(scope& s); - void add_cast(class_id src, class_id target, cast_function cast); + void add_cast(class_id src, class_id target, cast_function cast); private: class_registration* m_registration; }; -// MSVC complains about member being sensitive to alignment (C4121) -// when F is a pointer to member of a class with virtual bases. -# ifdef BOOST_MSVC + // MSVC complains about member being sensitive to alignment (C4121) + // when F is a pointer to member of a class with virtual bases. +# ifdef _MSC_VER # pragma pack(push) # pragma pack(16) # endif @@ -299,574 +265,327 @@ namespace luabind template struct memfun_registration : registration { - memfun_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) + memfun_registration(char const* name, F f) + : name(name), f(f) {} void register_(lua_State* L) const { - object fn = make_function( - L, f, deduce_signature(f, (Class*)0), policies); - - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); + // Need to check if the class type of the signature is a base of this class + object fn = make_function(L, f, deduce_signature_t(), Policies()); + add_overload(object(from_stack(L, -1)), name, fn); } char const* name; F f; - Policies policies; }; -# ifdef BOOST_MSVC +# ifdef _MSC_VER # pragma pack(pop) # endif - template - struct default_pointer - { - typedef P type; - }; + template + struct default_pointer + { + using type = P; + }; - template - struct default_pointer - { - typedef std::auto_ptr type; - }; + template + struct default_pointer + { + using type = std::unique_ptr; + }; - template - struct constructor_registration : registration - { - constructor_registration(Policies const& policies) - : policies(policies) - {} + template + struct constructor_registration : registration + { + constructor_registration() + {} - void register_(lua_State* L) const - { - typedef typename default_pointer::type pointer; + void register_(lua_State* L) const + { + using pointer = typename default_pointer::type; + object fn = make_function(L, construct(), Signature(), Policies()); + add_overload(object(from_stack(L, -1)), "__init", fn); + } + }; - object fn = make_function( - L - , construct(), Signature() - , policies - ); + template + struct reference_result + : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< T >::type > + {}; - add_overload( - object(from_stack(L, -1)) - , "__init" - , fn - ); - } + template + struct reference_argument + : std::conditional< std::is_pointer::value || is_primitive::value, T, typename std::add_lvalue_reference< typename std::add_const::type >::type > + {}; - Policies policies; - }; + template + struct inject_dependency_policy + { + using type = typename std::conditional < + is_primitive::value || meta::contains >::value, + Policies, + typename meta::push_back< Policies, call_policy_injector< dependency_policy<0, 1> > >::type + >::type; + }; - template - struct reference_result - : mpl::if_< - mpl::or_, is_primitive > - , T - , typename boost::add_reference::type - > - {}; + template + struct property_registration : registration + { + property_registration(char const* name, Get const& get, Set const& set = null_type()) + : name(name), get(get), set(set) + {} - template - struct inject_dependency_policy - : mpl::if_< - is_primitive - , Policies - , policy_cons, Policies> - > - {}; + template + object make_get(lua_State* L, F const& f, std::false_type /*member_ptr*/) const + { + return make_function(L, f, GetPolicies()); + } - template < - class Class - , class Get, class GetPolicies - , class Set = null_type, class SetPolicies = null_type - > - struct property_registration : registration - { - property_registration( - char const* name - , Get const& get - , GetPolicies const& get_policies - , Set const& set = Set() - , SetPolicies const& set_policies = SetPolicies() - ) - : name(name) - , get(get) - , get_policies(get_policies) - , set(set) - , set_policies(set_policies) - {} + template + object make_get(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const + { + using result_type = typename reference_result::type; + using get_signature = meta::type_list; + using injected_list = typename inject_dependency_policy< D, GetPolicies >::type; - void register_(lua_State* L) const - { - object context(from_stack(L, -1)); - register_aux( - L - , context - , make_get(L, get, boost::is_member_object_pointer()) - , set - ); - } + return make_function(L, access_member_ptr(mem_ptr), get_signature(), injected_list()); + } - template - object make_get(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), get_policies); - } + template + object make_set(lua_State* L, F const& f, std::false_type /*member_ptr*/) const + { + return make_function(L, f, deduce_signature_t(), SetPolicies()); + } - template - object make_get(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - typedef typename reference_result::type result_type; - typedef typename inject_dependency_policy< - D, GetPolicies>::type policies; + template + object make_set(lua_State* L, D T::* mem_ptr, std::true_type /*member_ptr*/) const + { + using argument_type = typename reference_argument::type; + using signature_type = meta::type_list; - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector2() - , policies() - ); - } + return make_function(L, access_member_ptr(mem_ptr), signature_type(), SetPolicies()); + } - template - object make_set(lua_State* L, F const& f, mpl::false_) const - { - return make_function( - L, f, deduce_signature(f, (Class*)0), set_policies); - } + // if a setter was given + template + void register_aux(lua_State* L, object const& context, object const& get_, SetterType const&) const + { + context[name] = property(get_, make_set(L, set, std::is_member_object_pointer())); + } - template - object make_set(lua_State* L, D T::* mem_ptr, mpl::true_) const - { - return make_function( - L - , access_member_ptr(mem_ptr) - , mpl::vector3() - , set_policies - ); - } + // if no setter was given + void register_aux(lua_State*, object const& context, object const& get_, null_type) const + { + context[name] = property(get_); + } - template - void register_aux( - lua_State* L, object const& context - , object const& get_, S const&) const - { - context[name] = property( - get_ - , make_set(L, set, boost::is_member_object_pointer()) - ); - } + // register entry + void register_(lua_State* L) const + { + object context(from_stack(L, -1)); + register_aux(L, context, make_get(L, get, std::is_member_object_pointer()), set); + } - void register_aux( - lua_State*, object const& context - , object const& get_, null_type) const - { - context[name] = property(get_); - } - char const* name; - Get get; - GetPolicies get_policies; - Set set; - SetPolicies set_policies; - }; + char const* name; + Get get; + Set set; + }; } // namespace detail // registers a class in the lua environment - template - struct class_: detail::class_base + template + struct class_ + : detail::class_base { - typedef class_ self_t; + using self_t = class_; + using BaseList = make_bases< BaseOrBases >; - private: - - template - class_(const class_&); public: - - typedef boost::mpl::vector4 parameters_type; - - // WrappedType MUST inherit from T - typedef typename detail::extract_parameter< - parameters_type - , boost::is_base_and_derived - , detail::null_type - >::type WrappedType; - - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::not_< - boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - , boost::is_base_and_derived - > - > - , detail::null_type - >::type HeldType; - - template - void add_downcast(Src*, Target*, boost::mpl::true_) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::dynamic_cast_::execute - ); - } - - template - void add_downcast(Src*, Target*, boost::mpl::false_) - {} - - // this function generates conversion information - // in the given class_rep structure. It will be able - // to implicitly cast to the given template type - template - void gen_base_info(detail::type_) - { - add_base(typeid(To), detail::static_cast_::execute); - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((To*)0, (T*)0, boost::is_polymorphic()); - } - - void gen_base_info(detail::type_) - {} - -#define LUABIND_GEN_BASE_INFO(z, n, text) gen_base_info(detail::type_()); - - template - void generate_baseclass_list(detail::type_ >) - { - BOOST_PP_REPEAT(LUABIND_MAX_BASES, LUABIND_GEN_BASE_INFO, _) - } - -#undef LUABIND_GEN_BASE_INFO - - class_(const char* name): class_base(name), scope(*this) + class_(const char* name) : class_base(name), scope(*this) { #ifndef NDEBUG detail::check_link_compatibility(); #endif - init(); - } - - template - class_& def(const char* name, F f) - { - return this->virtual_def( - name, f, detail::null_type() - , detail::null_type(), boost::mpl::true_()); + init(); } // virtual functions - template - class_& def(char const* name, F fn, DefaultOrPolicies default_or_policies) + template + class_& def(char const* name, F fn, policy_list< Injectors... > policies = no_policies()) { - return this->virtual_def( - name, fn, default_or_policies, detail::null_type() - , LUABIND_MSVC_TYPENAME detail::is_policy_cons::type()); + return this->virtual_def(name, fn, policies, null_type()); } - template - class_& def(char const* name, F fn - , Default default_, Policies const& policies) + // IntelliSense bug squiggles the code, but it does compile! + template + class_& def_nonconst(char const* name, Ret(C::*fn)(Args...), policy_list policies = no_policies()) { - return this->virtual_def( - name, fn, default_ - , policies, boost::mpl::false_()); + return def(name, fn, policies); } - template - class_& def(constructor sig) + // IntelliSense bug squiggles the code, but it does compile! + template + class_& def_const(char const* name, Ret(C::*fn)(Args...) const, policy_list policies = no_policies()) { - return this->def_constructor(&sig, detail::null_type()); + return def(name, fn, policies); } - template - class_& def(constructor sig, const Policies& policies) + template + class_& def(char const* name, F fn, Default default_, policy_list< Injectors... > policies = no_policies()) { - return this->def_constructor(&sig, policies); + return this->virtual_def(name, fn, policies, default_); } - template - class_& property(const char* name, Getter g) - { - this->add_member( - new detail::property_registration( - name, g, detail::null_type())); - return *this; - } - - template - class_& property(const char* name, Getter g, MaybeSetter s) - { - return property_impl( - name, g, s - , boost::mpl::bool_::value>() - ); - } - - template - class_& property(const char* name, Getter g, Setter s, const GetPolicies& get_policies) - { - typedef detail::property_registration< - T, Getter, GetPolicies, Setter, detail::null_type - > registration_type; - - this->add_member( - new registration_type(name, g, get_policies, s)); - return *this; - } - - template - class_& property( - const char* name - , Getter g, Setter s - , GetPolicies const& get_policies - , SetPolicies const& set_policies) - { - typedef detail::property_registration< - T, Getter, GetPolicies, Setter, SetPolicies - > registration_type; - - this->add_member( - new registration_type(name, g, get_policies, s, set_policies)); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, detail::null_type())); - return *this; - } - - template - class_& def_readonly(const char* name, D C::*mem_ptr, Policies const& policies) - { - typedef detail::property_registration - registration_type; - - this->add_member( - new registration_type(name, mem_ptr, policies)); - return *this; - } - - template - class_& def_readwrite(const char* name, D C::*mem_ptr) - { - typedef detail::property_registration< - T, D C::*, detail::null_type, D C::* - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, detail::null_type(), mem_ptr)); - return *this; - } - - template - class_& def_readwrite( - const char* name, D C::*mem_ptr, GetPolicies const& get_policies) - { - typedef detail::property_registration< - T, D C::*, GetPolicies, D C::* - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, get_policies, mem_ptr)); - return *this; - } - - template - class_& def_readwrite( - const char* name - , D C::*mem_ptr - , GetPolicies const& get_policies - , SetPolicies const& set_policies - ) - { - typedef detail::property_registration< - T, D C::*, GetPolicies, D C::*, SetPolicies - > registration_type; - - this->add_member( - new registration_type( - name, mem_ptr, get_policies, mem_ptr, set_policies)); - return *this; - } - - template - class_& def(detail::operator_, Policies const& policies) + template + class_& def(constructor sig, policy_list< Injectors... > policies = no_policies()) { - return this->def( - Derived::name() - , &Derived::template apply::execute - , policies - ); + return this->def_constructor(sig, policies); } - template - class_& def(detail::operator_) + // ====================== + // Start of reworked property overloads + // ====================== + + template + class_& property(const char* name, Getter g, policy_list< Injectors... > get_injectors = no_policies()) { - return this->def( - Derived::name() - , &Derived::template apply::execute - ); + return property(name, g, null_type(), get_injectors); + } + + template + class_& property(const char* name, Getter g, Setter s, policy_list = no_policies(), policy_list = no_policies()) + { + using registration_type = detail::property_registration, Setter, policy_list>; + this->add_member(new registration_type(name, g, s)); + return *this; + } + + template + class_& def_readonly(const char* name, D C::*mem_ptr, policy_list policies = no_policies()) + { + return property(name, mem_ptr, policies); + } + + template + class_& def_readwrite(const char* name, D C::*mem_ptr, policy_list get_injectors = no_policies(), policy_list set_injectors = no_policies()) + { + return property(name, mem_ptr, mem_ptr, get_injectors, set_injectors); + } + + // ===================== + // End of reworked property overloads + // ===================== + + template + class_& def(detail::operator_, policy_list policies = no_policies()) + { + using policy_list_type = policy_list; + return this->def(Derived::name(), &Derived::template apply::execute, policies); } detail::enum_maker enum_(const char*) { return detail::enum_maker(*this); } - + detail::static_scope scope; - + private: - void operator=(class_ const&); - - void add_wrapper_cast(detail::null_type*) - {} - - template - void add_wrapper_cast(U*) - { - add_cast( - detail::registered_class::id - , detail::registered_class::id - , detail::static_cast_::execute - ); - - add_downcast((T*)0, (U*)0, boost::is_polymorphic()); - } - void init() { - typedef typename detail::extract_parameter< - parameters_type - , boost::mpl::or_< - detail::is_bases - , boost::is_base_and_derived - > - , no_bases - >::type bases_t; - - typedef typename - boost::mpl::if_ - , bases_t - , bases - >::type Base; - - class_base::init( - typeid(T) - , detail::registered_class::id - , typeid(WrappedType) - , detail::registered_class::id - ); - - add_wrapper_cast((WrappedType*)0); - - generate_baseclass_list(detail::type_()); + class_base::init(typeid(T), detail::registered_class::id, typeid(WrapperType), detail::registered_class::id); + add_wrapper_cast((WrapperType*)0); + generate_baseclass_list(); } - template - class_& property_impl(const char* name, - Getter g, - GetPolicies policies, - boost::mpl::bool_) + + template + class_(const class_&); + + template + void add_downcast(Src*, Target*, std::true_type) { - this->add_member( - new detail::property_registration( - name, g, policies)); - return *this; + add_cast(detail::registered_class::id, detail::registered_class::id, detail::dynamic_cast_::execute); } - template - class_& property_impl(const char* name, - Getter g, - Setter s, - boost::mpl::bool_) - { - typedef detail::property_registration< - T, Getter, detail::null_type, Setter, detail::null_type - > registration_type; + template + void add_downcast(Src*, Target*, std::false_type) + {} - this->add_member( - new registration_type(name, g, detail::null_type(), s)); - return *this; + // this function generates conversion information + // in the given class_rep structure. It will be able + // to implicitly cast to the given template type + template + void gen_base_info(bases) + { + add_base(typeid(Class0), detail::static_cast_::execute); + add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); + add_downcast((Class0*)0, (T*)0, std::is_polymorphic()); + gen_base_info(bases()); + } + + void gen_base_info(bases<>) + { + } + + void generate_baseclass_list() + { + gen_base_info(BaseList()); + } + + void operator=(class_ const&); + + void add_wrapper_cast(null_type*) + {} + + template + void add_wrapper_cast(U*) + { + add_cast(detail::registered_class::id, detail::registered_class::id, detail::static_cast_::execute); + add_downcast((T*)0, (U*)0, std::is_polymorphic()); } // these handle default implementation of virtual functions - template - class_& virtual_def(char const* name, F const& fn - , Policies const&, detail::null_type, boost::mpl::true_) + template + class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, Default default_) { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); + using policy_list_type = policy_list< Injectors... >; + this->add_member(new detail::memfun_registration(name, fn)); + this->add_default_member(new detail::memfun_registration(name, default_)); return *this; } - template - class_& virtual_def(char const* name, F const& fn - , Default const& default_, Policies const&, boost::mpl::false_) + template + class_& virtual_def(char const* name, F const& fn, policy_list< Injectors... >, null_type) { - this->add_member( - new detail::memfun_registration( - name, fn, Policies())); - - this->add_default_member( - new detail::memfun_registration( - name, default_, Policies())); - + using policy_list_type = policy_list< Injectors... >; + this->add_member(new detail::memfun_registration(name, fn)); return *this; } - template - class_& def_constructor(Signature*, Policies const&) - { - typedef typename Signature::signature signature; + template + class_& def_constructor(constructor const&, policy_list< Injectors... > const&) + { + using signature_type = meta::type_list; + using policy_list_type = policy_list< Injectors... >; - typedef typename boost::mpl::if_< - boost::is_same - , T - , WrappedType - >::type construct_type; + using construct_type = typename std::conditional< + is_null_type::value, + T, + WrapperType + >::type; - this->add_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); + using registration_type = detail::constructor_registration; + this->add_member(new registration_type()); + this->add_default_member(new registration_type()); - this->add_default_member( - new detail::constructor_registration< - construct_type, HeldType, signature, Policies>( - Policies())); - - return *this; - } + return *this; + } }; } diff --git a/libs/luabind/luabind/class_info.hpp b/libs/luabind/luabind/class_info.hpp index a4f18a8cc..d779f250b 100644 --- a/libs/luabind/luabind/class_info.hpp +++ b/libs/luabind/luabind/class_info.hpp @@ -20,7 +20,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - #ifndef LUABIND_CLASS_INFO_HPP_INCLUDED #define LUABIND_CLASS_INFO_HPP_INCLUDED @@ -32,16 +31,16 @@ namespace luabind { struct LUABIND_API class_info - { + { std::string name; object methods; object attributes; }; - LUABIND_API class_info get_class_info(argument const&); + LUABIND_API class_info get_class_info(argument const&); - // returns a table of bound class names - LUABIND_API object get_class_names(lua_State* L); + // returns a table of bound class names + LUABIND_API object get_class_names(lua_State* L); LUABIND_API void bind_class_info(lua_State*); } diff --git a/libs/luabind/luabind/config.hpp b/libs/luabind/luabind/config.hpp index e8eea875c..e91c867de 100644 --- a/libs/luabind/luabind/config.hpp +++ b/libs/luabind/luabind/config.hpp @@ -20,57 +20,26 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - #ifndef LUABIND_CONFIG_HPP_INCLUDED #define LUABIND_CONFIG_HPP_INCLUDED -#include - -#ifdef BOOST_MSVC - #define LUABIND_ANONYMOUS_FIX static -#else - #define LUABIND_ANONYMOUS_FIX -#endif - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) - -#define for if (false) {} else for - -#include - -namespace std -{ - using ::strlen; - using ::strcmp; - using ::type_info; -} - -#endif - - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1300) - #define LUABIND_MSVC_TYPENAME -#else - #define LUABIND_MSVC_TYPENAME typename -#endif - // the maximum number of arguments of functions that's // registered. Must at least be 2 #ifndef LUABIND_MAX_ARITY - #define LUABIND_MAX_ARITY 10 +#define LUABIND_MAX_ARITY 100 #elif LUABIND_MAX_ARITY <= 1 - #undef LUABIND_MAX_ARITY - #define LUABIND_MAX_ARITY 2 +#undef LUABIND_MAX_ARITY +#define LUABIND_MAX_ARITY 2 #endif // the maximum number of classes one class // can derive from // max bases must at least be 1 #ifndef LUABIND_MAX_BASES - #define LUABIND_MAX_BASES 4 +#define LUABIND_MAX_BASES 100 #elif LUABIND_MAX_BASES <= 0 - #undef LUABIND_MAX_BASES - #define LUABIND_MAX_BASES 1 +#undef LUABIND_MAX_BASES +#define LUABIND_MAX_BASES 1 #endif // LUABIND_NO_ERROR_CHECKING @@ -101,12 +70,18 @@ namespace std // C code has undefined behavior, lua is written in C). #ifdef LUABIND_DYNAMIC_LINK -# ifdef BOOST_WINDOWS +# if defined (_WIN32) # ifdef LUABIND_BUILDING # define LUABIND_API __declspec(dllexport) # else # define LUABIND_API __declspec(dllimport) # endif +# elif defined (__CYGWIN__) +# ifdef LUABIND_BUILDING +# define LUABIND_API __attribute__ ((dllexport)) +# else +# define LUABIND_API __attribute__ ((dllimport)) +# endif # else # if defined(_GNUC_) && _GNUC_ >=4 # define LUABIND_API __attribute__ ((visibility("default"))) @@ -118,9 +93,19 @@ namespace std # define LUABIND_API #endif +// This switches between using tag arguments / structure specialization for code size tests +#define LUABIND_NO_INTERNAL_TAG_ARGUMENTS + namespace luabind { -LUABIND_API void disable_super_deprecation(); + LUABIND_API void disable_super_deprecation(); + + namespace detail { + const int max_argument_count = 100; + const int max_hierarchy_depth = 100; + } + + const int no_match = -(detail::max_argument_count*detail::max_hierarchy_depth + 1); } // namespace luabind diff --git a/libs/luabind/luabind/container_policy.hpp b/libs/luabind/luabind/container_policy.hpp index 68ad0a90f..460096abb 100644 --- a/libs/luabind/luabind/container_policy.hpp +++ b/libs/luabind/luabind/container_policy.hpp @@ -20,124 +20,111 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - #ifndef LUABIND_CONTAINER_POLICY_HPP_INCLUDED #define LUABIND_CONTAINER_POLICY_HPP_INCLUDED #include #include -#include +#include // for decorated_type +#include // for null_type (ptr only), etc -namespace luabind { namespace detail { +namespace luabind { + namespace detail { - namespace mpl = boost::mpl; - - template - struct container_converter_lua_to_cpp - { - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) + template + struct container_converter_lua_to_cpp { - typedef typename T::value_type value_type; + enum { consumed_args = 1 }; - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - T container; - - lua_pushnil(L); - while (lua_next(L, index)) + template + T to_cpp(lua_State* L, by_const_reference, int index) { - container.push_back(converter.apply(L, LUABIND_DECORATE_TYPE(value_type), -1)); - lua_pop(L, 1); // pop value + using value_type = typename T::value_type; + specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; + + T container; + + lua_pushnil(L); + while(lua_next(L, index - 1)) + { + container.push_back(converter.apply(L, decorated_type(), -1)); + lua_pop(L, 1); // pop value + } + + return container; } - return container; - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_istable(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct container_converter_cpp_to_lua - { - template - void apply(lua_State* L, const T& container) - { - typedef typename T::value_type value_type; - - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - lua_newtable(L); - - int index = 1; - - for (typename T::const_iterator i = container.begin(); i != container.end(); ++i) + template + T to_cpp(lua_State* L, by_value, int index) { - converter.apply(L, *i); - lua_rawseti(L, -2, index); - ++index; + return to_cpp(L, by_const_reference(), index); } - } - }; - template -// struct container_policy : converter_policy_tag - struct container_policy : conversion_policy - { -// BOOST_STATIC_CONSTANT(int, index = N); + template + static int match(lua_State* L, by_const_reference, int index) + { + if(lua_istable(L, index)) return 0; else return no_match; + } - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } - struct only_accepts_nonconst_pointers {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , container_converter_lua_to_cpp - , container_converter_cpp_to_lua - >::type type; + template + void converter_postcall(lua_State*, T, int) {} }; - }; -}} + template + struct container_converter_cpp_to_lua + { + template + void to_lua(lua_State* L, const T& container) + { + using value_type = typename T::value_type; + specialized_converter_policy_n<1, Policies, value_type, lua_to_cpp> converter; -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + lua_newtable(L); + + int index = 1; + + for(const auto& element : container) + { + converter.apply(L, element); + lua_rawseti(L, -2, index); + ++index; + } + } + }; + + template + struct container_policy + { + struct only_accepts_nonconst_pointers {}; + + template + struct specialize; + + template + struct specialize { + using type = container_converter_lua_to_cpp; + }; + + template + struct specialize { + using type = container_converter_cpp_to_lua; + }; + }; - template - detail::policy_cons, detail::null_type> - container(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); } } +namespace luabind +{ + template + using container_policy = meta::type_list>>; +} + #endif // LUABIND_CONTAINER_POLICY_HPP_INCLUDED + diff --git a/libs/luabind/luabind/copy_policy.hpp b/libs/luabind/luabind/copy_policy.hpp index 1a18b729b..7115a4511 100644 --- a/libs/luabind/luabind/copy_policy.hpp +++ b/libs/luabind/luabind/copy_policy.hpp @@ -8,52 +8,41 @@ # include namespace luabind { + namespace detail { -namespace detail -{ + struct copy_converter + { + template + void to_lua(lua_State* L, T const& x) + { + value_converter().to_lua(L, x); + } - struct copy_converter - { - template - void apply(lua_State* L, T const& x) - { - value_converter().apply(L, x); - } + template + void to_lua(lua_State* L, T* x) + { + if(!x) + lua_pushnil(L); + else + to_lua(L, *x); + } + }; - template - void apply(lua_State* L, T* x) - { - if (!x) - lua_pushnil(L); - else - apply(L, *x); - } - }; + struct copy_policy + { + template + struct specialize + { + static_assert(std::is_same::value, "Copy policy only supports cpp -> lua"); + using type = copy_converter; + }; + }; - template - struct copy_policy : conversion_policy - { - static void precall(lua_State*, index_map const&) - {} + } // namespace detail - static void postcall(lua_State*, index_map const&) - {} - - template - struct apply - { - typedef copy_converter type; - }; - }; - -} // namespace detail - -template -detail::policy_cons, detail::null_type> -copy(LUABIND_PLACEHOLDER_ARG(N)) -{ - return detail::policy_cons, detail::null_type>(); -} + // Caution: If we use the aliased type "policy_list" here, MSVC crashes. + template< unsigned int N > + using copy_policy = meta::type_list< converter_policy_injector< N, detail::copy_policy > >; } // namespace luabind diff --git a/libs/luabind/luabind/dependency_policy.hpp b/libs/luabind/luabind/dependency_policy.hpp index cafa49aa1..c16db1605 100644 --- a/libs/luabind/luabind/dependency_policy.hpp +++ b/libs/luabind/luabind/dependency_policy.hpp @@ -25,95 +25,75 @@ #define LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED #include -#include +#include // for policy_cons, etc +#include // for object_rep +#include // for null_type -namespace luabind { namespace detail -{ - // makes A dependent on B, meaning B will outlive A. - // internally A stores a reference to B - template - struct dependency_policy - { - static void postcall(lua_State* L, const index_map& indices) +namespace luabind { + namespace detail { + + // makes A dependent on B, meaning B will outlive A. + // internally A stores a reference to B + template + struct dependency_policy { - int nurse_index = indices[A]; - int patient = indices[B]; + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, A>::value)); - object_rep* nurse = static_cast(lua_touserdata(L, nurse_index)); + // If the nurse isn't an object_rep, just make this a nop. + if(nurse == 0) + return; - // If the nurse isn't an object_rep, just make this a nop. - if (nurse == 0) - return; - - nurse->add_dependency(L, patient); - } - }; - -}} - -#if defined (BOOST_MSVC) && (BOOST_MSVC <= 1200) - -namespace luabind -{ - // most absurd workaround of all time? - namespace detail - { - template - struct size_char_array - { - char storage[N + 2]; + nurse->add_dependency(L, meta::get, B>::value); + } }; - template - size_char_array deduce_size(LUABIND_PLACEHOLDER_ARG(N)); - - template - struct get_index_workaround + template + struct dependency_policy<0, B> { - static T t; - BOOST_STATIC_CONSTANT(int, value = sizeof(deduce_size(t)) - 2); + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, 0>::value + results)); + + // If the nurse isn't an object_rep, just make this a nop. + if(nurse == 0) + return; + + nurse->add_dependency(L, meta::get, B>::value); + } }; - } - template - detail::policy_cons::value - , detail::get_index_workaround::value>, detail::null_type> dependency(A,B) - { - return detail::policy_cons::value, detail::get_index_workaround::value> - , detail::null_type>(); - } + template + struct dependency_policy + { + template< unsigned int... StackIndices > + static void postcall(lua_State* L, int results, meta::index_list) + { + object_rep* nurse = static_cast(lua_touserdata(L, meta::get, A>::value)); + + // If the nurse isn't an object_rep, just make this a nop. + if(nurse == 0) + return; + + nurse->add_dependency(L, meta::get, 0>::value + results); + } + }; - template - detail::policy_cons::value>, detail::null_type> - return_internal_reference(A) - { - return detail::policy_cons::value>, detail::null_type>(); } } -#else - namespace luabind { - template - detail::policy_cons, detail::null_type> - dependency(LUABIND_PLACEHOLDER_ARG(A), LUABIND_PLACEHOLDER_ARG(B)) - { - return detail::policy_cons, detail::null_type>(); - } + // Caution: If we use the aliased type "policy_list" here, MSVC crashes. + template + using dependency_policy = meta::type_list>>; - template - detail::policy_cons, detail::null_type> - return_internal_reference(LUABIND_PLACEHOLDER_ARG(A)) - { - return detail::policy_cons, detail::null_type>(); - } + template + using return_internal_reference = meta::type_list>>; } -#endif - #endif // LUABIND_DEPENDENCY_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/call.hpp b/libs/luabind/luabind/detail/call.hpp index cd9402ef3..94dbb8d4d 100644 --- a/libs/luabind/luabind/detail/call.hpp +++ b/libs/luabind/luabind/detail/call.hpp @@ -1,323 +1,547 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is +// Copyright Daniel Wallin 208.Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#if !BOOST_PP_IS_ITERATING +#ifndef LUABIND_CALL2_080911_HPP +#define LUABIND_CALL2_080911_HPP -# ifndef LUABIND_CALL2_080911_HPP -# define LUABIND_CALL2_080911_HPP +#include +#include +#include +#include +#include +#include +#include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS +#include +#endif -# include -# include -# include +namespace luabind { + namespace detail { -namespace luabind { namespace detail { + struct invoke_context; -struct invoke_context; + struct LUABIND_API function_object + { + function_object(lua_CFunction entry) + : entry(entry) + , next(0) + {} -struct LUABIND_API function_object -{ - function_object(lua_CFunction entry) - : entry(entry) - , next(0) - {} + virtual ~function_object() + {} - virtual ~function_object() - {} + virtual int call(lua_State* L, invoke_context& ctx) /* const */ = 0; + virtual void format_signature(lua_State* L, char const* function) const = 0; - virtual int call( - lua_State* L, invoke_context& ctx) const = 0; - virtual void format_signature(lua_State* L, char const* function) const = 0; + lua_CFunction entry; + std::string name; + function_object* next; + object keepalive; + }; - lua_CFunction entry; - std::string name; - function_object* next; - object keepalive; -}; + struct LUABIND_API invoke_context + { + invoke_context() + : best_score((std::numeric_limits::max)()) + //This need to avoid static analyzer's treats + , candidates{ nullptr,nullptr,nullptr,nullptr,nullptr, + nullptr,nullptr,nullptr,nullptr,nullptr } + , candidate_index(0) + {} -struct LUABIND_API invoke_context -{ - invoke_context() - : best_score((std::numeric_limits::max)()) - , candidate_index(0) - {} + operator bool() const + { + return candidate_index == 1; + } - operator bool() const - { - return candidate_index == 1; - } + void format_error(lua_State* L, function_object const* overloads) const; - void format_error(lua_State* L, function_object const* overloads) const; + int best_score; + function_object const* candidates[10]; // This looks like it could crash if you provide too many overloads? + int candidate_index; + }; - int best_score; - function_object const* candidates[10]; - int candidate_index; -}; + namespace call_detail_new { -template -inline int invoke0( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const& policies, IsVoid, mpl::true_) -{ - return invoke_member( - L, self, ctx, f, Signature(), policies - , mpl::long_::value - 1>(), IsVoid() - ); -} + /* + Compute Stack Indices + Given the list of argument converter arities, computes the stack indices that each converter addresses. + */ -template -inline int invoke0( - lua_State* L, function_object const& self, invoke_context& ctx, - F const& f, Signature, Policies const& policies, IsVoid, mpl::false_) -{ - return invoke_normal( - L, self, ctx, f, Signature(), policies - , mpl::long_::value - 1>(), IsVoid() - ); -} + template< typename ConsumedList, unsigned int CurrentSum, unsigned int... StackIndices > + struct compute_stack_indices; -template -inline int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const& policies) -{ - return invoke0( - L, self, ctx, f, Signature(), policies - , boost::is_void::type>() - , boost::is_member_function_pointer() - ); -} + template< unsigned int Consumed0, unsigned int... Consumeds, unsigned int CurrentSum, unsigned int... StackIndices > + struct compute_stack_indices< meta::index_list< Consumed0, Consumeds... >, CurrentSum, StackIndices... > + { + using type = typename compute_stack_indices< meta::index_list< Consumeds... >, CurrentSum + Consumed0, StackIndices..., CurrentSum >::type; + }; -inline int maybe_yield_aux(lua_State*, int results, mpl::false_) -{ - return results; -} + template< unsigned int CurrentSum, unsigned int... StackIndices > + struct compute_stack_indices< meta::index_list< >, CurrentSum, StackIndices... > + { + using type = meta::index_list< StackIndices... >; + }; -inline int maybe_yield_aux(lua_State* L, int results, mpl::true_) -{ - return lua_yield(L, results); -} + template< typename Foo > + struct FooFoo { // Foo! + enum { consumed_args = Foo::consumed_args }; + }; -template -int maybe_yield(lua_State* L, int results, Policies*) -{ - return maybe_yield_aux( - L, results, mpl::bool_::value>()); -} -inline int sum_scores(int const* first, int const* last) -{ - int result = 0; + template< typename PolicyList, typename StackIndexList > + struct policy_list_postcall; - for (; first != last; ++first) - { - if (*first < 0) - return *first; - result += *first; - } + template< typename Policy0, typename... Policies, typename StackIndexList > + struct policy_list_postcall< meta::type_list< call_policy_injector, Policies... >, StackIndexList > { + static void postcall(lua_State* L, int results) { + Policy0::postcall(L, results, StackIndexList()); + policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); + } + }; - return result; -} + template< typename ConverterPolicy, typename StackIndexList, bool has_postcall > + struct converter_policy_postcall { + static void postcall(lua_State* L, int results) { + ConverterPolicy::postcall(L, results, StackIndexList()); + } + }; -# define LUABIND_INVOKE_NEXT_ITER(n) \ - typename mpl::next< \ - BOOST_PP_IF( \ - n, BOOST_PP_CAT(iter,BOOST_PP_DEC(n)), first) \ - >::type + template< typename ConverterPolicy, typename StackIndexList > + struct converter_policy_postcall< ConverterPolicy, StackIndexList, false > { + static void postcall(lua_State* /*L*/, int /*results*/) { + } + }; -# define LUABIND_INVOKE_NEXT_INDEX(n) \ - BOOST_PP_IF( \ - n \ - , BOOST_PP_CAT(index,BOOST_PP_DEC(n)) + \ - BOOST_PP_CAT(c,BOOST_PP_DEC(n)).consumed_args() \ - , 1 \ - ) + template< unsigned int Index, typename Policy, typename... Policies, typename StackIndexList > + struct policy_list_postcall< meta::type_list< converter_policy_injector< Index, Policy >, Policies... >, StackIndexList > { + static void postcall(lua_State* L, int results) { + converter_policy_postcall < Policy, StackIndexList, converter_policy_injector< Index, Policy >::has_postcall >::postcall(L, results); + policy_list_postcall< meta::type_list< Policies... >, StackIndexList >::postcall(L, results); + } + }; -# define LUABIND_INVOKE_COMPUTE_ARITY(n) + BOOST_PP_CAT(c,n).consumed_args() + template< typename StackIndexList > + struct policy_list_postcall< meta::type_list< >, StackIndexList > { + static void postcall(lua_State* /*L*/, int /*results*/) {} + }; -# define LUABIND_INVOKE_DECLARE_CONVERTER(n) \ - typedef LUABIND_INVOKE_NEXT_ITER(n) BOOST_PP_CAT(iter,n); \ - typedef typename mpl::deref::type \ - BOOST_PP_CAT(a,n); \ - typedef typename find_conversion_policy::type \ - BOOST_PP_CAT(p,n); \ - typename mpl::apply_wrap2< \ - BOOST_PP_CAT(p,n), BOOST_PP_CAT(a,n), lua_to_cpp>::type BOOST_PP_CAT(c,n); \ - int const BOOST_PP_CAT(index,n) = LUABIND_INVOKE_NEXT_INDEX(n); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template< typename... ArgumentConverters > + struct compute_invoke_values { + using consumed_list = meta::index_list< FooFoo::consumed_args... >; + using stack_index_list = typename compute_stack_indices< consumed_list, 1 >::type; + enum { arity = meta::sum::value }; + }; +#endif -# define LUABIND_INVOKE_COMPUTE_SCORE(n) \ - , BOOST_PP_CAT(c,n).match( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)) -# define LUABIND_INVOKE_ARG(z, n, base) \ - BOOST_PP_CAT(c,base(n)).apply( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,base(n))), BOOST_PP_CAT(index,base(n))) + } -# define LUABIND_INVOKE_CONVERTER_POSTCALL(n) \ - BOOST_PP_CAT(c,n).converter_postcall( \ - L, LUABIND_DECORATE_TYPE(BOOST_PP_CAT(a,n)), BOOST_PP_CAT(index,n)); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + inline int match_deferred(lua_State* L, meta::index_list<>, meta::type_list<>) + { + return 0; + } -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + template< unsigned int StackIndex0, unsigned int... StackIndices, + typename ArgumentType0, typename... ArgumentTypes, + typename ArgumentConverter0, typename... ArgumentConverters > + int match_deferred(lua_State* L, + meta::index_list< StackIndex0, StackIndices... >, + meta::type_list< ArgumentType0, ArgumentTypes... >, + ArgumentConverter0& converter0, ArgumentConverters&... converters + ) + { + const int this_match = converter0.match(L, decorated_type(), StackIndex0); + const int other_match = match_deferred(L, meta::index_list(), meta::type_list(), converters...); + return (this_match >= 0) ? // could also sum them all up unconditionally + this_match + match_deferred(L, meta::index_list(), meta::type_list(), converters...) + : no_match; + } -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + template< typename T, bool isvoid, bool memfun = std::is_member_function_pointer::value > struct do_call_struct; -# undef LUABIND_INVOKE_VOID -# define LUABIND_INVOKE_MEMBER -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + template< typename T > + struct do_call_struct< T, true, true /*memfun*/> { + template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > + static void do_call(lua_State* L, F& f, + meta::index_list, meta::type_list, + ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters + ) + { + ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( + arg_converters.to_cpp(L, decorated_type(), StackIndices)... + ); + } + }; -# define LUABIND_INVOKE_VOID -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + template< typename T > + struct do_call_struct< T, false, true /*memfun*/> { + template< typename F, typename ArgumentType0, typename... ArgumentTypes, unsigned int StackIndex0, unsigned int... StackIndices, typename ReturnConverter, typename Argument0Converter, typename... ArgumentConverters > + static void do_call(lua_State* L, F& f, + meta::index_list, meta::type_list, + ReturnConverter& result_converter, Argument0Converter& arg0_converter, ArgumentConverters&... arg_converters + ) + { + result_converter.to_lua(L, + ((arg0_converter.to_cpp(L, decorated_type(), StackIndex0)).*f)( + arg_converters.to_cpp(L, decorated_type(), StackIndices)... + ) + ); + } + }; -}} // namespace luabind::detail + + template< typename T > + struct do_call_struct< T, true, false > { + template< + typename F, + typename... ArgumentTypes, unsigned int... StackIndices, + typename ReturnConverter, typename... ArgumentConverters + > + static void do_call(lua_State* L, F& f, + meta::index_list, meta::type_list, + ReturnConverter& result_converter, ArgumentConverters&... arg_converters) + { + f(arg_converters.to_cpp(L, decorated_type(), StackIndices)...); + } + }; + + template< typename T > + struct do_call_struct< T, false, false > { + template< + typename F, + typename... ArgumentTypes, unsigned int... StackIndices, + typename ReturnConverter, typename... ArgumentConverters + > + static void do_call(lua_State* L, F& f, + meta::index_list, meta::type_list, + ReturnConverter& result_converter, ArgumentConverters&... arg_converters) + { + result_converter.to_lua(L, + f(arg_converters.to_cpp(L, decorated_type(), StackIndices)...) + ); + } + }; + + template< typename F, typename ReturnType, typename... Arguments, + typename ReturnConverter, typename... ArgumentConverters, + unsigned int Index0, unsigned int... Indices, typename PolicyList + > + int invoke3(lua_State* L, function_object const& self, invoke_context& ctx, F& f, + PolicyList, meta::index_list< Index0, Indices... > index_list, meta::type_list signature_list, + ReturnConverter return_converter, ArgumentConverters... argument_converters) + { + using invoke_values = typename call_detail_new::compute_invoke_values< ArgumentConverters... >; + using argument_list_type = meta::type_list; + using argument_index_list = meta::index_list; + + int const arguments = lua_gettop(L); + int score = no_match; + + if(invoke_values::arity == arguments) { + score = match_deferred(L, typename invoke_values::stack_index_list(), argument_list_type(), argument_converters...); + } + + if(score >= 0 && score < ctx.best_score) { + ctx.best_score = score; + ctx.candidates[0] = &self; + ctx.candidate_index = 1; + } else if(score == ctx.best_score) { + ctx.candidates[ctx.candidate_index++] = &self; + } + + int results = 0; + + if(self.next) + { + results = self.next->call(L, ctx); + } + + if(score == ctx.best_score && ctx.candidate_index == 1) + { + do_call_struct::value>::do_call(L, f, typename invoke_values::stack_index_list(), argument_list_type(), return_converter, argument_converters...); + meta::init_order{ (argument_converters.converter_postcall(L, decorated_type(), meta::get< typename invoke_values::stack_index_list, Indices - 1 >::value), 0)... }; + + results = lua_gettop(L) - invoke_values::arity; + if(has_call_policy::value) { + results = lua_yield(L, results); + } + + // call policiy list postcall + call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename invoke_values::stack_index_list, meta::index >::type >::postcall(L, results); + } + + return results; + } + + template< typename F, typename ReturnType, typename... Arguments, unsigned int Index0, unsigned int... Indices, typename PolicyList > + int invoke2(lua_State* L, function_object const& self, invoke_context& ctx, F& f, + meta::type_list signature, meta::index_list, PolicyList) + { + using signature_type = meta::type_list; + using return_converter = specialized_converter_policy_n<0, PolicyList, ReturnType, cpp_to_lua>; + return invoke3(L, self, ctx, f, + PolicyList(), meta::index_list(), signature, + return_converter(), specialized_converter_policy_n()... + ); + } + + + template + // boost::bind's operator() is const, std::bind's is not + inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f, Signature, + meta::type_list< PolicyInjectors... > const& injectors) + { + return invoke2(L, self, ctx, f, Signature(), typename meta::make_index_range<0, meta::size::value>::type(), injectors); + } +#endif + +#ifdef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + + // VC2013RC doesn't support expanding a template and its member template in one expression, that's why we have to to incrementally build + // the converter list instead of a single combined expansion. + template< typename ArgumentList, typename PolicyList, typename CurrentList = meta::type_list<>, unsigned int Counter = 1 > + struct compute_argument_converter_list; + + template< typename Argument0, typename... Arguments, typename PolicyList, typename... CurrentConverters, unsigned int Counter > + struct compute_argument_converter_list< meta::type_list, PolicyList, meta::type_list, Counter > + { + using converter_type = typename policy_detail::get_converter_policy::type; + using this_specialized = typename converter_type::template specialize::type; + using type = typename compute_argument_converter_list, PolicyList, meta::type_list, Counter + 1>::type; + }; + + template + struct compute_argument_converter_list< meta::type_list<>, PolicyList, meta::type_list, Counter > + { + using type = meta::type_list; + }; + + template< typename ConverterList > + struct build_consumed_list; + + template< typename... Converters > + struct build_consumed_list< meta::type_list< Converters... > > { + using consumed_list = meta::index_list< call_detail_new::FooFoo::consumed_args... >; + }; + + template< typename SignatureList, typename PolicyList > + struct invoke_traits; + + // Specialization for free functions + template< typename ResultType, typename... Arguments, typename PolicyList > + struct invoke_traits< meta::type_list, PolicyList > + { + using signature_list = meta::type_list; + using policy_list = PolicyList; + using result_type = ResultType; + using result_converter = specialized_converter_policy_n<0, PolicyList, result_type, cpp_to_lua >; + using argument_list = meta::type_list; + + using decorated_argument_list = meta::type_list< decorate_type_t... >; + // note that this is 0-based, so whenever you want to fetch from the converter list, you need to add 1 + using argument_index_list = typename meta::make_index_range< 0, sizeof...(Arguments) >::type; + using argument_converter_list = typename compute_argument_converter_list::type; + using argument_converter_tuple_type = typename meta::make_tuple::type; + using consumed_list = typename build_consumed_list::consumed_list; + using stack_index_list = typename call_detail_new::compute_stack_indices< consumed_list, 1 >::type; + enum { arity = meta::sum::value }; + }; + + template< typename StackIndexList, typename SignatureList, unsigned int End = meta::size::value, unsigned int Index = 1 > + struct match_struct { + template< typename TupleType > + static int match(lua_State* L, TupleType& tuple) + { + const int this_match = std::get(tuple).match(L, decorate_type_t>(), meta::get::value); + return this_match >= 0 ? // could also sum them up unconditionally + this_match + match_struct::match(L, tuple) + : no_match; + } + }; + + template< typename StackIndexList, typename SignatureList, unsigned int Index > + struct match_struct< StackIndexList, SignatureList, Index, Index > + { + template< typename TupleType > + static int match(lua_State* /*L*/, TupleType&) { + return 0; + } + }; + + template< typename PolicyList, typename Signature, typename F > + struct invoke_struct + { + using traits = invoke_traits< Signature, PolicyList >; + + template< bool IsMember, bool IsVoid, typename IndexList > + struct call_struct; + + template< unsigned int... ArgumentIndices > + struct call_struct< false /*member*/, false /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + using result_converter = typename traits::result_converter; + + result_converter().to_lua(L, + f((std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value))... + ) + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int... ArgumentIndices > + struct call_struct< false /*member*/, true /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + + // This prevents unused warnings with empty parameter lists + (void)L; + + f(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int ClassIndex, unsigned int... ArgumentIndices > + struct call_struct< true /*member*/, false /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + using result_converter = typename traits::result_converter; + + auto& object = std::get<0>(argument_tuple).to_cpp(L, + typename meta::get::type(), 1); + + result_converter().to_lua(L, + (object.*f)(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + ) + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + template< unsigned int ClassIndex, unsigned int... ArgumentIndices > + struct call_struct< true /*member*/, true /*void*/, meta::index_list > + { + static void call(lua_State* L, F& f, typename traits::argument_converter_tuple_type& argument_tuple) + { + using decorated_list = typename traits::decorated_argument_list; + using stack_indices = typename traits::stack_index_list; + + auto& object = std::get<0>(argument_tuple).to_cpp(L, typename meta::get::type(), 1); + + (object.*f)(std::get(argument_tuple).to_cpp(L, + typename meta::get::type(), + meta::get::value)... + ); + + meta::init_order{ + (std::get(argument_tuple).converter_postcall(L, + typename meta::get::type(), + meta::get::value), 0)... + }; + } + }; + + static int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) { + int const arguments = lua_gettop(L); + int score = no_match; + + // Even match needs the tuple, since pointer_converters buffer the cast result + typename traits::argument_converter_tuple_type converter_tuple; + + if(traits::arity == arguments) { + // Things to remember: + // 0 is the perfect match. match > 0 means that objects had to be casted, where the value + // is the total distance of all arguments to their given types (graph distance). + // This is why we can say MaxArguments = 100, MaxDerivationDepth = 100, so no match will be > 100*100=10k and -10k1 absorbs every match. + // This gets rid of the awkward checks during converter match traversal. + using struct_type = match_struct< typename traits::stack_index_list, typename traits::signature_list >; + score = struct_type::match(L, converter_tuple); + } + + if(score >= 0 && score < ctx.best_score) { + ctx.best_score = score; + ctx.candidates[0] = &self; + ctx.candidate_index = 1; + } else if(score == ctx.best_score) { + ctx.candidates[ctx.candidate_index++] = &self; + } + + int results = 0; + + if(self.next) + { + results = self.next->call(L, ctx); + } + + if(score == ctx.best_score && ctx.candidate_index == 1) + { + call_struct< + std::is_member_function_pointer::value, + std::is_void::value, + typename traits::argument_index_list + >::call(L, f, converter_tuple); + + results = lua_gettop(L) - traits::arity; + if(has_call_policy::value) { + results = lua_yield(L, results); + } + + call_detail_new::policy_list_postcall < PolicyList, typename meta::push_front< typename traits::stack_index_list, meta::index >::type >::postcall(L, results); + } + + return results; + } + + }; + + template< typename PolicyList, typename Signature, typename F> + inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) + { + return invoke_struct::invoke(L, self, ctx, f); + } +#endif + + } +} // namespace luabind::detail # endif // LUABIND_CALL2_080911_HPP -#else // BOOST_PP_IS_ITERATING - -# ifdef LUABIND_INVOKE_MEMBER -# define N BOOST_PP_INC(BOOST_PP_ITERATION()) -# else -# define N BOOST_PP_ITERATION() -# endif - -template -inline int -# ifdef LUABIND_INVOKE_MEMBER -invoke_member -# else -invoke_normal -# endif -( - lua_State* L, function_object const& self, invoke_context& ctx - , F const& f, Signature, Policies const&, mpl::long_ -# ifdef LUABIND_INVOKE_VOID - , mpl::true_ -# else - , mpl::false_ -# endif -) -{ - typedef typename mpl::begin::type first; -# ifndef LUABIND_INVOKE_VOID - typedef typename mpl::deref::type result_type; - typedef typename find_conversion_policy<0, Policies>::type result_policy; - typename mpl::apply_wrap2< - result_policy, result_type, cpp_to_lua>::type result_converter; -# endif - -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_DECLARE_CONVERTER(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - int const arity = 0 -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_ARITY(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - ; - - int const arguments = lua_gettop(L); - - int score = -1; - - if (arity == arguments) - { - int const scores[] = { - 0 -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_COMPUTE_SCORE(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - }; - - score = sum_scores(scores + 1, scores + 1 + N); - } - - if (score >= 0 && score < ctx.best_score) - { - ctx.best_score = score; - ctx.candidates[0] = &self; - ctx.candidate_index = 1; - } - else if (score == ctx.best_score) - { - ctx.candidates[ctx.candidate_index++] = &self; - } - - int results = 0; - - if (self.next) - { - results = self.next->call(L, ctx); - } - - if (score == ctx.best_score && ctx.candidate_index == 1) - { -# ifndef LUABIND_INVOKE_VOID - result_converter.apply( - L, -# endif -# ifdef LUABIND_INVOKE_MEMBER - (c0.apply(L, LUABIND_DECORATE_TYPE(a0), index0).*f)( - BOOST_PP_ENUM(BOOST_PP_DEC(N), LUABIND_INVOKE_ARG, BOOST_PP_INC) - ) -# else -# define LUABIND_INVOKE_IDENTITY(x) x - f( - BOOST_PP_ENUM(N, LUABIND_INVOKE_ARG, LUABIND_INVOKE_IDENTITY) - ) -# undef LUABIND_INVOKE_IDENTITY -# endif -# ifndef LUABIND_INVOKE_VOID - ) -# endif - ; - -# if N > 0 -# define BOOST_PP_LOCAL_MACRO(n) LUABIND_INVOKE_CONVERTER_POSTCALL(n) -# define BOOST_PP_LOCAL_LIMITS (0,N-1) -# include BOOST_PP_LOCAL_ITERATE() -# endif - - results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0); - - int const indices[] = { - arguments + results BOOST_PP_ENUM_TRAILING_PARAMS(N, index) - }; - - policy_list_postcall::apply(L, indices); - } - - return results; -} - -# undef N - -#endif - diff --git a/libs/luabind/luabind/detail/call_function.hpp b/libs/luabind/luabind/detail/call_function.hpp index e3ac2b761..90a6a4e1b 100644 --- a/libs/luabind/luabind/detail/call_function.hpp +++ b/libs/luabind/luabind/detail/call_function.hpp @@ -20,423 +20,175 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - -#if !BOOST_PP_IS_ITERATING - #ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED #define LUABIND_CALL_FUNCTION_HPP_INCLUDED #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include +#include #include +#include +#include namespace luabind { - namespace detail - { - - // if the proxy_function_caller returns non-void - template - class proxy_function_caller - { -// friend class luabind::object; - public: - - typedef int(*function_t)(lua_State*, int, int); - - proxy_function_caller( - lua_State* L - , int params - , function_t fun - , const Tuple args) - : m_state(L) - , m_params(params) - , m_fun(fun) - , m_args(args) - , m_called(false) - { - } - - proxy_function_caller(const proxy_function_caller& rhs) - : m_state(rhs.m_state) - , m_params(rhs.m_params) - , m_fun(rhs.m_fun) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_function_caller() - { - if (m_called) return; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - operator Ret() - { - typename mpl::apply_wrap2::type converter; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 1)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - template - Ret operator[](const Policies& p) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (m_fun(L, boost::tuples::length::value, 1)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); - -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - private: - - lua_State* m_state; - int m_params; - function_t m_fun; - Tuple m_args; - mutable bool m_called; - - }; - - // if the proxy_member_caller returns void - template - class proxy_function_void_caller - { - friend class luabind::object; - public: - - typedef int(*function_t)(lua_State*, int, int); - - proxy_function_void_caller( - lua_State* L - , int params - , function_t fun - , const Tuple args) - : m_state(L) - , m_params(params) - , m_fun(fun) - , m_args(args) - , m_called(false) - { - } - - proxy_function_void_caller(const proxy_function_void_caller& rhs) - : m_state(rhs.m_state) - , m_params(rhs.m_params) - , m_fun(rhs.m_fun) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_function_void_caller() - { - if (m_called) return; - - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - push_args_from_tuple<1>::apply(L, m_args); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - template - void operator[](const Policies& p) - { - m_called = true; - lua_State* L = m_state; - - int top = lua_gettop(L); - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (m_fun(L, boost::tuples::length::value, 0)) - { - assert(lua_gettop(L) == top - m_params + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - " If you want to handle the error you can use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function call - stack_pop pop(L, lua_gettop(L) - top + m_params); - } - - private: - - lua_State* m_state; - int m_params; - function_t m_fun; - Tuple m_args; - mutable bool m_called; - - }; - + namespace adl { + class object; } - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() + using adl::object; + + namespace detail { + + template< typename PolicyList, unsigned int pos > + void push_arguments(lua_State* /*L*/) {} + + template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args > + void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args) + { + using converter_type = specialized_converter_policy< fetched_converter_policy, Arg0, cpp_to_lua >; + converter_type().to_lua(L, unwrapped::get(std::forward(arg0))); + push_arguments(L, std::forward(args)...); + } + +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template + void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list, Args&&... args) + { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(fn(L, sizeof...(Args), 0)) { + assert(lua_gettop(L) == top - m_params + 1); + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + } + + template + Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */, meta::index_list, Args&&... args) + { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(fn(L, sizeof...(Args), 1)) { + assert(lua_gettop(L) == top - m_params + 1); + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + m_params); + + specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; + if(converter.match(L, decorate_type_t(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } +#else + template::value> + struct call_function_struct; + + template + struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, true /* void */ > + { + template< typename... Args > + static void call(lua_State* L, Args&&... args) { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(Function(L, sizeof...(Args), 0)) { + if(Function == &detail::pcall) { + assert(lua_gettop(L) == static_cast(top - NumParams + 1)); + } + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + NumParams); + } + }; + + template + struct call_function_struct< Ret, PolicyList, meta::index_list, NumParams, Function, false /* void */ > + { + template< typename... Args > + static Ret call(lua_State* L, Args&&... args) { + int top = lua_gettop(L); + + push_arguments(L, std::forward(args)...); + + if(Function(L, sizeof...(Args), 1)) { + if(Function == &detail::pcall) { + assert(lua_gettop(L) == static_cast(top - NumParams + 1)); + } + call_error(L); + } + // pops the return values from the function call + stack_pop pop(L, lua_gettop(L) - top + NumParams); + + specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter; + if(converter.match(L, decorate_type_t(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } + }; +#endif + } + + template + R call_pushed_function(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 1, &detail::pcall, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 1, &detail::pcall >::call(L, std::forward(args)...); +#endif + } + + template + R call_function(lua_State* L, const char* name, Args&&... args) + { + assert(name && "luabind::call_function() expects a function name"); + lua_getglobal(L, name); + return call_pushed_function(L, std::forward(args)...); + } + + template + R resume_pushed_function(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 1, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 1, &detail::resume_impl >::call(L, std::forward(args)...); +#endif + } + + template + R resume_function(lua_State* L, const char* name, Args&&... args) + { + assert(name && "luabind::resume_function() expects a function name"); + lua_getglobal(L, name); + return resume_pushed_function(L, std::forward(args)...); + } + + template + R resume(lua_State* L, Args&&... args) + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return detail::call_function_impl(L, 0, &detail::resume_impl, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); +#else + return detail::call_function_struct, 0, &detail::resume_impl >::call(L, std::forward(args)...); +#endif + } } #endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - call_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - assert(name && "luabind::call_function() expects a function name"); - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - call_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::pcall, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume_function(lua_State* L, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - assert(name && "luabind::resume_function() expects a function name"); - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - lua_getglobal(L, name); - - return proxy_type(L, 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume_function(luabind::object const& obj BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - obj.push(obj.interpreter()); - return proxy_type(obj.interpreter(), 1, &detail::resume_impl, args); - } - - template - typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type - resume(lua_State* L BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _) ) - { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - typedef typename boost::mpl::if_ - , luabind::detail::proxy_function_void_caller > - , luabind::detail::proxy_function_caller > >::type proxy_type; - - return proxy_type(L, 0, &detail::resume_impl, args); - } - - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#endif -#endif - diff --git a/libs/luabind/luabind/detail/call_member.hpp b/libs/luabind/luabind/detail/call_member.hpp index e63555bc6..23b1bd496 100644 --- a/libs/luabind/luabind/detail/call_member.hpp +++ b/libs/luabind/luabind/detail/call_member.hpp @@ -20,325 +20,82 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - -#if !BOOST_PP_IS_ITERATING - #ifndef LUABIND_CALL_MEMBER_HPP_INCLUDED #define LUABIND_CALL_MEMBER_HPP_INCLUDED #include -#include +#include #include #include #include -#include // TODO: REMOVE DEPENDENCY - -#include - -#include -#include -#include - -#include +#include +#include namespace luabind { - namespace detail - { + using adl::object; - namespace mpl = boost::mpl; + namespace detail { - // if the proxy_member_caller returns non-void - template - class proxy_member_caller - { -// friend class luabind::object; - public: + template + R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args) + { + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; - proxy_member_caller(lua_State* L_, const Tuple args) - : L(L_) - , m_args(args) - , m_called(false) - { - } - - proxy_member_caller(const proxy_member_caller& rhs) - : L(rhs.L) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_member_caller() - { - if (m_called) return; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - operator Ret() - { - typename mpl::apply_wrap2::type converter; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 1)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - template - Ret operator[](const Policies& p) - { - typedef typename find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (pcall(L, boost::tuples::length::value + 1, 1)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(Ret), -1) < 0) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(Ret)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(Ret)); - - assert(0 && "the lua function's return value could not be converted." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - return converter.apply(L, LUABIND_DECORATE_TYPE(Ret), -1); - } - - private: - - lua_State* L; - Tuple m_args; - mutable bool m_called; + // pcall will pop the function and self reference + // and all the parameters + meta::init_order{ ( + specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; - // if the proxy_member_caller returns void - template - class proxy_member_void_caller + if(pcall(L, sizeof...(Args)+1, 0)) { - friend class luabind::object; - public: + assert(lua_gettop(L) == top + 1); + call_error(L); + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + } - proxy_member_void_caller(lua_State* L_, const Tuple args) - : L(L_) - , m_args(args) - , m_called(false) - { - } + template + R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args) + { + // don't count the function and self-reference + // since those will be popped by pcall + int top = lua_gettop(L) - 2; - proxy_member_void_caller(const proxy_member_void_caller& rhs) - : L(rhs.L) - , m_args(rhs.m_args) - , m_called(rhs.m_called) - { - rhs.m_called = true; - } - - ~proxy_member_void_caller() - { - if (m_called) return; - - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - push_args_from_tuple<1>::apply(L, m_args); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - template - void operator[](const Policies& p) - { - m_called = true; - - // don't count the function and self-reference - // since those will be popped by pcall - int top = lua_gettop(L) - 2; - - // pcall will pop the function and self reference - // and all the parameters - - detail::push_args_from_tuple<1>::apply(L, m_args, p); - if (pcall(L, boost::tuples::length::value + 1, 0)) - { - assert(lua_gettop(L) == top + 1); -#ifndef LUABIND_NO_EXCEPTIONS - throw error(L); -#else - error_callback_fun e = get_error_callback(); - if (e) e(L); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - // pops the return values from the function - stack_pop pop(L, lua_gettop(L) - top); - } - - private: - lua_State* L; - Tuple m_args; - mutable bool m_called; + // pcall will pop the function and self reference + // and all the parameters + meta::init_order{ ( + specialized_converter_policy_n::type, cpp_to_lua>().to_lua(L, unwrapped::get(std::forward(args))), 0)... }; + if(pcall(L, sizeof...(Args)+1, 1)) + { + assert(lua_gettop(L) == top + 1); + call_error(L); + } + // pops the return values from the function + stack_pop pop(L, lua_gettop(L) - top); + + specialized_converter_policy_n<0, PolicyList, R, lua_to_cpp> converter; + if(converter.match(L, decorate_type_t(), -1) < 0) { + cast_error(L); + } + + return converter.to_cpp(L, decorate_type_t(), -1); + } + + } // detail - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() - -} - -#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED - -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type - call_member(object const& obj, const char* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _)) + template + R call_member(object const& obj, const char* name, Args&&... args) { - typedef boost::tuples::tuple tuple_t; -#if BOOST_PP_ITERATION() == 0 - tuple_t args; -#else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); -#endif - - typedef typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - // this will be cleaned up by the proxy object // once the call has been made @@ -354,12 +111,17 @@ namespace luabind // now the function and self objects // are on the stack. These will both // be popped by pcall - return proxy_type(obj.interpreter(), args); + + return detail::call_member_impl(obj.interpreter(), std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); } -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS + template + R call_member(wrap_base const* self, char const* fn, Args&&... args) + { + return self->call(fn, std::forward(args)...); + } -#endif -#endif +} + +#endif // LUABIND_CALL_MEMBER_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/call_operator_iterate.hpp b/libs/luabind/luabind/detail/call_operator_iterate.hpp deleted file mode 100644 index c6f95a10c..000000000 --- a/libs/luabind/luabind/detail/call_operator_iterate.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#define N BOOST_PP_ITERATION() - -#define LUABIND_UNWRAP_PARAMETER(z, n, _) \ - typename detail::unwrap_parameter_type::type \ - BOOST_PP_CAT(_, n) - -template -struct BOOST_PP_CAT(call_operator, N) - : detail::operator_< - BOOST_PP_CAT(call_operator, N)< - Self BOOST_PP_ENUM_TRAILING_PARAMS(N, A) - > - > -{ - BOOST_PP_CAT(call_operator, N)(int) {} - - template - struct apply - { - static void execute( - lua_State* L - , typename detail::unwrap_parameter_type::type self - BOOST_PP_ENUM_TRAILING(N, LUABIND_UNWRAP_PARAMETER, _) - ) - { - using namespace detail; - operator_result( - L -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - , self(BOOST_PP_ENUM_PARAMS(N, _)) -#else - , (self(BOOST_PP_ENUM_PARAMS(N, _)), detail::operator_void_return()) -#endif - , (Policies*)0 - ); - } - }; - - static char const* name() { return "__call"; } -}; - -#undef LUABIND_UNWRAP_PARAMETER -#undef N - diff --git a/libs/luabind/luabind/detail/object_call.hpp b/libs/luabind/luabind/detail/call_shared.hpp similarity index 51% rename from libs/luabind/luabind/detail/object_call.hpp rename to libs/luabind/luabind/detail/call_shared.hpp index 46ab0d958..9b33973aa 100644 --- a/libs/luabind/luabind/detail/object_call.hpp +++ b/libs/luabind/luabind/detail/call_shared.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,33 +20,46 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#if !BOOST_PP_IS_ITERATING -# error Do not include object_call.hpp directly! +#ifndef LUABIND_CALL_SHARED_HPP_INCLUDED +#define LUABIND_CALL_SHARED_HPP_INCLUDED + +namespace luabind { + namespace detail { + + inline void call_error(lua_State* L) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw luabind::error(L); +#else + error_callback_fun e = get_error_callback(); + if(e) e(L); + + assert(0 && "the lua function threw an error and exceptions are disabled." + " If you want to handle the error you can use luabind::set_error_callback()"); + std::terminate(); #endif + } -#include -#include -#include + template + void cast_error(lua_State* L) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(L, typeid(T)); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if(e) e(L, typeid(T)); -#define N BOOST_PP_ITERATION() + assert(0 && "the lua function's return value could not be converted." + " If you want to handle the error you can use luabind::set_cast_failed_callback()"); + std::terminate(); +#endif + } -template -call_proxy< - Derived - , boost::tuples::tuple< - BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) - > -> operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) -{ - typedef boost::tuples::tuple< - BOOST_PP_ENUM_BINARY_PARAMS(N, A, const* BOOST_PP_INTERCEPT) - > arguments; + template< typename... Args > + void expand_hack(Args... /*args*/) + {} - return call_proxy( - derived() - , arguments(BOOST_PP_ENUM_PARAMS(N, &a)) - ); + } } -#undef N - +#endif diff --git a/libs/luabind/luabind/detail/call_traits.hpp b/libs/luabind/luabind/detail/call_traits.hpp new file mode 100644 index 000000000..227e3662e --- /dev/null +++ b/libs/luabind/luabind/detail/call_traits.hpp @@ -0,0 +1,113 @@ +// This has been stripped from boost minus the compatibility for borland etc. +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// call_traits: defines typedefs for function usage +// (see libs/utility/call_traits.htm) + +/* Release notes: +23rd July 2000: +Fixed array specialization. (JM) +Added Borland specific fixes for reference types +(issue raised by Steve Cleary). +*/ + +#ifndef LUABIND_CALL_TRAITS_HPP_INCLUDED +#define LUABIND_CALL_TRAITS_HPP_INCLUDED + +namespace luabind { + namespace detail { + + template + struct ct_imp2 + { + using param_type = const T&; + }; + + template + struct ct_imp2 + { + using param_type = const T; + }; + + template + struct ct_imp + { + using param_type = const T&; + }; + + template + struct ct_imp + { + using param_type = typename ct_imp2::param_type; + }; + + template + struct ct_imp + { + using param_type = typename ct_imp2::param_type; + }; + + template + struct ct_imp + { + using param_type = const T; + }; + + template + struct call_traits + { + public: + using value_type = T; + using reference = T&; + using const_reference = const T&; + + using param_type = typename ct_imp< + T, + std::is_pointer::value, + std::is_integral::value || std::is_floating_point::value, + std::is_enum::value + >::param_type; + }; + + template + struct call_traits + { + using value_type = T&; + using reference = T&; + using const_reference = const T&; + using param_type = T&; + }; + + template + struct call_traits + { + private: + using array_type = T[N]; + public: + using value_type = const T*; + using reference = array_type&; + using const_reference = const array_type&; + using param_type = const T* const; + }; + + template + struct call_traits + { + private: + using array_type = const T[N]; + public: + using value_type = const T*; + using reference = array_type&; + using const_reference = const array_type&; + using param_type = const T* const; + }; + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/class_cache.hpp b/libs/luabind/luabind/detail/class_cache.hpp deleted file mode 100644 index f49687c30..000000000 --- a/libs/luabind/luabind/detail/class_cache.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef CLASS_CACHE_040218_HPP -#define CLASS_CACHE_040218_HPP - -#include -#include -#include - -namespace luabind { namespace detail { - -#ifdef LUABIND_NOT_THREADSAFE - - class class_rep; - - template - struct class_cache_impl - { - static lua_State* state; - static class_rep* class_; - }; - - template - lua_State* class_cache_impl::state = 0; - - template - class_rep* class_cache_impl::class_ = 0; - - template - struct class_cache - : class_cache_impl< - typename boost::add_reference< - typename boost::add_const< - T - >::type - >::type - > - { - }; - - template - class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) - { - if (class_cache::state != L) - { - class_cache::state = L; - - class_registry* registry = class_registry::get_registry(L); - class_cache::class_ = registry->find_class(typeid(T)); - } - - return class_cache::class_; - } - -#else - - template - class_rep* get_class_rep(lua_State* L, void(*)(T*) = 0) - { - class_registry* registry = class_registry::get_registry(L); - return registry->find_class(typeid(T)); - } - -#endif - -}} // namespace luabind::detail - -#endif // CLASS_CACHE_040218_HPP - diff --git a/libs/luabind/luabind/detail/class_registry.hpp b/libs/luabind/luabind/detail/class_registry.hpp index 12ed03cfe..da0a47080 100644 --- a/libs/luabind/luabind/detail/class_registry.hpp +++ b/libs/luabind/luabind/detail/class_registry.hpp @@ -30,56 +30,58 @@ #include #include -namespace luabind { namespace detail -{ - class class_rep; +namespace luabind { + namespace detail { - struct LUABIND_API class_registry - { - class_registry(lua_State* L); + class class_rep; - static class_registry* get_registry(lua_State* L); + struct LUABIND_API class_registry + { + class_registry(lua_State* L); - int cpp_instance() const { return m_instance_metatable; } - int cpp_class() const { return m_cpp_class_metatable; } + static class_registry* get_registry(lua_State* L); - int lua_instance() const { return m_instance_metatable; } - int lua_class() const { return m_lua_class_metatable; } - int lua_function() const { return m_lua_function_metatable; } + int cpp_instance() const { return m_instance_metatable; } + int cpp_class() const { return m_cpp_class_metatable; } - void add_class(type_id const& info, class_rep* crep); + int lua_instance() const { return m_instance_metatable; } + int lua_class() const { return m_lua_class_metatable; } + int lua_function() const { return m_lua_function_metatable; } - class_rep* find_class(type_id const& info) const; + void add_class(type_id const& info, class_rep* crep); - std::map const& get_classes() const - { - return m_classes; - } + class_rep* find_class(type_id const& info) const; - private: + std::map const& get_classes() const + { + return m_classes; + } - std::map m_classes; + private: - // this is a lua reference that points to the lua table - // that is to be used as meta table for all C++ class - // instances. It is a kind of v-table. - int m_instance_metatable; + std::map m_classes; - // this is a lua reference to the metatable to be used - // for all classes defined in C++. - int m_cpp_class_metatable; + // this is a lua reference that points to the lua table + // that is to be used as meta table for all C++ class + // instances. It is a kind of v-table. + int m_instance_metatable; - // this is a lua reference to the metatable to be used - // for all classes defined in lua - int m_lua_class_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in C++. + int m_cpp_class_metatable; - // this metatable only contains a destructor - // for luabind::Detail::free_functions::function_rep - int m_lua_function_metatable; + // this is a lua reference to the metatable to be used + // for all classes defined in lua + int m_lua_class_metatable; - }; + // this metatable only contains a destructor + // for luabind::Detail::free_functions::function_rep + int m_lua_function_metatable; -}} + }; + + } +} #endif // LUABIND_CLASS_REGISTRY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/class_rep.hpp b/libs/luabind/luabind/detail/class_rep.hpp index aa5e866d3..119e15888 100644 --- a/libs/luabind/luabind/detail/class_rep.hpp +++ b/libs/luabind/luabind/detail/class_rep.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -24,16 +24,12 @@ #ifndef LUABIND_CLASS_REP_HPP_INCLUDED #define LUABIND_CLASS_REP_HPP_INCLUDED -#include -#include - #include #include #include #include #include -#include #include #include #include @@ -43,171 +39,174 @@ #include #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { - LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); + LUABIND_API std::string stack_content_by_name(lua_State* L, int start_index); - struct class_registration; + struct class_registration; - struct conversion_storage; + struct conversion_storage; - // This function is used as a tag to identify "properties". - LUABIND_API int property_tag(lua_State*); + // This function is used as a tag to identify "properties". + LUABIND_API int property_tag(lua_State*); - // this is class-specific information, poor man's vtable - // this is allocated statically (removed by the compiler) - // a pointer to this structure is stored in the lua tables' - // metatable with the name __classrep - // it is used when matching parameters to function calls - // to determine possible implicit casts - // it is also used when finding the best match for overloaded - // methods + // this is class-specific information, poor man's vtable + // this is allocated statically (removed by the compiler) + // a pointer to this structure is stored in the lua tables' + // metatable with the name __classrep + // it is used when matching parameters to function calls + // to determine possible implicit casts + // it is also used when finding the best match for overloaded + // methods - class cast_graph; - class class_id_map; + class cast_graph; + class class_id_map; - class LUABIND_API class_rep - { - friend struct class_registration; - friend int super_callback(lua_State*); -//TODO: avoid the lua-prefix - friend int lua_class_gettable(lua_State*); - friend int lua_class_settable(lua_State*); - friend int static_class_gettable(lua_State*); - public: - - enum class_type + class LUABIND_API class_rep { - cpp_class = 0, - lua_class = 1 + friend struct class_registration; + friend int super_callback(lua_State*); + //TODO: avoid the lua-prefix + friend int lua_class_gettable(lua_State*); + friend int lua_class_settable(lua_State*); + friend int static_class_gettable(lua_State*); + public: + + enum class_type + { + cpp_class = 0, + lua_class = 1 + }; + + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(type_id const& type + , const char* name + , lua_State* L + ); + + // used when creating a lua class + // EXPECTS THE TOP VALUE ON THE LUA STACK TO + // BE THE USER DATA WHERE THIS CLASS IS BEING + // INSTANTIATED! + class_rep(lua_State* L, const char* name); + + ~class_rep(); + + std::pair allocate(lua_State* L) const; + + // this is called as metamethod __call on the class_rep. + static int constructor_dispatcher(lua_State* L); + + struct base_info + { + int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) + class_rep* base; + }; + + void add_base_class(const base_info& binfo); + + const std::vector& bases() const throw() { return m_bases; } + + void set_type(type_id const& t) { m_type = t; } + type_id const& type() const throw() { return m_type; } + + const char* name() const throw() { return m_name; } + + // the lua reference to the metatable for this class' instances + int metatable_ref() const throw() { return m_instance_metatable; } + + void get_table(lua_State* L) const { m_table.push(L); } + void get_default_table(lua_State* L) const { m_default_table.push(L); } + + class_type get_class_type() const { return m_class_type; } + + void add_static_constant(const char* name, int val); + + static int super_callback(lua_State* L); + + static int lua_settable_dispatcher(lua_State* L); + + // called from the metamethod for __index + // obj is the object pointer + static int static_class_gettable(lua_State* L); + + bool has_operator_in_lua(lua_State*, int id); + + cast_graph const& casts() const + { + return *m_casts; + } + + class_id_map const& classes() const + { + return *m_classes; + } + + private: + + // Code common to both constructors + void shared_init(lua_State * L); + + void cache_operators(lua_State*); + + // this is a pointer to the type_info structure for + // this type + // warning: this may be a problem when using dll:s, since + // typeid() may actually return different pointers for the same + // type. + type_id m_type; + + // a list of info for every class this class derives from + // the information stored here is sufficient to do + // type casts to the base classes + std::vector m_bases; + + // the class' name (as given when registered to lua with class_) + const char* m_name; + + // a reference to this structure itself. Since this struct + // is kept inside lua (to let lua collect it when lua_close() + // is called) we need to lock it to prevent collection. + // the actual reference is not currently used. + detail::lua_reference m_self_ref; + + // this should always be used when accessing + // members in instances of a class. + // this table contains c closures for all + // member functions in this class, they + // may point to both static and virtual functions + handle m_table; + + // this table contains default implementations of the + // virtual functions in m_table. + handle m_default_table; + + // the type of this class.. determines if it's written in c++ or lua + class_type m_class_type; + + // this is a lua reference that points to the lua table + // that is to be used as meta table for all instances + // of this class. + int m_instance_metatable; + + std::map m_static_constants; + + // the first time an operator is invoked + // we check the associated lua table + // and cache the result + int m_operator_cache; + + cast_graph* m_casts; + class_id_map* m_classes; }; - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(type_id const& type - , const char* name - , lua_State* L - ); + LUABIND_API bool is_class_rep(lua_State* L, int index); - // used when creating a lua class - // EXPECTS THE TOP VALUE ON THE LUA STACK TO - // BE THE USER DATA WHERE THIS CLASS IS BEING - // INSTANTIATED! - class_rep(lua_State* L, const char* name); - - ~class_rep(); - - std::pair allocate(lua_State* L) const; - - // this is called as metamethod __call on the class_rep. - static int constructor_dispatcher(lua_State* L); - - struct base_info - { - int pointer_offset; // the offset added to the pointer to obtain a basepointer (due to multiple-inheritance) - class_rep* base; - }; - - void add_base_class(const base_info& binfo); - - const std::vector& bases() const throw() { return m_bases; } - - void set_type(type_id const& t) { m_type = t; } - type_id const& type() const throw() { return m_type; } - - const char* name() const throw() { return m_name; } - - // the lua reference to the metatable for this class' instances - int metatable_ref() const throw() { return m_instance_metatable; } - - void get_table(lua_State* L) const { m_table.push(L); } - void get_default_table(lua_State* L) const { m_default_table.push(L); } - - class_type get_class_type() const { return m_class_type; } - - void add_static_constant(const char* name, int val); - - static int super_callback(lua_State* L); - - static int lua_settable_dispatcher(lua_State* L); - - // called from the metamethod for __index - // obj is the object pointer - static int static_class_gettable(lua_State* L); - - bool has_operator_in_lua(lua_State*, int id); - - cast_graph const& casts() const - { - return *m_casts; - } - - class_id_map const& classes() const - { - return *m_classes; - } - - private: - - void cache_operators(lua_State*); - - // this is a pointer to the type_info structure for - // this type - // warning: this may be a problem when using dll:s, since - // typeid() may actually return different pointers for the same - // type. - type_id m_type; - - // a list of info for every class this class derives from - // the information stored here is sufficient to do - // type casts to the base classes - std::vector m_bases; - - // the class' name (as given when registered to lua with class_) - const char* m_name; - - // a reference to this structure itself. Since this struct - // is kept inside lua (to let lua collect it when lua_close() - // is called) we need to lock it to prevent collection. - // the actual reference is not currently used. - detail::lua_reference m_self_ref; - - // this should always be used when accessing - // members in instances of a class. - // this table contains c closures for all - // member functions in this class, they - // may point to both static and virtual functions - handle m_table; - - // this table contains default implementations of the - // virtual functions in m_table. - handle m_default_table; - - // the type of this class.. determines if it's written in c++ or lua - class_type m_class_type; - - // this is a lua reference that points to the lua table - // that is to be used as meta table for all instances - // of this class. - int m_instance_metatable; - - std::map m_static_constants; - - // the first time an operator is invoked - // we check the associated lua table - // and cache the result - int m_operator_cache; - - cast_graph* m_casts; - class_id_map* m_classes; - }; - - bool is_class_rep(lua_State* L, int index); - -}} - -//#include + } +} #endif // LUABIND_CLASS_REP_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/compute_score.hpp b/libs/luabind/luabind/detail/compute_score.hpp deleted file mode 100644 index c9a7e9ea1..000000000 --- a/libs/luabind/luabind/detail/compute_score.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright Daniel Wallin 2008. Use, modification and distribution is -// subject to the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef LUABIND_COMPUTE_RANK_081006_HPP -# define LUABIND_COMPUTE_RANK_081006_HPP - -# include -# include -# include -# include -# include -# include - -namespace luabind { namespace detail { - -namespace mpl = boost::mpl; - -template -int compute_score_aux( - lua_State*L, int index, Idx, Iter, End end, Policies const& policies) -{ - typedef typename Iter::type arg_type; - typedef typename find_conversion_policy::type - conversion_policy; - typedef typename mpl::apply_wrap2< - conversion_policy, arg_type, lua_to_cpp>::type converter; - - int score = converter::match(L, LUABIND_DECORATE_TYPE(arg_type), index); - - if (score < 0) - return score; - - if (conversion_policy::has_arg) - ++index; - - int next = compute_score_aux( - L - , index - , typename mpl::next::type() - , typename mpl::next::type() - , end - , policies - ); - - if (next < 0) - return next; - - return score + next; -} - -template -int compute_score_aux(lua_State*, int, Idx, End, End, Policies const&) -{ - return 0; -} - -template -int compute_score(lua_State* L, Signature, Policies const& policies) -{ - return compute_score_aux( - L - , 1 - , mpl::int_<1>() - , typename mpl::next::type>::type() - , typename mpl::end::type() - , policies - ); -} - -}} // namespace luabind::detail - -#endif // LUABIND_COMPUTE_RANK_081006_HPP diff --git a/libs/luabind/luabind/detail/constructor.hpp b/libs/luabind/luabind/detail/constructor.hpp index 1cbceb789..964d07695 100644 --- a/libs/luabind/luabind/detail/constructor.hpp +++ b/libs/luabind/luabind/detail/constructor.hpp @@ -2,110 +2,64 @@ // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#if !BOOST_PP_IS_ITERATING +#ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +#define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -# ifndef LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -# define LUABIND_DETAIL_CONSTRUCTOR_081018_HPP +#include +#include +#include +#include -# include -# include -# include -# include +namespace luabind { + namespace detail { -# include -# include -# include -# include + inline void inject_backref(lua_State*, void*, void*) + {} -namespace luabind { namespace detail { + template + void inject_backref(lua_State* L, T* p, wrap_base*) + { + weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); + } -inline void inject_backref(lua_State*, void*, void*) -{} + template< class T, class Pointer, class Signature, class Arguments, class ArgumentIndices > + struct construct_aux_helper; -template -void inject_backref(lua_State* L, T* p, wrap_base*) -{ - weak_ref(get_main_thread(L), L, 1).swap(wrap_access::ref(*p)); -} + template< class T, class Pointer, class Signature, typename... Arguments, unsigned int... ArgumentIndices > + struct construct_aux_helper< T, Pointer, Signature, meta::type_list< Arguments... >, meta::index_list< ArgumentIndices... > > + { + using holder_type = pointer_holder; -template -struct construct_aux; + void operator()(argument const& self_, Arguments... args) const + { + object_rep* self = touserdata(self_); -template -struct construct - : construct_aux::value - 2, T, Pointer, Signature> -{}; + std::unique_ptr instance(new T(args...)); + inject_backref(self_.interpreter(), instance.get(), instance.get()); -template -struct construct_aux<0, T, Pointer, Signature> -{ - typedef pointer_holder holder_type; + void* naked_ptr = instance.get(); + Pointer ptr(instance.release()); - void operator()(argument const& self_) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); + void* storage = self->allocate(sizeof(holder_type)); - std::auto_ptr instance(new T); - inject_backref(self_.interpreter(), instance.get(), instance.get()); + self->set_instance(new (storage) holder_type(std::move(ptr), registered_class::id, naked_ptr)); + } + }; - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); - void* storage = self->allocate(sizeof(holder_type)); + template< class T, class Pointer, class Signature > + struct construct : + public construct_aux_helper < + T, + Pointer, + Signature, typename meta::sub_range< Signature, 2, meta::size::value >::type, + typename meta::make_index_range<0, meta::size::value - 2>::type > + { + }; - self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); - } -}; + } // namespace detail -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail +} // namespace luabind # endif // LUABIND_DETAIL_CONSTRUCTOR_081018_HPP -#else // !BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() - -template -struct construct_aux -{ - typedef typename mpl::begin::type first; - typedef typename mpl::next::type iter0; - -# define BOOST_PP_LOCAL_MACRO(n) \ - typedef typename mpl::next< \ - BOOST_PP_CAT(iter,BOOST_PP_DEC(n))>::type BOOST_PP_CAT(iter,n); \ - typedef typename BOOST_PP_CAT(iter,n)::type BOOST_PP_CAT(a,BOOST_PP_DEC(n)); - -# define BOOST_PP_LOCAL_LIMITS (1,N) -# include BOOST_PP_LOCAL_ITERATE() - - typedef pointer_holder holder_type; - - void operator()(argument const& self_, BOOST_PP_ENUM_BINARY_PARAMS(N,a,_)) const - { - object_rep* self = touserdata(self_); - class_rep* cls = self->crep(); - - std::auto_ptr instance(new T(BOOST_PP_ENUM_PARAMS(N,_))); - inject_backref(self_.interpreter(), instance.get(), instance.get()); - - void* naked_ptr = instance.get(); - Pointer ptr(instance.release()); - - void* storage = self->allocate(sizeof(holder_type)); - - self->set_instance(new (storage) holder_type( - ptr, registered_class::id, naked_ptr, cls)); - } -}; - -# undef N - -#endif - diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp new file mode 100644 index 000000000..6eb7ba4b8 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/conversion_base.hpp @@ -0,0 +1,81 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_CONVERSION_BASE_HPP_INCLUDED +#define LUABIND_CONVERSION_BASE_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + + +namespace luabind { + namespace detail { + + // Something's strange with the references here... need to know when to copy :( + template + void make_pointee_instance(lua_State* L, T&& x, std::true_type, Clone) + { + if(get_pointer(x)) + { + make_pointer_instance(L, std::forward(x)); + } + else + { + lua_pushnil(L); + } + } + + template + void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::true_type) + { + using value_type = typename std::remove_reference::type; + + std::unique_ptr ptr(new value_type(std::move(x))); + make_pointer_instance(L, std::move(ptr)); + } + + template + void make_pointee_instance(lua_State* L, T&& x, std::false_type, std::false_type) + { + // need a second make_instance that moves x into place + make_pointer_instance(L, &x); + } + + template + void make_pointee_instance(lua_State* L, T&& x, Clone) + { + make_pointee_instance(L, std::forward(x), has_get_pointer(), Clone()); + } + + } + + template + struct default_converter; + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp b/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp new file mode 100644 index 000000000..936982eb3 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/conversion_policies.hpp @@ -0,0 +1,89 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_CONVERSION_POLICIES_HPP_INCLUDED +#define LUABIND_CONVERSION_POLICIES_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace luabind { + + template <> + struct default_converter + { + enum { consumed_args = 0 }; + + template + lua_State* to_cpp(lua_State* L, U, int /*index*/) + { + return L; + } + + template + static int match(lua_State*, U, int /*index*/) + { + return 0; + } + + template + void converter_postcall(lua_State*, U, int) {} + }; + + namespace detail { + + // This is the one that gets hit, if default_policy doesn't hit one of the specializations defined all over the place + template< class T > + struct default_converter_generator + : public meta::select_ < + meta::case_< is_lua_proxy_arg, lua_proxy_converter >, + meta::case_< std::is_enum::type>, enum_converter >, + meta::case_< is_nonconst_pointer, pointer_converter >, + meta::case_< is_const_pointer, const_pointer_converter >, + meta::case_< is_nonconst_reference, ref_converter >, + meta::case_< is_const_reference, const_ref_converter >, + meta::default_< value_converter > + > ::type + { + }; + + } + + template + struct default_converter + : detail::default_converter_generator::type + {}; + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp new file mode 100644 index 000000000..dcdd82dd7 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/enum_converter.hpp @@ -0,0 +1,82 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_ENUM_CONVERTER_HPP_INCLUDED +#define LUABIND_ENUM_CONVERTER_HPP_INCLUDED + +#include +#include +#include + +namespace luabind { + namespace detail { + + struct enum_converter + { + using type = enum_converter; + using is_native = std::false_type; + + enum { consumed_args = 1 }; + + void to_lua(lua_State* L, int val) + { + lua_pushnumber(L, val); + } + + template + T to_cpp(lua_State* L, by_value, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_value, int index) + { + if(lua_isnumber(L, index)) { + return 0; + } else { + return no_match; + } + } + + template + T to_cpp(lua_State* L, by_const_reference, int index) + { + return static_cast(static_cast(lua_tonumber(L, index))); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + if(lua_isnumber(L, index)) return 0; else return no_match; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp new file mode 100644 index 000000000..13c27da09 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp @@ -0,0 +1,95 @@ +// Copyright Christian Neumüller 2013. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED +#define LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED +#include +#include +#include +#include +#include + +namespace luabind { + + template + struct function + { + using result_type = R; + + function(luabind::object const& obj) + : m_func(obj) + { + } + + template< typename... Args> + R operator() (Args&&... args) + { + return call_function(m_func, std::forward(args)...); + } + + private: + object m_func; + }; + + namespace detail { + + template< typename T > + struct is_function : public std::false_type {}; + + template< typename T > + struct is_function< std::function< T > > : public std::true_type {}; + + template< typename R, typename... Args, typename WrappedType > + struct deduce_signature , WrappedType > + { + using type = meta::type_list< R, Args... >; + }; + + } + + + template + struct default_converter>::value>::type> + { + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + void converter_postcall(lua_State*, U const&, int) + {} + + template + static int match(lua_State* L, U, int index) + { + if(lua_type(L, index) == LUA_TFUNCTION) + return 0; + if(luaL_getmetafield(L, index, "__call")) { + lua_pop(L, 1); + return 1; + } + return no_match; + } + + template + F to_cpp(lua_State* L, U, int index) + { + // If you get a compiler error here, you are probably trying to + // get a function pointer from Lua. This is not supported: + // you must use a type which is constructible from a + // luabind::function, e.g. std::function or boost::function. + return function(object(from_stack(L, index))); + } + + void to_lua(lua_State* L, F value) + { + make_function(L, value).push(L); + } + }; + +} // namespace luabind + + +#endif // LUABIND_FUNCTION_CONVERTER_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp new file mode 100644 index 000000000..302a0bffa --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/lua_proxy_converter.hpp @@ -0,0 +1,73 @@ +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED +#define LUABIND_VALUE_WRAPPER_CONVERTER_HPP_INCLUDED + +#include +#include + +namespace luabind { + namespace detail { + + template + struct lua_proxy_converter + { + using type = lua_proxy_converter; + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + T to_cpp(lua_State* L, by_const_reference, int index) + { + return T(from_stack(L, index)); + } + + template + T to_cpp(lua_State* L, by_value, int index) + { + return to_cpp(L, by_const_reference(), index); + } + + template + static int match(lua_State* L, by_const_reference, int index) + { + return lua_proxy_traits::check(L, index) + ? max_hierarchy_depth + : no_match; + } + + template + static int match(lua_State* L, by_value, int index) + { + return match(L, by_const_reference(), index); + } + + void converter_postcall(...) {} + + template + void to_lua(lua_State* interpreter, T const& value_wrapper) + { + lua_proxy_traits::unwrap(interpreter, value_wrapper); + } + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp new file mode 100644 index 000000000..35e2130e4 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/native_converter.hpp @@ -0,0 +1,302 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_NATIVE_CONVERTER_HPP_INCLUDED +#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif + +namespace luabind { + + template > + struct native_converter_base + { + using is_native = std::true_type; + using value_type = typename detail::call_traits::value_type; + using param_type = typename detail::call_traits::param_type; + + enum { consumed_args = 1 }; + + template + void converter_postcall(lua_State*, U const&, int) + {} + + int match(lua_State* L, by_value, int index) + { + return Derived::compute_score(L, index); + } + + int match(lua_State* L, by_value, int index) + { + return Derived::compute_score(L, index); + } + + + int match(lua_State* L, by_const_reference, int index) + { + return Derived::compute_score(L, index); + } + + value_type to_cpp(lua_State* L, by_value, int index) + { + return derived().to_cpp_deferred(L, index); + } + + value_type to_cpp(lua_State* L, by_const_reference, int index) + { + return derived().to_cpp_deferred(L, index); + } + + void to_lua(lua_State* L, param_type value) + { + derived().to_lua_deferred(L, value); + } + + Derived& derived() + { + return static_cast(*this); + } + }; + + template + struct integer_converter + : native_converter_base> + { + using T = remove_const_reference_t; + using value_type = typename native_converter_base::value_type; + using param_type = typename native_converter_base::param_type; + + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match; + } + + static value_type to_cpp_deferred(lua_State* L, int index) + { + if((std::is_unsigned::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) { + return static_cast(lua_tonumber(L, index)); + } else { + return static_cast(lua_tointeger(L, index)); + } + } + + void to_lua_deferred(lua_State* L, param_type value) + { + if((std::is_unsigned::value && sizeof(value_type) >= sizeof(lua_Integer)) || (sizeof(value_type) > sizeof(lua_Integer))) + { + lua_pushnumber(L, (lua_Number)value); + } else { + lua_pushinteger(L, static_cast(value)); + } + } + }; + + template + struct number_converter + : native_converter_base> + { + using T = remove_const_reference_t; + using value_type = typename native_converter_base::value_type; + using param_type = typename native_converter_base::param_type; + + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match; + } + + static value_type to_cpp_deferred(lua_State* L, int index) + { + return static_cast(lua_tonumber(L, index)); + } + + static void to_lua_deferred(lua_State* L, param_type value) + { + lua_pushnumber(L, static_cast(value)); + } + }; + + template <> + struct default_converter + : native_converter_base + { + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TBOOLEAN ? 0 : no_match; + } + + static bool to_cpp_deferred(lua_State* L, int index) + { + return lua_toboolean(L, index) == 1; + } + + static void to_lua_deferred(lua_State* L, bool value) + { + lua_pushboolean(L, value); + } + }; + + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : native_converter_base + { + static int compute_score(lua_State* L, int index) + { + return lua_type(L, index) == LUA_TSTRING ? 0 : no_match; + } + + static std::string to_cpp_deferred(lua_State* L, int index) + { + return std::string(lua_tostring(L, index), lua_rawlen(L, index)); + } + + static void to_lua_deferred(lua_State* L, std::string const& value) + { + lua_pushlstring(L, value.data(), value.size()); + } + }; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + { + using is_native = std::true_type; + + enum { consumed_args = 1 }; + + template + static int match(lua_State* L, U, int index) + { + int type = lua_type(L, index); + return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match; + } + + template + static char const* to_cpp(lua_State* L, U, int index) + { + return lua_tostring(L, index); + } + + static void to_lua(lua_State* L, char const* str) + { + lua_pushstring(L, str); + } + + template + void converter_postcall(lua_State*, U, int) + {} + }; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template <> + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter + : default_converter + {}; + + template + struct default_converter < T, typename std::enable_if< std::is_integral>::value >::type > + : integer_converter + { + }; + + template + struct default_converter < T, typename std::enable_if< std::is_floating_point>::value >::type > + : number_converter + { + }; + +} + +#if LUA_VERSION_NUM < 502 +# undef lua_rawlen +#endif + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp new file mode 100644 index 000000000..95289811d --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/pointer_converter.hpp @@ -0,0 +1,143 @@ +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_POINTER_CONVERTER_HPP_INCLUDED +#define LUABIND_POINTER_CONVERTER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + /* + Todo: Remove code duplication + */ + + namespace detail { + + struct pointer_converter + { + using type = pointer_converter; + using is_native = std::false_type; + + pointer_converter() + : result(0) + {} + + void* result; + + enum { consumed_args = 1 }; + + template + static void to_lua(lua_State* L, T* ptr) + { + if(ptr == 0) + { + lua_pushnil(L); + return; + } + + if(luabind::get_back_reference(L, ptr)) + return; + + make_pointer_instance(L, ptr); + } + + template + T* to_cpp(lua_State*, by_pointer, int /*index*/) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_pointer, int index) + { + if(lua_isnil(L, index)) return 0; + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; + + if(obj->is_const()) + return no_match; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_pointer, int /*index*/) + {} + }; + + struct const_pointer_converter + { + using type = const_pointer_converter; + using is_native = std::false_type; + + enum { consumed_args = 1 }; + + const_pointer_converter() + : result(0) + {} + + void* result; + + template + void to_lua(lua_State* L, const T* ptr) + { + if(ptr == 0) + { + lua_pushnil(L); + return; + } + + if(luabind::get_back_reference(L, ptr)) + return; + + make_pointer_instance(L, ptr); + } + + template + T const* to_cpp(lua_State*, by_const_pointer, int) + { + return static_cast(result); + } + + template + int match(lua_State* L, by_const_pointer, int index) + { + if(lua_isnil(L, index)) return 0; + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match + std::pair s = obj->get_instance(registered_class::id); + if(s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } + +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp new file mode 100644 index 000000000..679c63692 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/reference_converter.hpp @@ -0,0 +1,124 @@ +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED +#define LUABIND_REFERENCE_CONVERTER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + /* + TODO: Remove code duplication + */ + namespace detail { + + struct ref_converter : pointer_converter + { + using type = ref_converter; + using is_native = std::false_type; + + enum { consumed_args = 1 }; + + template + void to_lua(lua_State* L, T& ref) + { + if(luabind::get_back_reference(L, ref)) + return; + + make_pointee_instance(L, ref, std::false_type()); + } + + template + T& to_cpp(lua_State* L, by_reference, int index) + { + assert(!lua_isnil(L, index)); + return *pointer_converter::to_cpp(L, by_pointer(), index); + } + + template + int match(lua_State* L, by_reference, int index) + { + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; + + if(obj->is_const()) + return no_match; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + struct const_ref_converter + { + using type = const_ref_converter; + using is_native = std::false_type; + + enum { consumed_args = 1 }; + + const_ref_converter() + : result(0) + {} + + void* result; + + template + void to_lua(lua_State* L, T const& ref) + { + if(luabind::get_back_reference(L, ref)) + return; + + make_pointee_instance(L, ref, std::false_type()); + } + + template + T const& to_cpp(lua_State*, by_const_reference, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_const_reference, int index) + { + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; // if the type is not one of our own registered types, classify it as a non-match + + std::pair s = obj->get_instance(registered_class::id); + if(s.second >= 0 && !obj->is_const()) + s.second += 10; + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, by_const_reference, int) + { + } + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp new file mode 100644 index 000000000..fa91e6712 --- /dev/null +++ b/libs/luabind/luabind/detail/conversion_policies/value_converter.hpp @@ -0,0 +1,79 @@ +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_VALUE_CONVERTER_HPP_INCLUDED +#define LUABIND_VALUE_CONVERTER_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + namespace detail { + + struct value_converter + { + using type = value_converter; + using is_native = std::false_type; + + enum { consumed_args = 1 }; + + value_converter() + : result(0) + {} + + void* result; + + template + void to_lua(lua_State* L, T&& x) + { + if(luabind::get_back_reference(L, x)) + return; + + make_value_instance(L, std::forward(x)); + } + + template + T to_cpp(lua_State*, by_value, int) + { + return *static_cast(result); + } + + template + int match(lua_State* L, by_value, int index) + { + // special case if we get nil in, try to match the holder type + if(lua_isnil(L, index)) + return no_match; + + object_rep* obj = get_instance(L, index); + if(obj == 0) return no_match; + + std::pair s = obj->get_instance(registered_class::id); + result = s.first; + return s.second; + } + + template + void converter_postcall(lua_State*, T, int) {} + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/conversion_storage.hpp b/libs/luabind/luabind/detail/conversion_storage.hpp index 153112d62..9fc443163 100644 --- a/libs/luabind/luabind/detail/conversion_storage.hpp +++ b/libs/luabind/luabind/detail/conversion_storage.hpp @@ -6,36 +6,38 @@ # define LUABIND_CONVERSION_STORAGE_080930_HPP # include -# include +# include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -typedef void(*destruction_function)(void*); + using destruction_function = void(*)(void*); -// This is used by the converters in policy.hpp, and -// class_rep::convert_to as temporary storage when constructing -// holders. + // This is used by the converters in policy.hpp, and + // class_rep::convert_to as temporary storage when constructing + // holders. -struct conversion_storage -{ - conversion_storage() - : destructor(0) - {} + struct conversion_storage + { + conversion_storage() + : destructor(0) + {} - ~conversion_storage() - { - if (destructor) - destructor(&data); - } + ~conversion_storage() + { + if(destructor) + destructor(&data); + } - // Unfortunately the converters currently doesn't have access to - // the actual type being converted when this is instantiated, so - // we have to guess a max size. - boost::aligned_storage<128> data; - destruction_function destructor; -}; + // Unfortunately the converters currently doesn't have access to + // the actual type being converted when this is instantiated, so + // we have to guess a max size. + std::aligned_storage<128> data; + destruction_function destructor; + }; -}} // namespace luabind::detail + } +} // namespace luabind::detail #endif // LUABIND_CONVERSION_STORAGE_080930_HPP diff --git a/libs/luabind/luabind/detail/convert_to_lua.hpp b/libs/luabind/luabind/detail/convert_to_lua.hpp deleted file mode 100644 index f5aa89aea..000000000 --- a/libs/luabind/luabind/detail/convert_to_lua.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - - -#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED -#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED - -#include -#include -#include - -#include - -namespace luabind { namespace detail -{ - template - struct unwrap_ref - { - template - static const T& get(const T& r) { return r; } - - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct unwrap_ref - { - template - static T& get(const boost::reference_wrapper& r) { return r.get(); } - - template - struct apply - { - typedef typename T::type& type; - }; - }; - - namespace mpl = boost::mpl; - - template - void convert_to_lua(lua_State* L, const T& v) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } - - template - void convert_to_lua_p(lua_State* L, const T& v, const Policies&) - { - typedef typename mpl::apply_wrap1< - unwrap_ref::value> - , T - >::type value_type; - - typedef typename find_conversion_policy::type converter_policy; - typename mpl::apply_wrap2::type converter; - - converter.apply(L, unwrap_ref::value>::get(v)); - } -}} - -#endif - diff --git a/libs/luabind/luabind/detail/crtp_iterator.hpp b/libs/luabind/luabind/detail/crtp_iterator.hpp new file mode 100644 index 000000000..7973ba5fd --- /dev/null +++ b/libs/luabind/luabind/detail/crtp_iterator.hpp @@ -0,0 +1,58 @@ +#ifndef LUABIND_CRTP_ITERATOR_HPP_INCLUDED +#define LUABIND_CRTP_ITERATOR_HPP_INCLUDED + +#include + +namespace luabind { + namespace detail { + + template< typename CRTP, typename Category, typename ValueType, typename ReferenceType = ValueType&, typename DifferenceType = ptrdiff_t > + class crtp_iterator : + public std::iterator + { + public: + using base_type = std::iterator; + + + CRTP& operator++() + { + upcast().increment(); + return upcast(); + } + + CRTP operator++(int) + { + CRTP tmp(upcast()); + upcast().increment(); + return tmp; + } + + bool operator==(const CRTP& rhs) + { + return upcast().equal(rhs); + } + + bool operator!=(const CRTP& rhs) + { + return !upcast().equal(rhs); + } + + typename base_type::reference operator*() + { + return upcast().dereference(); + } + + typename base_type::reference operator->() + { + return upcast().dereference(); + } + + private: + CRTP& upcast() { return static_cast(*this); } + const CRTP& upcast() const { return static_cast(*this); } + }; + + } +} + +#endif diff --git a/libs/luabind/luabind/detail/debug.hpp b/libs/luabind/luabind/detail/debug.hpp index ef13bc886..e3e1c1f14 100644 --- a/libs/luabind/luabind/detail/debug.hpp +++ b/libs/luabind/luabind/detail/debug.hpp @@ -28,28 +28,32 @@ #include #include -namespace luabind { namespace detail -{ - struct stack_checker_type - { - stack_checker_type(lua_State* L) - : m_L(L) - , m_stack(lua_gettop(m_L)) - {} +namespace luabind { + namespace detail { - ~stack_checker_type() + struct stack_checker_type { - assert(m_stack == lua_gettop(m_L)); - } + stack_checker_type(lua_State* L) + : m_L(L) + , m_stack(lua_gettop(m_L)) + {} - lua_State* m_L; - int m_stack; - }; + ~stack_checker_type() + { + assert(m_stack == lua_gettop(m_L)); + } + + lua_State* m_L; + int m_stack; + }; + + } +} -}} #define LUABIND_CHECK_STACK(L) luabind::detail::stack_checker_type stack_checker_object(L) #else #define LUABIND_CHECK_STACK(L) do {} while (0) #endif #endif // LUABIND_DEBUG_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/decorate_type.hpp b/libs/luabind/luabind/detail/decorate_type.hpp index bb144c463..7752bfd4d 100644 --- a/libs/luabind/luabind/detail/decorate_type.hpp +++ b/libs/luabind/luabind/detail/decorate_type.hpp @@ -25,242 +25,62 @@ #define LUABIND_DECORATE_TYPE_HPP_INCLUDED #include -#include -namespace luabind { namespace detail -{ +namespace luabind { -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template struct by_value {}; + template struct by_const_reference {}; + template struct by_reference {}; + template struct by_rvalue_reference {}; + template struct by_pointer {}; + template struct by_const_pointer {}; template - struct decorated_type + struct decorate_type { - static by_value t; - static inline by_value& get() { return /*by_value()*/t; } + using type = by_value; }; template - by_value decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_pointer t; - static inline by_pointer& get() { return /*by_pointer()*/t; } + using type = by_pointer; }; template - by_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_pointer t; - static inline by_const_pointer get() { return /*by_const_pointer()*/t; } + using type = by_const_pointer; }; template - by_const_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_pointer t; - static inline by_const_pointer& get() { return /*by_const_pointer()*/t; } + using type = by_const_pointer; }; template - by_const_pointer decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_reference t; - static inline by_reference& get() { return /*by_reference()*/t; } + using type = by_reference; }; template - by_reference decorated_type::t; - - template - struct decorated_type + struct decorate_type { - static by_const_reference t; - static inline by_const_reference& get() { return /*by_const_reference()*/t; } + using type = by_const_reference; }; template - by_const_reference decorated_type::t; - - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get() - -#else - -#include - - namespace + struct decorate_type { - LUABIND_ANONYMOUS_FIX char decorated_type_array[64]; - } - - template - struct decorated_type_cref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_reference get(const U&) - { - return by_const_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_reference get(void(*f)(const U&)) - { return by_const_reference(); } -#endif + using type = by_rvalue_reference; }; - template - struct decorated_type_ref_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_reference get(U&) - { - return by_reference(); - } - static T data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } + template< typename T > + using decorate_type_t = typename decorate_type::type; - template - static by_reference get(void(*)(U&)) - { return by_reference(); } -#endif - }; - - template - struct decorated_type_cptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_const_pointer get(const U*) - { - return by_const_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_const_pointer get(void(*)(const U*)) - { return by_const_pointer(); } -#endif - }; - - template - struct decorated_type_ptr_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_pointer get(U*) - { - return by_pointer(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T) - { return (void(*)(T))0; } - - template - static by_pointer get(void(*)(U*)) - { return by_pointer(); } -#endif - }; - - template - struct decorated_type_value_impl - { -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - template - static by_value get(U&) - { - return by_value(); - } - static T& data() { return reinterpret_cast(decorated_type_array); } -#else - static void(*data())(T&) - { return (void(*)(T&))0; } - - template - static by_value get(void(*)(U&)) - { return by_value(); } -#endif - }; - - template<> - struct decorated_type_value_impl - { - static by_value get(int) - { - return by_value(); - } - static int data() { return 0; } - }; - - template - struct decorated_type_array_impl - { - template - static by_pointer get(U*) - { - return by_pointer(); - } - - template - static by_pointer get(void(*)(U)) - { return by_pointer(); } - - static T& data() { return reinterpret_cast(decorated_type_array); } - }; - - template - struct decorated_type -// : boost::mpl::if_ -// , decorated_type_array_impl - : boost::mpl::if_ - , decorated_type_cref_impl - , typename boost::mpl::if_ - , decorated_type_ref_impl - , typename boost::mpl::if_ - , decorated_type_ptr_impl - , typename boost::mpl::if_ - , decorated_type_cptr_impl - , decorated_type_value_impl - >::type - >::type - >::type - >::type -// >::type - { - }; - -#if defined(BOOST_MSVC) && BOOST_MSVC == 1200 - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) -#else -// #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get((void(*)(type))0) - #define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(luabind::detail::decorated_type::data()) - //#define LUABIND_DECORATE_TYPE(t) luabind::detail::decorated_type::get(type()) -#endif - -#endif - -}} +} #endif // LUABIND_DECORATE_TYPE_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/deduce_signature.hpp b/libs/luabind/luabind/detail/deduce_signature.hpp index e47e22f4e..012d052d5 100644 --- a/libs/luabind/luabind/detail/deduce_signature.hpp +++ b/libs/luabind/luabind/detail/deduce_signature.hpp @@ -2,117 +2,19 @@ // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#if !BOOST_PP_IS_ITERATING - # ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP -# define LUABIND_DEDUCE_SIGNATURE_080911_HPP +# define LUABIND_DEDUCE_SIGNATURE_080911_HPP -# include +#include +#include -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include +namespace luabind { + namespace detail { -namespace luabind { namespace detail { -namespace mpl = boost::mpl; + } // namespace detail -template -mpl::vector1 deduce_signature(R(*)(), ...) -{ - return mpl::vector1(); -} - -template -mpl::vector2 deduce_signature(R(T::*)()) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type&> -deduce_signature(R(T::*)(), Wrapped*) -{ - return mpl::vector2::type&>(); -} - -template -mpl::vector2 deduce_signature(R(T::*)() const) -{ - return mpl::vector2(); -} - -template -mpl::vector2::type const&> -deduce_signature(R(T::*)() const, Wrapped*) -{ - return mpl::vector2::type const&>(); -} - -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (1, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() - -}} // namespace luabind::detail +} // namespace luabind # endif // LUABIND_DEDUCE_SIGNATURE_080911_HPP -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -BOOST_PP_CAT(mpl::vector,NPLUS1) -deduce_signature(R(*)(BOOST_PP_ENUM_PARAMS(N,A)), ...) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS1)(); -} - -# define NPLUS2 BOOST_PP_INC(NPLUS1) - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A))) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::type&, BOOST_PP_ENUM_PARAMS(N,A) -> -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)), Wrapped*) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)< - R,typename most_derived::type&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2) -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)(); -} - -template -BOOST_PP_CAT(mpl::vector,NPLUS2)< - R, typename most_derived::type const&, BOOST_PP_ENUM_PARAMS(N,A) -> -deduce_signature(R(T::*)(BOOST_PP_ENUM_PARAMS(N,A)) const, Wrapped*) -{ - return BOOST_PP_CAT(mpl::vector,NPLUS2)< - R,typename most_derived::type const&,BOOST_PP_ENUM_PARAMS(N,A)>(); -} - -# undef NPLUS2 -# undef NPLUS1 -# undef N - -#endif // BOOST_PP_IS_ITERATING - diff --git a/libs/luabind/luabind/detail/enum_maker.hpp b/libs/luabind/luabind/detail/enum_maker.hpp index fadbe3e52..20161ec3f 100644 --- a/libs/luabind/luabind/detail/enum_maker.hpp +++ b/libs/luabind/luabind/detail/enum_maker.hpp @@ -30,8 +30,8 @@ #include #include -namespace luabind -{ +namespace luabind { + struct value; struct value_vector : public std::vector @@ -45,7 +45,7 @@ namespace luabind struct value { - friend class std::vector; + friend class std::vector; template value(const char* name, T v) : name_(name) @@ -65,7 +65,7 @@ namespace luabind return v; } - private: + private: value() {} }; @@ -93,19 +93,18 @@ namespace luabind template struct enum_maker { - explicit enum_maker(From& from): from_(from) {} + explicit enum_maker(From& from) : from_(from) {} From& operator[](const value& val) { from_.add_static_constant(val.name_, val.val_); return from_; } - + From& operator[](const value_vector& values) { - for (value_vector::const_iterator i = values.begin(); i != values.end(); ++i) - { - from_.add_static_constant(i->name_, i->val_); + for(const auto& val : values) { + from_.add_static_constant(val.name_, val.val_); } return from_; @@ -114,10 +113,11 @@ namespace luabind From& from_; private: - void operator=(enum_maker const&); // C4512, assignment operator could not be generated + void operator=(enum_maker const&); // C4512, assignment operator could not be generated template void operator,(T const&) const; }; } } #endif // LUABIND_ENUM_MAKER_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/format_signature.hpp b/libs/luabind/luabind/detail/format_signature.hpp index ec56b6196..bb6679dba 100644 --- a/libs/luabind/luabind/detail/format_signature.hpp +++ b/libs/luabind/luabind/detail/format_signature.hpp @@ -5,73 +5,70 @@ #ifndef LUABIND_FORMAT_SIGNATURE_081014_HPP # define LUABIND_FORMAT_SIGNATURE_081014_HPP -# include -# include -# include +#include +#include +#include +#include -# include -# include -# include +namespace luabind { + namespace adl { -namespace luabind { namespace adl { + class object; + class argument; + template + struct table; - class object; - class argument; - template - struct table; -} // namespace adl + } // namespace adl -using adl::object; -using adl::argument; -using adl::table; + using adl::object; + using adl::argument; + using adl::table; -} // namespace luabind + namespace detail { -namespace luabind { namespace detail { + LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); -LUABIND_API std::string get_class_name(lua_State* L, type_id const& i); + template + struct type_to_string + { + static void get(lua_State* L) + { + lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - lua_pushstring(L, get_class_name(L, typeid(T)).c_str()); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "*"); + lua_concat(L, 2); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "*"); - lua_concat(L, 2); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, "&"); + lua_concat(L, 2); + } + }; -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, "&"); - lua_concat(L, 2); - } -}; - -template -struct type_to_string -{ - static void get(lua_State* L) - { - type_to_string::get(L); - lua_pushstring(L, " const"); - lua_concat(L, 2); - } -}; + template + struct type_to_string + { + static void get(lua_State* L) + { + type_to_string::get(L); + lua_pushstring(L, " const"); + lua_concat(L, 2); + } + }; # define LUABIND_TYPE_TO_STRING(x) \ template <> \ @@ -87,67 +84,67 @@ struct type_to_string LUABIND_TYPE_TO_STRING(x) \ LUABIND_TYPE_TO_STRING(unsigned x) -LUABIND_INTEGRAL_TYPE_TO_STRING(char) -LUABIND_INTEGRAL_TYPE_TO_STRING(short) -LUABIND_INTEGRAL_TYPE_TO_STRING(int) -LUABIND_INTEGRAL_TYPE_TO_STRING(long) + LUABIND_INTEGRAL_TYPE_TO_STRING(char) + LUABIND_INTEGRAL_TYPE_TO_STRING(short) + LUABIND_INTEGRAL_TYPE_TO_STRING(int) + LUABIND_INTEGRAL_TYPE_TO_STRING(long) -LUABIND_TYPE_TO_STRING(void) -LUABIND_TYPE_TO_STRING(bool) -LUABIND_TYPE_TO_STRING(std::string) -LUABIND_TYPE_TO_STRING(lua_State) + LUABIND_TYPE_TO_STRING(void) + LUABIND_TYPE_TO_STRING(bool) + LUABIND_TYPE_TO_STRING(std::string) + LUABIND_TYPE_TO_STRING(lua_State) -LUABIND_TYPE_TO_STRING(luabind::object) -LUABIND_TYPE_TO_STRING(luabind::argument) + LUABIND_TYPE_TO_STRING(luabind::object) + LUABIND_TYPE_TO_STRING(luabind::argument) # undef LUABIND_INTEGRAL_TYPE_TO_STRING # undef LUABIND_TYPE_TO_STRING -template -struct type_to_string > -{ - static void get(lua_State* L) - { - lua_pushstring(L, "table"); - } -}; + template + struct type_to_string > + { + static void get(lua_State* L) + { + lua_pushstring(L, "table"); + } + }; -template -void format_signature_aux(lua_State*, bool, End, End) -{} + inline void format_signature_aux(lua_State*, bool, meta::type_list< >) + {} -template -void format_signature_aux(lua_State* L, bool first, Iter, End end) -{ - if (!first) - lua_pushstring(L, ","); - type_to_string::get(L); - format_signature_aux(L, false, typename mpl::next::type(), end); -} + template + void format_signature_aux(lua_State* L, bool first, Signature) + { + if(!first) + lua_pushstring(L, ","); + type_to_string::type>::get(L); + format_signature_aux(L, false, typename meta::pop_front::type()); + } -template -void format_signature(lua_State* L, char const* function, Signature) -{ - typedef typename mpl::begin::type first; + template + void format_signature(lua_State* L, char const* function, Signature) + { + using first = typename meta::front::type; - type_to_string::get(L); + type_to_string::get(L); - lua_pushstring(L, " "); - lua_pushstring(L, function); + lua_pushstring(L, " "); + lua_pushstring(L, function); - lua_pushstring(L, "("); - format_signature_aux( - L - , true - , typename mpl::next::type() - , typename mpl::end::type() - ); - lua_pushstring(L, ")"); + lua_pushstring(L, "("); + format_signature_aux( + L + , true + , typename meta::pop_front::type() + ); + lua_pushstring(L, ")"); + constexpr size_t ncat = meta::size::value * 2 + 2 + (meta::size::value == 1 ? 1 : 0); + lua_concat(L, static_cast(ncat)); + } - lua_concat(L, static_cast(mpl::size()) * 2 + 2); -} + } // namespace detail -}} // namespace luabind::detail +} // namespace luabind #endif // LUABIND_FORMAT_SIGNATURE_081014_HPP diff --git a/libs/luabind/luabind/detail/garbage_collector.hpp b/libs/luabind/luabind/detail/garbage_collector.hpp index c0d68aa36..9e55d2b4a 100644 --- a/libs/luabind/luabind/detail/garbage_collector.hpp +++ b/libs/luabind/luabind/detail/garbage_collector.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -26,28 +26,31 @@ #include -namespace luabind { namespace detail -{ - // function that is used as __gc metafunction on several objects - template - inline int garbage_collector(lua_State* L) - { - T* obj = static_cast(lua_touserdata(L, -1)); - obj->~T(); - return 0; - } +namespace luabind { + namespace detail { - template - struct garbage_collector_s - { - static int apply(lua_State* L) + // function that is used as __gc metafunction on several objects + template + inline int garbage_collector(lua_State* L) { T* obj = static_cast(lua_touserdata(L, -1)); obj->~T(); return 0; } - }; -}} + template + struct garbage_collector_s + { + static int apply(lua_State* L) + { + T* obj = static_cast(lua_touserdata(L, -1)); + obj->~T(); + return 0; + } + }; + + } +} #endif // LUABIND_GARBAGE_COLLECTOR_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/has_get_pointer.hpp b/libs/luabind/luabind/detail/has_get_pointer.hpp deleted file mode 100644 index 8a001ddda..000000000 --- a/libs/luabind/luabind/detail/has_get_pointer.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef LUABIND_HAS_GET_POINTER_051022_HPP -# define LUABIND_HAS_GET_POINTER_051022_HPP - -# include - -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -# include -# endif - -namespace luabind { namespace detail { - -namespace has_get_pointer_ -{ - - struct any - { - template any(T const&); - }; - - struct no_overload_tag - {}; - - typedef char (&yes)[1]; - typedef char (&no)[2]; - - no_overload_tag operator,(no_overload_tag, int); - -// -// On compilers with ADL, we need these generic overloads in this -// namespace as well as in luabind::. Otherwise get_pointer(any) -// will be found before them. -// -# ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP - - template - T* get_pointer(T const volatile*); - - template - T* get_pointer(std::auto_ptr const&); - -# endif - -// -// On compilers that doesn't support ADL, the overload below has to -// live in luabind::. -// -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -}} // namespace detail::has_get_pointer_ -# endif - -detail::has_get_pointer_::no_overload_tag - get_pointer(detail::has_get_pointer_::any); - -# ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -namespace detail { namespace has_get_pointer_ -{ -# endif - - template - yes check(T const&); - no check(no_overload_tag); - - template - struct impl - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, - value = sizeof(has_get_pointer_::check( (get_pointer(x),0) )) == 1 - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace has_get_pointer_ - -template -struct has_get_pointer - : has_get_pointer_::impl::type -{}; - -}} // namespace luabind::detail - -#endif // LUABIND_HAS_GET_POINTER_051022_HPP - diff --git a/libs/luabind/luabind/detail/inheritance.hpp b/libs/luabind/luabind/detail/inheritance.hpp index a7afe0156..26bde136a 100644 --- a/libs/luabind/luabind/detail/inheritance.hpp +++ b/libs/luabind/luabind/detail/inheritance.hpp @@ -1,168 +1,169 @@ // Copyright Daniel Wallin 2009. Use, modification and distribution is // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - #ifndef LUABIND_INHERITANCE_090217_HPP # define LUABIND_INHERITANCE_090217_HPP +# include # include # include # include # include # include # include -# include -namespace luabind { namespace detail { +namespace luabind { -typedef void*(*cast_function)(void*); -typedef std::size_t class_id; + namespace detail { -class_id const unknown_class = (std::numeric_limits::max)(); + using cast_function = void*(*)(void*); + using class_id = std::size_t; -class class_rep; + constexpr class_id unknown_class = std::numeric_limits::max(); -class LUABIND_API cast_graph -{ -public: - cast_graph(); - ~cast_graph(); + class class_rep; - // `src` and `p` here describe the *most derived* object. This means that - // for a polymorphic type, the pointer must be cast with - // dynamic_cast before being passed in here, and `src` has to - // match typeid(*p). - std::pair cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); + class LUABIND_API cast_graph + { + public: + cast_graph(); + ~cast_graph(); -private: - class impl; - boost::scoped_ptr m_impl; -}; + // `src` and `p` here describe the *most derived* object. This means that + // for a polymorphic type, the pointer must be cast with + // dynamic_cast before being passed in here, and `src` has to + // match typeid(*p). + std::pair cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const; + void insert(class_id src, class_id target, cast_function cast); -// Maps a type_id to a class_id. Note that this actually partitions the -// id-space into two, using one half for "local" ids; ids that are used only as -// keys into the conversion cache. This is needed because we need a unique key -// even for types that hasn't been registered explicitly. -class LUABIND_API class_id_map -{ -public: - class_id_map(); + private: + class impl; + std::unique_ptr m_impl; + }; - class_id get(type_id const& type) const; - class_id get_local(type_id const& type); - void put(class_id id, type_id const& type); + // Maps a type_id to a class_id. Note that this actually partitions the + // id-space into two, using one half for "local" ids; ids that are used only as + // keys into the conversion cache. This is needed because we need a unique key + // even for types that hasn't been registered explicitly. + class LUABIND_API class_id_map + { + public: + class_id_map(); -private: - typedef std::map map_type; - map_type m_classes; - class_id m_local_id; + class_id get(type_id const& type) const; + class_id get_local(type_id const& type); + void put(class_id id, type_id const& type); - static class_id const local_id_base; -}; + private: + using map_type = std::map; + map_type m_classes; + class_id m_local_id; -inline class_id_map::class_id_map() - : m_local_id(local_id_base) -{} + static class_id const local_id_base; + }; -inline class_id class_id_map::get(type_id const& type) const -{ - map_type::const_iterator i = m_classes.find(type); - if (i == m_classes.end() || i->second >= local_id_base) - return unknown_class; - return i->second; -} + inline class_id_map::class_id_map() + : m_local_id(local_id_base) + {} -inline class_id class_id_map::get_local(type_id const& type) -{ - std::pair result = m_classes.insert( - std::make_pair(type, 0)); + inline class_id class_id_map::get(type_id const& type) const + { + map_type::const_iterator i = m_classes.find(type); + if(i == m_classes.end() || i->second >= local_id_base) { + return unknown_class; + } + else { + return i->second; + } + } - if (result.second) - result.first->second = m_local_id++; + inline class_id class_id_map::get_local(type_id const& type) + { + std::pair result = m_classes.insert(std::make_pair(type, 0)); - assert(m_local_id >= local_id_base); + if(result.second) result.first->second = m_local_id++; + assert(m_local_id >= local_id_base); + return result.first->second; + } - return result.first->second; -} + inline void class_id_map::put(class_id id, type_id const& type) + { + assert(id < local_id_base); -inline void class_id_map::put(class_id id, type_id const& type) -{ - assert(id < local_id_base); + std::pair result = m_classes.insert( + std::make_pair(type, 0)); - std::pair result = m_classes.insert( - std::make_pair(type, 0)); + assert( + result.second + || result.first->second == id + || result.first->second >= local_id_base + ); - assert( - result.second - || result.first->second == id - || result.first->second >= local_id_base - ); + result.first->second = id; + } - result.first->second = id; -} + class class_map + { + public: + class_rep* get(class_id id) const; + void put(class_id id, class_rep* cls); -class class_map -{ -public: - class_rep* get(class_id id) const; - void put(class_id id, class_rep* cls); + private: + std::vector m_classes; + }; -private: - std::vector m_classes; -}; + inline class_rep* class_map::get(class_id id) const + { + if(id >= m_classes.size()) + return 0; + return m_classes[id]; + } -inline class_rep* class_map::get(class_id id) const -{ - if (id >= m_classes.size()) - return 0; - return m_classes[id]; -} + inline void class_map::put(class_id id, class_rep* cls) + { + if(id >= m_classes.size()) + m_classes.resize(id + 1); + m_classes[id] = cls; + } -inline void class_map::put(class_id id, class_rep* cls) -{ - if (id >= m_classes.size()) - m_classes.resize(id + 1); - m_classes[id] = cls; -} + template + struct static_cast_ + { + static void* execute(void* p) + { + return static_cast(static_cast(p)); + } + }; -template -struct static_cast_ -{ - static void* execute(void* p) - { - return static_cast(static_cast(p)); - } -}; + template + struct dynamic_cast_ + { + static void* execute(void* p) + { + return dynamic_cast(static_cast(p)); + } + }; -template -struct dynamic_cast_ -{ - static void* execute(void* p) - { - return dynamic_cast(static_cast(p)); - } -}; + // Thread safe class_id allocation. + LUABIND_API class_id allocate_class_id(type_id const& cls); -// Thread safe class_id allocation. -LUABIND_API class_id allocate_class_id(type_id const& cls); + template + struct registered_class + { + static class_id const id; + }; -template -struct registered_class -{ - static class_id const id; -}; + template + class_id const registered_class::id = allocate_class_id(typeid(T)); -template -class_id const registered_class::id = allocate_class_id(typeid(T)); + template + struct registered_class + : registered_class + {}; -template -struct registered_class - : registered_class -{}; + } // namespace detail -}} // namespace luabind::detail +} // namespace luabind #endif // LUABIND_INHERITANCE_090217_HPP + diff --git a/libs/luabind/luabind/detail/instance_holder.hpp b/libs/luabind/luabind/detail/instance_holder.hpp index 456e13e6b..bf51ebb06 100644 --- a/libs/luabind/luabind/detail/instance_holder.hpp +++ b/libs/luabind/luabind/detail/instance_holder.hpp @@ -6,126 +6,160 @@ # define LUABIND_INSTANCE_HOLDER_081024_HPP # include -# include // TODO -# include +# include # include -# include # include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -class instance_holder -{ -public: - instance_holder(class_rep* cls, bool pointee_const) - : m_cls(cls) - , m_pointee_const(pointee_const) - {} + class instance_holder + { + public: + instance_holder(bool pointee_const) + : m_pointee_const(pointee_const) + {} - virtual ~instance_holder() - {} + virtual ~instance_holder() + {} - virtual std::pair get(class_id target) const = 0; + virtual std::pair get(cast_graph const& casts, class_id target) const = 0; + virtual void release() = 0; - virtual void release() = 0; + bool pointee_const() const + { + return m_pointee_const; + } - class_rep* get_class() const - { - return m_cls; - } + private: + bool m_pointee_const; + }; - bool pointee_const() const - { - return m_pointee_const; - } + template + class pointer_holder : public instance_holder + { + public: + pointer_holder(P p, class_id dynamic_id, void* dynamic_ptr) : + instance_holder(detail::is_pointer_to_const

()), + p(std::move(p)), weak(0), dynamic_id(dynamic_id), dynamic_ptr(dynamic_ptr) + { + } -private: - class_rep* m_cls; - bool m_pointee_const; -}; + std::pair get(cast_graph const& casts, class_id target) const override + { + // if somebody wants the smart-ptr, he can get a reference to it + if(target == registered_class

::id) return std::pair(&this->p, 0); -namespace mpl = boost::mpl; + void* naked_ptr = const_cast(static_cast(weak ? weak : get_pointer(p))); + if(!naked_ptr) return std::pair(nullptr, 0); -inline mpl::false_ check_const_pointer(void*) -{ - return mpl::false_(); -} + using pointee_type = typename std::remove_cv::type>::type; -inline mpl::true_ check_const_pointer(void const*) -{ - return mpl::true_(); -} + return casts.cast(naked_ptr, + registered_class< pointee_type >::id, + target, dynamic_id, dynamic_ptr); + } -template -void release_ownership(std::auto_ptr& p) -{ - p.release(); -} + explicit operator bool() const + { + return p ? true : false; + } -template -void release_ownership(P const&) -{ - throw std::runtime_error( - "luabind: smart pointer does not allow ownership transfer"); -} + void release() override + { + weak = const_cast(static_cast(get_pointer(p))); + release_ownership(p); + } -template -class_id static_class_id(T*) -{ - return registered_class::id; -} + private: + mutable P p; + // weak will hold a possibly stale pointer to the object owned + // by p once p has released it's owership. This is a workaround + // to make adopt() work with virtual function wrapper classes. + void* weak; + class_id dynamic_id; + void* dynamic_ptr; + }; -template -class pointer_holder : public instance_holder -{ -public: - pointer_holder( - P p, class_id dynamic_id, void* dynamic_ptr, class_rep* cls - ) - : instance_holder(cls, check_const_pointer(false ? get_pointer(p) : 0)) - , p(p) - , weak(0) - , dynamic_id(dynamic_id) - , dynamic_ptr(dynamic_ptr) - {} + template + class value_holder : + public instance_holder + { + public: + // No need for dynamic_id / dynamic_ptr, since we always get the most derived type + value_holder(lua_State* /*L*/, ValueType val) + : instance_holder(false), val_(std::move(val)) + {} - std::pair get(class_id target) const - { - if (target == registered_class

::id) - return std::pair(&this->p, 0); + explicit operator bool() const + { + return true; + } - void* naked_ptr = const_cast(static_cast( - weak ? weak : get_pointer(p))); + std::pair get(cast_graph const& casts, class_id target) const override + { + const auto this_id = registered_class::id; + void* const naked_ptr = const_cast((const void*)&val_); + if(target == this_id) return std::pair(naked_ptr, 0); + return casts.cast(naked_ptr, this_id, target, this_id, naked_ptr); + } - if (!naked_ptr) - return std::pair((void*)0, 0); + void release() override + {} - return get_class()->casts().cast( - naked_ptr - , static_class_id(false ? get_pointer(p) : 0) - , target - , dynamic_id - , dynamic_ptr - ); - } + private: + ValueType val_; + }; - void release() - { - weak = const_cast(static_cast( - get_pointer(p))); - release_ownership(p); - } + /* + Pointer types should automatically convert to reference types + */ + template + class pointer_like_holder : + public instance_holder + { + public: + // No need for dynamic_id / dynamic_ptr, since we always get the most derived type + pointer_like_holder(lua_State* /*L*/, ValueType val, class_id dynamic_id, void* dynamic_ptr) + : + instance_holder(std::is_const< decltype(*get_pointer(val)) >::value), + val_(std::move(val)), + dynamic_id_(dynamic_id), + dynamic_ptr_(dynamic_ptr) + { + } -private: - mutable P p; - // weak will hold a possibly stale pointer to the object owned - // by p once p has released it's owership. This is a workaround - // to make adopt() work with virtual function wrapper classes. - void* weak; - class_id dynamic_id; - void* dynamic_ptr; -}; + explicit operator bool() const + { + return val_ ? true : false; + } -}} // namespace luabind::detail + std::pair get(cast_graph const& casts, class_id target) const override + { + const auto value_id = registered_class::id; + void* const naked_value_ptr = const_cast((const void*)&val_); + if(target == value_id) return std::pair(naked_value_ptr, 0); + // If we were to support automatic pointer conversion, this would be the place + + using pointee_type = typename std::remove_cv::type >::type; + const auto pointee_id = registered_class< pointee_type >::id; + void* const naked_pointee_ptr = const_cast((const void*)get_pointer(val_)); + return casts.cast(naked_pointee_ptr, pointee_id, target, dynamic_id_, dynamic_ptr_); + } + + void release() override + {} + + private: + ValueType val_; + class_id dynamic_id_; + void* dynamic_ptr_; + // weak? must understand what the comment up there really means + }; + + } + +} // namespace luabind::detail #endif // LUABIND_INSTANCE_HOLDER_081024_HPP + diff --git a/libs/luabind/luabind/detail/is_indirect_const.hpp b/libs/luabind/luabind/detail/is_indirect_const.hpp deleted file mode 100644 index b6c1282fb..000000000 --- a/libs/luabind/luabind/detail/is_indirect_const.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef IS_INDIRECT_CONST_040211_HPP -#define IS_INDIRECT_CONST_040211_HPP - -#include -#include -#include - -namespace luabind { - - namespace detail { - - template - typename boost::is_const::type - is_indirect_const_check(T(*)(), int); - - template - typename boost::is_const::type - is_indirect_const_check(T*(*)(), long); - - template - typename boost::is_const::type - is_indirect_const_check(T&(*)(), long); - - yes_t to_yes_no(boost::mpl::true_); - no_t to_yes_no(boost::mpl::false_); - - } // namespace detail - - // returns true for: - // T = U* is_const - // T = U& is_const - // T = U is_const - template - struct is_indirect_const - { - BOOST_STATIC_CONSTANT(int, value = ( - sizeof( - detail::to_yes_no( - detail::is_indirect_const_check((T(*)())0, 0L) - )) - == sizeof(detail::yes_t) - )); - }; - -} // namespace luabind - -#endif // IS_INDIRECT_CONST_040211_HPP - diff --git a/libs/luabind/luabind/detail/link_compatibility.hpp b/libs/luabind/luabind/detail/link_compatibility.hpp index 6f0006afa..33cb9a985 100644 --- a/libs/luabind/luabind/detail/link_compatibility.hpp +++ b/libs/luabind/luabind/detail/link_compatibility.hpp @@ -25,36 +25,38 @@ #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { #ifdef LUABIND_NOT_THREADSAFE - LUABIND_API void not_threadsafe_defined_conflict(); + LUABIND_API void not_threadsafe_defined_conflict(); #else - LUABIND_API void not_threadsafe_not_defined_conflict(); + LUABIND_API void not_threadsafe_not_defined_conflict(); #endif #ifdef LUABIND_NO_ERROR_CHECKING - LUABIND_API void no_error_checking_defined_conflict(); + LUABIND_API void no_error_checking_defined_conflict(); #else - LUABIND_API void no_error_checking_not_defined_conflict(); + LUABIND_API void no_error_checking_not_defined_conflict(); #endif - inline void check_link_compatibility() - { - #ifdef LUABIND_NOT_THREADSAFE - not_threadsafe_defined_conflict(); - #else - not_threadsafe_not_defined_conflict(); - #endif + inline void check_link_compatibility() + { +#ifdef LUABIND_NOT_THREADSAFE + not_threadsafe_defined_conflict(); +#else + not_threadsafe_not_defined_conflict(); +#endif + +#ifdef LUABIND_NO_ERROR_CHECKING + no_error_checking_defined_conflict(); +#else + no_error_checking_not_defined_conflict(); +#endif + } - #ifdef LUABIND_NO_ERROR_CHECKING - no_error_checking_defined_conflict(); - #else - no_error_checking_not_defined_conflict(); - #endif } - -}} +} #endif + diff --git a/libs/luabind/luabind/detail/make_instance.hpp b/libs/luabind/luabind/detail/make_instance.hpp index 3150cf048..94c89330c 100644 --- a/libs/luabind/luabind/detail/make_instance.hpp +++ b/libs/luabind/luabind/detail/make_instance.hpp @@ -5,101 +5,167 @@ #ifndef LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP # define LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP -# include # include # include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -template -std::pair get_dynamic_class_aux( - lua_State* L, T const* p, mpl::true_) -{ - lua_pushliteral(L, "__luabind_class_id_map"); - lua_rawget(L, LUA_REGISTRYINDEX); + template + std::pair get_dynamic_class_aux(lua_State* L, T const* p, std::true_type) + { + lua_pushliteral(L, "__luabind_class_id_map"); + lua_rawget(L, LUA_REGISTRYINDEX); + class_id_map& class_ids = *static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - class_id_map& class_ids = *static_cast( - lua_touserdata(L, -1)); + return std::make_pair(class_ids.get_local(typeid(*p)), dynamic_cast(const_cast(p))); + } - lua_pop(L, 1); + template + std::pair get_dynamic_class_aux(lua_State*, T const* p, std::false_type) + { + return std::make_pair(registered_class::id, (void*)p); + } - return std::make_pair( - class_ids.get_local(typeid(*p)) - , dynamic_cast(const_cast(p)) - ); -} + template + std::pair get_dynamic_class(lua_State* L, T* p) + { + return get_dynamic_class_aux(L, p, std::is_polymorphic()); + } -template -std::pair get_dynamic_class_aux( - lua_State*, T const* p, mpl::false_) -{ - return std::make_pair(registered_class::id, (void*)p); -} + template + class_rep* get_pointee_class(class_map const& classes, T*) + { + return classes.get(registered_class::id); + } -template -std::pair get_dynamic_class(lua_State* L, T* p) -{ - return get_dynamic_class_aux(L, p, boost::is_polymorphic()); -} + template + class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) + { + lua_pushliteral(L, "__luabind_class_map"); + lua_rawget(L, LUA_REGISTRYINDEX); -template -class_rep* get_pointee_class(class_map const& classes, T*) -{ - return classes.get(registered_class::id); -} + class_map const& classes = *static_cast(lua_touserdata(L, -1)); -template -class_rep* get_pointee_class(lua_State* L, P const& p, class_id dynamic_id) -{ - lua_pushliteral(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); + lua_pop(L, 1); - class_map const& classes = *static_cast( - lua_touserdata(L, -1)); + class_rep* cls = classes.get(dynamic_id); - lua_pop(L, 1); + if(!cls) { + cls = get_pointee_class(classes, get_pointer(p)); + } - class_rep* cls = classes.get(dynamic_id); + return cls; + } - if (!cls) - cls = get_pointee_class(classes, get_pointer(p)); + // Create an appropriate instance holder for the given pointer like object. + template + void make_pointer_instance(lua_State* L, P p) + { + std::pair dynamic = get_dynamic_class(L, get_pointer(p)); - return cls; -} + class_rep* cls = get_pointee_class(L, p, dynamic.first); -// Create an appropriate instance holder for the given pointer like object. -template -void make_instance(lua_State* L, P p) -{ - std::pair dynamic = get_dynamic_class(L, get_pointer(p)); + if(!cls) + { + throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(P).name())); + } - class_rep* cls = get_pointee_class(L, p, dynamic.first); + object_rep* instance = push_new_instance(L, cls); - if (!cls) - { - throw std::runtime_error("Trying to use unregistered class"); - } + using value_type = typename std::remove_reference

::type; + using holder_type = pointer_holder; - object_rep* instance = push_new_instance(L, cls); + void* storage = instance->allocate(sizeof(holder_type)); - typedef pointer_holder

holder_type; + try + { + new (storage) holder_type(std::move(p), dynamic.first, dynamic.second); + } + catch(...) + { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } - void* storage = instance->allocate(sizeof(holder_type)); + instance->set_instance(static_cast(storage)); + } - try - { - new (storage) holder_type(p, dynamic.first, dynamic.second, cls); - } - catch (...) - { - instance->deallocate(storage); - lua_pop(L, 1); - throw; - } - instance->set_instance(static_cast(storage)); -} + template< typename ValueType > + void make_value_instance(lua_State* L, ValueType&& val, std::true_type /* is smart ptr */) + { + if(get_pointer(val)) { + std::pair dynamic = get_dynamic_class(L, get_pointer(val)); + class_rep* cls = get_pointee_class(L, val, dynamic.first); -}} // namespace luabind::detail + using pointee_type = decltype(*get_pointer(val)); + + if(!cls) { + throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(pointee_type).name())); + } + + object_rep* instance = push_new_instance(L, cls); + + using value_type = typename std::remove_reference::type; + using holder_type = pointer_like_holder; + + void* storage = instance->allocate(sizeof(holder_type)); + + try { + new (storage) holder_type(L, std::forward(val), dynamic.first, dynamic.second); + } + catch(...) { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } + + instance->set_instance(static_cast(storage)); + } else { + lua_pushnil(L); + } + } + + template< typename ValueType > + void make_value_instance(lua_State* L, ValueType&& val, std::false_type /* smart ptr */) + { + const auto value_type_id = detail::registered_class::id; + class_rep* cls = get_pointee_class(L, &val, value_type_id); + + if(!cls) { + throw std::runtime_error("Trying to use unregistered class: " + std::string(typeid(ValueType).name())); + } + + object_rep* instance = push_new_instance(L, cls); + + using value_type = typename std::remove_reference::type; + using holder_type = value_holder; + + void* storage = instance->allocate(sizeof(holder_type)); + + try { + new (storage) holder_type(L, std::forward(val)); + } + catch(...) { + instance->deallocate(storage); + lua_pop(L, 1); + throw; + } + + instance->set_instance(static_cast(storage)); + } + + template< typename ValueType > + void make_value_instance(lua_State* L, ValueType&& val) + { + make_value_instance(L, std::forward(val), has_get_pointer()); + } + + } // namespace detail +} // namespace luabind #endif // LUABIND_DETAIL_MAKE_INSTANCE_090310_HPP + diff --git a/libs/luabind/luabind/detail/meta.hpp b/libs/luabind/luabind/detail/meta.hpp new file mode 100644 index 000000000..8b6acc303 --- /dev/null +++ b/libs/luabind/luabind/detail/meta.hpp @@ -0,0 +1,581 @@ +// Copyright Michael Steinberg 2013. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_META_HPP_INCLUDED +#define LUABIND_META_HPP_INCLUDED + +#include + +namespace luabind { + namespace meta { + + struct type_list_tag {}; + struct index_list_tag {}; + + /* + Index list and type list share pretty common patterns... is there a way to unify them? + */ + + template< unsigned int > + struct count + {}; + + template< unsigned int > + struct index + {}; + + template< typename Type > + struct type + {}; + + // Use this to unpack a parameter pack into a list of T's + template< typename T, typename DontCare > + struct unpack_helper + { + using type = T; + }; + + struct init_order { + init_order(std::initializer_list) {} + }; + + // common operators + template< typename T > + struct size; + + template< typename T, unsigned int Index > // Specializations so index lists can use the same syntax + struct get; + + template< typename... Lists > + struct join; + + template< typename List1, typename List2, typename... Lists > + struct join< List1, List2, Lists... > { + // Could try to join on both sides + using type = typename join< typename join< List1, List2 >::type, Lists... >::type; + }; + + // convenience + template< typename T > + struct front : public get< T, 0 > + { + }; + + template< typename List, typename T > + struct push_front; + + template< typename List, typename T > + struct push_back; + + template< typename T > + struct pop_front; + + template< typename T > + struct pop_back; + + template< typename List, unsigned int Index, typename T > + struct replace; + + template< typename List, unsigned int Index, template< typename > class T > + struct enwrap; + + template< typename List, template< typename > class T > + struct enwrap_all; + + template< typename List, unsigned int Index, template< typename > class T > + struct transform; + + template< typename List, unsigned int Index, template< typename > class Function > + using transform_t = typename transform< List, Index, Function >::type; + + template< typename List, template< typename > class Function > + struct transform_all; + + template< typename List, template< typename > class Function > + using transform_all_t = typename transform_all< List, Function >::type; + + + template< typename T, unsigned int start, unsigned int end > + struct sub_range; + + /* + aliases + */ + template< typename T > + using pop_front_t = typename pop_front::type; + + template< typename T1, typename... Types > + using join_t = typename join< T1, Types... >::type; + + template< typename T, unsigned int start, unsigned int end > + using sub_range_t = typename sub_range< T, start, end >::type; + + template< typename T, unsigned int index > + using get_t = typename get< T, index >::type; + + + // Used as terminator on type and index lists + struct null_type {}; + + template< typename... Types > + struct type_list : public type_list_tag + { + template< unsigned int Index > + using at = typename get::type; + }; + + template< typename... Types1, typename... Types2 > + type_list operator|(const type_list&, const type_list&) { + return type_list(); + } + + template< typename T > + struct is_typelist : public std::false_type + { + static const bool value = false; + }; + + template< typename... Types > + struct is_typelist< type_list< Types... > > : public std::true_type + { + static const bool value = true; + }; + + /* + Find type + */ + + template< typename TypeList, typename Type > + struct contains; + + template< typename Type0, typename... Types, typename Type > + struct contains< type_list, Type > + : std::conditional< std::is_same::value, std::true_type, contains< type_list, Type > >::type + { + }; + + template< typename Type > + struct contains< type_list< >, Type > + : std::false_type + { + }; + + /* + size + */ + + template< > + struct size< type_list< > > { + enum { value = 0 }; + }; + + template< typename Type0, typename... Types > + struct size< type_list< Type0, Types... > > { + enum { value = 1 + size< type_list >::value }; + }; + + + template< typename... Types, typename Type > + struct push_front< type_list, Type > + { + using type = type_list< Type, Types... >; + }; + + template< typename... Types, typename Type > + struct push_back< type_list, Type > + { + using type = type_list< Types..., Type >; + }; + + /* + pop_front + */ + + template< typename Type0, typename... Types > + struct pop_front< type_list< Type0, Types... > > + { + using type = type_list< Types... >; + }; + + template< > + struct pop_front< type_list< > > + { + using type = type_list< >; + }; + + /* + Index access to type list + */ + template< typename Element0, typename... Elements, unsigned int Index > + struct get< type_list, Index > { + using type = typename get< type_list, Index - 1 >::type; + }; + + template< typename Element0, typename... Elements > + struct get< type_list, 0 > + { + using type = Element0; + }; + + template< unsigned int Index > + struct get< type_list< >, Index > + { + static_assert(size< type_list< int > >::value == 1, "Bad Index"); + }; + + /* + Join Type Lists + */ + template< typename... Types1, typename... Types2 > + struct join< type_list< Types1... >, type_list< Types2... > > + { + using type = type_list< Types1..., Types2... >; + }; + + namespace detail { + template< typename HeadList, typename TailList, typename Type, unsigned int Index > + struct replace_helper; + + template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type, unsigned int Index > + struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, Index> { + using type = typename replace_helper< type_list< HeadTypes..., CurrentType >, type_list, Type, Index - 1 >::type; + }; + + template< typename... HeadTypes, typename CurrentType, typename... TailTypes, typename Type > + struct replace_helper< type_list< HeadTypes... >, type_list< CurrentType, TailTypes... >, Type, 0 > { + using type = type_list< HeadTypes..., Type, TailTypes... >; + }; + } + + template< typename... Types, unsigned int Index, typename Type > + struct replace< type_list< Types... >, Index, Type > + { + using TypeList = type_list< Types... >; + + using type = join_t< + sub_range_t< TypeList, 0, Index >, + meta::type_list, + sub_range_t< TypeList, Index + 1, sizeof...(Types) > + >; + }; + + /* + Enwrap all elements of a type list in an template + */ + template< typename... Types, unsigned int Index, template< typename > class Enwrapper > + struct enwrap< type_list< Types... >, Index, Enwrapper > { + using type = join_t< + sub_range_t< type_list, 0, Index >, + Enwrapper< get_t< type_list, Index> >, + sub_range_t< type_list, Index + 1, sizeof...(Types) > + >; + }; + + template< typename... Types, template< typename > class Enwrapper > + struct enwrap_all< type_list< Types... >, Enwrapper > + { + using type = type_list< Enwrapper< Types >... >; + }; + + /* + Transform a certain element of a type list + */ + template< typename T, unsigned int Index, template< typename > class Function > + struct transform; + + template< typename... Types, unsigned int Index, template< typename > class Function > + struct transform< type_list< Types... >, Index, Function > { + using type = join_t< + sub_range_t< type_list, 0, Index >, + typename Function< get_t< type_list, Index> >::type, + sub_range_t< type_list, Index + 1, sizeof...(Types) > + >; + }; + + /* + Transform all elements of a type list + */ + template< typename... Types, template< typename > class Function > + struct transform_all< type_list< Types... >, Function > { + using type = type_list< typename Function::type... >; + }; + + /* + Tuple from type list + */ + template< class TypeList > + struct make_tuple; + + template< typename... Types > + struct make_tuple< type_list< Types... > > + { + using type = std::tuple< Types... >; + }; + + + /* + Type selection + */ + + template< typename ConvertibleToTrueFalse, typename Result > + struct case_ : public ConvertibleToTrueFalse { + using type = Result; + }; + + template< typename Result > + struct default_ { + using type = Result; + }; + + + template< typename Case, typename... CaseList > + struct select_ + { + using type = typename std::conditional< + std::is_convertible::value, + typename Case::type, + typename select_::type + >::type; + }; + + template< typename Case > + struct select_< Case > + { + using type = typename std::conditional< + std::is_convertible::value, + typename Case::type, + null_type + >::type; + }; + + template< typename T > + struct select_< default_ > { + using type = typename default_::type; + }; + + /* + Create index lists to expand on type_lists + */ + + template< unsigned int... Indices > + struct index_list : public index_list_tag + { + }; + + /* + Index index list + */ + + namespace detail { + + template< unsigned int Index, unsigned int Value0, unsigned int... Values > + struct get_iterate { + static const unsigned int value = get_iterate< Index - 1, Values... >::value; + }; + + template< unsigned int Value0, unsigned int... Values > + struct get_iterate< 0, Value0, Values... > { + static const unsigned int value = Value0; + }; + + } + + template< unsigned int... Values, unsigned int Index > + struct get< index_list< Values... >, Index > + { + static_assert(sizeof...(Values) > Index, "Bad Index"); + static const unsigned int value = detail::get_iterate< Index, Values... >::value; + }; + + /* + Index list size + */ + + template< unsigned int... Values > + struct size< index_list< Values... > > { + static const unsigned int value = sizeof...(Values); + }; + + + /* + Index list push front + */ + template< unsigned int... Indices, unsigned int Index > + struct push_front< index_list< Indices... >, index > + { + using type = index_list< Index, Indices... >; + }; + + /* + Index list push back + */ + template< unsigned int... Indices, unsigned int Index > + struct push_back< index_list< Indices... >, index > + { + using type = index_list< Indices..., Index >; + }; + + /* + Index list pop_front + */ + template< unsigned int Index0, unsigned int... Indices > + struct pop_front< index_list< Index0, Indices... > > { + using type = index_list< Indices... >; + }; + + template< > + struct pop_front< index_list< > > { + using type = index_list< >; + }; + + /* + Index list range creation + */ + namespace detail { + + template< unsigned int curr, unsigned int end, unsigned int... Indices > + struct make_index_range : + public make_index_range< curr + 1, end, Indices..., curr > + { + }; + + template< unsigned int end, unsigned int... Indices > + struct make_index_range< end, end, Indices... > + { + using type = index_list< Indices... >; + }; + + } + + /* + make_index_range< start, end > + Creates the index list list of range [start, end) + */ + template< unsigned int start, unsigned int end > + struct make_index_range { + static_assert(end >= start, "end must be greater than or equal to start"); + using type = typename detail::make_index_range< start, end >::type; + }; + + template< unsigned int start, unsigned int end > + using index_range = typename make_index_range::type; + + namespace detail { + // These implementation are not really efficient... + template< typename SourceList, typename IndexList > + struct sub_range_index; + + template< typename SourceList, unsigned int... Indices > + struct sub_range_index< SourceList, index_list< Indices... > > { + using type = index_list< get< SourceList, Indices >::value... >; + }; + + template< typename SourceList, typename IndexList > + struct sub_range_type; + + template< typename SourceList, unsigned int... Indices > + struct sub_range_type< SourceList, index_list< Indices... > > { + using type = type_list< typename get< SourceList, Indices >::type... >; + }; + + } + + /* + Index list sub_range [start, end) + */ + template< unsigned int start, unsigned int end, unsigned int... Indices > + struct sub_range< index_list, start, end > + { + static_assert(end >= start, "end must be greater or equal to start"); + using type = typename detail::sub_range_index< index_list, typename make_index_range::type >::type; + }; + + /* + Type list sub_range [start, end) + */ + template< unsigned int start, unsigned int end, typename... Types > + struct sub_range< type_list, start, end > + { + static_assert(end >= start, "end must be greater or equal to start"); + using type = typename detail::sub_range_type< type_list, typename make_index_range::type >::type; + }; + + /* + Index list sum + */ + + namespace detail { + + template< typename T, T... Values > + struct sum_values; + + template< typename T, T Value0, T... Values > + struct sum_values< T, Value0, Values... > { + static const T value = Value0 + sum_values< T, Values... >::value; + }; + + template< typename T > + struct sum_values< T > + { + static const T value = 0; + }; + + } + + template< typename T > + struct sum; + + template< unsigned int... Args > + struct sum< index_list > + { + static const unsigned int value = detail::sum_values::value; + }; + + /* + and_ or_ + */ + + template< typename... ConvertiblesToTrueFalse > + struct and_; + + template< typename Convertible0, typename... Convertibles > + struct and_< Convertible0, Convertibles... > + : std::conditional < + std::is_convertible< Convertible0, std::true_type >::value, + and_< Convertibles... >, + std::false_type > ::type + { + }; + + template< > + struct and_< > + : std::true_type + { + }; + + + template< typename... ConvertiblesToTrueFalse > + struct or_; + + template< typename Convertible0, typename... Convertibles > + struct or_< Convertible0, Convertibles... > + : std::conditional < + std::is_convertible< Convertible0, std::true_type >::value, + std::true_type, + or_< Convertibles... > + > ::type + { + }; + + template< > + struct or_< > + : std::true_type + { + }; + + } +} + +#endif + diff --git a/libs/luabind/luabind/detail/object.hpp b/libs/luabind/luabind/detail/object.hpp new file mode 100644 index 000000000..a6fea5928 --- /dev/null +++ b/libs/luabind/luabind/detail/object.hpp @@ -0,0 +1,386 @@ +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_OBJECT_050419_HPP +#define LUABIND_OBJECT_050419_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif + +namespace luabind { + namespace adl { + + // An object holds a reference to a Lua value residing + // in the registry. + class object : + public lua_proxy_interface + { + public: + object() + {} + + explicit object(handle const& other) + : m_handle(other) + {} + + explicit object(from_stack const& stack_reference) + : m_handle(stack_reference.interpreter, stack_reference.index) + { + } + + template + object(lua_State* interpreter, T&& value) + { + detail::push_to_lua(interpreter, std::forward(value)); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + template + object(lua_State* interpreter, T&& value, Policies const&) + { + detail::push_to_lua<1, Policies>(interpreter, std::forward(value)); + detail::stack_pop pop(interpreter, 1); + handle(interpreter, -1).swap(m_handle); + } + + void push(lua_State* interpreter) const; + lua_State* interpreter() const; + bool is_valid() const; + + template + index_proxy operator[](T const& key) const + { + return index_proxy( + *this, m_handle.interpreter(), key + ); + } + + void swap(object& other) + { + m_handle.swap(other.m_handle); + } + + private: + handle m_handle; + }; + + inline void object::push(lua_State* interpreter) const + { + m_handle.push(interpreter); + } + + inline lua_State* object::interpreter() const + { + return m_handle.interpreter(); + } + + inline bool object::is_valid() const + { + return m_handle.interpreter() != 0; + } + + } // namespace adl + + using adl::object; + + template<> + struct lua_proxy_traits + { + using is_specialized = std::true_type; + + static lua_State* interpreter(object const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, object const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } + }; + + template + R call_function(luabind::object const& obj, Args&&... args) + { + obj.push(obj.interpreter()); + return call_pushed_function(obj.interpreter(), std::forward(args)...); + } + + template + R resume_function(luabind::object const& obj, Args&&... args) + { + obj.push(obj.interpreter()); + return resume_pushed_function(obj.interpreter(), std::forward(args)...); + } + + // declared in luabind/lua_index_proxy.hpp + template + adl::index_proxy::operator object() + { + detail::stack_pop pop(m_interpreter, 1); + push(m_interpreter); + return object(from_stack(m_interpreter, -1)); + } + + // declared in luabind/lua_proxy_interface.hpp + template + template + object adl::lua_proxy_interface::call(Args&&... args) + { + return call_function(derived(), std::forward(args)...); + } + + // declared in luabind/lua_proxy_interface.hpp + template + template + object adl::lua_proxy_interface::operator()(Args&&... args) + { + return call(std::forward(args)...); + } + + // declared in luabind/lua_iterator_proxy.hpp + template + adl::iterator_proxy::operator object() + { + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + detail::stack_pop pop(m_interpreter, 1); + return object(from_stack(m_interpreter, -1)); + } + + // declared in luabind/lua_iterator_proxy.hpp + template + object detail::basic_iterator::key() const + { + return object(m_key); + } + + namespace adl { + // Simple value_wrapper adaptor with the sole purpose of helping with + // overload resolution. Use this as a function parameter type instead + // of "object" or "argument" to restrict the parameter to Lua tables. + template + struct table : Base + { + table(from_stack const& stack_reference) + : Base(stack_reference) + {} + }; + + } // namespace adl + + using adl::table; + + template + struct lua_proxy_traits > + : lua_proxy_traits + { + static bool check(lua_State* L, int idx) + { + return lua_proxy_traits::check(L, idx) && + lua_istable(L, idx); + } + }; + + inline object newtable(lua_State* interpreter) + { + lua_newtable(interpreter); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + // this could be optimized by returning a proxy + inline object globals(lua_State* interpreter) + { + lua_pushglobaltable(interpreter); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + // this could be optimized by returning a proxy + inline object registry(lua_State* interpreter) + { + lua_pushvalue(interpreter, LUA_REGISTRYINDEX); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + template + inline object gettable(ValueWrapper const& table, K&& key) + { + lua_State* interpreter = lua_proxy_traits::interpreter(table); + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push_to_lua(interpreter, std::forward(key)); + lua_gettable(interpreter, -2); + return object(from_stack(interpreter, -1)); + } + + template + inline void settable(ValueWrapper const& table, K&& key, T&& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(table); + + // TODO: Exception safe? + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push_to_lua(interpreter, std::forward(key)); + detail::push_to_lua(interpreter, std::forward(value)); + lua_settable(interpreter, -3); + } + + template + inline object rawget(ValueWrapper const& table, K&& key) + { + lua_State* interpreter = lua_proxy_traits::interpreter( + table + ); + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 2); + detail::push_to_lua(interpreter, std::forward(key)); + lua_rawget(interpreter, -2); + return object(from_stack(interpreter, -1)); + } + + template + inline void rawset(ValueWrapper const& table, K&& key, T&& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter( + table + ); + + // TODO: Exception safe? + + lua_proxy_traits::unwrap(interpreter, table); + detail::stack_pop pop(interpreter, 1); + detail::push_to_lua(interpreter, std::forward(key)); + detail::push_to_lua(interpreter, std::forward(value)); + lua_rawset(interpreter, -3); + } + + template + inline int type(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_type(interpreter, -1); + } + + template + inline object getmetatable(ValueWrapper const& obj) + { + lua_State* interpreter = lua_proxy_traits::interpreter(obj); + lua_proxy_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 2); + lua_getmetatable(interpreter, -1); + return object(from_stack(interpreter, -1)); + } + + template + inline void setmetatable(ValueWrapper1 const& obj, ValueWrapper2 const& metatable) + { + lua_State* interpreter = lua_proxy_traits::interpreter(obj); + lua_proxy_traits::unwrap(interpreter, obj); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, metatable); + lua_setmetatable(interpreter, -2); + } + + template + inline std::tuple getupvalue(ValueWrapper const& value, int index) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 2); + const char* name = lua_getupvalue(interpreter, -1, index); + return std::make_tuple(name, object(from_stack(interpreter, -1))); + } + + template + inline void setupvalue(ValueWrapper1 const& function, int index, ValueWrapper2 const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(function); + + lua_proxy_traits::unwrap(interpreter, function); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, value); + lua_setupvalue(interpreter, -2, index); + } + + template + object property(GetValueWrapper const& get) + { + lua_State* interpreter = lua_proxy_traits::interpreter(get); + lua_proxy_traits::unwrap(interpreter, get); + lua_pushnil(interpreter); + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + + template + object property(GetValueWrapper const& get, SetValueWrapper const& set) + { + lua_State* interpreter = lua_proxy_traits::interpreter(get); + lua_proxy_traits::unwrap(interpreter, get); + lua_proxy_traits::unwrap(interpreter, set); + lua_pushcclosure(interpreter, &detail::property_tag, 2); + detail::stack_pop pop(interpreter, 1); + return object(from_stack(interpreter, -1)); + } + +} // namespace luabind + +#if LUA_VERSION_NUM < 502 +#undef lua_pushglobaltable +#endif + +#include + +#endif // LUABIND_OBJECT_050419_HPP + diff --git a/libs/luabind/luabind/detail/object_funs.hpp b/libs/luabind/luabind/detail/object_funs.hpp deleted file mode 100644 index 2600238d9..000000000 --- a/libs/luabind/luabind/detail/object_funs.hpp +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef LUABIND_OBJECT_PROXY_HPP_INCLUDED -#define LUABIND_OBJECT_PROXY_HPP_INCLUDED - -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace luabind -{ - - namespace detail - { - - namespace mpl = boost::mpl; - - template - inline T object_cast_impl(const Obj& obj, const Policies&) - { - if (obj.lua_state() == 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(0, typeid(T)); -#else - lua_State* L = obj.lua_state(); - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(T)); - - assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - LUABIND_CHECK_STACK(obj.lua_state()); - - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - obj.pushvalue(); - - lua_State* L = obj.lua_state(); - detail::stack_pop p(L, 1); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(L, typeid(T)); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(L, typeid(T)); - - assert(0 && "object_cast failed. If you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } -#endif - - return converter.apply(L, LUABIND_DECORATE_TYPE(T), -1); - } - - template - boost::optional object_cast_nothrow_impl(const Obj& obj, const Policies&) - { - typedef typename detail::find_conversion_policy<0, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - - if (obj.lua_state() == 0) return boost::optional(); - LUABIND_CHECK_STACK(obj.lua_state()); - - obj.pushvalue(); - - lua_State* L = obj.lua_state(); - detail::stack_pop p(L, 1); - -#ifndef LUABIND_NO_ERROR_CHECKING - - if (converter.match(L, LUABIND_DECORATE_TYPE(T), -1) < 0) - return boost::optional(); -#endif - - return boost::optional(converter.apply(L, LUABIND_DECORATE_TYPE(T), -1)); - } - } - - template - T object_cast(const object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_raw_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_raw_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - template - T object_cast(const detail::proxy_array_object& obj) - { return detail::object_cast_impl(obj, detail::null_type()); } - - template - T object_cast(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_impl(obj, p); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj) - { return detail::object_cast_nothrow_impl(obj, detail::null_type()); } - - template - boost::optional object_cast_nothrow(const detail::proxy_array_object& obj, const Policies& p) - { return detail::object_cast_nothrow_impl(obj, p); } - - - - - inline object get_globals(lua_State* L) - { - lua_pushvalue(L, LUA_GLOBALSINDEX); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } - - inline object get_registry(lua_State* L) - { - lua_pushvalue(L, LUA_REGISTRYINDEX); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } - - inline object newtable(lua_State* L) - { - lua_newtable(L); - detail::lua_reference ref; - ref.set(L); - return object(L, ref, true/*object::reference()*/); - } -} - -/* - -struct A -{ -}; - -object f = class_(); - -A* ptr = object_cast(f(), adopt(_1)); - -delete ptr; - -*/ - -#endif // LUABIND_OBJECT_PROXY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/object_rep.hpp b/libs/luabind/luabind/detail/object_rep.hpp index 93b3e39d6..139a1f64c 100644 --- a/libs/luabind/luabind/detail/object_rep.hpp +++ b/libs/luabind/luabind/detail/object_rep.hpp @@ -24,110 +24,114 @@ #ifndef LUABIND_OBJECT_REP_HPP_INCLUDED #define LUABIND_OBJECT_REP_HPP_INCLUDED -#include #include +#include #include #include +#include // std::aligned_storage #include -namespace luabind { namespace detail -{ - class class_rep; +namespace luabind { + namespace detail { - void finalize(lua_State* L, class_rep* crep); + void finalize(lua_State* L, class_rep* crep); - // this class is allocated inside lua for each pointer. - // it contains the actual c++ object-pointer. - // it also tells if it is const or not. - class LUABIND_API object_rep - { - public: - object_rep(instance_holder* instance, class_rep* crep); - ~object_rep(); - - const class_rep* crep() const { return m_classrep; } - class_rep* crep() { return m_classrep; } - - void set_instance(instance_holder* instance) { m_instance = instance; } - - void add_dependency(lua_State* L, int index); - void release_dependency_refs(lua_State* L); - - std::pair get_instance(class_id target) const + // this class is allocated inside lua for each pointer. + // it contains the actual c++ object-pointer. + // it also tells if it is const or not. + class LUABIND_API object_rep { - if (m_instance == 0) - return std::pair((void*)0, -1); - return m_instance->get(target); - } + public: + object_rep(instance_holder* instance, class_rep* crep); + ~object_rep(); - bool is_const() const + const class_rep* crep() const { return m_classrep; } + class_rep* crep() { return m_classrep; } + + void set_instance(instance_holder* instance) { m_instance = instance; } + + void add_dependency(lua_State* L, int index); + + std::pair get_instance(class_id target) const + { + if(m_instance == 0) + return std::pair(nullptr, -1); + return m_instance->get(m_classrep->casts(), target); + } + + bool is_const() const + { + return m_instance && m_instance->pointee_const(); + } + + void release() + { + if(m_instance) + m_instance->release(); + } + + void* allocate(std::size_t size) + { + if(size <= 32) { + return &m_instance_buffer; + } + else { + return std::malloc(size); + } + + } + + void deallocate(void* storage) + { + if(storage == &m_instance_buffer) { + return; + } + else { + std::free(storage); + } + } + + private: + object_rep(object_rep const&) = delete; + void operator=(object_rep const&) = delete; + + instance_holder* m_instance; + std::aligned_storage<32>::type m_instance_buffer; + class_rep* m_classrep; // the class information about this object's type + detail::lua_reference m_dependency_ref; // reference to lua table holding dependency references + }; + + template + struct delete_s { - return m_instance && m_instance->pointee_const(); - } + static void apply(void* ptr) + { + delete static_cast(ptr); + } + }; - void release() - { - if (m_instance) - m_instance->release(); - } - - void* allocate(std::size_t size) + template + struct destruct_only_s { - if (size <= 32) - return &m_instance_buffer; - return std::malloc(size); - } - - void deallocate(void* storage) - { - if (storage == &m_instance_buffer) - return; - std::free(storage); - } - - private: - - object_rep(object_rep const&) - {} - - void operator=(object_rep const&) - {} - - instance_holder* m_instance; - boost::aligned_storage<32> m_instance_buffer; - class_rep* m_classrep; // the class information about this object's type - std::size_t m_dependency_cnt; // counts dependencies - }; - - template - struct delete_s - { - static void apply(void* ptr) - { - delete static_cast(ptr); - } - }; - - template - struct destruct_only_s - { - static void apply(void* ptr) - { - // Removes unreferenced formal parameter warning on VC7. - (void)ptr; + static void apply(void* ptr) + { + // Removes unreferenced formal parameter warning on VC7. + (void)ptr; #ifndef NDEBUG - int completeness_check[sizeof(T)]; - (void)completeness_check; + int completeness_check[sizeof(T)]; + (void)completeness_check; #endif - static_cast(ptr)->~T(); - } - }; + static_cast(ptr)->~T(); + } + }; - LUABIND_API object_rep* get_instance(lua_State* L, int index); - LUABIND_API void push_instance_metatable(lua_State* L); - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); + LUABIND_API object_rep* get_instance(lua_State* L, int index); + LUABIND_API void push_instance_metatable(lua_State* L); + LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls); -}} + } // namespace detail + +} // namespace luabind #endif // LUABIND_OBJECT_REP_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/operator_id.hpp b/libs/luabind/luabind/detail/operator_id.hpp index ed64ba6d5..3b6564ac6 100644 --- a/libs/luabind/luabind/detail/operator_id.hpp +++ b/libs/luabind/luabind/detail/operator_id.hpp @@ -26,54 +26,58 @@ #include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { - enum operator_id - { - op_add = 0, - op_sub, - op_mul, - op_div, - op_pow, - op_lt, - op_le, - op_eq, - op_call, - op_unm, - op_tostring, - op_concat, - op_len, + enum operator_id + { + op_add = 0, + op_sub, + op_mul, + op_div, + op_mod, + op_pow, + op_lt, + op_le, + op_eq, + op_call, + op_unm, + op_tostring, + op_concat, + op_len, - number_of_operators - }; + number_of_operators + }; - inline const char* get_operator_name(int i) - { - static const char* a[number_of_operators] = { - "__add", "__sub", "__mul", "__div", "__pow", - "__lt", "__le", "__eq", "__call", "__unm", - "__tostring", "__concat", "__len" }; - return a[i]; - } + inline const char* get_operator_name(int i) + { + static const char* a[number_of_operators] = { + "__add", "__sub", "__mul", "__div", "__mod", "__pow", + "__lt", "__le", "__eq", "__call", "__unm", + "__tostring", "__concat", "__len" }; + return a[i]; + } - inline const char* get_operator_symbol(int i) - { - static const char* a[number_of_operators] = { - "+", "-", "*", "/", "^", "<", - "<=", "==", "()", "- (unary)", - "tostring", "..", "#" }; - return a[i]; - } + inline const char* get_operator_symbol(int i) + { + static const char* a[number_of_operators] = { + "+", "-", "*", "/", "%", "^", "<", + "<=", "==", "()", "- (unary)", + "tostring", "..", "#" }; + return a[i]; + } - inline bool is_unary(int i) - { - // the reason why unary minus is not considered a unary operator here is - // that it always is given two parameters, where the second parameter always - // is nil. - return i == op_tostring; - } + inline bool is_unary(int i) + { + // the reason why unary minus is not considered a unary operator here is + // that it always is given two parameters, where the second parameter always + // is nil. + return i == op_tostring; + } -}} + } // namespace detail +} // namespace luabind #endif // LUABIND_OPERATOR_ID_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/other.hpp b/libs/luabind/luabind/detail/other.hpp index 679058c9e..d2f48c93d 100644 --- a/libs/luabind/luabind/detail/other.hpp +++ b/libs/luabind/luabind/detail/other.hpp @@ -33,87 +33,34 @@ // to its suitability for any purpose. #include -#include -namespace luabind -{ +namespace luabind { + template struct other { - typedef T type; - }; -} - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -namespace luabind { namespace detail -{ - template - class unwrap_other - { - public: - typedef T type; + using type = T; }; - template - class unwrap_other > - { - public: - typedef T type; - }; -}} // namespace luabind::detail +} // namespace luabind -# else // no partial specialization +namespace luabind { + namespace detail { + template + class unwrap_other + { + public: + using type = T; + }; -#include - -namespace luabind { namespace detail -{ - typedef char (&yes_other_t)[1]; - typedef char (&no_other_t)[2]; - - no_other_t is_other_test(...); - - template - yes_other_t is_other_test(type_< other >); - - template - struct other_unwrapper - { - template - struct apply - { - typedef T type; - }; - }; - - template<> - struct other_unwrapper - { - template - struct apply - { - typedef typename T::type type; - }; - }; - - template - class is_other - { - public: - BOOST_STATIC_CONSTANT( - bool, value = ( - sizeof(detail::is_other_test(type_())) - == sizeof(detail::yes_other_t))); - }; - - template - class unwrap_other - : public detail::other_unwrapper< - is_other::value - >::template apply - {}; - -}} // namespace luabind::detail -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION + template + class unwrap_other > + { + public: + using type = T; + }; + } +} // namespace luabind::detail #endif // LUABIND_OTHER_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/pcall.hpp b/libs/luabind/luabind/detail/pcall.hpp index f0d72b162..ab9f63c02 100644 --- a/libs/luabind/luabind/detail/pcall.hpp +++ b/libs/luabind/luabind/detail/pcall.hpp @@ -25,12 +25,14 @@ #include -struct lua_State; +#include -namespace luabind { namespace detail -{ - LUABIND_API int pcall(lua_State *L, int nargs, int nresults); - LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); -}} +namespace luabind { + namespace detail { + LUABIND_API int pcall(lua_State *L, int nargs, int nresults); + LUABIND_API int resume_impl(lua_State *L, int nargs, int nresults); + } +} #endif + diff --git a/libs/luabind/luabind/detail/policy.hpp b/libs/luabind/luabind/detail/policy.hpp index 79577c9a4..195b369f5 100644 --- a/libs/luabind/luabind/detail/policy.hpp +++ b/libs/luabind/luabind/detail/policy.hpp @@ -25,998 +25,131 @@ #define LUABIND_POLICY_HPP_INCLUDED #include +#include +#include #include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif namespace luabind { - namespace detail - { - struct conversion_policy_base {}; + template< typename... T > + using policy_list = meta::type_list< T... >; + using no_policies = policy_list< >; + + namespace detail { + + struct converter_policy_has_postcall_tag {}; + } - template - struct conversion_policy : detail::conversion_policy_base + // A converter policy injector instructs the call mechanism to use a certain converter policy for + // an element of a function call signature that is denoted by the parameter Index + // 0 stands for the return value, while 1 might denote an implicit "this" argument or the first + // actual argument of the function call. + template< unsigned int Index, typename T > + struct converter_policy_injector { - BOOST_STATIC_CONSTANT(int, index = N); - BOOST_STATIC_CONSTANT(bool, has_arg = HasArg); + static constexpr bool has_postcall = std::is_convertible::value; }; - class index_map - { - public: - index_map(const int* m): m_map(m) {} + // A call policy injector instructs the call mechanism to call certain static function "postcall" on type T + // after having executed a call. + template< typename T > + struct call_policy_injector + {}; - int operator[](int index) const + template< typename T, typename Enable = void > + struct default_converter; + + namespace detail + { + struct lua_to_cpp {}; + struct cpp_to_lua {}; + + struct default_policy { - return m_map[index]; - } - - private: - const int* m_map; - }; - -// template class functor; - class weak_ref; -} - -namespace luabind { namespace detail -{ - template - struct policy_cons - { - typedef H head; - typedef T tail; - - template - policy_cons > operator,(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator+(policy_cons) - { - return policy_cons >(); - } - - template - policy_cons > operator|(policy_cons) - { - return policy_cons >(); - } - }; - - struct indirection_layer - { - template - indirection_layer(const T&); - }; - - yes_t is_policy_cons_test(const null_type&); - template - yes_t is_policy_cons_test(const policy_cons&); - no_t is_policy_cons_test(...); - - template - struct is_policy_cons - { - static const T& t; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_policy_cons_test(t)) == sizeof(yes_t)); - - typedef boost::mpl::bool_ type; - }; - - template - struct is_string_literal - { - static no_t helper(indirection_layer); - static yes_t helper(const char*); - }; - - template<> - struct is_string_literal - { - static no_t helper(indirection_layer); - }; - - - namespace mpl = boost::mpl; - - template - void make_pointee_instance(lua_State* L, T& x, mpl::true_, Clone) - { - if (get_pointer(x)) - { - make_instance(L, x); - } - else - { - lua_pushnil(L); - } - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::true_) - { - std::auto_ptr ptr(new T(x)); - make_instance(L, ptr); - } - - template - void make_pointee_instance(lua_State* L, T& x, mpl::false_, mpl::false_) - { - make_instance(L, &x); - } - - template - void make_pointee_instance(lua_State* L, T& x, Clone) - { - make_pointee_instance(L, x, has_get_pointer(), Clone()); - } - -// ********** pointer converter *********** - - struct pointer_converter - { - typedef pointer_converter type; - typedef mpl::false_ is_native; - - pointer_converter() - : result(0) - {} - - void* result; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T* ptr) - { - if (ptr == 0) + template + struct specialize { - lua_pushnil(L); - return; - } - - if (luabind::get_back_reference(L, ptr)) - return; - - make_instance(L, ptr); - } + using type = default_converter; + }; + }; template - T* apply(lua_State*, by_pointer, int) - { - return static_cast(result); - } + struct is_primitive + : default_converter::is_native + {}; - template - int match(lua_State* L, by_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; + namespace policy_detail { + template< unsigned int Index, typename PoliciesList > + struct get_converter_policy; - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_pointer, int) - {} - }; - -// ******* value converter ******* - - struct value_converter - { - typedef value_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - value_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T x) - { - if (luabind::get_back_reference(L, x)) - return; - - make_pointee_instance(L, x, mpl::true_()); - } - - template - T apply(lua_State*, by_value, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_value, int index) - { - // special case if we get nil in, try to match the holder type - if (lua_isnil(L, index)) - return -1; - - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* const pointer converter ******* - - struct const_pointer_converter - { - typedef const_pointer_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_pointer_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, const T* ptr) - { - if (ptr == 0) + template< unsigned int Index, typename Injector0, typename... Injectors > + struct get_converter_policy< Index, meta::type_list< Injector0, Injectors... > > { - lua_pushnil(L); - return; - } + using type = typename get_converter_policy< Index, meta::type_list< Injectors... > >::type; + }; - if (luabind::get_back_reference(L, ptr)) - return; + template< unsigned int Index, typename ConverterPolicy, typename... Injectors > + struct get_converter_policy< Index, meta::type_list< converter_policy_injector< Index, ConverterPolicy >, Injectors... > > + { + using type = ConverterPolicy; + }; - make_instance(L, ptr); + template< unsigned int Index > + struct get_converter_policy< Index, meta::type_list< > > + { + using type = default_policy; + }; } - template - T const* apply(lua_State*, by_const_pointer, int) + // Fetches converter policy for Signature element [Index] from policy list [PolicyList] + template + using fetched_converter_policy = typename policy_detail::get_converter_policy::type; + + // Specializes converter policy [ConverterPolicy] for type [Type] in direction [Direction] + template + using specialized_converter_policy = typename ConverterPolicy::template specialize::type; + + // Fetches the converter policy for Signature element [Index] from the policy list [PolicyList] and specializes it + // for the concrete type [T] with [Direction] being either "lua_to_cpp" or "cpp_to_lua". + template + using specialized_converter_policy_n = typename policy_detail::get_converter_policy::type::template specialize::type; + + /* + call_policies + */ + + template< typename List, class Sought > + struct has_call_policy : public meta::contains< List, call_policy_injector< Sought > > { - return static_cast(result); - } + }; - template - int match(lua_State* L, by_const_pointer, int index) - { - if (lua_isnil(L, index)) return 0; - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } + } +} // namespace luabind::detail - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******* reference converter ******* - - struct ref_converter : pointer_converter - { - typedef ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void apply(lua_State* L, T& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T& apply(lua_State* L, by_reference, int index) - { - assert(!lua_isnil(L, index)); - return *pointer_converter::apply(L, by_pointer(), index); - } - - template - int match(lua_State* L, by_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; - - if (obj->is_const()) - return -1; - - std::pair s = obj->get_instance(registered_class::id); - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - -// ******** const reference converter ********* - - struct const_ref_converter - { - typedef const_ref_converter type; - typedef mpl::false_ is_native; - - int const consumed_args(...) - { - return 1; - } - - const_ref_converter() - : result(0) - {} - - void* result; - - template - void apply(lua_State* L, T const& ref) - { - if (luabind::get_back_reference(L, ref)) - return; - - make_pointee_instance(L, ref, mpl::false_()); - } - - template - T const& apply(lua_State*, by_const_reference, int) - { - return *static_cast(result); - } - - template - int match(lua_State* L, by_const_reference, int index) - { - object_rep* obj = get_instance(L, index); - if (obj == 0) return -1; // if the type is not one of our own registered types, classify it as a non-match - - std::pair s = obj->get_instance(registered_class::id); - if (s.second >= 0 && !obj->is_const()) - s.second += 10; - result = s.first; - return s.second; - } - - template - void converter_postcall(lua_State*, by_const_reference, int) - { - } - }; - - // ****** enum converter ******** - - struct enum_converter - { - typedef enum_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - void apply(lua_State* L, int val) - { - lua_pushnumber(L, val); - } - - template - T apply(lua_State* L, by_value, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_value, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return static_cast(static_cast(lua_tonumber(L, index))); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - if (lua_isnumber(L, index)) return 0; else return -1; - } - - template - void converter_postcall(lua_State*, T, int) {} - }; - - template - struct value_wrapper_converter - { - typedef value_wrapper_converter type; - typedef mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - T apply(lua_State* L, by_const_reference, int index) - { - return T(from_stack(L, index)); - } - - template - T apply(lua_State* L, by_value, int index) - { - return apply(L, by_const_reference(), index); - } - - template - static int match(lua_State* L, by_const_reference, int index) - { - return value_wrapper_traits::check(L, index) - ? (std::numeric_limits::max)() / LUABIND_MAX_ARITY - : -1; - } - - template - static int match(lua_State* L, by_value, int index) - { - return match(L, by_const_reference(), index); - } - - void converter_postcall(...) {} - - template - void apply(lua_State* interpreter, T const& value_wrapper) - { - value_wrapper_traits::unwrap(interpreter, value_wrapper); - } - }; - - template - struct default_converter_generator - : mpl::eval_if< - is_value_wrapper_arg - , value_wrapper_converter - , mpl::eval_if< - boost::is_enum::type> - , enum_converter - , mpl::eval_if< - is_nonconst_pointer - , pointer_converter - , mpl::eval_if< - is_const_pointer - , const_pointer_converter - , mpl::eval_if< - is_nonconst_reference - , ref_converter - , mpl::eval_if< - is_const_reference - , const_ref_converter - , value_converter - > - > - > - > - > - > - {}; - -} // namespace detail - -// *********** default_policy ***************** - -template -struct default_converter - : detail::default_converter_generator::type -{}; - -template > -struct native_converter_base -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - void converter_postcall(lua_State*, U const&, int) - {} - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_value, int index) - { - return derived().compute_score(L, index); - } - - int match(lua_State* L, detail::by_const_reference, int index) - { - return derived().compute_score(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_value, int index) - { - return derived().from(L, index); - } - - T apply(lua_State* L, detail::by_const_reference, int index) - { - return derived().from(L, index); - } - - void apply(lua_State* L, T const& value) - { - derived().to(L, value); - } - - Derived& derived() - { - return static_cast(*this); - } -}; - -template -lua_Integer as_lua_integer(T v) -{ - return static_cast(v); +namespace luabind { + constexpr meta::index<0> return_value; + constexpr meta::index<0> result; + constexpr meta::index<1> _1; + constexpr meta::index<2> _2; + constexpr meta::index<3> _3; + constexpr meta::index<4> _4; + constexpr meta::index<5> _5; + constexpr meta::index<6> _6; + constexpr meta::index<7> _7; + constexpr meta::index<8> _8; + constexpr meta::index<9> _9; } -template -lua_Number as_lua_number(T v) -{ - return static_cast(v); -} - -# define LUABIND_NUMBER_CONVERTER(type, kind) \ - template <> \ -struct default_converter \ - : native_converter_base \ -{ \ - int compute_score(lua_State* L, int index) \ - { \ - return lua_type(L, index) == LUA_TNUMBER ? 0 : -1; \ - }; \ - \ - type from(lua_State* L, int index) \ - { \ - return static_cast(BOOST_PP_CAT(lua_to, kind)(L, index)); \ - } \ - \ - void to(lua_State* L, type const& value) \ - { \ - BOOST_PP_CAT(lua_push, kind)(L, BOOST_PP_CAT(as_lua_, kind)(value)); \ - } \ -}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; \ -\ -template <> \ -struct default_converter \ - : default_converter \ -{}; - -LUABIND_NUMBER_CONVERTER(char, integer) -LUABIND_NUMBER_CONVERTER(signed char, integer) -LUABIND_NUMBER_CONVERTER(unsigned char, integer) -LUABIND_NUMBER_CONVERTER(signed short, integer) -LUABIND_NUMBER_CONVERTER(unsigned short, integer) -LUABIND_NUMBER_CONVERTER(signed int, integer) - -LUABIND_NUMBER_CONVERTER(unsigned int, number) -LUABIND_NUMBER_CONVERTER(unsigned long, number) - -LUABIND_NUMBER_CONVERTER(signed long, integer) -LUABIND_NUMBER_CONVERTER(float, number) -LUABIND_NUMBER_CONVERTER(double, number) -LUABIND_NUMBER_CONVERTER(long double, number) - -# undef LUABIND_NUMBER_CONVERTER - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TBOOLEAN ? 0 : -1; - } - - bool from(lua_State* L, int index) - { - return lua_toboolean(L, index) == 1; - } - - void to(lua_State* L, bool value) - { - lua_pushboolean(L, value); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : native_converter_base -{ - static int compute_score(lua_State* L, int index) - { - return lua_type(L, index) == LUA_TSTRING ? 0 : -1; - } - - std::string from(lua_State* L, int index) - { - return std::string(lua_tostring(L, index), lua_strlen(L, index)); - } - - void to(lua_State* L, std::string const& value) - { - lua_pushlstring(L, value.data(), value.size()); - } -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - typedef boost::mpl::true_ is_native; - - int const consumed_args(...) - { - return 1; - } - - template - static int match(lua_State* L, U, int index) - { - int type = lua_type(L, index); - return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : -1; - } - - template - char const* apply(lua_State* L, U, int index) - { - return lua_tostring(L, index); - } - - void apply(lua_State* L, char const* str) - { - lua_pushstring(L, str); - } - - template - void converter_postcall(lua_State*, U, int) - {} -}; - -template <> -struct default_converter - : default_converter -{}; - -template <> -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template -struct default_converter - : default_converter -{}; - -template <> -struct default_converter -{ - int const consumed_args(...) - { - return 0; - } - - template - lua_State* apply(lua_State* L, U, int) - { - return L; - } - - template - static int match(lua_State*, U, int) - { - return 0; - } - - template - void converter_postcall(lua_State*, U, int) {} -}; - -namespace detail -{ - - struct default_policy : converter_policy_tag - { - BOOST_STATIC_CONSTANT(bool, has_arg = true); - - template - static void precall(lua_State*, T, int) {} - - template - struct apply - { - typedef default_converter type; - }; - }; - - template - struct is_primitive - : default_converter::is_native - {}; - -// ============== new policy system ================= - - template struct find_conversion_policy; - - template - struct find_conversion_impl - { - template - struct apply - { - typedef typename find_conversion_policy::type type; - }; - }; - - template<> - struct find_conversion_impl - { - template - struct apply - { - typedef typename Policies::head head; - typedef typename Policies::tail tail; - - BOOST_STATIC_CONSTANT(bool, found = (N == head::index)); - - typedef typename - boost::mpl::if_c::type - >::type type; - }; - }; - - template - struct find_conversion_impl2 - { - template - struct apply - : find_conversion_impl< - boost::is_base_and_derived::value - >::template apply - { - }; - }; - - template<> - struct find_conversion_impl2 - { - template - struct apply - { - typedef default_policy type; - }; - }; - - template - struct find_conversion_policy : find_conversion_impl2::template apply - { - }; - - template - struct policy_list_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, const index_map& i) - { - head::postcall(L, i); - policy_list_postcall::apply(L, i); - } - }; - - template<> - struct policy_list_postcall - { - static void apply(lua_State*, const index_map&) {} - }; - -// ================================================== - -// ************** precall and postcall on policy_cons ********************* - - - template - struct policy_precall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::precall(L, index); - policy_precall::apply(L, index); - } - }; - - template<> - struct policy_precall - { - static void apply(lua_State*, int) {} - }; - - template - struct policy_postcall - { - typedef typename List::head head; - typedef typename List::tail tail; - - static void apply(lua_State* L, int index) - { - head::postcall(L, index); - policy_postcall::apply(L, index); - } - }; - - template<> - struct policy_postcall - { - static void apply(lua_State*, int) {} - }; - -}} // namespace luabind::detail - - -namespace luabind { namespace -{ -#if defined(__GNUC__) && ( \ - (BOOST_VERSION < 103500) \ - || (BOOST_VERSION < 103900 && (__GNUC__ * 100 + __GNUC_MINOR__ <= 400)) \ - || (__GNUC__ * 100 + __GNUC_MINOR__ < 400)) - static inline boost::arg<0> return_value() - { - return boost::arg<0>(); - } - - static inline boost::arg<0> result() - { - return boost::arg<0>(); - } -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg(*)() -#elif defined(BOOST_MSVC) || defined(__MWERKS__) \ - || (BOOST_VERSION >= 103900 && defined(__GNUC__) \ - && (__GNUC__ * 100 + __GNUC_MINOR__ == 400)) - static boost::arg<0> return_value; - static boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#else - boost::arg<0> return_value; - boost::arg<0> result; -# define LUABIND_PLACEHOLDER_ARG(N) boost::arg -#endif -}} - #endif // LUABIND_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/primitives.hpp b/libs/luabind/luabind/detail/primitives.hpp index 04ce17b87..a5fe734d8 100644 --- a/libs/luabind/luabind/detail/primitives.hpp +++ b/libs/luabind/luabind/detail/primitives.hpp @@ -24,62 +24,40 @@ #ifndef LUABIND_PRIMITIVES_HPP_INCLUDED #define LUABIND_PRIMITIVES_HPP_INCLUDED -#include + // std::reference_wrapper... +#include // std::true_type... #include -#include -#include +namespace luabind { + namespace detail { -namespace luabind { namespace detail -{ - template - struct identity - { - typedef T type; - }; + template + struct type_ {}; - template - struct type_ {}; + struct ltstr + { + bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } + }; - struct null_type {}; + template + struct aligned + { + char storage[N]; + }; -/* typedef char yes_t; - typedef double no_t;*/ + // returns the offset added to a Derived* when cast to a Base* + template + ptrdiff_t ptr_offset(type_, type_) + { + aligned obj; + Derived* ptr = reinterpret_cast(&obj); - struct lua_to_cpp {}; - struct cpp_to_lua {}; + return ptrdiff_t(static_cast(static_cast(static_cast(ptr))) + - static_cast(static_cast(ptr))); + } - template struct by_value {}; - template struct by_reference {}; - template struct by_const_reference {}; - template struct by_pointer {}; - template struct by_const_pointer {}; - - struct converter_policy_tag {}; - - struct ltstr - { - bool operator()(const char* s1, const char* s2) const { return std::strcmp(s1, s2) < 0; } - }; - - template - struct aligned - { - char storage[N]; - }; - - // returns the offset added to a Derived* when cast to a Base* - // TODO: return ptrdiff - template - int ptr_offset(type_, type_) - { - aligned obj; - Derived* ptr = reinterpret_cast(&obj); - - return int(static_cast(static_cast(static_cast(ptr))) - - static_cast(static_cast(ptr))); } - -}} +} #endif // LUABIND_PRIMITIVES_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/property.hpp b/libs/luabind/luabind/detail/property.hpp index 2c30ce000..e177df209 100644 --- a/libs/luabind/luabind/detail/property.hpp +++ b/libs/luabind/luabind/detail/property.hpp @@ -5,29 +5,31 @@ #ifndef LUABIND_PROPERTY_081020_HPP # define LUABIND_PROPERTY_081020_HPP -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -template -struct access_member_ptr -{ - access_member_ptr(T Class::* mem_ptr) - : mem_ptr(mem_ptr) - {} + template + struct access_member_ptr + { + access_member_ptr(T Class::* mem_ptr) + : mem_ptr(mem_ptr) + {} - Result operator()(Class const& x) const - { - return const_cast(x).*mem_ptr; - } + Result operator()(Class const& x) const + { + return const_cast(x).*mem_ptr; + } - void operator()(Class& x, T const& value) const - { - x.*mem_ptr = value; - } + void operator()(Class& x, T const& value) const + { + x.*mem_ptr = value; + } - T Class::* mem_ptr; -}; + T Class::* mem_ptr; + }; -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind #endif // LUABIND_PROPERTY_081020_HPP diff --git a/libs/luabind/luabind/detail/calc_arity.hpp b/libs/luabind/luabind/detail/push_to_lua.hpp similarity index 53% rename from libs/luabind/luabind/detail/calc_arity.hpp rename to libs/luabind/luabind/detail/push_to_lua.hpp index c2e0aad91..22ad8534f 100644 --- a/libs/luabind/luabind/detail/calc_arity.hpp +++ b/libs/luabind/luabind/detail/push_to_lua.hpp @@ -20,42 +20,54 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#if !BOOST_PP_IS_ITERATING -# include +#ifndef LUABIND_CONVERT_TO_LUA_HPP_INCLUDED +#define LUABIND_CONVERT_TO_LUA_HPP_INCLUDED -#ifndef LUABIND_CALC_ARITY_HPP_INCLUDED -#define LUABIND_CALC_ARITY_HPP_INCLUDED +#include +#include -#define LUABIND_FIND_CONV(z,n,text) typedef typename find_conversion_policy::type p##n; -#define LUABIND_CALC_ARITY(z,n,text) + BOOST_PP_CAT(p,n)::has_arg +namespace luabind { -namespace luabind { namespace detail -{ - template struct calc_arity; + namespace detail { - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() -}} + template< typename T > + struct unwrapped { + static const bool is_wrapped_ref = false; + using type = T; -#undef LUABIND_CALC_ARITY -#undef LUABIND_FIND_CONV + static const T& get(const T& t) { + return t; + } + }; - -#endif // LUABIND_CALC_ARITY_HPP_INCLUDED - -#else // BOOST_PP_ITERATE - - template<> - struct calc_arity - { - template - static int apply(constructor, Policies*) + template< typename T > + struct unwrapped< std::reference_wrapper< T > > { - BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_FIND_CONV, _) - return 0 BOOST_PP_REPEAT(BOOST_PP_ITERATION(), LUABIND_CALC_ARITY, _); + static const bool is_wrapped_ref = true; + using type = T&; + + static T& get(const std::reference_wrapper& refwrap) + { + return refwrap.get(); + } + }; + + template + using unwrapped_t = typename unwrapped< T >::type; + + template + void push_to_lua(lua_State* L, T&& v) + { + using value_type = unwrapped_t>; + + specialized_converter_policy_n() + .to_lua(L, unwrapped::get(v)); } - }; + + } + +} #endif diff --git a/libs/luabind/luabind/detail/ref.hpp b/libs/luabind/luabind/detail/ref.hpp index 3edbfebfb..73d7b6328 100644 --- a/libs/luabind/luabind/detail/ref.hpp +++ b/libs/luabind/luabind/detail/ref.hpp @@ -33,80 +33,83 @@ namespace luabind { -namespace detail -{ - - struct lua_reference + namespace detail { - lua_reference(lua_State* L_ = 0) - : L(L_) - , m_ref(LUA_NOREF) - {} - lua_reference(lua_reference const& r) - : L(r.L) - , m_ref(LUA_NOREF) + + struct lua_reference { - if (!r.is_valid()) return; - r.get(L); - set(L); - } - ~lua_reference() { reset(); } + lua_reference(lua_State* L_ = 0) + : L(L_) + , m_ref(LUA_NOREF) + {} + lua_reference(lua_reference const& r) + : L(r.L) + , m_ref(LUA_NOREF) + { + if(!r.is_valid()) return; + r.get(L); + set(L); + } + ~lua_reference() { reset(); } - lua_State* state() const { return L; } + lua_State* state() const { return L; } - void operator=(lua_reference const& r) - { - // TODO: self assignment problems - reset(); - if (!r.is_valid()) return; - r.get(r.state()); - set(r.state()); - } + void operator=(lua_reference const& r) + { + // TODO: self assignment problems + reset(); + if(!r.is_valid()) return; + r.get(r.state()); + set(r.state()); + } - bool is_valid() const - { return m_ref != LUA_NOREF; } + bool is_valid() const + { + return m_ref != LUA_NOREF; + } - void set(lua_State* L_) - { - reset(); - L = L_; - m_ref = luaL_ref(L, LUA_REGISTRYINDEX); - } + void set(lua_State* L_) + { + reset(); + L = L_; + m_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } - void replace(lua_State* L_) - { - lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); - } + void replace(lua_State* L_) + { + lua_rawseti(L_, LUA_REGISTRYINDEX, m_ref); + } - // L may not be the same pointer as - // was used when creating this reference - // since it may be a thread that shares - // the same globals table. - void get(lua_State* L_) const - { - assert(m_ref != LUA_NOREF); - assert(L_); - lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); - } + // L may not be the same pointer as + // was used when creating this reference + // since it may be a thread that shares + // the same globals table. + void get(lua_State* L_) const + { + assert(m_ref != LUA_NOREF); + assert(L_); + lua_rawgeti(L_, LUA_REGISTRYINDEX, m_ref); + } - void reset() - { - if (L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); - m_ref = LUA_NOREF; - } + void reset() + { + if(L && m_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, m_ref); + m_ref = LUA_NOREF; + } - void swap(lua_reference& r) - { - assert(r.L == L); - std::swap(r.m_ref, m_ref); - } + void swap(lua_reference& r) + { + assert(r.L == L); + std::swap(r.m_ref, m_ref); + } - private: - lua_State* L; - int m_ref; - }; + private: + lua_State* L; + int m_ref; + }; -}} + } +} #endif // LUABIND_REF_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/signature_match.hpp b/libs/luabind/luabind/detail/signature_match.hpp index d76ed6627..f0f32f18e 100644 --- a/libs/luabind/luabind/detail/signature_match.hpp +++ b/libs/luabind/luabind/detail/signature_match.hpp @@ -25,37 +25,5 @@ #include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace luabind -{ - - namespace adl - { - class argument; - } - - template - struct constructor - { - typedef BOOST_PP_CAT( - boost::mpl::vector, BOOST_PP_INC(BOOST_PP_INC(LUABIND_MAX_ARITY)))< - void, argument const&, BOOST_PP_ENUM_PARAMS(LUABIND_MAX_ARITY, A) - > signature0; - - typedef typename boost::mpl::remove< - signature0, detail::null_type>::type signature; - }; - -} - #endif // LUABIND_SIGNATURE_MATCH_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/stack_utils.hpp b/libs/luabind/luabind/detail/stack_utils.hpp index 15f3a7fce..624d58975 100644 --- a/libs/luabind/luabind/detail/stack_utils.hpp +++ b/libs/luabind/luabind/detail/stack_utils.hpp @@ -23,30 +23,36 @@ #ifndef LUABIND_STACK_UTILS_HPP_INCLUDED #define LUABIND_STACK_UTILS_HPP_INCLUDED +#ifndef LUA_INCLUDE_HPP_INCLUDED +#include +#endif + #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { - struct stack_pop - { - stack_pop(lua_State* L, int n) - : m_state(L) - , m_n(n) + struct stack_pop + { + stack_pop(lua_State* L, int n) + : m_state(L) + , m_n(n) { } - ~stack_pop() - { - lua_pop(m_state, m_n); - } + ~stack_pop() + { + lua_pop(m_state, m_n); + } - private: + private: - lua_State* m_state; - int m_n; - }; -}} + lua_State* m_state; + int m_n; + }; + + } // namespace detail +} // namespace luabind #endif // LUABIND_STACK_UTILS_HPP_INCLUDED diff --git a/libs/luabind/luabind/detail/type_traits.hpp b/libs/luabind/luabind/detail/type_traits.hpp new file mode 100644 index 000000000..d1a0e7cb9 --- /dev/null +++ b/libs/luabind/luabind/detail/type_traits.hpp @@ -0,0 +1,189 @@ +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + + +#ifndef LUABIND_TYPETRAITS_HPP_INCLUDED +#define LUABIND_TYPETRAITS_HPP_INCLUDED + +#include +#include // reference_wrapper +#include + +namespace luabind { + + namespace detail { + + template< typename T > + struct is_const_reference + : public std::conditional< std::is_reference::value && std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_nonconst_reference + : public std::conditional< std::is_reference::value && !std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_const_pointer + : public std::conditional< std::is_const::type>::value && std::is_pointer::value, std::true_type, std::false_type >::type + { + }; + + template + struct is_nonconst_pointer : + public std::conditional < std::is_pointer::value && !std::is_const::type>::value, std::true_type, std::false_type >::type + { + }; + + template + struct max_c + { + enum { value = (v1 > v2) ? v1 : v2 }; + }; + + } // namespace detail + + template< typename T > + struct remove_const_reference { + using type = typename std::remove_const::type>::type; + }; + + template< typename T > + using remove_const_reference_t = typename remove_const_reference::type; + + // + // most_derived + // + + template + struct most_derived + { + using type = typename std::conditional< + std::is_base_of::value + , B + , A + >::type; + }; + + template< typename A, typename B > + using most_derived_t = typename most_derived::type; + + // + // null_type + // + + struct null_type {}; + + template< typename T > + struct is_null_type : public std::false_type {}; + + template< > + struct is_null_type< null_type > : public std::true_type {}; + + // + // deduce_signature + // + + template< typename, typename > struct tagged_function; + + template< typename T, typename WrappedType = null_type > + struct deduce_signature; + + template< typename R, typename... Args, typename WrappedType > + struct deduce_signature < R(Args...), WrappedType > + { + using type = meta::type_list< R, Args... >; + }; + + template< typename R, typename... Args, typename WrappedType > + struct deduce_signature < R(*)(Args...), WrappedType > + { + using type = meta::type_list< R, Args... >; + }; + + template< typename R, typename Class, typename... Args > + struct deduce_signature < R(Class::*)(Args...), null_type > + { + using type = meta::type_list< R, Class&, Args... >; + }; + + template< typename R, typename Class, typename... Args > + struct deduce_signature < R(Class::*)(Args...) const, null_type > + { + using type = meta::type_list< R, Class const&, Args... >; + }; + + template< typename R, typename Class, typename... Args, class WrappedType > + struct deduce_signature < R(Class::*)(Args...), WrappedType > + { + using type = meta::type_list< R, typename most_derived::type&, Args... >; + }; + + template< typename R, typename Class, typename... Args, class WrappedType > + struct deduce_signature < R(Class::*)(Args...) const, WrappedType > + { + using type = meta::type_list< R, typename most_derived::type const&, Args... >; + }; + + template< typename Signature, typename F, class WrappedType > + struct deduce_signature< tagged_function< Signature, F >, WrappedType > + { + using type = Signature; + }; + + template< typename T, typename WrappedType = null_type > + using deduce_signature_t = typename deduce_signature::type; + + // + // is_reference_wrapper + // + + template< typename T > struct is_reference_wrapper : public std::false_type { }; + template< typename T > struct is_reference_wrapper< std::reference_wrapper > : public std::true_type { }; + + // + // apply_reference_wrapper + // + + template< typename T > struct apply_reference_wrapper { using type = T; }; + template< typename T > struct apply_reference_wrapper< std::reference_wrapper > { using type = T&; }; + + template< typename T > + using apply_reference_wrapper_t = typename apply_reference_wrapper::type; + + // + // identity + // + + template< typename T > struct identity { using type = T; }; + + template< typename T > + using identity_t = typename identity::type; + + template< typename Dst > Dst implicit_cast(typename identity::type t) { return t; } + +} // namespace luabind + +#endif // LUABIND_TYPETRAITS_HPP_INCLUDED + diff --git a/libs/luabind/luabind/detail/typetraits.hpp b/libs/luabind/luabind/detail/typetraits.hpp deleted file mode 100644 index f27934e98..000000000 --- a/libs/luabind/luabind/detail/typetraits.hpp +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - - -#ifndef LUABIND_TYPETRAITS_HPP_INCLUDED -#define LUABIND_TYPETRAITS_HPP_INCLUDED - -#include -#include -#include -#include -#include - -namespace luabind { namespace detail -{ - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - - template - struct is_const_type - { - typedef typename boost::mpl::if_ - , yes_t - , no_t - >::type type; - }; - - template - struct is_const_reference_helper - { - template - struct apply - { - enum - { - value = false - }; - }; - }; - - template - typename is_const_type::type is_const_reference_tester(T&); - no_t is_const_reference_tester(...); - - template<> - struct is_const_reference_helper - { - template - struct apply - { - static T getT(); - - enum - { - value = sizeof(is_const_reference_tester(getT())) == sizeof(yes_t) - }; - }; - }; - - template - struct is_const_reference - : is_const_reference_helper::value>::template apply - { - typedef boost::mpl::bool_ type; - }; - -#else - - template - struct is_const_reference - { - enum { value = false }; - typedef boost::mpl::bool_ type; - }; - - template - struct is_const_reference - { - enum { value = true }; - typedef boost::mpl::bool_ type; - }; - -#endif - - - template - struct is_nonconst_reference - { - enum - { - value = boost::is_reference::value && !is_const_reference::value - }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_const_pointer_helper(void(*)(const A*)); - no_t is_const_pointer_helper(...); - - template - struct is_const_pointer - { - enum { value = sizeof(is_const_pointer_helper((void(*)(T))0)) == sizeof(yes_t) }; - typedef boost::mpl::bool_ type; - }; - - template - yes_t is_nonconst_pointer_helper(void(*)(A*)); - no_t is_nonconst_pointer_helper(...); - - template - struct is_nonconst_pointer - { - enum { value = sizeof(is_nonconst_pointer_helper((void(*)(T))0)) == sizeof(yes_t) && !is_const_pointer::value }; - typedef boost::mpl::bool_ type; - }; -/* - template - struct is_constructable_from_helper - { - static yes_t check(const T&); - static no_t check(...); - }; - - template - struct is_constructable_from - { - static From getFrom(); - - enum - { - value = sizeof(is_constructable_from_helper::check(getFrom())) == sizeof(yes_t) - }; - }; - - template - struct is_const_member_function_helper - { - static no_t test(...); - template - static yes_t test(R(T::*)() const); - template - static yes_t test(R(T::*)(A1) const); - template - static yes_t test(R(T::*)(A1,A2) const); - template - static yes_t test(R(T::*)(A1,A2,A3) const); - }; - - template - struct is_const_member_function - { - static U getU(); - - enum - { - value = sizeof(is_const_member_function_helper::test(getU())) == sizeof(yes_t) - }; - }; -*/ - - template - struct max_c - { - enum { value = (v1>v2)?v1:v2 }; - }; - -}} - -#endif // LUABIND_TYPETRAITS_HPP_INCLUDED - diff --git a/libs/luabind/luabind/discard_result_policy.hpp b/libs/luabind/luabind/discard_result_policy.hpp index 149a7b1bc..277d88137 100644 --- a/libs/luabind/luabind/discard_result_policy.hpp +++ b/libs/luabind/luabind/discard_result_policy.hpp @@ -20,52 +20,41 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. - #ifndef LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #define LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED #include -#include +#include // for index_map, etc +#include // for null_type, etc +#include -namespace luabind { namespace detail -{ - struct discard_converter - { - template - void apply(lua_State*, T) {} - }; +namespace luabind { + namespace detail { - struct discard_result_policy : conversion_policy<0> - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct can_only_convert_from_cpp_to_lua {}; - - template - struct apply + struct discard_converter { - typedef typename boost::mpl::if_ - , discard_converter - , can_only_convert_from_cpp_to_lua - >::type type; + template + void to_lua(lua_State*, T) {} }; - }; -}} + struct discard_result_policy + { + struct can_only_convert_from_cpp_to_lua {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, cpp_to_lua >::value, "Can only convert from cpp to lua"); + using type = discard_converter; + }; + }; + + } +} namespace luabind { - detail::policy_cons< - detail::discard_result_policy, detail::null_type> const discard_result = {}; - - namespace detail - { - inline void ignore_unused_discard_result() - { - (void)discard_result; - } - } + using discard_result = meta::type_list>; } #endif // LUABIND_DISCARD_RESULT_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/error.hpp b/libs/luabind/luabind/error.hpp index b282a411a..cf42091aa 100644 --- a/libs/luabind/luabind/error.hpp +++ b/libs/luabind/luabind/error.hpp @@ -26,9 +26,13 @@ #include #include #include -#include +#include +#include +#include -struct lua_State; +#ifndef LUABIND_NO_EXCEPTIONS +#include +#endif namespace luabind { @@ -38,22 +42,19 @@ namespace luabind // this exception usually means that the lua function you called // from C++ failed with an error code. You will have to // read the error code from the top of the lua stack - // the reason why this exception class doesn't contain - // the message itself is that std::string's copy constructor + // note that std::string's copy constructor // may throw, if the copy constructor of an exception that is // being thrown throws another exception, terminate will be called // and the entire application is killed. class LUABIND_API error : public std::exception { public: - explicit error(lua_State* L): m_L(L) {} - lua_State* state() const throw() { return m_L; } - virtual const char* what() const throw() - { - return "lua runtime error"; - } + explicit error(lua_State* L); + + virtual const char* what() const throw(); + private: - lua_State* m_L; + std::string m_message; }; // if an object_cast<>() fails, this is thrown @@ -62,7 +63,7 @@ namespace luabind class LUABIND_API cast_failed : public std::exception { public: - cast_failed(lua_State* L, type_id const& i): m_L(L), m_info(i) {} + cast_failed(lua_State* L, type_id const& i) : m_L(L), m_info(i) {} lua_State* state() const throw() { return m_L; } type_id info() const throw() { return m_info; } virtual const char* what() const throw() { return "unable to make cast"; } @@ -73,9 +74,6 @@ namespace luabind #else - typedef void(*error_callback_fun)(lua_State*); - typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); - LUABIND_API void set_error_callback(error_callback_fun e); LUABIND_API void set_cast_failed_callback(cast_failed_callback_fun c); LUABIND_API error_callback_fun get_error_callback(); @@ -83,7 +81,6 @@ namespace luabind #endif - typedef int(*pcall_callback_fun)(lua_State*); LUABIND_API void set_pcall_callback(pcall_callback_fun e); LUABIND_API pcall_callback_fun get_pcall_callback(); diff --git a/libs/luabind/luabind/detail/pointee_typeid.hpp b/libs/luabind/luabind/error_callback_fun.hpp similarity index 63% rename from libs/luabind/luabind/detail/pointee_typeid.hpp rename to libs/luabind/luabind/error_callback_fun.hpp index ab4113711..f25e67d17 100644 --- a/libs/luabind/luabind/detail/pointee_typeid.hpp +++ b/libs/luabind/luabind/error_callback_fun.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,21 +20,27 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef POINTEE_TYPEID_040211_HPP -#define POINTEE_TYPEID_040211_HPP +#ifndef INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +#define INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 +// Internal Includes #include -#include +#include -namespace luabind { namespace detail { +// Library/third-party includes +// - none - template - type_id pointee_typeid(T*) - { - return typeid(T); - } +// Standard includes +// - none -}} // namespace luabind::detail +namespace luabind +{ + class type_id; -#endif // POINTEE_TYPEID_040211_HPP + using error_callback_fun = void(*)(lua_State*); + using cast_failed_callback_fun = void(*)(lua_State*, type_id const&); + using pcall_callback_fun = void(*)(lua_State*); +} + +#endif // INCLUDED_error_callback_fun_hpp_GUID_1150976a_4348_495f_99ce_9d7edd00a0b8 diff --git a/libs/luabind/luabind/exception_handler.hpp b/libs/luabind/luabind/exception_handler.hpp index 0048563af..71d3fd20f 100644 --- a/libs/luabind/luabind/exception_handler.hpp +++ b/libs/luabind/luabind/exception_handler.hpp @@ -3,106 +3,73 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LUABIND_EXCEPTION_HANDLER_050601_HPP -# define LUABIND_EXCEPTION_HANDLER_050601_HPP +#define LUABIND_EXCEPTION_HANDLER_050601_HPP -# include -# include -# include -# include - -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) -# include -# include -# endif +#include // for LUABIND_API +#include +#include +#include namespace luabind { # ifndef LUABIND_NO_EXCEPTIONS -namespace detail -{ + namespace detail { - struct LUABIND_API exception_handler_base - { - exception_handler_base() - : next(0) - {} + struct LUABIND_API exception_handler_base + { + exception_handler_base() + : next(0) + {} - virtual ~exception_handler_base() {} - virtual void handle(lua_State*) const = 0; + virtual ~exception_handler_base() {} + virtual void handle(lua_State*) const = 0; - void try_next(lua_State*) const; + void try_next(lua_State*) const; - exception_handler_base* next; - }; + exception_handler_base* next; + }; - namespace mpl = boost::mpl; + template + struct exception_handler : exception_handler_base + { + using argument = E const&; - template - struct exception_handler : exception_handler_base - { -# if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - typedef typename mpl::if_< - boost::is_pointer, E, E const& - >::type argument; -# else - typedef E const& argument; -# endif + exception_handler(Handler handler) + : handler(handler) + {} - exception_handler(Handler handler) - : handler(handler) - {} + void handle(lua_State* L) const + { + try + { + try_next(L); + } + catch(argument e) + { + handler(L, e); + } + } - void handle(lua_State* L) const - { - try - { - try_next(L); - } - catch (argument e) - { - handler(L, e); - } - } + Handler handler; + }; - Handler handler; - }; + LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void register_exception_handler(exception_handler_base*); - LUABIND_API void handle_exception_aux(lua_State* L); - LUABIND_API void register_exception_handler(exception_handler_base*); - -} // namespace detail + } // namespace detail # endif -template -void register_exception_handler(Handler handler, boost::type* = 0) -{ + template + void register_exception_handler(Handler handler, meta::type* = 0) + { # ifndef LUABIND_NO_EXCEPTIONS - detail::register_exception_handler( - new detail::exception_handler(handler) - ); + detail::register_exception_handler( + new detail::exception_handler(handler) + ); # endif -} - -template -boost::optional handle_exceptions(lua_State* L, F fn, boost::type* = 0) -{ -# ifndef LUABIND_NO_EXCEPTIONS - try - { - return fn(); - } - catch (...) - { - detail::handle_exception_aux(L); - } - - return boost::optional(); -# else - return fn(); -# endif -} + } } // namespace luabind diff --git a/libs/luabind/luabind/from_stack.hpp b/libs/luabind/luabind/from_stack.hpp index 56bc268d8..cde5644a1 100644 --- a/libs/luabind/luabind/from_stack.hpp +++ b/libs/luabind/luabind/from_stack.hpp @@ -23,18 +23,20 @@ #ifndef LUABIND_FROM_STACK_050715_HPP #define LUABIND_FROM_STACK_050715_HPP +#include + namespace luabind { -struct from_stack -{ - from_stack(lua_State* interpreter, int index) - : interpreter(interpreter) - , index(index) - {} + struct from_stack + { + from_stack(lua_State* interpreter, int index) + : interpreter(interpreter) + , index(index) + {} - lua_State* interpreter; - int index; -}; + lua_State* interpreter; + int index; + }; } // namespace luabind diff --git a/libs/luabind/luabind/function.hpp b/libs/luabind/luabind/function.hpp index e156fbfcb..815108a98 100644 --- a/libs/luabind/luabind/function.hpp +++ b/libs/luabind/luabind/function.hpp @@ -11,50 +11,43 @@ namespace luabind { -namespace detail -{ + namespace detail + { - template - struct function_registration : registration - { - function_registration(char const* name, F f, Policies const& policies) - : name(name) - , f(f) - , policies(policies) - {} + template + struct function_registration : registration + { + function_registration(char const* name, F f) + : name(name) + , f(f) + {} - void register_(lua_State* L) const - { - object fn = make_function(L, f, deduce_signature(f), policies); + void register_(lua_State* L) const + { + object fn = make_function(L, f, PolicyInjectors()); + add_overload(object(from_stack(L, -1)), name, fn); + } - add_overload( - object(from_stack(L, -1)) - , name - , fn - ); - } + char const* name; + F f; + }; - char const* name; - F f; - Policies policies; - }; + LUABIND_API bool is_luabind_function(lua_State* L, int index); - LUABIND_API bool is_luabind_function(lua_State* L, int index); + } // namespace detail -} // namespace detail + template + scope def(char const* name, F f, policy_list const&) + { + return scope(std::unique_ptr( + new detail::function_registration>(name, f))); + } -template -scope def(char const* name, F f, Policies const& policies) -{ - return scope(std::auto_ptr( - new detail::function_registration(name, f, policies))); -} - -template -scope def(char const* name, F f) -{ - return def(name, f, detail::null_type()); -} + template + scope def(char const* name, F f) + { + return def(name, f, no_policies()); + } } // namespace luabind diff --git a/libs/luabind/luabind/detail/pointee_sizeof.hpp b/libs/luabind/luabind/function_introspection.hpp similarity index 57% rename from libs/luabind/luabind/detail/pointee_sizeof.hpp rename to libs/luabind/luabind/function_introspection.hpp index 3875c09dd..c18dab7df 100644 --- a/libs/luabind/luabind/detail/pointee_sizeof.hpp +++ b/libs/luabind/luabind/function_introspection.hpp @@ -1,5 +1,17 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg +/** @file + @brief Header + @date 2012 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2012. // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation @@ -20,35 +32,25 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef POINTEE_SIZEOF_040211_HPP -#define POINTEE_SIZEOF_040211_HPP +#ifndef INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 +#define INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 + +// Internal Includes +#include +#include + +// Library/third-party includes +// - none + +// Standard includes +// - none -#include namespace luabind { - namespace detail { + LUABIND_API int bind_function_introspection(lua_State * L); - template T& deref_type(T(*)(), int); - template T& deref_type(T*(*)(), long); +} // end of namespace luabind - } // namespace detail - - // returns the indirect sizeof U, as in - // sizeof(T*) = sizeof(T) - // sizeof(T&) = sizeof(T) - // sizeof(T) = sizeof(T) - template - struct pointee_sizeof - { - BOOST_STATIC_CONSTANT(int, value = ( - sizeof(detail::deref_type((T(*)())0), 0L) - )); - - typedef boost::mpl::int_ type; - }; - -} // namespace luabind - -#endif // POINTEE_SIZEOF_040211_HPP +#endif // INCLUDED_function_introspection_hpp_GUID_b55783e7_e6da_4816_925e_9256245c1065 diff --git a/libs/luabind/luabind/get_main_thread.hpp b/libs/luabind/luabind/get_main_thread.hpp index f94d6e4bc..80b44ef10 100644 --- a/libs/luabind/luabind/get_main_thread.hpp +++ b/libs/luabind/luabind/get_main_thread.hpp @@ -6,11 +6,13 @@ # define LUABIND_GET_MAIN_THREAD_090321_HPP # include +# include namespace luabind { -LUABIND_API lua_State* get_main_thread(lua_State* L); + LUABIND_API lua_State* get_main_thread(lua_State* L); } // namespace luabind #endif // LUABIND_GET_MAIN_THREAD_090321_HPP + diff --git a/libs/luabind/luabind/handle.hpp b/libs/luabind/luabind/handle.hpp index 14adacbae..5aa98aa14 100644 --- a/libs/luabind/luabind/handle.hpp +++ b/libs/luabind/luabind/handle.hpp @@ -24,119 +24,115 @@ #define LUABIND_HANDLE_050420_HPP #include -#include +#include +#include namespace luabind { -// A reference to a Lua value. Represents an entry in the -// registry table. -class handle -{ -public: - handle(); - handle(lua_State* interpreter, int stack_index); - handle(lua_State* main, lua_State* interpreter, int stack_index); - handle(handle const& other); - ~handle(); + // A reference to a Lua value. Represents an entry in the + // registry table. + class handle + { + public: + handle(); + handle(lua_State* interpreter, int stack_index); + handle(lua_State* main, lua_State* interpreter, int stack_index); + handle(handle const& other); + ~handle(); - handle& operator=(handle const& other); - void swap(handle& other); + handle& operator=(handle const& other); + void swap(handle& other); - void push(lua_State* interpreter) const; + void push(lua_State* interpreter) const; - lua_State* interpreter() const; + lua_State* interpreter() const; - void replace(lua_State* interpreter, int stack_index); + void replace(lua_State* interpreter, int stack_index); -private: - lua_State* m_interpreter; - int m_index; -}; + private: + lua_State* m_interpreter; + int m_index; + }; -inline handle::handle() - : m_interpreter(0) - , m_index(LUA_NOREF) -{} + inline handle::handle() + : m_interpreter(0), m_index(LUA_NOREF) + {} -inline handle::handle(handle const& other) - : m_interpreter(other.m_interpreter) - , m_index(LUA_NOREF) -{ - if (m_interpreter == 0) return; - lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); - m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); -} + inline handle::handle(handle const& other) + : m_interpreter(other.m_interpreter), m_index(LUA_NOREF) + { + if(m_interpreter == 0) return; + lua_rawgeti(m_interpreter, LUA_REGISTRYINDEX, other.m_index); + m_index = luaL_ref(m_interpreter, LUA_REGISTRYINDEX); + } -inline handle::handle(lua_State* interpreter, int stack_index) - : m_interpreter(interpreter) - , m_index(LUA_NOREF) -{ - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); -} + inline handle::handle(lua_State* interpreter, int stack_index) + : m_interpreter(interpreter), m_index(LUA_NOREF) + { + lua_pushvalue(interpreter, stack_index); + m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); + } -inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) - : m_interpreter(main) - , m_index(LUA_NOREF) -{ - lua_pushvalue(interpreter, stack_index); - m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); -} + inline handle::handle(lua_State* main, lua_State* interpreter, int stack_index) + : m_interpreter(main), m_index(LUA_NOREF) + { + lua_pushvalue(interpreter, stack_index); + m_index = luaL_ref(interpreter, LUA_REGISTRYINDEX); + } -inline handle::~handle() -{ - if (m_interpreter && m_index != LUA_NOREF) - luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); -} + inline handle::~handle() + { + if(m_interpreter && m_index != LUA_NOREF) luaL_unref(m_interpreter, LUA_REGISTRYINDEX, m_index); + } -inline handle& handle::operator=(handle const& other) -{ - handle(other).swap(*this); - return *this; -} + inline handle& handle::operator=(handle const& other) + { + handle(other).swap(*this); + return *this; + } -inline void handle::swap(handle& other) -{ - std::swap(m_interpreter, other.m_interpreter); - std::swap(m_index, other.m_index); -} + inline void handle::swap(handle& other) + { + std::swap(m_interpreter, other.m_interpreter); + std::swap(m_index, other.m_index); + } -inline void handle::push(lua_State* interpreter) const -{ - lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); -} + inline void handle::push(lua_State* interpreter) const + { + lua_rawgeti(interpreter, LUA_REGISTRYINDEX, m_index); + } -inline lua_State* handle::interpreter() const -{ - return m_interpreter; -} + inline lua_State* handle::interpreter() const + { + return m_interpreter; + } -inline void handle::replace(lua_State* interpreter, int stack_index) -{ - lua_pushvalue(interpreter, stack_index); - lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); -} + inline void handle::replace(lua_State* interpreter, int stack_index) + { + lua_pushvalue(interpreter, stack_index); + lua_rawseti(interpreter, LUA_REGISTRYINDEX, m_index); + } -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; + template<> + struct lua_proxy_traits + { + using is_specialized = std::true_type; - static lua_State* interpreter(handle const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, handle const& value) - { - value.push(interpreter); - } + static lua_State* interpreter(handle const& value) + { + return value.interpreter(); + } - static bool check(...) - { - return true; - } -}; + static void unwrap(lua_State* interpreter, handle const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } + }; } // namespace luabind diff --git a/libs/luabind/luabind/iterator_policy.hpp b/libs/luabind/luabind/iterator_policy.hpp index b1f827fe3..03840a968 100644 --- a/libs/luabind/luabind/iterator_policy.hpp +++ b/libs/luabind/luabind/iterator_policy.hpp @@ -5,108 +5,105 @@ #ifndef LUABIND_ITERATOR_POLICY__071111_HPP # define LUABIND_ITERATOR_POLICY__071111_HPP -# include -# include -# include +# include // for LUABIND_ANONYMOUS_FIX +# include // for convert_to_lua +# include // for index_map, etc -namespace luabind { namespace detail { +# include // for operator new -template -struct iterator -{ - static int next(lua_State* L) - { - iterator* self = static_cast( - lua_touserdata(L, lua_upvalueindex(1))); +namespace luabind { + namespace detail { - if (self->first != self->last) - { - convert_to_lua(L, *self->first); - ++self->first; - } - else - { - lua_pushnil(L); - } + template + struct iterator + { + static int next(lua_State* L) + { + iterator* self = static_cast( + lua_touserdata(L, lua_upvalueindex(1))); - return 1; - } + if(self->first != self->last) + { + push_to_lua(L, *self->first); + ++self->first; + } else + { + lua_pushnil(L); + } - static int destroy(lua_State* L) - { - iterator* self = static_cast(lua_touserdata(L, 1)); - self->~iterator(); - return 0; - } + return 1; + } - iterator(Iterator first, Iterator last) - : first(first) - , last(last) - {} + static int destroy(lua_State* L) + { + iterator* self = static_cast(lua_touserdata(L, 1)); + self->~iterator(); + return 0; + } - Iterator first; - Iterator last; -}; + iterator(Iterator first, Iterator last) + : first(first) + , last(last) + {} -template -int make_range(lua_State* L, Iterator first, Iterator last) -{ - void* storage = lua_newuserdata(L, sizeof(iterator)); - lua_newtable(L); - lua_pushcclosure(L, iterator::destroy, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - lua_pushcclosure(L, iterator::next, 1); - new (storage) iterator(first, last); - return 1; -} + Iterator first; + Iterator last; + }; -template -int make_range(lua_State* L, Container& container) -{ - return make_range(L, container.begin(), container.end()); -} + template + int make_range(lua_State* L, Iterator first, Iterator last) + { + void* storage = lua_newuserdata(L, sizeof(iterator)); + lua_newtable(L); + lua_pushcclosure(L, iterator::destroy, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); + lua_pushcclosure(L, iterator::next, 1); + new (storage) iterator(first, last); + return 1; + } -struct iterator_converter -{ - typedef iterator_converter type; + template + int make_range(lua_State* L, Container& container) + { + return make_range(L, container.begin(), container.end()); + } - template - void apply(lua_State* L, Container& container) - { - make_range(L, container); - } + struct iterator_converter + { + using type = iterator_converter; - template - void apply(lua_State* L, Container const& container) - { - make_range(L, container); - } -}; + template + void to_lua(lua_State* L, Container& container) + { + make_range(L, container); + } -struct iterator_policy : conversion_policy<0> -{ - static void precall(lua_State*, index_map const&) - {} + template + void tu_lua(lua_State* L, Container const& container) + { + make_range(L, container); + } + }; - static void postcall(lua_State*, index_map const&) - {} + struct iterator_policy + { + template + struct specialize + { + static_assert(std::is_same::value, "Iterator policy can only convert from cpp to lua."); + using type = iterator_converter; + }; + }; - template - struct apply - { - typedef iterator_converter type; - }; -}; + } // namespace detail +} // namespace luabind -}} // namespace luabind::detail +namespace luabind { -namespace luabind { namespace { + using return_stl_iterator = policy_list>; -LUABIND_ANONYMOUS_FIX detail::policy_cons< - detail::iterator_policy, detail::null_type> return_stl_iterator; - -}} // namespace luabind::unnamed +} // namespace luabind #endif // LUABIND_ITERATOR_POLICY__071111_HPP diff --git a/libs/luabind/luabind/lua_argument_proxy.hpp b/libs/luabind/luabind/lua_argument_proxy.hpp new file mode 100644 index 000000000..ed5997961 --- /dev/null +++ b/libs/luabind/luabind/lua_argument_proxy.hpp @@ -0,0 +1,71 @@ +#ifndef LUA_ARGUMENT_PROXY_HPP_INCLUDED +#define LUA_ARGUMENT_PROXY_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + namespace adl { + + class argument : public lua_proxy_interface + { + public: + argument(from_stack const& stack_reference) + : m_interpreter(stack_reference.interpreter), m_index(stack_reference.index) + { + if(m_index < 0) m_index = lua_gettop(m_interpreter) - m_index + 1; + } + + template + index_proxy operator[](T const& key) const + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* L) const + { + lua_pushvalue(L, m_index); + } + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + lua_State* m_interpreter; + int m_index; + }; + + } + + using adl::argument; + + template<> + struct lua_proxy_traits + { + using is_specialized = std::true_type; + + static lua_State* interpreter(argument const& value) + { + return value.interpreter(); + } + + static void unwrap(lua_State* interpreter, argument const& value) + { + value.push(interpreter); + } + + static bool check(...) + { + return true; + } + }; + +} + +#endif + diff --git a/libs/luabind/luabind/lua_include.hpp b/libs/luabind/luabind/lua_include.hpp index 7327b533e..64c595bf3 100644 --- a/libs/luabind/luabind/lua_include.hpp +++ b/libs/luabind/luabind/lua_include.hpp @@ -28,8 +28,8 @@ extern "C" { #endif - #include "lua.h" - #include "lauxlib.h" +#include "lua.h" +#include "lauxlib.h" #ifndef LUABIND_CPLUSPLUS_LUA } diff --git a/libs/luabind/luabind/lua_index_proxy.hpp b/libs/luabind/luabind/lua_index_proxy.hpp new file mode 100644 index 000000000..f8c726de1 --- /dev/null +++ b/libs/luabind/luabind/lua_index_proxy.hpp @@ -0,0 +1,137 @@ +#ifndef LUA_INDEX_PROXY_HPP_INCLUDED +#define LUA_INDEX_PROXY_HPP_INCLUDED + +#include +#include +#include +#include + +namespace luabind { + + namespace adl { + + class object; + + template + class index_proxy + : public lua_proxy_interface > + { + public: + using this_type = index_proxy; + + template + index_proxy(Next const& next, lua_State* interpreter, Key const& key) + : m_interpreter(interpreter), m_key_index(lua_gettop(interpreter) + 1), m_next(next) + { + detail::push_to_lua(m_interpreter, key); + } + + index_proxy(index_proxy const& other) + : m_interpreter(other.m_interpreter), m_key_index(other.m_key_index), m_next(other.m_next) + { + other.m_interpreter = 0; + } + + ~index_proxy() + { + if(m_interpreter) + lua_pop(m_interpreter, 1); + } + + // This is non-const to prevent conversion on lvalues. + // defined in luabind/detail/object.hpp + operator object(); + + // this will set the value to nil + this_type& operator=(luabind::detail::nil_type) + { + lua_proxy_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + lua_settable(m_interpreter, -3); + return *this; + } + + template + this_type& operator=(T&& value) + { + lua_proxy_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push_to_lua(m_interpreter, std::forward(value)); + lua_settable(m_interpreter, -3); + return *this; + } + + this_type& operator=(this_type const& value) + { + lua_proxy_traits::unwrap(m_interpreter, m_next); + detail::stack_pop pop(m_interpreter, 1); + + lua_pushvalue(m_interpreter, m_key_index); + detail::push(m_interpreter, value); + lua_settable(m_interpreter, -3); + return *this; + } + + template + index_proxy operator[](T const& key) + { + return index_proxy(*this, m_interpreter, key); + } + + void push(lua_State* interpreter); + + lua_State* interpreter() const + { + return m_interpreter; + } + + private: + struct hidden_type {}; + mutable lua_State* m_interpreter; + int m_key_index; + + Next const& m_next; + }; + + template + inline void index_proxy::push(lua_State* interpreter) + { + assert(interpreter == m_interpreter); + + lua_proxy_traits::unwrap(m_interpreter, m_next); + + lua_pushvalue(m_interpreter, m_key_index); + lua_gettable(m_interpreter, -2); + lua_remove(m_interpreter, -2); + } + + } // namespace adl + + template + struct lua_proxy_traits > + { + using is_specialized = std::true_type; + + template + static lua_State* interpreter(adl::index_proxy const& proxy) + { + return proxy.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) + { + const_cast&>(proxy).push(interpreter); + } + }; + + +} // namespace luabind + +#endif + diff --git a/libs/luabind/luabind/lua_iterator_proxy.hpp b/libs/luabind/luabind/lua_iterator_proxy.hpp new file mode 100644 index 000000000..155c67ef2 --- /dev/null +++ b/libs/luabind/luabind/lua_iterator_proxy.hpp @@ -0,0 +1,230 @@ +#ifndef LUA_ITERATOR_PROXY_HPP_INCLUDED +#define LUA_ITERATOR_PROXY_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) +# define LUA_OPEQ lua_equal +#endif + +namespace luabind { + + namespace adl { + + template + class iterator_proxy : + public lua_proxy_interface > + { + public: + iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) + : m_interpreter(interpreter), m_table_index(lua_gettop(interpreter) + 1), m_key_index(m_table_index + 1) + { + table.push(m_interpreter); + key.push(m_interpreter); + } + + iterator_proxy(iterator_proxy const& other) + : m_interpreter(other.m_interpreter), m_table_index(other.m_table_index), m_key_index(other.m_key_index) + { + other.m_interpreter = 0; + } + + ~iterator_proxy() + { + if(m_interpreter) lua_pop(m_interpreter, 2); + } + + // this will set the value to nil + iterator_proxy & operator=(luabind::detail::nil_type) + { + lua_pushvalue(m_interpreter, m_key_index); + lua_pushnil(m_interpreter); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + iterator_proxy& operator=(T&& value) + { + lua_pushvalue(m_interpreter, m_key_index); + detail::push_to_lua(m_interpreter, std::forward(value)); + AccessPolicy::set(m_interpreter, m_table_index); + return *this; + } + + template + index_proxy > operator[](Key const& key) + { + return index_proxy >( + *this, m_interpreter, key + ); + } + + // This is non-const to prevent conversion on lvalues. + // defined in luabind/object.hpp + operator object(); + + lua_State* interpreter() const + { + return m_interpreter; + } + + // TODO: Why is it non-const? + void push(lua_State* interpreter) + { + assert(interpreter == m_interpreter); + lua_pushvalue(m_interpreter, m_key_index); + AccessPolicy::get(m_interpreter, m_table_index); + } + + private: + mutable lua_State* m_interpreter; + int m_table_index; + int m_key_index; + }; + + } + + template + struct lua_proxy_traits > + { + using is_specialized = std::true_type; + + template + static lua_State* interpreter(Proxy const& p) + { + return p.interpreter(); + } + + template + static void unwrap(lua_State* interpreter, Proxy const& p) + { + // TODO: Why const_cast? + const_cast(p).push(interpreter); + } + }; + + namespace detail + { + struct basic_access + { + static void set(lua_State* interpreter, int table) + { + lua_settable(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_gettable(interpreter, table); + } + }; + + struct raw_access + { + static void set(lua_State* interpreter, int table) + { + lua_rawset(interpreter, table); + } + + static void get(lua_State* interpreter, int table) + { + lua_rawget(interpreter, table); + } + }; + + template + class basic_iterator : + public detail::crtp_iterator< basic_iterator, adl::iterator_proxy, std::forward_iterator_tag, adl::iterator_proxy > + { + public: + basic_iterator() + : m_interpreter(0) + {} + + template + explicit basic_iterator(ValueWrapper const& value_wrapper) + : m_interpreter(lua_proxy_traits::interpreter(value_wrapper)) + { + detail::stack_pop pop(m_interpreter, 1); + lua_proxy_traits::unwrap(m_interpreter, value_wrapper); + + lua_pushnil(m_interpreter); + if(lua_next(m_interpreter, -2) != 0) { + detail::stack_pop pop(m_interpreter, 2); + handle(m_interpreter, -2).swap(m_key); + } else { + m_interpreter = 0; + return; + } + + handle(m_interpreter, -1).swap(m_table); + } + + // defined in luabind/detail/object.hpp + adl::object key() const; + + private: + template< typename, typename, typename, typename, typename > + friend class detail::crtp_iterator; + + void increment() + { + m_table.push(m_interpreter); + m_key.push(m_interpreter); + + detail::stack_pop pop(m_interpreter, 1); + + if(lua_next(m_interpreter, -2) != 0) { + m_key.replace(m_interpreter, -2); + lua_pop(m_interpreter, 2); + } else { + m_interpreter = 0; + handle().swap(m_table); + handle().swap(m_key); + } + } + + bool equal(basic_iterator const& other) const + { + if(m_interpreter == 0 && other.m_interpreter == 0) + return true; + + if(m_interpreter != other.m_interpreter) + return false; + + detail::stack_pop pop(m_interpreter, 2); + m_key.push(m_interpreter); + other.m_key.push(m_interpreter); + return lua_compare(m_interpreter, -2, -1, LUA_OPEQ) != 0; + } + + adl::iterator_proxy dereference() const + { + return adl::iterator_proxy(m_interpreter, m_table, m_key); + } + + lua_State* m_interpreter; + handle m_table; + handle m_key; + }; + + } // namespace detail + + using iterator = detail::basic_iterator; + using raw_iterator = detail::basic_iterator; + +} + +#if LUA_VERSION_NUM < 502 +#undef LUA_OPEQ +#undef lua_compare +#endif + +#endif + diff --git a/libs/luabind/luabind/detail/most_derived.hpp b/libs/luabind/luabind/lua_proxy.hpp similarity index 64% rename from libs/luabind/luabind/detail/most_derived.hpp rename to libs/luabind/luabind/lua_proxy.hpp index 4dd9d9159..6ecdf82fc 100644 --- a/libs/luabind/luabind/detail/most_derived.hpp +++ b/libs/luabind/luabind/lua_proxy.hpp @@ -20,25 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef MOST_DERIVED_051018_HPP -# define MOST_DERIVED_051018_HPP +#ifndef LUABIND_VALUE_WRAPPER_050419_HPP +#define LUABIND_VALUE_WRAPPER_050419_HPP -# include -# include +#include +#include -namespace luabind { namespace detail { +namespace luabind { -template -struct most_derived -{ - typedef typename boost::mpl::if_< - boost::is_base_and_derived - , WrappedClass - , Class - >::type type; -}; + // + // Concept "lua_proxy" + // -}} // namespace luabind::detail + template + struct lua_proxy_traits + { + using is_specialized = std::false_type; + }; -#endif // MOST_DERIVED_051018_HPP + template + struct is_lua_proxy_type + : lua_proxy_traits::is_specialized + {}; + + template< class T > + struct is_lua_proxy_arg + : std::conditional>::value, std::true_type, std::false_type >::type + {}; + +} // namespace luabind + +#endif // LUABIND_VALUE_WRAPPER_050419_HPP diff --git a/libs/luabind/luabind/lua_proxy_interface.hpp b/libs/luabind/luabind/lua_proxy_interface.hpp new file mode 100644 index 000000000..80f2de354 --- /dev/null +++ b/libs/luabind/luabind/lua_proxy_interface.hpp @@ -0,0 +1,306 @@ +#ifndef LUA_PROXY_INTERFACE_HPP_INCLUDED +#define LUA_PROXY_INTERFACE_HPP_INCLUDED + +#include +#include +#include +#include + +#if LUA_VERSION_NUM < 502 +# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) +# define LUA_OPEQ lua_equal +# define LUA_OPLT lua_lessthan +# define lua_rawlen lua_objlen +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif + +namespace luabind { + + namespace adl { + + template + class lua_proxy_interface; + + namespace check_object_interface + { + template + std::true_type check(lua_proxy_interface*); + std::false_type check(void*); + } // namespace is_object_interface_aux + + template + struct is_object_interface : public decltype(check_object_interface::check((remove_const_reference_t*)nullptr)) + {}; + + template + struct enable_binary + : std::enable_if< is_object_interface::value || is_object_interface::value, R > + {}; + + template + int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs, std::true_type, std::true_type) + { + L = lua_proxy_traits::interpreter(lhs); + lua_State* L2 = lua_proxy_traits::interpreter(rhs); + + // you are comparing objects with different interpreters + // that's not allowed. + assert(L == L2 || L == 0 || L2 == 0); + + // if the two objects we compare have different interpreters + // then they + + if(L != L2) return -1; + if(L == 0) return 1; + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const&, std::true_type, std::false_type) + { + L = lua_proxy_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const&, U const& x, std::false_type, std::true_type) + { + L = lua_proxy_traits::interpreter(x); + return 0; + } + + template + int binary_interpreter(lua_State*& L, T const& x, U const& y) + { + return binary_interpreter(L, x, y, is_lua_proxy_type(), is_lua_proxy_type()); + } + + template + typename enable_binary::type + operator==(LHS&& lhs, RHS&& rhs) + { + lua_State* L = 0; + switch(binary_interpreter(L, lhs, rhs)) { + case 1: return true; + case-1: return false; + } + assert(L); + detail::stack_pop pop1(L, 1); + detail::push_to_lua(L, std::forward(lhs)); + detail::stack_pop pop2(L, 1); + detail::push_to_lua(L, std::forward(rhs)); + return lua_compare(L, -1, -2, LUA_OPEQ) != 0; + } + + template + typename enable_binary::type + operator<(LHS&& lhs, RHS&& rhs) + { + lua_State* L = 0; + switch(binary_interpreter(L, lhs, rhs)) { + case 1: return true; + case-1: return false; + } + assert(L); + detail::stack_pop pop1(L, 1); + detail::push_to_lua(L, std::forward(lhs)); + detail::stack_pop pop2(L, 1); + detail::push_to_lua(L, std::forward(rhs)); + return lua_compare(L, -1, -2, LUA_OPLT) != 0; + } + + template + std::ostream& operator<<(std::ostream& os, lua_proxy_interface const& v) + { + using namespace luabind; + lua_State* interpreter = lua_proxy_traits::interpreter( + static_cast(v)); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, static_cast(v)); + char const* p = lua_tostring(interpreter, -1); + std::size_t len = lua_rawlen(interpreter, -1); + os.write(p, len); + //std::copy(p, p+len, std::ostream_iterator(os)); + return os; + } + + + template + typename enable_binary::type + operator>(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs || lhs == rhs); + } + + template + typename enable_binary::type + operator<=(LHS const& lhs, RHS const& rhs) + { + return lhs < rhs || lhs == rhs; + } + + template + typename enable_binary::type + operator>=(LHS const& lhs, RHS const& rhs) + { + return !(lhs < rhs); + } + + template + typename enable_binary::type + operator!=(LHS const& lhs, RHS const& rhs) + { + return !(lhs == rhs); + } + + template + class lua_proxy_interface + { + public: + ~lua_proxy_interface() {} + + // defined in luabind/detail/object.hpp + template + object operator()(Args&&... args); + + // defined in luabind/detail/object.hpp + template + object call(Args&&... args); + + explicit operator bool() const + { + lua_State* L = lua_proxy_traits::interpreter(derived()); + if(!L) return 0; + lua_proxy_traits::unwrap(L, derived()); + detail::stack_pop pop(L, 1); + return lua_toboolean(L, -1) == 1; + } + + private: + Derived& derived() { return *static_cast(this); } + Derived const& derived() const { return *static_cast(this); } + }; + + } + + template + std::string to_string(adl::lua_proxy_interface const& v) + { + using namespace luabind; + lua_State* interpreter = lua_proxy_traits::interpreter(static_cast(v)); + detail::stack_pop pop(interpreter, 1); + lua_proxy_traits::unwrap(interpreter, static_cast(v)); + char const* p = lua_tostring(interpreter, -1); + std::size_t len = lua_rawlen(interpreter, -1); + return std::string(p, len); + } + + namespace detail + { + template + ReturnType object_cast_aux(ValueWrapper const& value_wrapper, T*, Policies*, ErrorPolicy error_policy, ReturnType*) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value_wrapper); + +#ifndef LUABIND_NO_ERROR_CHECKING + if(!interpreter) + return error_policy.handle_error(interpreter, typeid(void)); +#endif + lua_proxy_traits::unwrap(interpreter, value_wrapper); + detail::stack_pop pop(interpreter, 1); + specialized_converter_policy_n<0, Policies, T, lua_to_cpp> cv; + + if(cv.match(interpreter, decorate_type_t(), -1) < 0) { + return error_policy.handle_error(interpreter, typeid(T)); + } + return cv.to_cpp(interpreter, decorate_type_t(), -1); + } + + template + struct throw_error_policy + { + T handle_error(lua_State* interpreter, type_id const& type_info) + { +#ifndef LUABIND_NO_EXCEPTIONS + throw cast_failed(interpreter, type_info); +#else + cast_failed_callback_fun e = get_cast_failed_callback(); + if(e) e(interpreter, type_info); + + assert(0 && "object_cast failed. If you want to handle this error use " + "luabind::set_error_callback()"); + std::terminate(); +#endif + //return *(typename std::remove_reference::type*)0; //DEAD CODE! + } + }; + + template + struct nothrow_error_policy + { + nothrow_error_policy(T rhs) : value(rhs) {} + + T handle_error(lua_State*, type_id const&) + { + return value; + } + private: + T value; + }; + } // namespace detail + + template inline + T object_cast(ValueWrapper const& value_wrapper) + { + return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::throw_error_policy(), (T*)0); + } + + template inline + T object_cast(ValueWrapper const& value_wrapper, Policies const&) + { + return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::throw_error_policy(), (T*)0); + } + + template inline + ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, ReturnValue default_value) + { + return detail::object_cast_aux(value_wrapper, (T*)0, (no_policies*)0, detail::nothrow_error_policy(default_value), (ReturnValue*)0); + } + + template inline + ReturnValue object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&, ReturnValue default_value) + { + return detail::object_cast_aux(value_wrapper, (T*)0, (Policies*)0, detail::nothrow_error_policy(default_value), (ReturnValue*)0); + } + + template + inline lua_CFunction tocfunction(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return lua_tocfunction(interpreter, -1); + } + + template + inline T* touserdata(ValueWrapper const& value) + { + lua_State* interpreter = lua_proxy_traits::interpreter(value); + + lua_proxy_traits::unwrap(interpreter, value); + detail::stack_pop pop(interpreter, 1); + return static_cast(lua_touserdata(interpreter, -1)); + } + +} + +#if LUA_VERSION_NUM < 502 +# undef lua_compare +# undef LUA_OPEQ +# undef LUA_OPLT +# undef lua_rawlen +# undef lua_pushglobaltable +#endif + +#endif + diff --git a/libs/luabind/luabind/get_pointer.hpp b/libs/luabind/luabind/lua_state_fwd.hpp similarity index 77% rename from libs/luabind/luabind/get_pointer.hpp rename to libs/luabind/luabind/lua_state_fwd.hpp index b9aae48a7..215574a13 100644 --- a/libs/luabind/luabind/get_pointer.hpp +++ b/libs/luabind/luabind/lua_state_fwd.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2005 Daniel Wallin +// Copyright (c) 2005 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,20 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_GET_POINTER_051023_HPP -# define LUABIND_GET_POINTER_051023_HPP +#ifndef LUABIND_LUA_STATE_FWD_HPP +#define LUABIND_LUA_STATE_FWD_HPP -// -// We need these overloads in the luabind namespace. -// +#ifndef LUABIND_CPLUSPLUS_LUA +extern "C" +{ +#endif -# include + struct lua_State; -namespace luabind { +#ifndef LUABIND_CPLUSPLUS_LUA +} +#endif -using boost::get_pointer; - -} // namespace luabind - -#endif // LUABIND_GET_POINTER_051023_HPP +#endif // LUABIND_BACK_REFERENCE_FWD_040510_HPP diff --git a/libs/luabind/luabind/luabind.hpp b/libs/luabind/luabind/luabind.hpp index 82298484c..9b47f01e2 100644 --- a/libs/luabind/luabind/luabind.hpp +++ b/libs/luabind/luabind/luabind.hpp @@ -28,5 +28,7 @@ #include #include #include +#include #endif // LUABIND_BIND_HPP_INCLUDED + diff --git a/libs/luabind/luabind/make_function.hpp b/libs/luabind/luabind/make_function.hpp index a1ac8716b..81bbe8f8f 100644 --- a/libs/luabind/luabind/make_function.hpp +++ b/libs/luabind/luabind/make_function.hpp @@ -3,119 +3,125 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef LUABIND_MAKE_FUNCTION_081014_HPP -# define LUABIND_MAKE_FUNCTION_081014_HPP +#define LUABIND_MAKE_FUNCTION_081014_HPP -# include -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include namespace luabind { -namespace detail -{ + namespace detail + { # ifndef LUABIND_NO_EXCEPTIONS - LUABIND_API void handle_exception_aux(lua_State* L); + LUABIND_API void handle_exception_aux(lua_State* L); # endif -// MSVC complains about member being sensitive to alignment (C4121) -// when F is a pointer to member of a class with virtual bases. -# ifdef BOOST_MSVC + // MSVC complains about member being sensitive to alignment (C4121) + // when F is a pointer to member of a class with virtual bases. +# ifdef _MSC_VER # pragma pack(push) # pragma pack(16) # endif - template - struct function_object_impl : function_object - { - function_object_impl(F f, Policies const& policies) - : function_object(&entry_point) - , f(f) - , policies(policies) - {} + template + struct function_object_impl : function_object + { + function_object_impl(F f) + : function_object(&entry_point), f(f) + {} - int call(lua_State* L, invoke_context& ctx) const - { - return invoke(L, *this, ctx, f, Signature(), policies); - } + int call(lua_State* L, invoke_context& ctx) /*const*/ + { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + return invoke(L, *this, ctx, f, Signature(), InjectorList()); +#else + return invoke(L, *this, ctx, f); +#endif + } - void format_signature(lua_State* L, char const* function) const - { - detail::format_signature(L, function, Signature()); - } + void format_signature(lua_State* L, char const* function) const + { + detail::format_signature(L, function, Signature()); + } - static int entry_point(lua_State* L) - { - function_object_impl const* impl = - *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); + static bool invoke_defer(lua_State* L, function_object_impl* impl, invoke_context& ctx, int& results) + { + bool exception_caught = false; - invoke_context ctx; + try { +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); +#else + results = invoke(L, *impl, ctx, impl->f); +#endif + } + catch(...) { + exception_caught = true; + handle_exception_aux(L); + } - int results = 0; + return exception_caught; + } + + static int entry_point(lua_State* L) + { + function_object_impl const* impl_const = *(function_object_impl const**)lua_touserdata(L, lua_upvalueindex(1)); + + // TODO: Can this be done differently? + function_object_impl* impl = const_cast(impl_const); + invoke_context ctx; + int results = 0; # ifndef LUABIND_NO_EXCEPTIONS - bool exception_caught = false; - - try - { - results = invoke( - L, *impl, ctx, impl->f, Signature(), impl->policies); - } - catch (...) - { - exception_caught = true; - handle_exception_aux(L); - } - - if (exception_caught) - lua_error(L); + bool exception_caught = invoke_defer(L, impl, ctx, results); + if(exception_caught) lua_error(L); # else - results = invoke(L, *impl, ctx, impl->f, Signature(), impl->policies); +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + results = invoke(L, *impl, ctx, impl->f, Signature(), InjectorList()); +#else + results = invoke(L, *impl, ctx, impl->f); +#endif # endif + if(!ctx) { + ctx.format_error(L, impl); + lua_error(L); + } - if (!ctx) - { - ctx.format_error(L, impl); - lua_error(L); - } + return results; + } - return results; - } + F f; + }; - F f; - Policies policies; - }; - -# ifdef BOOST_MSVC +# ifdef _MSC_VER # pragma pack(pop) # endif - LUABIND_API object make_function_aux( - lua_State* L, function_object* impl - ); + LUABIND_API object make_function_aux(lua_State* L, function_object* impl); + LUABIND_API void add_overload(object const&, char const*, object const&); - LUABIND_API void add_overload(object const&, char const*, object const&); + } // namespace detail -} // namespace detail + template + object make_function(lua_State* L, F f, meta::type_list< SignatureElements... >, meta::type_list< PolicyInjectors... >) + { + return detail::make_function_aux(L, new detail::function_object_impl, meta::type_list< PolicyInjectors...> >(f)); + } -template -object make_function(lua_State* L, F f, Signature, Policies) -{ - return detail::make_function_aux( - L - , new detail::function_object_impl( - f, Policies() - ) - ); -} + template + object make_function(lua_State* L, F f, meta::type_list< PolicyInjectors... >) + { + return make_function(L, f, deduce_signature_t(), meta::type_list< PolicyInjectors... >()); + } -template -object make_function(lua_State* L, F f) -{ - return make_function(L, detail::deduce_signature(f), detail::null_type()); -} + template + object make_function(lua_State* L, F f) + { + return make_function(L, f, deduce_signature_t(), no_policies()); + } } // namespace luabind diff --git a/libs/luabind/luabind/nil.hpp b/libs/luabind/luabind/nil.hpp index 5f9ba4db1..9955cdb21 100644 --- a/libs/luabind/luabind/nil.hpp +++ b/libs/luabind/luabind/nil.hpp @@ -27,13 +27,12 @@ namespace luabind { - namespace detail - { - struct nil_type {}; - } + namespace detail + { + struct nil_type {}; + } - // defined in class.cpp - extern LUABIND_API detail::nil_type nil; + constexpr detail::nil_type nil; } #endif diff --git a/libs/luabind/luabind/no_dependency.hpp b/libs/luabind/luabind/no_dependency.hpp new file mode 100644 index 000000000..89f996bee --- /dev/null +++ b/libs/luabind/luabind/no_dependency.hpp @@ -0,0 +1,28 @@ +// Copyright Daniel Wallin 2010. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef LUABIND_NO_DEPENDENCY_100324_HPP +# define LUABIND_NO_DEPENDENCY_100324_HPP + +# include + +namespace luabind { + + namespace detail + { + + struct no_dependency_policy + { + static void postcall(lua_State*, int /*results*/, meta::index_list_tag) + {} + }; + + } // namespace detail + + using no_dependency = policy_list>; + +} // namespace luabind + +#endif // LUABIND_NO_DEPENDENCY_100324_HPP + diff --git a/libs/luabind/luabind/object.hpp b/libs/luabind/luabind/object.hpp index 0feb7bd48..5659486e5 100644 --- a/libs/luabind/luabind/object.hpp +++ b/libs/luabind/luabind/object.hpp @@ -20,1393 +20,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUABIND_OBJECT_050419_HPP -#define LUABIND_OBJECT_050419_HPP +#ifndef LUABIND_OBJECT_HPP +#define LUABIND_OBJECT_HPP -#include // detail::push() -#include // detail::push() -#include // value_wrapper_traits specializations -#include -#include -#include +#include +#include -#include -#include -#include -#include -#include -#include -#include -#include // REFACTOR -#include - -#include // iterator - -#include -#include - -namespace luabind { - -namespace detail -{ - namespace mpl = boost::mpl; - - template - void push_aux(lua_State* interpreter, T& value, ConverterGenerator*) - { - typedef typename boost::mpl::if_< - boost::is_reference_wrapper - , BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - , T - >::type unwrapped_type; - - typename mpl::apply_wrap2< - ConverterGenerator,unwrapped_type,cpp_to_lua - >::type cv; - - cv.apply( - interpreter - , boost::implicit_cast< - BOOST_DEDUCED_TYPENAME boost::unwrap_reference::type& - >(value) - ); - } - - template - void push(lua_State* interpreter, T& value, Policies const&) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type converter_policy; - - push_aux(interpreter, value, (converter_policy*)0); - } - - template - void push(lua_State* interpreter, T& value) - { - push(interpreter, value, null_type()); - } - -} // namespace detail - -namespace adl -{ - namespace mpl = boost::mpl; - - template - class object_interface; - - namespace is_object_interface_aux - { - typedef char (&yes)[1]; - typedef char (&no)[2]; - - template - yes check(object_interface*); - no check(void*); - - template - struct impl - { - BOOST_STATIC_CONSTANT(bool, value = - sizeof(is_object_interface_aux::check((T*)0)) == sizeof(yes) - ); - - typedef mpl::bool_ type; - }; - - } // namespace detail - - template - struct is_object_interface - : is_object_interface_aux::impl::type - {}; - - template - struct enable_binary -# ifndef BOOST_NO_SFINAE - : boost::enable_if< - mpl::or_< - is_object_interface - , is_object_interface - > - , R - > - {}; -# else - { - typedef R type; - }; -# endif - - template - int binary_interpreter(lua_State*& L, T const& lhs, U const& rhs - , boost::mpl::true_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(lhs); - lua_State* L2 = value_wrapper_traits::interpreter(rhs); - - // you are comparing objects with different interpreters - // that's not allowed. - assert(L == L2 || L == 0 || L2 == 0); - - // if the two objects we compare have different interpreters - // then they - - if (L != L2) return -1; - if (L == 0) return 1; - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& - , boost::mpl::true_, boost::mpl::false_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const&, U const& x, boost::mpl::false_, boost::mpl::true_) - { - L = value_wrapper_traits::interpreter(x); - return 0; - } - - template - int binary_interpreter(lua_State*& L, T const& x, U const& y) - { - return binary_interpreter( - L - , x - , y - , is_value_wrapper() - , is_value_wrapper() - ); - } - -#define LUABIND_BINARY_OP_DEF(op, fn) \ - template \ - typename enable_binary::type \ - operator op(LHS const& lhs, RHS const& rhs) \ - { \ - lua_State* L = 0; \ - switch (binary_interpreter(L, lhs, rhs)) \ - { \ - case 1: \ - return true; \ - case -1: \ - return false; \ - } \ -\ - assert(L); \ -\ - detail::stack_pop pop1(L, 1); \ - detail::push(L, lhs); \ - detail::stack_pop pop2(L, 1); \ - detail::push(L, rhs); \ -\ - return fn(L, -1, -2) != 0; \ - } - -LUABIND_BINARY_OP_DEF(==, lua_equal) -LUABIND_BINARY_OP_DEF(<, lua_lessthan) - - template - std::ostream& operator<<(std::ostream& os - , object_interface const& v) - { - using namespace luabind; - lua_State* interpreter = value_wrapper_traits::interpreter( - static_cast(v)); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter - , static_cast(v)); - char const* p = lua_tostring(interpreter, -1); - std::size_t len = lua_strlen(interpreter, -1); - std::copy(p, p + len, std::ostream_iterator(os)); - return os; - } - -#undef LUABIND_BINARY_OP_DEF - - template - typename enable_binary::type - operator>(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs || lhs == rhs); - } - - template - typename enable_binary::type - operator<=(LHS const& lhs, RHS const& rhs) - { - return lhs < rhs || lhs == rhs; - } - - template - typename enable_binary::type - operator>=(LHS const& lhs, RHS const& rhs) - { - return !(lhs < rhs); - } - - template - typename enable_binary::type - operator!=(LHS const& lhs, RHS const& rhs) - { - return !(lhs == rhs); - } - - template - struct call_proxy; - - template - class index_proxy; - - class object; - - template - class object_interface - { - struct safe_bool_type {}; - public: - ~object_interface() {} - - call_proxy > operator()(); - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0) - ); - } - - template - call_proxy< - Derived - , boost::tuples::tuple - > operator()(A0 const& a0, A1 const& a1) - { - typedef boost::tuples::tuple arguments; - - return call_proxy( - derived() - , arguments(&a0, &a1) - ); - } - - // The rest of the overloads are PP-generated. - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (3, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - - operator safe_bool_type*() const - { - lua_State* L = value_wrapper_traits::interpreter(derived()); - - if (!L) - return 0; - - value_wrapper_traits::unwrap(L, derived()); - detail::stack_pop pop(L, 1); - - return lua_toboolean(L, -1) == 1 ? (safe_bool_type*)1 : 0; - } - - private: - Derived& derived() - { - return *static_cast(this); - } - - Derived const& derived() const - { - return *static_cast(this); - } - }; - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct iterator_proxy_tag; -#endif - - template - class iterator_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef iterator_proxy_tag value_wrapper_tag; -#endif - - iterator_proxy(lua_State* interpreter, handle const& table, handle const& key) - : m_interpreter(interpreter) - , m_table_index(lua_gettop(interpreter) + 1) - , m_key_index(m_table_index + 1) - { - table.push(m_interpreter); - key.push(m_interpreter); - } - - iterator_proxy(iterator_proxy const& other) - : m_interpreter(other.m_interpreter) - , m_table_index(other.m_table_index) - , m_key_index(other.m_key_index) - { - other.m_interpreter = 0; - } - - ~iterator_proxy() - { - if (m_interpreter) - lua_pop(m_interpreter, 2); - } - - // this will set the value to nil - iterator_proxy & operator=(luabind::detail::nil_type) - { - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - iterator_proxy& operator=(T const& value) - { - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - AccessPolicy::set(m_interpreter, m_table_index); - return *this; - } - - template - index_proxy > operator[](Key const& key) - { - return index_proxy >( - *this, m_interpreter, key - ); - } - - // This is non-const to prevent conversion on lvalues. - operator object(); - - lua_State* interpreter() const - { - return m_interpreter; - } - - // TODO: Why is it non-const? - void push(lua_State* interpreter) - { - assert(interpreter == m_interpreter); - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - } - - private: - mutable lua_State* m_interpreter; - int m_table_index; - int m_key_index; - }; - -} // namespace adl - -namespace detail -{ - struct basic_access - { - static void set(lua_State* interpreter, int table) - { - lua_settable(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_gettable(interpreter, table); - } - }; - - struct raw_access - { - static void set(lua_State* interpreter, int table) - { - lua_rawset(interpreter, table); - } - - static void get(lua_State* interpreter, int table) - { - lua_rawget(interpreter, table); - } - }; - - template - class basic_iterator - : public boost::iterator_facade< - basic_iterator - , adl::iterator_proxy - , boost::single_pass_traversal_tag - , adl::iterator_proxy - > - { - public: - basic_iterator() - : m_interpreter(0) - {} - - template - explicit basic_iterator(ValueWrapper const& value_wrapper) - : m_interpreter( - value_wrapper_traits::interpreter(value_wrapper) - ) - { - detail::stack_pop pop(m_interpreter, 1); - value_wrapper_traits::unwrap(m_interpreter, value_wrapper); - - lua_pushnil(m_interpreter); - if (lua_next(m_interpreter, -2) != 0) - { - detail::stack_pop pop(m_interpreter, 2); - handle(m_interpreter, -2).swap(m_key); - } - else - { - m_interpreter = 0; - return; - } - - handle(m_interpreter, -1).swap(m_table); - } - - adl::object key() const; - - private: - friend class boost::iterator_core_access; - - void increment() - { - m_table.push(m_interpreter); - m_key.push(m_interpreter); - - detail::stack_pop pop(m_interpreter, 1); - - if (lua_next(m_interpreter, -2) != 0) - { - m_key.replace(m_interpreter, -2); - lua_pop(m_interpreter, 2); - } - else - { - m_interpreter = 0; - handle().swap(m_table); - handle().swap(m_key); - } - } - - bool equal(basic_iterator const& other) const - { - if (m_interpreter == 0 && other.m_interpreter == 0) - return true; - - if (m_interpreter != other.m_interpreter) - return false; - - detail::stack_pop pop(m_interpreter, 2); - m_key.push(m_interpreter); - other.m_key.push(m_interpreter); - return lua_equal(m_interpreter, -2, -1) != 0; - } - - adl::iterator_proxy dereference() const - { - return adl::iterator_proxy(m_interpreter, m_table, m_key); - } - - lua_State* m_interpreter; - handle m_table; - handle m_key; - }; - -// Needed because of some strange ADL issues. -#if BOOST_VERSION < 105700 - -#define LUABIND_OPERATOR_ADL_WKND(op) \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } \ - \ - inline bool operator op( \ - basic_iterator const& x \ - , basic_iterator const& y) \ - { \ - return boost::operator op(x, y); \ - } - - LUABIND_OPERATOR_ADL_WKND(==) - LUABIND_OPERATOR_ADL_WKND(!=) - -#undef LUABIND_OPERATOR_ADL_WKND -#endif - -} // namespace detail - -namespace adl -{ - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - struct index_proxy_tag; -#endif - - template - class index_proxy - : public object_interface > - { - public: -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - typedef index_proxy_tag value_wrapper_tag; -#endif - - typedef index_proxy this_type; - - template - index_proxy(Next const& next, lua_State* interpreter, Key const& key) - : m_interpreter(interpreter) - , m_key_index(lua_gettop(interpreter) + 1) - , m_next(next) - { - detail::push(m_interpreter, key); - } - - index_proxy(index_proxy const& other) - : m_interpreter(other.m_interpreter) - , m_key_index(other.m_key_index) - , m_next(other.m_next) - { - other.m_interpreter = 0; - } - - ~index_proxy() - { - if (m_interpreter) - lua_pop(m_interpreter, 1); - } - - // This is non-const to prevent conversion on lvalues. - operator object(); - - // this will set the value to nil - this_type& operator=(luabind::detail::nil_type) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - lua_pushnil(m_interpreter); - lua_settable(m_interpreter, -3); - return *this; - } - - template - this_type& operator=(T const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - this_type& operator=(this_type const& value) - { - value_wrapper_traits::unwrap(m_interpreter, m_next); - detail::stack_pop pop(m_interpreter, 1); - - lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); - lua_settable(m_interpreter, -3); - return *this; - } - - template - index_proxy operator[](T const& key) - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* interpreter); - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - struct hidden_type {}; - -// this_type& operator=(index_proxy const&); - - mutable lua_State* m_interpreter; - int m_key_index; - - Next const& m_next; - }; - -} // namespace adl - -typedef detail::basic_iterator iterator; -typedef detail::basic_iterator raw_iterator; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::index_proxy const& proxy) - { - return proxy.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, adl::index_proxy const& proxy) - { - const_cast&>(proxy).push(interpreter); - } -}; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(Proxy const& p) - { - return p.interpreter(); - } - - template - static void unwrap(lua_State* interpreter, Proxy const& p) - { - // TODO: Why const_cast? - const_cast(p).push(interpreter); - } -}; - -namespace adl -{ - - // An object holds a reference to a Lua value residing - // in the registry. - class object : public object_interface - { - public: - object() - {} - - explicit object(handle const& other) - : m_handle(other) - {} - - explicit object(from_stack const& stack_reference) - : m_handle(stack_reference.interpreter, stack_reference.index) - { - } - - template - object(lua_State* interpreter, T const& value) - { - detail::push(interpreter, value); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - template - object(lua_State* interpreter, T const& value, Policies const&) - { - detail::push(interpreter, value, Policies()); - detail::stack_pop pop(interpreter, 1); - handle(interpreter, -1).swap(m_handle); - } - - void push(lua_State* interpreter) const; - lua_State* interpreter() const; - bool is_valid() const; - - template - index_proxy operator[](T const& key) const - { - return index_proxy( - *this, m_handle.interpreter(), key - ); - } - - void swap(object& other) - { - m_handle.swap(other.m_handle); - } - - private: - handle m_handle; - }; - - inline void object::push(lua_State* interpreter) const - { - m_handle.push(interpreter); - } - - inline lua_State* object::interpreter() const - { - return m_handle.interpreter(); - } - - inline bool object::is_valid() const - { - return m_handle.interpreter() != 0; - } - - class argument : public object_interface - { - public: - argument(from_stack const& stack_reference) - : m_interpreter(stack_reference.interpreter) - , m_index(stack_reference.index) - { - if (m_index < 0) - m_index = lua_gettop(m_interpreter) - m_index + 1; - } - - template - index_proxy operator[](T const& key) const - { - return index_proxy(*this, m_interpreter, key); - } - - void push(lua_State* L) const - { - lua_pushvalue(L, m_index); - } - - lua_State* interpreter() const - { - return m_interpreter; - } - - private: - lua_State* m_interpreter; - int m_index; - }; - -} // namespace adl - -using adl::object; -using adl::argument; - -#ifndef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits > -#else -template<> -struct value_wrapper_traits -#endif -{ - typedef boost::mpl::true_ is_specialized; - - template - static lua_State* interpreter(adl::call_proxy const& proxy) - { - return value_wrapper_traits::interpreter(*proxy.value_wrapper); - } - - template - static void unwrap(lua_State*, adl::call_proxy const& proxy) - { - object result = const_cast&>(proxy); - result.push(result.interpreter()); - } -}; - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - static lua_State* interpreter(object const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, object const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } -}; - -template<> -struct value_wrapper_traits -{ - typedef boost::mpl::true_ is_specialized; - - static lua_State* interpreter(argument const& value) - { - return value.interpreter(); - } - - static void unwrap(lua_State* interpreter, argument const& value) - { - value.push(interpreter); - } - - static bool check(...) - { - return true; - } -}; - -template -inline void adl::index_proxy::push(lua_State* interpreter) -{ - assert(interpreter == m_interpreter); - - value_wrapper_traits::unwrap(m_interpreter, m_next); - - lua_pushvalue(m_interpreter, m_key_index); - lua_gettable(m_interpreter, -2); - lua_remove(m_interpreter, -2); -} - -template -inline adl::index_proxy::operator object() -{ - detail::stack_pop pop(m_interpreter, 1); - push(m_interpreter); - return object(from_stack(m_interpreter, -1)); -} - -template -adl::iterator_proxy::operator object() -{ - lua_pushvalue(m_interpreter, m_key_index); - AccessPolicy::get(m_interpreter, m_table_index); - detail::stack_pop pop(m_interpreter, 1); - return object(from_stack(m_interpreter, -1)); -} - -template -object detail::basic_iterator::key() const -{ - return object(m_key); -} - -namespace detail -{ - - template< - class T - , class ValueWrapper - , class Policies - , class ErrorPolicy - , class ReturnType - > - ReturnType object_cast_aux( - ValueWrapper const& value_wrapper - , T* - , Policies* - , ErrorPolicy* - , ReturnType* - ) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - value_wrapper - ); - -#ifndef LUABIND_NO_ERROR_CHECKING - if (!interpreter) - return ErrorPolicy::handle_error(interpreter, typeid(void)); -#endif - - value_wrapper_traits::unwrap(interpreter, value_wrapper); - - detail::stack_pop pop(interpreter, 1); - - typedef typename detail::find_conversion_policy< - 0 - , Policies - >::type converter_generator; - - typename mpl::apply_wrap2::type cv; - -#ifndef LUABIND_NO_ERROR_CHECKING - if (cv.match(interpreter, LUABIND_DECORATE_TYPE(T), -1) < 0) - { - return ErrorPolicy::handle_error(interpreter, typeid(T)); - } -#endif - - return cv.apply(interpreter, LUABIND_DECORATE_TYPE(T), -1); - } - -# ifdef BOOST_MSVC -# pragma warning(push) -# pragma warning(disable:4702) // unreachable code -# endif - - template - struct throw_error_policy - { - static T handle_error(lua_State* interpreter, type_id const& type_info) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw cast_failed(interpreter, type_info); -#else - cast_failed_callback_fun e = get_cast_failed_callback(); - if (e) e(interpreter, type_info); - - assert(0 && "object_cast failed. If you want to handle this error use " - "luabind::set_error_callback()"); - std::terminate(); -#endif - return *(typename boost::remove_reference::type*)0; - } - }; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif - - template - struct nothrow_error_policy - { - static boost::optional handle_error(lua_State*, type_id const&) - { - return boost::optional(); - } - }; - -} // namespace detail - -template -T object_cast(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -T object_cast(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::throw_error_policy*)0 - , (T*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (detail::null_type*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -template -boost::optional object_cast_nothrow(ValueWrapper const& value_wrapper, Policies const&) -{ - return detail::object_cast_aux( - value_wrapper - , (T*)0 - , (Policies*)0 - , (detail::nothrow_error_policy*)0 - , (boost::optional*)0 - ); -} - -namespace detail -{ - - template - struct push_args_from_tuple - { - template - inline static void apply(lua_State* L, const boost::tuples::cons& x, const Policies& p) - { - convert_to_lua_p(L, *x.get_head(), p); - push_args_from_tuple::apply(L, x.get_tail(), p); - } - - template - inline static void apply(lua_State* L, const boost::tuples::cons& x) - { - convert_to_lua(L, *x.get_head()); - push_args_from_tuple::apply(L, x.get_tail()); - } - - template - inline static void apply(lua_State*, const boost::tuples::null_type&, const Policies&) {} - - inline static void apply(lua_State*, const boost::tuples::null_type&) {} - }; - -} // namespace detail - -namespace adl -{ - - template - struct call_proxy - { - call_proxy(ValueWrapper& value_wrapper, Arguments arguments) - : value_wrapper(&value_wrapper) - , arguments(arguments) - {} - - call_proxy(call_proxy const& other) - : value_wrapper(other.value_wrapper) - , arguments(other.arguments) - { - other.value_wrapper = 0; - } - - ~call_proxy() - { - if (value_wrapper) - call((detail::null_type*)0); - } - - operator object() - { - return call((detail::null_type*)0); - } - - template - object operator[](Policies const&) - { - return call((Policies*)0); - } - - template - object call(Policies*) - { - lua_State* interpreter = value_wrapper_traits::interpreter( - *value_wrapper - ); - - value_wrapper_traits::unwrap( - interpreter - , *value_wrapper - ); - - value_wrapper = 0; - - detail::push_args_from_tuple<1>::apply(interpreter, arguments, Policies()); - - if (detail::pcall(interpreter, boost::tuples::length::value, 1)) - { -#ifndef LUABIND_NO_EXCEPTIONS - throw luabind::error(interpreter); -#else - error_callback_fun e = get_error_callback(); - if (e) e(interpreter); - - assert(0 && "the lua function threw an error and exceptions are disabled." - "if you want to handle this error use luabind::set_error_callback()"); - std::terminate(); -#endif - } - - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); - } - - mutable ValueWrapper* value_wrapper; - Arguments arguments; - }; - - template - call_proxy > - object_interface::operator()() - { - return call_proxy >( - derived() - , boost::tuples::tuple<>() - ); - } - - // Simple value_wrapper adaptor with the sole purpose of helping with - // overload resolution. Use this as a function parameter type instead - // of "object" or "argument" to restrict the parameter to Lua tables. - template - struct table : Base - { - table(from_stack const& stack_reference) - : Base(stack_reference) - {} - }; - -} // namespace adl - -using adl::table; - -template -struct value_wrapper_traits > - : value_wrapper_traits -{ - static bool check(lua_State* L, int idx) - { - return value_wrapper_traits::check(L, idx) && - lua_istable(L, idx); - } -}; - -inline object newtable(lua_State* interpreter) -{ - lua_newtable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -// this could be optimized by returning a proxy -inline object globals(lua_State* interpreter) -{ - lua_pushglobaltable(interpreter); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -// this could be optimized by returning a proxy -inline object registry(lua_State* interpreter) -{ - lua_pushvalue(interpreter, LUA_REGISTRYINDEX); - detail::stack_pop pop(interpreter, 1); - return object(from_stack(interpreter, -1)); -} - -template -inline object gettable(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_gettable(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void settable(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_settable(interpreter, -3); -} - -template -inline object rawget(ValueWrapper const& table, K const& key) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 2); - detail::push(interpreter, key); - lua_rawget(interpreter, -2); - return object(from_stack(interpreter, -1)); -} - -template -inline void rawset(ValueWrapper const& table, K const& key, T const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - table - ); - - // TODO: Exception safe? - - value_wrapper_traits::unwrap(interpreter, table); - detail::stack_pop pop(interpreter, 1); - detail::push(interpreter, key); - detail::push(interpreter, value); - lua_rawset(interpreter, -3); -} - -template -inline int type(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_type(interpreter, -1); -} - -template -inline object getmetatable(ValueWrapper const& obj) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 2); - lua_getmetatable(interpreter, -1); - return object(from_stack(interpreter, -1)); -} - -template -inline void setmetatable( - ValueWrapper1 const& obj, ValueWrapper2 const& metatable) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - obj - ); - - value_wrapper_traits::unwrap(interpreter, obj); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, metatable); - lua_setmetatable(interpreter, -2); -} - -template -inline lua_CFunction tocfunction(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return lua_tocfunction(interpreter, -1); -} - -template -inline T* touserdata(ValueWrapper const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 1); - return static_cast(lua_touserdata(interpreter, -1)); -} - -template -inline object getupvalue(ValueWrapper const& value, int index) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - value - ); - - value_wrapper_traits::unwrap(interpreter, value); - detail::stack_pop pop(interpreter, 2); - lua_getupvalue(interpreter, -1, index); - return object(from_stack(interpreter, -1)); -} - -template -inline void setupvalue( - ValueWrapper1 const& function, int index, ValueWrapper2 const& value) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - function - ); - - value_wrapper_traits::unwrap(interpreter, function); - detail::stack_pop pop(interpreter, 1); - value_wrapper_traits::unwrap(interpreter, value); - lua_setupvalue(interpreter, -2, index); -} - -template -object property(GetValueWrapper const& get) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::unwrap(interpreter, get); - lua_pushnil(interpreter); - - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - - return object(from_stack(interpreter, -1)); -} - -template -object property(GetValueWrapper const& get, SetValueWrapper const& set) -{ - lua_State* interpreter = value_wrapper_traits::interpreter( - get - ); - - value_wrapper_traits::unwrap(interpreter, get); - value_wrapper_traits::unwrap(interpreter, set); - - lua_pushcclosure(interpreter, &detail::property_tag, 2); - detail::stack_pop pop(interpreter, 1); - - return object(from_stack(interpreter, -1)); - -} - - -} // namespace luabind - -#endif // LUABIND_OBJECT_050419_HPP +#endif // LUABIND_OBJECT_HPP diff --git a/libs/luabind/luabind/open.hpp b/libs/luabind/luabind/open.hpp index cca4c7a52..5fe28f409 100644 --- a/libs/luabind/luabind/open.hpp +++ b/libs/luabind/luabind/open.hpp @@ -26,6 +26,8 @@ #include +#include + namespace luabind { LUABIND_API void open(lua_State* L); diff --git a/libs/luabind/luabind/operator.hpp b/libs/luabind/luabind/operator.hpp index aeb651c03..bde759290 100644 --- a/libs/luabind/luabind/operator.hpp +++ b/libs/luabind/luabind/operator.hpp @@ -23,15 +23,6 @@ #ifndef OPERATOR_040729_HPP #define OPERATOR_040729_HPP -#include -#include -#include -#include -#include -#include -#include -#include - #if defined(__GNUC__) && __GNUC__ < 3 # define LUABIND_NO_STRINGSTREAM #else @@ -46,154 +37,155 @@ #include #endif -namespace luabind { namespace detail { +#include +#include +#include +#include - template struct unwrap_parameter_type; - template struct operator_ {}; +namespace luabind { + namespace detail { - struct operator_void_return {}; + template struct unwrap_parameter_type; + template struct operator_ {}; -#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) - template - inline T const& operator,(T const& x, operator_void_return) - { - return x; - } -#endif - -}} // namespace luabind + struct operator_void_return {}; -namespace luabind { namespace operators { + template + inline T const& operator,(T const& x, operator_void_return) + { + return x; + } - #define BOOST_PP_ITERATION_PARAMS_1 (3, \ - (0, LUABIND_MAX_ARITY, )) - #include BOOST_PP_ITERATE() - -}} // namespace luabind::operators + template + inline void operator_result(lua_State*, operator_void_return, Policies*) + { + } -#include + template + inline void operator_result(lua_State* L, T const& x, Policies*) + { + specialized_converter_policy_n<0, Policies, T, cpp_to_lua >().to_lua(L, x); + } + + } +} // namespace luabind + + +namespace luabind { + namespace operators { + + template + struct call_operator + : detail::operator_ < call_operator< Self, Args... > > + { + call_operator(int) {} + + template + struct apply + { + static void execute( + lua_State* L + , typename detail::unwrap_parameter_type::type self + , typename detail::unwrap_parameter_type::type... args + ) + { + using namespace detail; + operator_result( + L + , (self(args...), detail::operator_void_return()) + , (Policies*)0 + ); + } + }; + + static char const* name() { return "__call"; } + }; + + } +} // namespace luabind::operators namespace luabind { - template - struct self_base - { - operators::call_operator0 operator()() const - { - return 0; - } - -#define BOOST_PP_LOCAL_MACRO(n) \ - template \ - BOOST_PP_CAT(operators::call_operator, n)< \ - Derived \ - BOOST_PP_ENUM_TRAILING_PARAMS(n, A) \ - >\ - operator()( \ - BOOST_PP_ENUM_BINARY_PARAMS(n, A, const& BOOST_PP_INTERCEPT) \ - ) const \ - { \ - return 0; \ - } + template + struct self_base + { + template< typename... Args > + operators::call_operator operator()(const Args&...) const + { + return 0; + } + }; -#define BOOST_PP_LOCAL_LIMITS (1, LUABIND_MAX_ARITY) -#include BOOST_PP_LOCAL_ITERATE() + struct self_type : self_base + { + }; - }; + struct const_self_type : self_base + { + }; - struct self_type : self_base - { - }; + namespace detail { - struct const_self_type : self_base - { - }; + template + struct unwrap_parameter_type + { + using type = typename meta::select_ < + meta::case_< std::is_same, W& >, + meta::case_< std::is_same, W const& >, + meta::default_< typename unwrap_other::type > + > ::type; + }; -namespace detail { + template + struct binary_operator + : operator_ > + { + binary_operator(int) {} - template - struct unwrap_parameter_type - { - typedef typename boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , boost::mpl::eval_if< - boost::is_same - , boost::mpl::identity - , unwrap_other - > - >::type type; - }; + template + struct apply + { + using arg0 = typename unwrap_parameter_type::type; + using arg1 = typename unwrap_parameter_type::type; - template - struct binary_operator - : operator_ > - { - binary_operator(int) {} + static void execute(lua_State* L, arg0 _0, arg1 _1) + { + Derived::template apply::execute( + L, _0, _1); + } + }; - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; - typedef typename unwrap_parameter_type::type arg1; + static char const* name() + { + return Derived::name(); + } + }; - static void execute(lua_State* L, arg0 _0, arg1 _1) - { - Derived::template apply::execute( - L, _0, _1); - } - }; + template + struct unary_operator + : operator_ > + { + unary_operator(int) {} - static char const* name() - { - return Derived::name(); - } - }; + template + struct apply + { + using arg0 = typename unwrap_parameter_type::type; - template - struct unary_operator - : operator_ > - { - unary_operator(int) {} - - template - struct apply - { - typedef typename unwrap_parameter_type::type arg0; + static void execute(lua_State* L, arg0 _0) + { + Derived::template apply::execute(L, _0); + } + }; - static void execute(lua_State* L, arg0 _0) - { - Derived::template apply::execute(L, _0); - } - }; + static char const* name() + { + return Derived::name(); + } + }; - static char const* name() - { - return Derived::name(); - } - }; - - template - inline void operator_result(lua_State* L, operator_void_return, Policies*) - { - } - - namespace mpl = boost::mpl; - - template - inline void operator_result(lua_State* L, T const& x, Policies*) - { - typedef typename find_conversion_policy< - 0 - , Policies - >::type cv_policy; - - typename mpl::apply_wrap2::type cv; - - cv.apply(L, x); - } - -}} // namespace detail::luabind + } +} // namespace detail::luabind namespace luabind { @@ -281,16 +273,17 @@ namespace luabind { return 0; \ } - LUABIND_BINARY_OPERATOR(add, +) - LUABIND_BINARY_OPERATOR(sub, -) - LUABIND_BINARY_OPERATOR(mul, *) - LUABIND_BINARY_OPERATOR(div, /) - LUABIND_BINARY_OPERATOR(pow, ^) - LUABIND_BINARY_OPERATOR(lt, <) - LUABIND_BINARY_OPERATOR(le, <=) - LUABIND_BINARY_OPERATOR(eq, ==) + LUABIND_BINARY_OPERATOR(add, +) + LUABIND_BINARY_OPERATOR(sub, -) + LUABIND_BINARY_OPERATOR(mul, *) + LUABIND_BINARY_OPERATOR(div, / ) + LUABIND_BINARY_OPERATOR(mod, %) + LUABIND_BINARY_OPERATOR(pow, ^) + LUABIND_BINARY_OPERATOR(lt, < ) + LUABIND_BINARY_OPERATOR(le, <= ) + LUABIND_BINARY_OPERATOR(eq, == ) -#undef LUABIND_UNARY_OPERATOR +#undef LUABIND_BINARY_OPERATOR #define LUABIND_UNARY_OPERATOR(name_, op, fn) \ namespace operators { \ @@ -324,31 +317,29 @@ namespace luabind { return 0; \ } - template - std::string tostring_operator(T const& x) - { + template + std::string tostring_operator(T const& x) + { #ifdef LUABIND_NO_STRINGSTREAM - std::strstream s; - s << x << std::ends; + std::strstream s; + s << x << std::ends; #else - std::stringstream s; - s << x; + std::stringstream s; + s << x; #endif - return s.str(); - } - - LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) - LUABIND_UNARY_OPERATOR(unm, -, operator-) + return s.str(); + } -#undef LUABIND_BINARY_OPERATOR + LUABIND_UNARY_OPERATOR(tostring, tostring_operator, tostring) + LUABIND_UNARY_OPERATOR(unm, -, operator-) - namespace { +#undef LUABIND_UNARY_OPERATOR + + + extern LUABIND_API self_type self; + extern LUABIND_API const_self_type const_self; - LUABIND_ANONYMOUS_FIX self_type self; - LUABIND_ANONYMOUS_FIX const_self_type const_self; - } // namespace unnamed - } // namespace luabind #endif // OPERATOR_040729_HPP diff --git a/libs/luabind/luabind/out_value_policy.hpp b/libs/luabind/luabind/out_value_policy.hpp index ca496b527..5fb5ada33 100644 --- a/libs/luabind/luabind/out_value_policy.hpp +++ b/libs/luabind/luabind/out_value_policy.hpp @@ -25,255 +25,247 @@ #define LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED #include -#include -#include +#include // for find_conversion_policy, etc +#include // for decorated_type +#include // for by_pointer, by_reference, etc +#include // for is_nonconst_pointer, is_nonconst_reference, etc +#include // for operator new -namespace luabind { namespace detail -{ - template - struct char_array - { - char storage[N]; - }; +namespace luabind { + namespace detail { -#if defined(__GNUC__) && ( __GNUC__ == 3 && __GNUC_MINOR__ == 1 ) - - template - char_array indirect_sizeof_test(by_reference); - - template - char_array indirect_sizeof_test(by_const_reference); - - template - char_array indirect_sizeof_test(by_pointer); - - template - char_array indirect_sizeof_test(by_const_pointer); - - template - char_array indirect_sizeof_test(by_value); - -#else - - template - char_array::type)> indirect_sizeof_test(by_reference); - - template - char_array::type)> indirect_sizeof_test(by_const_reference); - - template - char_array::type)> indirect_sizeof_test(by_pointer); - - template - char_array::type)> indirect_sizeof_test(by_const_pointer); - - template - char_array::type)> indirect_sizeof_test(by_value); - -#endif - - template - struct indirect_sizeof - { - BOOST_STATIC_CONSTANT(int, value = sizeof(indirect_sizeof_test(LUABIND_DECORATE_TYPE(T)))); - }; - - namespace mpl = boost::mpl; - - template - struct out_value_converter - { - int const consumed_args(...) - { - return 1; - } - - template - T& apply(lua_State* L, by_reference, int index) + template + struct char_array { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return *reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_reference, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - new (m_storage) T(converter.apply(L, LUABIND_DECORATE_TYPE(T), index)); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State* L, by_pointer, int index) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typedef typename mpl::apply_wrap2::type converter; - return converter::match(L, LUABIND_DECORATE_TYPE(T), index); - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<2, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - char m_storage[Size]; - }; - - template - struct out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; + char storage[N]; }; - }; - template - struct pure_out_value_converter - { - int const consumed_args(...) - { - return 0; - } + template + char_array::type)> indirect_sizeof_test(by_reference); - template - T& apply(lua_State*, by_reference, int) - { - new (m_storage) T(); - return *reinterpret_cast(m_storage); - } + template + char_array::type)> indirect_sizeof_test(by_const_reference); + + template + char_array::type)> indirect_sizeof_test(by_pointer); + + template + char_array::type)> indirect_sizeof_test(by_const_pointer); + + template + char_array::type)> indirect_sizeof_test(by_value); template - static int match(lua_State*, by_reference, int) + struct indirect_sizeof { - return 0; - } - - template - void converter_postcall(lua_State* L, by_reference, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - template - T* apply(lua_State*, by_pointer, int) - { - new (m_storage) T(); - return reinterpret_cast(m_storage); - } - - template - static int match(lua_State*, by_pointer, int) - { - return 0; - } - - template - void converter_postcall(lua_State* L, by_pointer, int) - { - typedef typename find_conversion_policy<1, Policies>::type converter_policy; - typename mpl::apply_wrap2::type converter; - converter.apply(L, *reinterpret_cast(m_storage)); - reinterpret_cast(m_storage)->~T(); - } - - - char m_storage[Size]; - }; - - template - struct pure_out_value_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - struct only_accepts_nonconst_references_or_pointers {}; - struct can_only_convert_from_lua_to_cpp {}; - - template - struct apply - { - typedef typename boost::mpl::if_ - , typename boost::mpl::if_, is_nonconst_pointer > - , pure_out_value_converter::value, Policies> - , only_accepts_nonconst_references_or_pointers - >::type - , can_only_convert_from_lua_to_cpp - >::type type; + static const int value = sizeof(indirect_sizeof_test(decorate_type_t())); }; - }; - -}} + + namespace out_value_detail { + + template< int Size > + struct temporary_storage_size { + + template< typename T, typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + template + T& get() { + return *reinterpret_cast(&m_storage); + } + + template + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + template + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + template< typename T > + struct temporary_storage_type { + + template< typename... Args > + void construct(Args&&... args) + { + new (&m_storage) T(std::forward(args)...); + } + + T& get() { + return *reinterpret_cast(&m_storage); + } + + const T& get() const { + return *reinterpret_cast(&m_storage); + } + + void destroy() + { + get().~T(); + } + + typename std::aligned_storage::type m_storage; + + }; + + } + + // See note in out_value_policy about why we're not templating + // for the parameter type. + template + struct out_value_converter + { + enum { consumed_args = 1 }; + + T& to_cpp(lua_State* L, by_reference, int index) + { + //specialized_converter_policy_n<1, Policies, T, lua_to_cpp> converter; + storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); + return storage_.get(); + } + + int match(lua_State* L, by_reference, int index) + { + return converter_.match(L, decorate_type_t(), index); + } + + void converter_postcall(lua_State* L, by_reference, int) + { + //specialized_converter_policy_n<2,Policies,T,cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); + } + + T* to_cpp(lua_State* L, by_pointer, int index) + { + storage_.construct(converter_.to_cpp(L, decorate_type_t(), index)); + return &storage_.get(); + } + + int match(lua_State* L, by_pointer, int index) + { + return converter_.match(L, decorate_type_t(), index); + } + + void converter_postcall(lua_State* L, by_pointer, int) + { + //specialized_converter_policy_n<2, Policies, T, cpp_to_lua> converter; + converter_.to_lua(L, storage_.get()); + storage_.destroy(); + } + + private: + specialized_converter_policy_n<1, Policies, T, lua_to_cpp > converter_; + out_value_detail::temporary_storage_type storage_; + }; + + template + struct out_value_policy + { + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, lua_to_cpp >::value, "Out value policy can only convert from lua to cpp"); + static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Out value policy only accepts non const references or pointers"); + + // Note to myself: + // Using the size and template members instead of a policy templated for the type seems + // to be done to tame template bloat. Need to check if this is worth is. + using base_type = typename std::remove_pointer< typename std::remove_reference< T >::type >::type; + using type = out_value_converter; + }; + }; + + template + struct pure_out_value_converter + { + enum { consumed_args = 0 }; + + template + T& to_cpp(lua_State*, by_reference, int) + { + storage_.decltype(storage_)::template construct(); + return storage_.template get(); + } + + template + static int match(lua_State*, by_reference, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_reference, int) + { + specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; + converter.to_lua(L, storage_.template get()); + storage_.template destroy(); + } + + template + T* to_cpp(lua_State*, by_pointer, int) + { + storage_.decltype(storage_)::template construct(); + return &storage_.template get(); + } + + template + static int match(lua_State*, by_pointer, int) + { + return 0; + } + + template + void converter_postcall(lua_State* L, by_pointer, int) + { + specialized_converter_policy_n<1, Policies, T, cpp_to_lua> converter; + converter.to_lua(L, storage_.template get()); + storage_.template destroy(); + } + + private: + out_value_detail::temporary_storage_size storage_; + }; + + template + struct pure_out_value_policy + { + struct only_accepts_nonconst_references_or_pointers {}; + struct can_only_convert_from_lua_to_cpp {}; + + template + struct specialize + { + static_assert(std::is_same< Direction, lua_to_cpp >::value, "Pure out value policy can only convert from lua to cpp"); + static_assert(meta::or_< is_nonconst_reference, is_nonconst_pointer >::value, "Pure out value policy only accepts non const references or pointers"); + + using type = pure_out_value_converter::value, Policies>; + }; + }; + + } +} namespace luabind { - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } + template + using out_value = meta::type_list>>; - template - detail::policy_cons, detail::null_type> - out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); - } - - template - detail::policy_cons, detail::null_type> - pure_out_value(LUABIND_PLACEHOLDER_ARG(N), const Policies&) - { - return detail::policy_cons, detail::null_type>(); - } + template + using pure_out_value = meta::type_list>>; } #endif // LUABIND_OUT_VALUE_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/pointer_traits.hpp b/libs/luabind/luabind/pointer_traits.hpp new file mode 100644 index 000000000..899d40f74 --- /dev/null +++ b/libs/luabind/luabind/pointer_traits.hpp @@ -0,0 +1,148 @@ +// Copyright (c) 2005 Daniel Wallin + +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef LUABIND_GET_POINTER_051023_HPP +# define LUABIND_GET_POINTER_051023_HPP +#include +#include + +// TODO: Rename to pointer_traits + +namespace luabind { + + template + T* get_pointer(T* pointer) + { + return pointer; + } + + template + T* get_pointer(const std::unique_ptr& pointer) + { + return pointer.get(); + } + + template + T* get_pointer(const std::shared_ptr& pointer) + { + return pointer.get(); + } + + + namespace detail { + + template + struct pointer_traits { + enum { is_pointer = false }; + }; + + template + struct pointer_traits + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + struct pointer_traits> + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + struct pointer_traits> + { + enum { is_pointer = true }; + using value_type = T; + }; + + template + using is_pointer_to_const = std::is_const< typename pointer_traits::value_type >; + + template + void release_ownership(std::unique_ptr& p) + { + p.release(); + } + + template + void release_ownership(P const&) + { + throw std::runtime_error( + "luabind: smart pointer does not allow ownership transfer"); + } + + namespace has_get_pointer_ + { + + struct any + { + template any(T const&); + }; + + struct no_overload_tag + {}; + + typedef char(&yes)[1]; + typedef char(&no)[2]; + + no_overload_tag operator, (no_overload_tag, int); + + template + T* get_pointer(T const volatile*); + + template + T* get_pointer(std::unique_ptr const&); + + template + T* get_pointer(std::shared_ptr const&); + + detail::has_get_pointer_::no_overload_tag + get_pointer(detail::has_get_pointer_::any); + + ///@TODO: Rework + template + yes check(T const&); + no check(no_overload_tag); + + template + struct impl + { + static typename std::add_lvalue_reference::type x; + static const bool value = (sizeof(has_get_pointer_::check((get_pointer(x), 0))) == 1); + typedef std::integral_constant type; + }; + + } // namespace has_get_pointer_ + + template + struct has_get_pointer + : has_get_pointer_::impl::type + {}; + + } // namespace detail + +} // namespace luabind + +#endif // LUABIND_GET_POINTER_051023_HPP + diff --git a/libs/luabind/luabind/raw_policy.hpp b/libs/luabind/luabind/raw_policy.hpp index 6d22da246..ad3ecbfc1 100644 --- a/libs/luabind/luabind/raw_policy.hpp +++ b/libs/luabind/luabind/raw_policy.hpp @@ -27,58 +27,40 @@ #include #include -namespace luabind { namespace detail { - - struct raw_converter - { - int const consumed_args(...) - { - return 0; - } - - lua_State* apply(lua_State* L, by_pointer, int) - { - return L; - } - - static int match(...) - { - return 0; - } - - void converter_postcall(lua_State*, by_pointer, int) {} - }; - - template - struct raw_policy : conversion_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - - template - struct apply - { - typedef raw_converter type; - }; - }; - -}} // namespace luabind::detail - namespace luabind { + namespace detail { + + struct raw_converter + { + enum { consumed_args = 0 }; + + lua_State* to_cpp(lua_State* L, by_pointer, int) + { + return L; + } + + static int match(...) + { + return 0; + } + + void converter_postcall(lua_State*, by_pointer, int) {} + }; + + struct raw_policy + { + template + struct specialize + { + using type = raw_converter; + }; + }; - template - detail::policy_cons< - detail::raw_policy - , detail::null_type - > - inline raw(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons< - detail::raw_policy - , detail::null_type - >(); } + template + using raw_policy = meta::type_list< converter_policy_injector< N, detail::raw_policy > >(); + } // namespace luabind #endif // LUABIND_RAW_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/return_reference_to_policy.hpp b/libs/luabind/luabind/return_reference_to_policy.hpp index 1432f79e0..e9e8846bf 100644 --- a/libs/luabind/luabind/return_reference_to_policy.hpp +++ b/libs/luabind/luabind/return_reference_to_policy.hpp @@ -23,50 +23,49 @@ #ifndef LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED #define LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED -namespace luabind { namespace detail -{ - template - struct return_reference_to_converter; +#include // for index_map, policy_cons, etc +#include // for lua_State, lua_pushnil, etc + +namespace luabind { + namespace detail { + + struct cpp_to_lua; - template<> - struct return_reference_to_converter - { template - void apply(lua_State* L, const T&) - { - lua_pushnil(L); - } - }; + struct return_reference_to_converter; - template - struct return_reference_to_policy : conversion_policy<0> - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State* L, const index_map& indices) + template<> + struct return_reference_to_converter { - int result_index = indices[0]; - int ref_to_index = indices[N]; - - lua_pushvalue(L, ref_to_index); - lua_replace(L, result_index); - } - - template - struct apply - { - typedef return_reference_to_converter type; + template + void to_lua(lua_State* L, const T&) + { + lua_pushnil(L); + } + }; + + template< unsigned int N > + struct return_reference_to_policy : detail::converter_policy_has_postcall_tag + { + template + static void postcall(lua_State* L, int results, StackIndexList) + { + lua_pushvalue(L, (meta::get::value)); + lua_replace(L, (meta::get::value + results)); + } + + template + struct specialize + { + using type = return_reference_to_converter; + }; }; - }; -}} -namespace luabind -{ - template - detail::policy_cons, detail::null_type> - return_reference_to(LUABIND_PLACEHOLDER_ARG(N)) - { - return detail::policy_cons, detail::null_type>(); } + + template + using return_reference_to = meta::type_list>>; + } #endif // LUABIND_RETURN_REFERENCE_TO_POLICY_HPP_INCLUDED diff --git a/libs/luabind/luabind/scope.hpp b/libs/luabind/luabind/scope.hpp index 3b5f293bf..ff0237f4a 100644 --- a/libs/luabind/luabind/scope.hpp +++ b/libs/luabind/luabind/scope.hpp @@ -25,77 +25,79 @@ #include #include -#include +#include #include -namespace luabind { - - struct scope; - -} // namespace luabind - -namespace luabind { namespace detail { - - struct LUABIND_API registration - { - registration(); - virtual ~registration(); - - protected: - virtual void register_(lua_State*) const = 0; - - private: - friend struct ::luabind::scope; - registration* m_next; - }; - -}} // namespace luabind::detail - namespace luabind { - struct LUABIND_API scope - { - scope(); - explicit scope(std::auto_ptr reg); - scope(scope const& other_); - ~scope(); + struct scope; - scope& operator=(scope const& other_); +} // namespace luabind - scope& operator,(scope s); +namespace luabind { + namespace detail { - void register_(lua_State* L) const; + struct LUABIND_API registration + { + registration(); + virtual ~registration(); - private: - detail::registration* m_chain; - }; + protected: + virtual void register_(lua_State*) const = 0; - class LUABIND_API namespace_ : public scope - { - public: - explicit namespace_(char const* name); - namespace_& operator[](scope s); + private: + friend struct ::luabind::scope; + registration* m_next; + }; - private: - struct registration_; - registration_* m_registration; - }; + } +} // namespace luabind::detail - class LUABIND_API module_ - { - public: - module_(lua_State* L_, char const* name); - void operator[](scope s); +namespace luabind { - private: - lua_State* m_state; - char const* m_name; - }; + struct LUABIND_API scope + { + scope(); + explicit scope(std::unique_ptr reg); + scope(scope const& other_); + ~scope(); - inline module_ module(lua_State* L, char const* name = 0) - { - return module_(L, name); - } + scope& operator=(scope const& other_); + + scope& operator,(scope s); + + void register_(lua_State* L) const; + + private: + detail::registration* m_chain; + }; + + class LUABIND_API namespace_ : public scope + { + public: + explicit namespace_(char const* name); + namespace_& operator[](scope s); + + private: + struct registration_; + registration_* m_registration; + }; + + class LUABIND_API module_ + { + public: + module_(lua_State* L_, char const* name); + void operator[](scope s); + + private: + lua_State* m_state; + char const* m_name; + }; + + inline module_ module(lua_State* L, char const* name = 0) + { + return module_(L, name); + } } // namespace luabind diff --git a/libs/luabind/luabind/lua502.hpp b/libs/luabind/luabind/set_package_preload.hpp similarity index 56% rename from libs/luabind/luabind/lua502.hpp rename to libs/luabind/luabind/set_package_preload.hpp index 5006128ec..3ea227359 100644 --- a/libs/luabind/luabind/lua502.hpp +++ b/libs/luabind/luabind/set_package_preload.hpp @@ -1,5 +1,17 @@ -// Copyright (c) 2004 Daniel Wallin and Arvid Norberg +/** @file + @brief Header + @date 2012 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2012. // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation @@ -20,37 +32,23 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef LUA_502_HPP -#define LUA_502_HPP +#ifndef INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e +#define INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e -#if LUA_VERSION_NUM >= 502 +// Internal Includes +#include +#include -inline LUA_API int lua_equal(lua_State *L, int idx1, int idx2) -{ - return lua_compare(L, idx1, idx2, LUA_OPEQ); +// Library/third-party includes +// - none + +// Standard includes +// - none + + +namespace luabind { + + LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)); } +#endif // INCLUDED_set_package_preload_hpp_GUID_563c882e_86f7_4ea7_8603_4594ea41737e -inline LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) -{ - return lua_compare(L, idx1, idx2, LUA_OPLT); -} - -#undef lua_strlen -#define lua_strlen lua_rawlen - -#undef lua_getfenv -#define lua_getfenv lua_getuservalue - -#undef lua_setfenv -#define lua_setfenv lua_setuservalue - -#undef lua_open -#define lua_open luaL_newstate - -#else // LUA_VERSION_NUM >= 502 - -#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) - -#endif // LUA_VERSION_NUM >= 502 - -#endif \ No newline at end of file diff --git a/libs/luabind/luabind/shared_ptr_converter.hpp b/libs/luabind/luabind/shared_ptr_converter.hpp index 2f61b5cff..d5c0d50e6 100644 --- a/libs/luabind/luabind/shared_ptr_converter.hpp +++ b/libs/luabind/luabind/shared_ptr_converter.hpp @@ -5,79 +5,79 @@ #ifndef LUABIND_SHARED_PTR_CONVERTER_090211_HPP # define LUABIND_SHARED_PTR_CONVERTER_090211_HPP -# include -# include -# include -# include +#include +#include // for default_converter, etc +#include // for get_main_thread +#include // for handle +#include // for decorated_type +#include namespace luabind { -namespace detail -{ + namespace detail + { - struct shared_ptr_deleter - { - shared_ptr_deleter(lua_State* L, int index) - : life_support(get_main_thread(L), L, index) - {} + struct shared_ptr_deleter + { + shared_ptr_deleter(lua_State* L, int index) + : life_support(get_main_thread(L), L, index) + {} - void operator()(void const*) - { - handle().swap(life_support); - } + void operator()(void const*) + { + handle().swap(life_support); + } - handle life_support; - }; + handle life_support; + }; -} // namespace detail + } // namespace detail -template -struct default_converter > - : default_converter -{ - typedef boost::mpl::false_ is_native; + template + struct default_converter > + : default_converter + { + using is_native = std::false_type; - template - int match(lua_State* L, U, int index) - { - return default_converter::match( - L, LUABIND_DECORATE_TYPE(T*), index); - } + template + int match(lua_State* L, U, int index) + { + return default_converter::match(L, decorate_type_t(), index); + } - template - boost::shared_ptr apply(lua_State* L, U, int index) - { - T* raw_ptr = default_converter::apply( - L, LUABIND_DECORATE_TYPE(T*), index); - if (!raw_ptr) - return boost::shared_ptr(); - return boost::shared_ptr( - raw_ptr, detail::shared_ptr_deleter(L, index)); - } + template + std::shared_ptr to_cpp(lua_State* L, U, int index) + { + T* raw_ptr = default_converter::to_cpp(L, decorate_type_t(), index); - void apply(lua_State* L, boost::shared_ptr const& p) - { - if (detail::shared_ptr_deleter* d = - boost::get_deleter(p)) - { - d->life_support.push(L); - } - else - { - detail::value_converter().apply(L, p); - } - } + if(!raw_ptr) { + return std::shared_ptr(); + } else { + return std::shared_ptr(raw_ptr, detail::shared_ptr_deleter(L, index)); + } + } - template - void converter_postcall(lua_State*, U const&, int) - {} -}; + void to_lua(lua_State* L, std::shared_ptr const& p) + { + if(detail::shared_ptr_deleter* d = std::get_deleter(p)) + { + d->life_support.push(L); + } else { + detail::value_converter().to_lua(L, p); + } + } -template -struct default_converter const&> - : default_converter > -{}; + template + void converter_postcall(lua_State*, U const&, int) + {} + }; + + template + struct default_converter const&> + : default_converter > + {}; } // namespace luabind #endif // LUABIND_SHARED_PTR_CONVERTER_090211_HPP + diff --git a/libs/luabind/luabind/tag_function.hpp b/libs/luabind/luabind/tag_function.hpp index 51fe97b75..ba8382ee5 100644 --- a/libs/luabind/luabind/tag_function.hpp +++ b/libs/luabind/luabind/tag_function.hpp @@ -2,87 +2,62 @@ // subject to the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#if !BOOST_PP_IS_ITERATING +#ifndef LUABIND_TAG_FUNCTION_081129_HPP +#define LUABIND_TAG_FUNCTION_081129_HPP -# ifndef LUABIND_TAG_FUNCTION_081129_HPP -# define LUABIND_TAG_FUNCTION_081129_HPP - -# if LUABIND_MAX_ARITY <= 8 -# include -# else -# include -# endif -# include -# include -# include -# include +#include +#include +#include namespace luabind { -namespace detail -{ + template + struct tagged_function + { + tagged_function(F f) + : f(f) + {} - template - struct tagged_function - { - tagged_function(F f) - : f(f) - {} + F f; + }; - F f; - }; + namespace detail + { - template - Signature deduce_signature(tagged_function const&, ...) - { - return Signature(); - } + struct invoke_context; + struct function_object; - template - int invoke( - lua_State* L, function_object const& self, invoke_context& ctx - , tagged_function const& tagged - , Signature, Policies const& policies) - { - return invoke(L, self, ctx, tagged.f, Signature(), policies); - } +#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS + template + int invoke( + lua_State* L, function_object const& self, invoke_context& ctx + // std::bind operator() is nonconst... is that fixable? + , tagged_function /*const*/& tagged + , Signature, meta::type_list const& injectors) + { + return invoke(L, self, ctx, tagged.f, Signature(), injectors); + } +#else + //template< typename PolicyList, typename Signature, typename F> + //inline int invoke(lua_State* L, function_object const& self, invoke_context& ctx, F& f) - template - struct signature_from_function; + template < typename PolicyList, typename Signature, typename F > + int invoke(lua_State* L, function_object const& self, invoke_context& ctx, tagged_function /*const*/& tagged) + { + return invoke(L, self, ctx, tagged.f); + } +#endif -# define BOOST_PP_ITERATION_PARAMS_1 \ - (3, (0, LUABIND_MAX_ARITY, )) -# include BOOST_PP_ITERATE() + } // namespace detail -} // namespace detail - -template -detail::tagged_function< - typename detail::signature_from_function::type - , F -> -tag_function(F f) -{ - return f; -} + template + tagged_function, F > + tag_function(F f) + { + return f; + } } // namespace luabind # endif // LUABIND_TAG_FUNCTION_081129_HPP -#else // BOOST_PP_IS_ITERATING - -# define N BOOST_PP_ITERATION() -# define NPLUS1 BOOST_PP_INC(N) - -template -struct signature_from_function -{ - typedef BOOST_PP_CAT(mpl::vector, NPLUS1)< - R BOOST_PP_ENUM_TRAILING_PARAMS(N, A) - > type; -}; - -#endif // BOOST_PP_IS_ITERATING - - diff --git a/libs/luabind/luabind/typeid.hpp b/libs/luabind/luabind/typeid.hpp index d92d8fbac..9f8161bd3 100644 --- a/libs/luabind/luabind/typeid.hpp +++ b/libs/luabind/luabind/typeid.hpp @@ -5,59 +5,50 @@ #ifndef LUABIND_TYPEID_081227_HPP # define LUABIND_TYPEID_081227_HPP -# include # include -# include +# include namespace luabind { -# ifdef BOOST_MSVC -# pragma warning(push) -// std::type_info::before() returns int, rather than bool. -// At least on MSVC7.1, this is true for the comparison -// operators as well. -# pragma warning(disable:4800) -# endif + class type_id + { + public: + type_id() + : id(&typeid(null_type)) + {} -class type_id - : public boost::less_than_comparable -{ -public: - type_id() - : id(&typeid(detail::null_type)) - {} + type_id(std::type_info const& id) + : id(&id) + {} - type_id(std::type_info const& id) - : id(&id) - {} + bool operator!=(type_id const& other) const + { + return *id != *other.id; + } - bool operator!=(type_id const& other) const - { - return *id != *other.id; - } + bool operator==(type_id const& other) const + { + return *id == *other.id; + } - bool operator==(type_id const& other) const - { - return *id == *other.id; - } + bool operator<(type_id const& other) const + { + return id->before(*other.id); + } - bool operator<(type_id const& other) const - { - return id->before(*other.id); - } + size_t hash_code() const + { + return id->hash_code(); + } - char const* name() const - { - return id->name(); - } + char const* name() const + { + return id->name(); + } -private: - std::type_info const* id; -}; - -# ifdef BOOST_MSVC -# pragma warning(pop) -# endif + private: + std::type_info const* id; + }; } // namespace luabind diff --git a/libs/luabind/luabind/value_wrapper.hpp b/libs/luabind/luabind/value_wrapper.hpp deleted file mode 100644 index 8e09395d5..000000000 --- a/libs/luabind/luabind/value_wrapper.hpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) 2005 Daniel Wallin and Arvid Norberg - -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE -// OR OTHER DEALINGS IN THE SOFTWARE. - -#ifndef LUABIND_VALUE_WRAPPER_050419_HPP -#define LUABIND_VALUE_WRAPPER_050419_HPP - -#include -#include -#include - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -# define LUABIND_USE_VALUE_WRAPPER_TAG -#else -#endif - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -namespace luabind { - -// -// Concept ``ValueWrapper`` -// - -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG -template -struct value_wrapper_traits; - -namespace detail -{ - - BOOST_MPL_HAS_XXX_TRAIT_DEF(value_wrapper_tag); - - struct unspecialized_value_wrapper_traits - { - typedef boost::mpl::false_ is_specialized; - }; - - template - struct value_wrapper_traits_aux - { - typedef value_wrapper_traits type; - }; - -} // namespace detail -#endif - -template -struct value_wrapper_traits -#ifdef LUABIND_USE_VALUE_WRAPPER_TAG - : boost::mpl::eval_if< - boost::mpl::and_< - boost::mpl::not_< - boost::mpl::or_< - boost::is_reference - , boost::is_pointer - , boost::is_array - > - > - , detail::has_value_wrapper_tag - > - , detail::value_wrapper_traits_aux - , boost::mpl::identity - >::type -{}; -#else -{ - typedef boost::mpl::false_ is_specialized; -}; -#endif - -template -struct is_value_wrapper - : boost::mpl::aux::msvc_eti_base< - typename value_wrapper_traits::is_specialized - >::type -{}; - -} // namespace luabind - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -# include -# include - -namespace luabind { - -template -struct is_value_wrapper_arg - : is_value_wrapper< - typename boost::remove_const< - typename boost::remove_reference::type - >::type - > -{}; - -} // namespace luabind - -#else - -# include -# include - -namespace luabind { - -namespace detail -{ - template - typename is_value_wrapper::type is_value_wrapper_arg_check(T const*); - - yes_t to_yesno(boost::mpl::true_); - no_t to_yesno(boost::mpl::false_); - - template - struct is_value_wrapper_arg_aux - { - static typename boost::add_reference::type x; - - BOOST_STATIC_CONSTANT(bool, value = - sizeof(to_yesno(is_value_wrapper_arg_check(&x))) - == sizeof(yes_t) - ); - - typedef boost::mpl::bool_ type; - }; - -} // namespace detail - -template -struct is_value_wrapper_arg - : detail::is_value_wrapper_arg_aux::type -{ -}; - -} // namespace luabind - -#endif - -#endif // LUABIND_VALUE_WRAPPER_050419_HPP - diff --git a/libs/luabind/luabind/version.hpp b/libs/luabind/luabind/version.hpp index 63acaf765..89625ac5b 100644 --- a/libs/luabind/luabind/version.hpp +++ b/libs/luabind/luabind/version.hpp @@ -14,3 +14,4 @@ // patch = LUABIND_VERSION % 100 #endif // LUABIND_VERSION_090216_HPP + diff --git a/libs/luabind/luabind/weak_ref.hpp b/libs/luabind/luabind/weak_ref.hpp index e08e250dc..c7a2a32ce 100644 --- a/libs/luabind/luabind/weak_ref.hpp +++ b/libs/luabind/luabind/weak_ref.hpp @@ -25,33 +25,33 @@ #include -struct lua_State; +#include namespace luabind { - class LUABIND_API weak_ref - { - public: - weak_ref(); - weak_ref(lua_State* main, lua_State* L, int index); - weak_ref(weak_ref const&); - ~weak_ref(); + class LUABIND_API weak_ref + { + public: + weak_ref(); + weak_ref(lua_State* main, lua_State* L, int index); + weak_ref(weak_ref const&); + ~weak_ref(); - weak_ref& operator=(weak_ref const&); + weak_ref& operator=(weak_ref const&); - void swap(weak_ref&); + void swap(weak_ref&); // returns a unique id that no // other weak ref will return int id() const; - lua_State* state() const; - void get(lua_State* L) const; + lua_State* state() const; + void get(lua_State* L) const; - private: - struct impl; - impl* m_impl; - }; + private: + struct impl; + impl* m_impl; + }; } // namespace luabind diff --git a/libs/luabind/luabind/wrapper_base.hpp b/libs/luabind/luabind/wrapper_base.hpp index 9adc05a35..7845e12d3 100644 --- a/libs/luabind/luabind/wrapper_base.hpp +++ b/libs/luabind/luabind/wrapper_base.hpp @@ -20,19 +20,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#if !BOOST_PP_IS_ITERATING - #ifndef LUABIND_WRAPPER_BASE_HPP_INCLUDED #define LUABIND_WRAPPER_BASE_HPP_INCLUDED #include #include #include -#include - -#include -#include - +#include +#include #include namespace luabind @@ -48,9 +43,15 @@ namespace luabind // on the top of the stack (the input self reference will // be popped) LUABIND_API void do_call_member_selection(lua_State* L, char const* name); + + template, unsigned int... Indices, typename... Args> + R call_member_impl(lua_State* L, std::true_type /*void*/, meta::index_list, Args&&... args); + + template, unsigned int... Indices, typename... Args> + R call_member_impl(lua_State* L, std::false_type /*void*/, meta::index_list, Args&&... args); } - struct wrapped_self_t: weak_ref + struct wrapped_self_t : weak_ref { detail::lua_reference m_strong_ref; }; @@ -60,16 +61,41 @@ namespace luabind friend struct detail::wrap_access; wrap_base() {} - #define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 1)) - #include BOOST_PP_ITERATE() + template + R call(char const* name, Args&&... args) const + { + // this will be cleaned up by the proxy object + // once the call has been made + + // TODO: what happens if this virtual function is + // dispatched from a lua thread where the state + // pointer is different? + + // get the function + lua_State* L = m_self.state(); + m_self.get(L); + assert(!lua_isnil(L, -1)); + detail::do_call_member_selection(L, name); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + throw std::runtime_error("Attempt to call nonexistent function"); + } + + // push the self reference as the first parameter + m_self.get(L); + + // now the function and self objects + // are on the stack. These will both + // be popped by pcall + return detail::call_member_impl(L, std::is_void(), meta::index_range<1, sizeof...(Args)+1>(), std::forward(args)...); + } private: wrapped_self_t m_self; }; -#define BOOST_PP_ITERATION_PARAMS_1 (4, (0, LUABIND_MAX_ARITY, , 2)) -#include BOOST_PP_ITERATE() - namespace detail { struct wrap_access @@ -89,104 +115,3 @@ namespace luabind #endif // LUABIND_WRAPPER_BASE_HPP_INCLUDED -#else -#if BOOST_PP_ITERATION_FLAGS() == 1 - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template - typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type - call(char const* name BOOST_PP_COMMA_IF(BOOST_PP_ITERATION()) BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_OPERATOR_PARAMS, _), detail::type_* = 0) const - { - typedef boost::tuples::tuple tuple_t; - #if BOOST_PP_ITERATION() == 0 - tuple_t args; - #else - tuple_t args(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), &a)); - #endif - - typedef typename boost::mpl::if_ - , luabind::detail::proxy_member_void_caller > - , luabind::detail::proxy_member_caller > >::type proxy_type; - - // this will be cleaned up by the proxy object - // once the call has been made - - // TODO: what happens if this virtual function is - // dispatched from a lua thread where the state - // pointer is different? - - // get the function - lua_State* L = m_self.state(); - m_self.get(L); - assert(!lua_isnil(L, -1)); - detail::do_call_member_selection(L, name); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - throw std::runtime_error("Attempt to call nonexistent function"); - } - - // push the self reference as the first parameter - m_self.get(L); - - // now the function and self objects - // are on the stack. These will both - // be popped by pcall - return proxy_type(L, args); - } - -#undef LUABIND_CALL_MEMBER_NAME -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#else // free call_member forwardarding functions - -#define N BOOST_PP_ITERATION() - -#define LUABIND_TUPLE_PARAMS(z, n, data) const A##n * -#define LUABIND_OPERATOR_PARAMS(z, n, data) const A##n & a##n - - template< - class R - BOOST_PP_ENUM_TRAILING_PARAMS(N, class A) - > - typename boost::mpl::if_< - boost::is_void - , detail::proxy_member_void_caller< - boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - , detail::proxy_member_caller< - R - , boost::tuples::tuple< - BOOST_PP_ENUM(N, LUABIND_TUPLE_PARAMS, _) - > - > - >::type - call_member( - wrap_base const* self - , char const* fn - BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(N, A, &a) - , detail::type_* = 0 - ) - { - return self->call( - fn - BOOST_PP_ENUM_TRAILING_PARAMS(N, a) - , (detail::type_*)0 - ); - } - -#undef LUABIND_OPERATOR_PARAMS -#undef LUABIND_TUPLE_PARAMS - -#undef N - -#endif -#endif \ No newline at end of file diff --git a/libs/luabind/luabind/yield_policy.hpp b/libs/luabind/luabind/yield_policy.hpp index 9dbbefa29..5622b62a3 100644 --- a/libs/luabind/luabind/yield_policy.hpp +++ b/libs/luabind/luabind/yield_policy.hpp @@ -27,40 +27,18 @@ #include #include -namespace luabind { namespace detail -{ - struct yield_policy - { - static void precall(lua_State*, const index_map&) {} - static void postcall(lua_State*, const index_map&) {} - }; +namespace luabind { - template - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, - value = (boost::is_same::value || - has_yield::value)); - }; + namespace detail { - template<> - struct has_yield - { - BOOST_STATIC_CONSTANT(bool, value = false); - }; -}} + struct yield_policy + { + static void postcall(lua_State*, int /*results*/, meta::index_list_tag) {} + }; -namespace luabind -{ - detail::policy_cons const yield = {}; + } - namespace detail - { - inline void ignore_unused_yield() - { - (void)yield; - } - } + using yield = policy_list>; } #endif // LUABIND_YIELD_POLICY_HPP_INCLUDED diff --git a/libs/luabind/src/CMakeLists.txt b/libs/luabind/src/CMakeLists.txt new file mode 100644 index 000000000..a839fb65a --- /dev/null +++ b/libs/luabind/src/CMakeLists.txt @@ -0,0 +1,182 @@ +# Build for LuaBind +# Ryan Pavlik +# http://academic.cleardefinition.com/ +# Iowa State University HCI Graduate Program/VRAC + +set(LUABIND_SRCS + class.cpp + class_info.cpp + class_registry.cpp + class_rep.cpp + create_class.cpp + error.cpp + exception_handler.cpp + function.cpp + function_introspection.cpp + inheritance.cpp + link_compatibility.cpp + object_rep.cpp + open.cpp + operator.cpp + pcall.cpp + scope.cpp + set_package_preload.cpp + stack_content_by_name.cpp + weak_ref.cpp + wrapper_base.cpp) + +set(LUABIND_API + ../luabind/back_reference_fwd.hpp + ../luabind/back_reference.hpp + ../luabind/class.hpp + ../luabind/class_info.hpp + ../luabind/config.hpp + ../luabind/error.hpp + ../luabind/error_callback_fun.hpp + ../luabind/exception_handler.hpp + ../luabind/from_stack.hpp + ../luabind/function.hpp + ../luabind/function_introspection.hpp + ../luabind/get_main_thread.hpp + ../luabind/pointer_traits.hpp + ../luabind/handle.hpp + ../luabind/luabind.hpp + ../luabind/lua_argument_proxy.hpp + ../luabind/lua_include.hpp + ../luabind/lua_index_proxy.hpp + ../luabind/lua_iterator_proxy.hpp + ../luabind/lua_proxy_interface.hpp + ../luabind/lua_state_fwd.hpp + ../luabind/make_function.hpp + ../luabind/nil.hpp + ../luabind/object.hpp + ../luabind/open.hpp + ../luabind/operator.hpp + ../luabind/prefix.hpp + ../luabind/scope.hpp + ../luabind/set_package_preload.hpp + ../luabind/shared_ptr_converter.hpp + ../luabind/tag_function.hpp + ../luabind/typeid.hpp + ../luabind/lua_proxy.hpp + ../luabind/version.hpp + ../luabind/weak_ref.hpp + ../luabind/wrapper_base.hpp +) +source_group(API FILES ${LUABIND_API}) + +set(LUABIND_DETAIL_API + ../luabind/detail/meta.hpp + ../luabind/detail/call_traits.hpp + ../luabind/detail/call_shared.hpp + ../luabind/detail/crtp_iterator.hpp + ../luabind/detail/call_function.hpp + ../luabind/detail/call.hpp + ../luabind/detail/call_member.hpp + ../luabind/detail/class_registry.hpp + ../luabind/detail/class_rep.hpp + ../luabind/detail/constructor.hpp + ../luabind/detail/conversion_storage.hpp + ../luabind/detail/push_to_lua.hpp + ../luabind/detail/debug.hpp + ../luabind/detail/decorate_type.hpp + ../luabind/detail/deduce_signature.hpp + ../luabind/detail/enum_maker.hpp + ../luabind/detail/format_signature.hpp + ../luabind/detail/garbage_collector.hpp + ../luabind/detail/inheritance.hpp + ../luabind/detail/instance_holder.hpp + ../luabind/detail/link_compatibility.hpp + ../luabind/detail/make_instance.hpp + ../luabind/detail/object.hpp + ../luabind/detail/object_rep.hpp + ../luabind/detail/open.hpp + ../luabind/detail/operator_id.hpp + ../luabind/detail/other.hpp + ../luabind/detail/pcall.hpp + ../luabind/detail/policy.hpp + ../luabind/detail/primitives.hpp + ../luabind/detail/property.hpp + ../luabind/detail/ref.hpp + ../luabind/detail/signature_match.hpp + ../luabind/detail/stack_utils.hpp + ../luabind/detail/type_traits.hpp +) +source_group(Internal FILES ${LUABIND_DETAIL_API}) + +set(LUABIND_DEFAULT_POLICIES + ../luabind/detail/conversion_policies/pointer_converter.hpp + ../luabind/detail/conversion_policies/reference_converter.hpp + ../luabind/detail/conversion_policies/value_converter.hpp + ../luabind/detail/conversion_policies/enum_converter.hpp + ../luabind/detail/conversion_policies/function_converter.hpp + ../luabind/detail/conversion_policies/conversion_base.hpp + ../luabind/detail/conversion_policies/conversion_policies.hpp + ../luabind/detail/conversion_policies/lua_proxy_converter.hpp + ../luabind/detail/conversion_policies/native_converter.hpp + ) +source_group("Default Policies" FILES ${LUABIND_DEFAULT_POLICIES} ) + +set(LUABIND_USER_POLICIES + ../luabind/yield_policy.hpp + ../luabind/no_dependency.hpp + ../luabind/iterator_policy.hpp + ../luabind/container_policy.hpp + ../luabind/copy_policy.hpp + ../luabind/dependency_policy.hpp + ../luabind/discard_result_policy.hpp + ../luabind/adopt_policy.hpp + ../luabind/out_value_policy.hpp + ../luabind/return_reference_to_policy.hpp + ../luabind/raw_policy.hpp +) +source_group("User Policies" FILES ${LUABIND_USER_POLICIES} ) + +set(LUABIND_EXTRA_LIBS) +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") +elseif(CMAKE_COMPILER_IS_GNUCXX) + list(APPEND LUABIND_EXTRA_LIBS m) +endif() + +add_library(luabind ${LUABIND_SRCS} ${LUABIND_API} ${LUABIND_DETAIL_API} ${LUABIND_DEFAULT_POLICIES} ${LUABIND_USER_POLICIES}) +target_link_libraries(luabind ${LUA_LIBRARIES} ${LUABIND_EXTRA_LIBS}) + +set_property(TARGET luabind PROPERTY COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) +set_property(TARGET luabind PROPERTY PROJECT_LABEL "LuaBind Library") + +set(ALLHEADERS ${LUABIND_API} ${LUABIND_DETAIL_API} PARENT_SCOPE) +set(APIHEADERS ${LUABIND_API} PARENT_SCOPE) + +if(LUABIND_INSTALL) + if(NOT INCLUDE_DIR) + set(INCLUDE_DIR include) + endif() + if(NOT LIB_DIR) + set(LIB_DIR lib) + endif() + if(NOT ARCH_DIR) + set(ARCH_DIR lib) + endif() + if(NOT BIN_DIR) + set(BIN_DIR bin) + endif() + install(FILES ${LUABIND_API} + DESTINATION ${INCLUDE_DIR}/luabind + COMPONENT sdk) + install(FILES ${LUABIND_USER_POLICIES} + DESTINATION ${INCLUDE_DIR}/luabind + COMPONENT sdk) + install(FILES ${LUABIND_DETAIL_API} + DESTINATION ${INCLUDE_DIR}/luabind/detail + COMPONENT sdk) + install(FILES ${LUABIND_DEFAULT_POLICIES} + DESTINATION ${INCLUDE_DIR}/luabind/detail/conversion_policies + COMPONENT sdk) + install(TARGETS luabind + EXPORT luabind + RUNTIME DESTINATION ${BIN_DIR} COMPONENT runtime + LIBRARY DESTINATION ${LIB_DIR} COMPONENT runtime + ARCHIVE DESTINATION ${ARCH_DIR} COMPONENT sdk) +endif() + diff --git a/libs/luabind/src/class.cpp b/libs/luabind/src/class.cpp index 8a67cf6f3..ee772b643 100644 --- a/libs/luabind/src/class.cpp +++ b/libs/luabind/src/class.cpp @@ -22,316 +22,307 @@ #define LUABIND_BUILDING -#include - #include #include #include #include +#include #include #include -namespace luabind -{ - LUABIND_API detail::nil_type nil; -} +namespace luabind { + namespace detail { -namespace luabind { namespace detail { - - namespace - { - struct cast_entry - { - cast_entry(class_id src, class_id target, cast_function cast) - : src(src) - , target(target) - , cast(cast) - {} + namespace + { + struct cast_entry + { + cast_entry(class_id src, class_id target, cast_function cast) + : src(src) + , target(target) + , cast(cast) + {} - class_id src; - class_id target; - cast_function cast; - }; + class_id src; + class_id target; + cast_function cast; + }; - } // namespace unnamed + } // namespace unnamed - struct class_registration : registration - { - class_registration(char const* name); + struct class_registration : registration + { + class_registration(char const* name); - void register_(lua_State* L) const; + void register_(lua_State* L) const; - const char* m_name; + const char* m_name; - mutable std::map m_static_constants; + mutable std::map m_static_constants; - typedef std::pair base_desc; - mutable std::vector m_bases; + using base_desc = std::pair; + mutable std::vector m_bases; - type_id m_type; - class_id m_id; - class_id m_wrapper_id; - type_id m_wrapper_type; - std::vector m_casts; + type_id m_type; + class_id m_id; + class_id m_wrapper_id; + type_id m_wrapper_type; + std::vector m_casts; - scope m_scope; - scope m_members; - scope m_default_members; - }; - - class_registration::class_registration(char const* name) - { - m_name = name; - } - - void class_registration::register_(lua_State* L) const - { - LUABIND_CHECK_STACK(L); - - assert(lua_type(L, -1) == LUA_TTABLE); - - lua_pushstring(L, m_name); - - detail::class_rep* crep; - - detail::class_registry* r = detail::class_registry::get_registry(L); - // create a class_rep structure for this class. - // allocate it within lua to let lua collect it on - // lua_close(). This is better than allocating it - // as a static, since it will then be destructed - // when the program exits instead. - // warning: we assume that lua will not - // move the userdata memory. - lua_newuserdata(L, sizeof(detail::class_rep)); - crep = reinterpret_cast(lua_touserdata(L, -1)); - - new(crep) detail::class_rep( - m_type - , m_name - , L - ); - - // register this new type in the class registry - r->add_class(m_type, crep); - - lua_pushstring(L, "__luabind_class_map"); - lua_rawget(L, LUA_REGISTRYINDEX); - class_map& classes = *static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - classes.put(m_id, crep); - - bool const has_wrapper = m_wrapper_id != registered_class::id; - - if (has_wrapper) - classes.put(m_wrapper_id, crep); - - crep->m_static_constants.swap(m_static_constants); - - detail::class_registry* registry = detail::class_registry::get_registry(L); - - crep->get_default_table(L); - m_scope.register_(L); - m_default_members.register_(L); - lua_pop(L, 1); - - crep->get_table(L); - m_members.register_(L); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - cast_graph* const casts = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_id_map* const class_ids = static_cast( - lua_touserdata(L, -1)); - lua_pop(L, 1); - - class_ids->put(m_id, m_type); - - if (has_wrapper) - class_ids->put(m_wrapper_id, m_wrapper_type); - - BOOST_FOREACH(cast_entry const& e, m_casts) - { - casts->insert(e.src, e.target, e.cast); - } - - for (std::vector::iterator i = m_bases.begin(); - i != m_bases.end(); ++i) - { - LUABIND_CHECK_STACK(L); - - // the baseclass' class_rep structure - detail::class_rep* bcrep = registry->find_class(i->first); - - detail::class_rep::base_info base; - base.pointer_offset = 0; - base.base = bcrep; - - crep->add_base_class(base); - - // copy base class table - crep->get_table(L); - bcrep->get_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); - - // copy base class detaults table - crep->get_default_table(L); - bcrep->get_default_table(L); - lua_pushnil(L); - - while (lua_next(L, -2)) - { - lua_pushvalue(L, -2); // copy key - lua_gettable(L, -5); - - if (!lua_isnil(L, -1)) - { - lua_pop(L, 2); - continue; - } - - lua_pop(L, 1); - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - - lua_settable(L, -5); - } - lua_pop(L, 2); + scope m_scope; + scope m_members; + scope m_default_members; + }; + class_registration::class_registration(char const* name) + { + m_name = name; } - lua_settable(L, -3); - } - - // -- interface --------------------------------------------------------- + void class_registration::register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); - class_base::class_base(char const* name) - : scope(std::auto_ptr( - m_registration = new class_registration(name)) - ) - { - } + assert(lua_type(L, -1) == LUA_TTABLE); - void class_base::init( - type_id const& type_id_, class_id id - , type_id const& wrapper_type, class_id wrapper_id) - { - m_registration->m_type = type_id_; - m_registration->m_id = id; - m_registration->m_wrapper_type = wrapper_type; - m_registration->m_wrapper_id = wrapper_id; - } + lua_pushstring(L, m_name); - void class_base::add_base(type_id const& base, cast_function cast) - { - m_registration->m_bases.push_back(std::make_pair(base, cast)); - } + detail::class_rep* crep; + + detail::class_registry* r = detail::class_registry::get_registry(L); + // create a class_rep structure for this class. + // allocate it within lua to let lua collect it on + // lua_close(). This is better than allocating it + // as a static, since it will then be destructed + // when the program exits instead. + // warning: we assume that lua will not + // move the userdata memory. + lua_newuserdata(L, sizeof(detail::class_rep)); + crep = reinterpret_cast(lua_touserdata(L, -1)); + + new(crep) detail::class_rep( + m_type + , m_name + , L + ); + + // register this new type in the class registry + r->add_class(m_type, crep); + + lua_pushstring(L, "__luabind_class_map"); + lua_rawget(L, LUA_REGISTRYINDEX); + class_map& classes = *static_cast( + lua_touserdata(L, -1)); + lua_pop(L, 1); + + classes.put(m_id, crep); + + bool const has_wrapper = m_wrapper_id != registered_class::id; + + if(has_wrapper) + classes.put(m_wrapper_id, crep); + + crep->m_static_constants.swap(m_static_constants); + + detail::class_registry* registry = detail::class_registry::get_registry(L); + + crep->get_default_table(L); + m_scope.register_(L); + m_default_members.register_(L); + lua_pop(L, 1); + + crep->get_table(L); + m_members.register_(L); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + cast_graph* const casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_id_map* const class_ids = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + class_ids->put(m_id, m_type); + + if(has_wrapper) { + class_ids->put(m_wrapper_id, m_wrapper_type); + } + + for(auto const& e : m_casts) { + casts->insert(e.src, e.target, e.cast); + } + + for(const auto& base_pair : m_bases) { + LUABIND_CHECK_STACK(L); + + // the baseclass' class_rep structure + detail::class_rep* bcrep = registry->find_class(base_pair.first); + + detail::class_rep::base_info base; + base.pointer_offset = 0; + base.base = bcrep; + + crep->add_base_class(base); + + // copy base class table + crep->get_table(L); + bcrep->get_table(L); + lua_pushnil(L); + + while(lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); + + if(!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } + + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + + lua_settable(L, -5); + } + lua_pop(L, 2); + + // copy base class detaults table + crep->get_default_table(L); + bcrep->get_default_table(L); + lua_pushnil(L); + + while(lua_next(L, -2)) + { + lua_pushvalue(L, -2); // copy key + lua_gettable(L, -5); + + if(!lua_isnil(L, -1)) + { + lua_pop(L, 2); + continue; + } + + lua_pop(L, 1); + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + + lua_settable(L, -5); + } + lua_pop(L, 2); + + } + + lua_settable(L, -3); + } + + // -- interface --------------------------------------------------------- + + class_base::class_base(char const* name) + : scope(std::unique_ptr( + m_registration = new class_registration(name)) + ) + { + } + + void class_base::init( + type_id const& type_id_, class_id id + , type_id const& wrapper_type, class_id wrapper_id) + { + m_registration->m_type = type_id_; + m_registration->m_id = id; + m_registration->m_wrapper_type = wrapper_type; + m_registration->m_wrapper_id = wrapper_id; + } + + void class_base::add_base(type_id const& base, cast_function cast) + { + m_registration->m_bases.push_back(std::make_pair(base, cast)); + } + + void class_base::add_member(registration* member) + { + std::unique_ptr ptr(member); + m_registration->m_members.operator,(scope(std::move(ptr))); + } + + void class_base::add_default_member(registration* member) + { + std::unique_ptr ptr(member); + m_registration->m_default_members.operator,(scope(std::move(ptr))); + } + + const char* class_base::name() const + { + return m_registration->m_name; + } + + void class_base::add_static_constant(const char* name, int val) + { + m_registration->m_static_constants[name] = val; + } + + void class_base::add_inner_scope(scope& s) + { + m_registration->m_scope.operator,(s); + } + + void class_base::add_cast( + class_id src, class_id target, cast_function cast) + { + m_registration->m_casts.push_back(cast_entry(src, target, cast)); + } + + void add_custom_name(type_id const& i, std::string& s) + { + s += " ["; + s += i.name(); + s += "]"; + } + + std::string get_class_name(lua_State* L, type_id const& i) + { + std::string ret; + + assert(L); + + class_registry* r = class_registry::get_registry(L); + class_rep* crep = r->find_class(i); + + if(crep == 0) + { + ret = "custom"; + add_custom_name(i, ret); + } else + { + /* TODO reimplement this? + if (i == crep->holder_type()) + { + ret += "smart_ptr<"; + ret += crep->name(); + ret += ">"; + } + else if (i == crep->const_holder_type()) + { + ret += "smart_ptrname(); + ret += ">"; + } + else*/ + { + ret += crep->name(); + } + } + return ret; + } - void class_base::add_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_members.operator,(scope(ptr)); } - - void class_base::add_default_member(registration* member) - { - std::auto_ptr ptr(member); - m_registration->m_default_members.operator,(scope(ptr)); - } - - const char* class_base::name() const - { - return m_registration->m_name; - } - - void class_base::add_static_constant(const char* name, int val) - { - m_registration->m_static_constants[name] = val; - } - - void class_base::add_inner_scope(scope& s) - { - m_registration->m_scope.operator,(s); - } - - void class_base::add_cast( - class_id src, class_id target, cast_function cast) - { - m_registration->m_casts.push_back(cast_entry(src, target, cast)); - } - - void add_custom_name(type_id const& i, std::string& s) - { - s += " ["; - s += i.name(); - s += "]"; - } - - std::string get_class_name(lua_State* L, type_id const& i) - { - std::string ret; - - assert(L); - - class_registry* r = class_registry::get_registry(L); - class_rep* crep = r->find_class(i); - - if (crep == 0) - { - ret = "custom"; - add_custom_name(i, ret); - } - else - { - /* TODO reimplement this? - if (i == crep->holder_type()) - { - ret += "smart_ptr<"; - ret += crep->name(); - ret += ">"; - } - else if (i == crep->const_holder_type()) - { - ret += "smart_ptrname(); - ret += ">"; - } - else*/ - { - ret += crep->name(); - } - } - return ret; - } - -}} // namespace luabind::detail +} // namespace luabind::detail diff --git a/libs/luabind/src/class_info.cpp b/libs/luabind/src/class_info.cpp index 531f6e0cc..3f219e827 100644 --- a/libs/luabind/src/class_info.cpp +++ b/libs/luabind/src/class_info.cpp @@ -27,94 +27,111 @@ #include #include #include +#include +#include + +/* +#include +#define VERBOSE(X) std::cout << __FILE__ << ":" << __LINE__ << ": " << X << std::endl +*/ +#define VERBOSE(X) + +namespace luabind { -namespace luabind -{ LUABIND_API class_info get_class_info(argument const& o) { lua_State* L = o.interpreter(); - + detail::class_rep * crep = NULL; + o.push(L); - detail::object_rep* obj = detail::get_instance(L, -1); + if(detail::is_class_rep(L, -1)) { + VERBOSE("OK, got a class rep"); + // OK, o is a class rep, now at the top of the stack + crep = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + } else { - if (!obj) - { - class_info result; - result.name = lua_typename(L, lua_type(L, -1)); - lua_pop(L, 1); - result.methods = newtable(L); - result.attributes = newtable(L); - return result; - } + VERBOSE("Not a class rep"); + detail::object_rep* obj = detail::get_instance(L, -1); - lua_pop(L, 1); + if(!obj) + { + VERBOSE("Not a obj rep"); + class_info result; + result.name = lua_typename(L, lua_type(L, -1)); + lua_pop(L, 1); + result.methods = newtable(L); + result.attributes = newtable(L); + return result; + } else { + lua_pop(L, 1); + // OK, we were given an object - gotta get the crep. + crep = obj->crep(); + } + } + crep->get_table(L); + object table(from_stack(L, -1)); + lua_pop(L, 1); - obj->crep()->get_table(L); - object table(from_stack(L, -1)); - lua_pop(L, 1); + class_info result; + result.name = crep->name(); + result.methods = newtable(L); + result.attributes = newtable(L); - class_info result; - result.name = obj->crep()->name(); - result.methods = newtable(L); - result.attributes = newtable(L); + std::size_t index = 1; - std::size_t index = 1; + for(iterator i(table), e; i != e; ++i) + { + if(type(*i) != LUA_TFUNCTION) + continue; - for (iterator i(table), e; i != e; ++i) - { - if (type(*i) != LUA_TFUNCTION) - continue; + // We have to create a temporary `object` here, otherwise the proxy + // returned by operator->() will mess up the stack. This is a known + // problem that probably doesn't show up in real code very often. + object member(*i); + member.push(L); + detail::stack_pop pop(L, 1); - // We have to create a temporary `object` here, otherwise the proxy - // returned by operator->() will mess up the stack. This is a known - // problem that probably doesn't show up in real code very often. - object member(*i); - member.push(L); - detail::stack_pop pop(L, 1); + if(lua_tocfunction(L, -1) == &detail::property_tag) + { + result.attributes[index++] = i.key(); + } else + { + result.methods[i.key()] = *i; + } + } - if (lua_tocfunction(L, -1) == &detail::property_tag) - { - result.attributes[index++] = i.key(); - } - else - { - result.methods[i.key()] = *i; - } - } - - return result; + return result; } - LUABIND_API object get_class_names(lua_State* L) - { - detail::class_registry* reg = detail::class_registry::get_registry(L); + LUABIND_API object get_class_names(lua_State* L) + { + detail::class_registry* reg = detail::class_registry::get_registry(L); - std::map const& classes = reg->get_classes(); + std::map const& classes = reg->get_classes(); - object result = newtable(L); - std::size_t index = 1; + object result = newtable(L); + std::size_t index = 1; - for (std::map::const_iterator iter = classes.begin(); - iter != classes.end(); ++iter) - { - result[index++] = iter->second->name(); - } + for(const auto& cl : classes) { + result[index++] = cl.second->name(); + } - return result; - } + return result; + } LUABIND_API void bind_class_info(lua_State* L) { module(L) - [ - class_("class_info_data") + [ + class_("class_info_data") .def_readonly("name", &class_info::name) - .def_readonly("methods", &class_info::methods) - .def_readonly("attributes", &class_info::attributes), - - def("class_info", &get_class_info), - def("class_names", &get_class_names) - ]; + .def_readonly("methods", &class_info::methods) + .def_readonly("attributes", &class_info::attributes), + + def("class_info", &get_class_info), + def("class_names", &get_class_names) + ]; } } diff --git a/libs/luabind/src/class_registry.cpp b/libs/luabind/src/class_registry.cpp index 79df30ade..046cb689b 100644 --- a/libs/luabind/src/class_registry.cpp +++ b/libs/luabind/src/class_registry.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2004 Daniel Wallin // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -22,145 +22,121 @@ #define LUABIND_BUILDING -#include +#include // for lua_pushstring, lua_rawset, etc -#include -#include -#include -#include +#include // for LUABIND_API +#include // for type_id +#include // for class_registry +#include // for class_rep +#include // for garbage_collector -namespace luabind { namespace detail { - LUABIND_API void push_instance_metatable(lua_State* L); +#include // for assert +#include // for map, etc +#include // for pair - namespace { +namespace luabind { + namespace detail { - int create_cpp_class_metatable(lua_State* L) - { - lua_newtable(L); + LUABIND_API void push_instance_metatable(lua_State* L); - // mark the table with our (hopefully) unique tag - // that says that the user data that has this - // metatable is a class_rep - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); + namespace { - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &garbage_collector_s< - detail::class_rep - >::apply - , 0); + /// @todo is this redundant with the following function? All that differs is the __gc closure + int create_cpp_class_metatable(lua_State* L) + { + lua_newtable(L); - lua_rawset(L, -3); + // mark the table with our (hopefully) unique tag + // that says that the user data that has this + // metatable is a class_rep + lua_pushstring(L, "__luabind_classrep"); + lua_pushboolean(L, 1); + lua_rawset(L, -3); - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__gc"); + lua_pushcclosure(L, &garbage_collector, 0); - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); + lua_rawset(L, -3); - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__call"); + lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); + lua_rawset(L, -3); - return luaL_ref(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "__index"); + lua_pushcclosure(L, &class_rep::static_class_gettable, 0); + lua_rawset(L, -3); - int create_lua_class_metatable(lua_State* L) - { - lua_newtable(L); + lua_pushstring(L, "__newindex"); + lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); + lua_rawset(L, -3); - lua_pushstring(L, "__luabind_classrep"); - lua_pushboolean(L, 1); - lua_rawset(L, -3); + return luaL_ref(L, LUA_REGISTRYINDEX); + } - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , &detail::garbage_collector_s< - detail::class_rep - >::apply - , 0); + int create_lua_class_metatable(lua_State* L) + { + return create_cpp_class_metatable(L); + } - lua_rawset(L, -3); + } // namespace unnamed - lua_pushstring(L, "__newindex"); - lua_pushcclosure(L, &class_rep::lua_settable_dispatcher, 0); - lua_rawset(L, -3); + class class_rep; - lua_pushstring(L, "__call"); - lua_pushcclosure(L, &class_rep::constructor_dispatcher, 0); - lua_rawset(L, -3); + class_registry::class_registry(lua_State* L) + : m_cpp_class_metatable(create_cpp_class_metatable(L)) + , m_lua_class_metatable(create_lua_class_metatable(L)) + { + push_instance_metatable(L); + m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); + } - lua_pushstring(L, "__index"); - lua_pushcclosure(L, &class_rep::static_class_gettable, 0); - lua_rawset(L, -3); - - return luaL_ref(L, LUA_REGISTRYINDEX); - } - - } // namespace unnamed - - class class_rep; - - class_registry::class_registry(lua_State* L) - : m_cpp_class_metatable(create_cpp_class_metatable(L)) - , m_lua_class_metatable(create_lua_class_metatable(L)) - { - push_instance_metatable(L); - m_instance_metatable = luaL_ref(L, LUA_REGISTRYINDEX); - } - - class_registry* class_registry::get_registry(lua_State* L) - { + class_registry* class_registry::get_registry(lua_State* L) + { #ifdef LUABIND_NOT_THREADSAFE - // if we don't have to be thread safe, we can keep a - // chache of the class_registry pointer without the - // need of a mutex - static lua_State* cache_key = 0; - static class_registry* registry_cache = 0; - if (cache_key == L) return registry_cache; + // if we don't have to be thread safe, we can keep a + // chache of the class_registry pointer without the + // need of a mutex + static lua_State* cache_key = 0; + static class_registry* registry_cache = 0; + if(cache_key == L) return registry_cache; #endif - lua_pushstring(L, "__luabind_classes"); - lua_gettable(L, LUA_REGISTRYINDEX); - class_registry* p = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_classes"); + lua_gettable(L, LUA_REGISTRYINDEX); + class_registry* p = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); #ifdef LUABIND_NOT_THREADSAFE - cache_key = L; - registry_cache = p; + cache_key = L; + registry_cache = p; #endif - return p; - } + return p; + } - void class_registry::add_class(type_id const& info, class_rep* crep) - { - // class is already registered - assert((m_classes.find(info) == m_classes.end()) - && "you are trying to register a class twice"); - m_classes[info] = crep; - } + void class_registry::add_class(type_id const& info, class_rep* crep) + { + // class is already registered + assert((m_classes.find(info) == m_classes.end()) + && "you are trying to register a class twice"); + m_classes[info] = crep; + } - class_rep* class_registry::find_class(type_id const& info) const - { - std::map::const_iterator i( - m_classes.find(info)); + class_rep* class_registry::find_class(type_id const& info) const + { + std::map::const_iterator i( + m_classes.find(info)); - if (i == m_classes.end()) return 0; // the type is not registered - return i->second; - } + if(i == m_classes.end()) return 0; // the type is not registered + return i->second; + } -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/class_rep.cpp b/libs/luabind/src/class_rep.cpp index 5f03f3931..f6d7da015 100644 --- a/libs/luabind/src/class_rep.cpp +++ b/libs/luabind/src/class_rep.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -31,17 +31,23 @@ #include #include +#if LUA_VERSION_NUM < 502 +# define lua_rawlen lua_objlen +#endif + using namespace luabind::detail; -namespace luabind { namespace detail -{ - LUABIND_API int property_tag(lua_State* L) +namespace luabind { + namespace detail { - lua_pushstring(L, "luabind: property_tag function can't be called"); - lua_error(L); - return 0; + LUABIND_API int property_tag(lua_State* L) + { + lua_pushstring(L, "luabind: property_tag function can't be called"); + lua_error(L); + return 0; + } } -}} +} luabind::detail::class_rep::class_rep(type_id const& type , const char* name @@ -52,6 +58,11 @@ luabind::detail::class_rep::class_rep(type_id const& type , m_class_type(cpp_class) , m_operator_cache(0) { + shared_init(L); +} + + +void luabind::detail::class_rep::shared_init(lua_State * L) { lua_newtable(L); handle(L, -1).swap(m_table); lua_newtable(L); @@ -59,25 +70,27 @@ luabind::detail::class_rep::class_rep(type_id const& type lua_pop(L, 2); class_registry* r = class_registry::get_registry(L); + // the following line should be equivalent whether or not this is a cpp class assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - lua_rawgeti(L, LUA_REGISTRYINDEX, r->cpp_class()); + lua_rawgeti(L, LUA_REGISTRYINDEX, (m_class_type == cpp_class) ? r->cpp_class() : r->lua_class()); lua_setmetatable(L, -2); lua_pushvalue(L, -1); // duplicate our user data m_self_ref.set(L); - m_instance_metatable = r->cpp_instance(); + m_instance_metatable = (m_class_type == cpp_class) ? r->cpp_instance() : r->lua_instance(); - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + lua_pushstring(L, "__luabind_cast_graph"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_casts = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + + lua_pushstring(L, "__luabind_class_id_map"); + lua_gettable(L, LUA_REGISTRYINDEX); + m_classes = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); } luabind::detail::class_rep::class_rep(lua_State* L, const char* name) @@ -86,31 +99,7 @@ luabind::detail::class_rep::class_rep(lua_State* L, const char* name) , m_class_type(lua_class) , m_operator_cache(0) { - lua_newtable(L); - handle(L, -1).swap(m_table); - lua_newtable(L); - handle(L, -1).swap(m_default_table); - lua_pop(L, 2); - - class_registry* r = class_registry::get_registry(L); - assert((r->cpp_class() != LUA_NOREF) && "you must call luabind::open()"); - - lua_rawgeti(L, LUA_REGISTRYINDEX, r->lua_class()); - lua_setmetatable(L, -2); - lua_pushvalue(L, -1); // duplicate our user data - m_self_ref.set(L); - - m_instance_metatable = r->lua_instance(); - - lua_pushstring(L, "__luabind_cast_graph"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_casts = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); - - lua_pushstring(L, "__luabind_class_id_map"); - lua_gettable(L, LUA_REGISTRYINDEX); - m_classes = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + shared_init(L); } luabind::detail::class_rep::~class_rep() @@ -118,61 +107,61 @@ luabind::detail::class_rep::~class_rep() } // leaves object on lua stack -std::pair +std::pair luabind::detail::class_rep::allocate(lua_State* L) const { const int size = sizeof(object_rep); char* mem = static_cast(lua_newuserdata(L, size)); - return std::pair(mem, (void*)0); + return std::pair(mem, (void*)0); } namespace { - bool super_deprecation_disabled = false; + bool super_deprecation_disabled = false; } // namespace unnamed // this is called as metamethod __call on the class_rep. int luabind::detail::class_rep::constructor_dispatcher(lua_State* L) { - class_rep* cls = static_cast(lua_touserdata(L, 1)); + class_rep* cls = static_cast(lua_touserdata(L, 1)); - int args = lua_gettop(L); + int args = lua_gettop(L); - push_new_instance(L, cls); + push_new_instance(L, cls); - if (super_deprecation_disabled - && cls->get_class_type() == class_rep::lua_class - && !cls->bases().empty()) - { - lua_pushvalue(L, 1); - lua_pushvalue(L, -2); - lua_pushcclosure(L, super_callback, 2); - lua_setglobal(L, "super"); - } + if(super_deprecation_disabled + && cls->get_class_type() == class_rep::lua_class + && !cls->bases().empty()) + { + lua_pushvalue(L, 1); + lua_pushvalue(L, -2); + lua_pushcclosure(L, super_callback, 2); + lua_setglobal(L, "super"); + } - lua_pushvalue(L, -1); - lua_replace(L, 1); + lua_pushvalue(L, -1); + lua_replace(L, 1); - cls->get_table(L); - lua_pushliteral(L, "__init"); - lua_gettable(L, -2); + cls->get_table(L); + lua_pushliteral(L, "__init"); + lua_gettable(L, -2); - lua_insert(L, 1); + lua_insert(L, 1); - lua_pop(L, 1); - lua_insert(L, 1); + lua_pop(L, 1); + lua_insert(L, 1); - lua_call(L, args, 0); + lua_call(L, args, 0); - if (super_deprecation_disabled) - { - lua_pushnil(L); - lua_setglobal(L, "super"); - } + if(super_deprecation_disabled) + { + lua_pushnil(L); + lua_setglobal(L, "super"); + } - return 1; + return 1; } void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep::base_info& binfo) @@ -187,11 +176,9 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep class_rep* bcrep = binfo.base; // import all static constants - for (std::map::const_iterator i = bcrep->m_static_constants.begin(); - i != bcrep->m_static_constants.end(); ++i) - { - int& v = m_static_constants[i->first]; - v = i->second; + for(const auto& scon : bcrep->m_static_constants) { + int& v = m_static_constants[scon.first]; + v = scon.second; } // also, save the baseclass info to be used for typecasts @@ -200,17 +187,17 @@ void luabind::detail::class_rep::add_base_class(const luabind::detail::class_rep LUABIND_API void luabind::disable_super_deprecation() { - super_deprecation_disabled = true; + super_deprecation_disabled = true; } int luabind::detail::class_rep::super_callback(lua_State* L) { int args = lua_gettop(L); - + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); class_rep* base = crep->bases()[0].base; - if (base->bases().empty()) + if(base->bases().empty()) { lua_pushnil(L); lua_setglobal(L, "super"); @@ -265,7 +252,7 @@ int luabind::detail::class_rep::lua_settable_dispatcher(lua_State* L) lua_rawset(L, -3); crep->m_operator_cache = 0; // invalidate cache - + return 0; } @@ -282,12 +269,12 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) crep->get_default_table(L); lua_pushvalue(L, 2); lua_gettable(L, -2); - if (!lua_isnil(L, -1)) return 1; + if(!lua_isnil(L, -1)) return 1; else lua_pop(L, 2); const char* key = lua_tostring(L, 2); - if (std::strlen(key) != lua_strlen(L, 2)) + if(std::strlen(key) != lua_rawlen(L, 2)) { lua_pushnil(L); return 1; @@ -295,7 +282,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) std::map::const_iterator j = crep->m_static_constants.find(key); - if (j != crep->m_static_constants.end()) + if(j != crep->m_static_constants.end()) { lua_pushnumber(L, j->second); return 1; @@ -303,14 +290,7 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) #ifndef LUABIND_NO_ERROR_CHECKING - { - std::string msg = "no static '"; - msg += key; - msg += "' in class '"; - msg += crep->name(); - msg += "'"; - lua_pushstring(L, msg.c_str()); - } + lua_pushfstring(L, "no static '%s' in class '%s'", key, crep->name()); lua_error(L); #endif @@ -320,13 +300,13 @@ int luabind::detail::class_rep::static_class_gettable(lua_State* L) return 1; } -bool luabind::detail::is_class_rep(lua_State* L, int index) +LUABIND_API bool luabind::detail::is_class_rep(lua_State* L, int index) { - if (lua_getmetatable(L, index) == 0) return false; + if(lua_getmetatable(L, index) == 0) return false; lua_pushstring(L, "__luabind_classrep"); lua_gettable(L, -2); - if (lua_toboolean(L, -1)) + if(lua_toboolean(L, -1)) { lua_pop(L, 2); return true; @@ -338,15 +318,15 @@ bool luabind::detail::is_class_rep(lua_State* L, int index) void luabind::detail::finalize(lua_State* L, class_rep* crep) { - if (crep->get_class_type() != class_rep::lua_class) return; + if(crep->get_class_type() != class_rep::lua_class) return; -// lua_pushvalue(L, -1); // copy the object ref + // lua_pushvalue(L, -1); // copy the object ref crep->get_table(L); - lua_pushliteral(L, "__finalize"); + lua_pushliteral(L, "__finalize"); lua_gettable(L, -2); lua_remove(L, -2); - if (lua_isnil(L, -1)) + if(lua_isnil(L, -1)) { lua_pop(L, 1); } @@ -356,10 +336,8 @@ void luabind::detail::finalize(lua_State* L, class_rep* crep) lua_call(L, 1, 0); } - for (std::vector::const_iterator - i = crep->bases().begin(); i != crep->bases().end(); ++i) - { - if (i->base) finalize(L, i->base); + for(const auto& baseinfo : crep->bases()) { + if(baseinfo.base) finalize(L, baseinfo.base); } } @@ -367,13 +345,13 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) { m_operator_cache = 0x1; - for (int i = 0; i < number_of_operators; ++i) + for(int i = 0; i < number_of_operators; ++i) { get_table(L); lua_pushstring(L, get_operator_name(i)); lua_rawget(L, -2); - if (lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); + if(lua_isfunction(L, -1)) m_operator_cache |= 1 << (i + 1); lua_pop(L, 2); } @@ -381,10 +359,11 @@ void luabind::detail::class_rep::cache_operators(lua_State* L) bool luabind::detail::class_rep::has_operator_in_lua(lua_State* L, int id) { - if ((m_operator_cache & 0x1) == 0) + if((m_operator_cache & 0x1) == 0) cache_operators(L); const int mask = 1 << (id + 1); return (m_operator_cache & mask) != 0; } + diff --git a/libs/luabind/src/create_class.cpp b/libs/luabind/src/create_class.cpp index 47251ef23..4468374b7 100644 --- a/libs/luabind/src/create_class.cpp +++ b/libs/luabind/src/create_class.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2003 Daniel Wallin and Arvid Norberg +// Copyright (c) 2003 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -26,114 +26,122 @@ #include -namespace luabind { namespace detail -{ - namespace - { - // expects two tables on the lua stack: - // 1: destination - // 2: source - void copy_member_table(lua_State* L) - { - lua_pushnil(L); +#if LUA_VERSION_NUM < 502 +# define lua_compare(L, index1, index2, fn) fn(L, index1, index2) +# define LUA_OPEQ lua_equal +# define lua_rawlen lua_objlen +#endif - while (lua_next(L, -2)) +namespace luabind { + namespace detail { + namespace { + + // expects two tables on the lua stack: + // 1: destination + // 2: source + void copy_member_table(lua_State* L) { - lua_pushstring(L, "__init"); - if (lua_equal(L, -1, -3)) - { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __init string + lua_pushnil(L); - lua_pushstring(L, "__finalize"); - if (lua_equal(L, -1, -3)) + while(lua_next(L, -2)) { - lua_pop(L, 2); - continue; - } - else lua_pop(L, 1); // __finalize string + lua_pushstring(L, "__init"); + if(lua_compare(L, -1, -3, LUA_OPEQ)) + { + lua_pop(L, 2); + continue; + } + else lua_pop(L, 1); // __init string - lua_pushvalue(L, -2); // copy key - lua_insert(L, -2); - lua_settable(L, -5); + lua_pushstring(L, "__finalize"); + if(lua_compare(L, -1, -3, LUA_OPEQ)) + { + lua_pop(L, 2); + continue; + } + else lua_pop(L, 1); // __finalize string + + lua_pushvalue(L, -2); // copy key + lua_insert(L, -2); + lua_settable(L, -5); + } } - } - } + + } // namespace unnamed - int create_class::stage2(lua_State* L) - { - class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); - assert((crep != 0) && "internal error, please report"); - assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (!is_class_rep(L, 1)) + int create_class::stage2(lua_State* L) { - lua_pushstring(L, "expected class to derive from or a newline"); - lua_error(L); + class_rep* crep = static_cast(lua_touserdata(L, lua_upvalueindex(1))); + assert((crep != 0) && "internal error, please report"); + assert((is_class_rep(L, lua_upvalueindex(1))) && "internal error, please report"); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if(!is_class_rep(L, 1)) + { + lua_pushstring(L, "expected class to derive from or a newline"); + lua_error(L); + } + +#endif + + class_rep* base = static_cast(lua_touserdata(L, 1)); + class_rep::base_info binfo; + + binfo.pointer_offset = 0; + binfo.base = base; + crep->add_base_class(binfo); + + // copy base class members + + crep->get_table(L); + base->get_table(L); + copy_member_table(L); + + crep->get_default_table(L); + base->get_default_table(L); + copy_member_table(L); + + crep->set_type(base->type()); + + return 0; } - #endif - - class_rep* base = static_cast(lua_touserdata(L, 1)); - class_rep::base_info binfo; - - binfo.pointer_offset = 0; - binfo.base = base; - crep->add_base_class(binfo); - - // copy base class members - - crep->get_table(L); - base->get_table(L); - copy_member_table(L); - - crep->get_default_table(L); - base->get_default_table(L); - copy_member_table(L); - - crep->set_type(base->type()); - - return 0; - } - - int create_class::stage1(lua_State* L) - { - - #ifndef LUABIND_NO_ERROR_CHECKING - - if (lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) + int create_class::stage1(lua_State* L) { - lua_pushstring(L, "invalid construct, expected class name"); - lua_error(L); + +#ifndef LUABIND_NO_ERROR_CHECKING + + if(lua_gettop(L) != 1 || lua_type(L, 1) != LUA_TSTRING || lua_isnumber(L, 1)) + { + lua_pushstring(L, "invalid construct, expected class name"); + lua_error(L); + } + + if(std::strlen(lua_tostring(L, 1)) != lua_rawlen(L, 1)) + { + lua_pushstring(L, "luabind does not support class names with extra nulls"); + lua_error(L); + } + +#endif + + const char* name = lua_tostring(L, 1); + + void* c = lua_newuserdata(L, sizeof(class_rep)); + new(c) class_rep(L, name); + + // make the class globally available + lua_pushvalue(L, -1); + lua_setglobal(L, name); + + // also add it to the closure as return value + lua_pushcclosure(L, &stage2, 1); + + return 1; } - if (std::strlen(lua_tostring(L, 1)) != lua_strlen(L, 1)) - { - lua_pushstring(L, "luabind does not support class names with extra nulls"); - lua_error(L); - } - - #endif - - const char* name = lua_tostring(L, 1); - - void* c = lua_newuserdata(L, sizeof(class_rep)); - new(c) class_rep(L, name); - - // make the class globally available - lua_pushvalue(L, -1); - lua_setglobal(L, name); - - // also add it to the closure as return value - lua_pushcclosure(L, &stage2, 1); - - return 1; - } - -}} + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/error.cpp b/libs/luabind/src/error.cpp index 73bbf5c62..07e352026 100644 --- a/libs/luabind/src/error.cpp +++ b/libs/luabind/src/error.cpp @@ -23,11 +23,32 @@ #define LUABIND_BUILDING #include +#ifndef LUA_INCLUDE_HPP_INCLUDED +#include +#endif -namespace luabind -{ +namespace luabind { +#ifndef LUABIND_NO_EXCEPTIONS + error::error(lua_State* L) + { + const char* message = lua_tostring(L, -1); + + if(message) + { + m_message = message; + } + + lua_pop(L, 1); + } + + + const char* error::what() const throw() + { + return m_message.c_str(); + } +#endif namespace { pcall_callback_fun pcall_callback = 0; @@ -40,9 +61,6 @@ namespace luabind #ifdef LUABIND_NO_EXCEPTIONS - typedef void(*error_callback_fun)(lua_State*); - typedef void(*cast_failed_callback_fun)(lua_State*, type_id const&); - void set_error_callback(error_callback_fun e) { error_callback = e; @@ -76,3 +94,4 @@ namespace luabind } } + diff --git a/libs/luabind/src/exception_handler.cpp b/libs/luabind/src/exception_handler.cpp index 555d3858c..d4ee7764a 100644 --- a/libs/luabind/src/exception_handler.cpp +++ b/libs/luabind/src/exception_handler.cpp @@ -4,84 +4,93 @@ #define LUABIND_BUILDING -#include -#include -#include -#include +#include + +#include // for LUABIND_API #ifndef LUABIND_NO_EXCEPTIONS +#include // for error +#include // for exception_handler_base -namespace luabind { namespace detail { +#include // for exception +#include // for logic_error, runtime_error -namespace -{ - exception_handler_base* handler_chain = 0; +namespace luabind { + namespace detail { - void push_exception_string(lua_State* L, char const* exception, char const* what) - { - lua_pushstring(L, exception); - lua_pushstring(L, ": '"); - lua_pushstring(L, what); - lua_pushstring(L, "'"); - lua_concat(L, 4); - } -} + namespace { -void exception_handler_base::try_next(lua_State* L) const -{ - if (next) - next->handle(L); - else - throw; -} + exception_handler_base* handler_chain = 0; -LUABIND_API void handle_exception_aux(lua_State* L) -{ - try - { - if (handler_chain) - handler_chain->handle(L); - else - throw; - } - catch (error const&) - {} - catch (std::logic_error const& e) - { - push_exception_string(L, "std::logic_error", e.what()); - } - catch (std::runtime_error const& e) - { - push_exception_string(L, "std::runtime_error", e.what()); - } - catch (std::exception const& e) - { - push_exception_string(L, "std::exception", e.what()); - } - catch (char const* str) - { - push_exception_string(L, "c-string", str); - } - catch (...) - { - lua_pushstring(L, "Unknown C++ exception"); - } -} + void push_exception_string(lua_State* L, char const* exception, char const* what) + { + lua_pushstring(L, exception); + lua_pushstring(L, ": '"); + lua_pushstring(L, what); + lua_pushstring(L, "'"); + lua_concat(L, 4); + } + } -LUABIND_API void register_exception_handler(exception_handler_base* handler) -{ - if (!handler_chain) handler_chain = handler; - else - { - exception_handler_base* p = handler_chain; + void exception_handler_base::try_next(lua_State* L) const + { + if(next) + next->handle(L); + else + throw; + } - for (; p->next; p = p->next); + LUABIND_API void handle_exception_aux(lua_State* L) + { + try + { + if(handler_chain) + handler_chain->handle(L); + else + throw; + } + catch(error const&) + { + // is always thrown in the context where an error message was already pushed to the lua stack. + } + catch(std::logic_error const& e) + { + push_exception_string(L, "std::logic_error", e.what()); + } + catch(std::runtime_error const& e) + { + push_exception_string(L, "std::runtime_error", e.what()); + } + catch(std::exception const& e) + { + push_exception_string(L, "std::exception", e.what()); + } + catch(char const* str) + { + push_exception_string(L, "c-string", str); + } + catch(...) + { + lua_pushstring(L, "Unknown C++ exception"); + } + } - handler->next = 0; - p->next = handler; - } -} + LUABIND_API void register_exception_handler(exception_handler_base* handler) + { + if(!handler_chain) handler_chain = handler; + else + { + exception_handler_base* p = handler_chain; -}} // namespace luabind::detail + for(; p->next; p = p->next); + + handler->next = 0; + p->next = handler; + } + } + + } // namespace detail +} // namespace luabind #endif // LUABIND_NO_EXCEPTIONS + diff --git a/libs/luabind/src/function.cpp b/libs/luabind/src/function.cpp index 20569b2bd..cacaf777c 100644 --- a/libs/luabind/src/function.cpp +++ b/libs/luabind/src/function.cpp @@ -4,133 +4,139 @@ #define LUABIND_BUILDING +#include #include +#include +#include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -namespace -{ + namespace { - int function_destroy(lua_State* L) - { - function_object* fn = *(function_object**)lua_touserdata(L, 1); - delete fn; - return 0; - } + int function_destroy(lua_State* L) + { + function_object* fn = *(function_object**)lua_touserdata(L, 1); + delete fn; + return 0; + } - void push_function_metatable(lua_State* L) - { - lua_pushstring(L, "luabind.function"); - lua_rawget(L, LUA_REGISTRYINDEX); + void push_function_metatable(lua_State* L) + { + lua_pushstring(L, "luabind.function"); + lua_rawget(L, LUA_REGISTRYINDEX); - if (lua_istable(L, -1)) - return; + if(lua_istable(L, -1)) + return; - lua_pop(L, 1); + lua_pop(L, 1); - lua_newtable(L); + lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure(L, &function_destroy, 0); - lua_rawset(L, -3); + lua_pushstring(L, "__gc"); + lua_pushcclosure(L, &function_destroy, 0); + lua_rawset(L, -3); - lua_pushstring(L, "luabind.function"); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } + lua_pushstring(L, "luabind.function"); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } - // A pointer to this is used as a tag value to identify functions exported - // by luabind. - int function_tag = 0; + // A pointer to this is used as a tag value to identify functions exported + // by luabind. + int function_tag = 0; -} // namespace unnamed + } // namespace unnamed -LUABIND_API bool is_luabind_function(lua_State* L, int index) -{ - if (!lua_getupvalue(L, index, 2)) - return false; - bool result = lua_touserdata(L, -1) == &function_tag; - lua_pop(L, 1); - return result; -} + LUABIND_API bool is_luabind_function(lua_State* L, int index) + { + if(!lua_getupvalue(L, index, 2)) + return false; + bool result = lua_touserdata(L, -1) == &function_tag; + lua_pop(L, 1); + return result; + } -namespace -{ + namespace + { - inline bool is_luabind_function(object const& obj) - { - obj.push(obj.interpreter()); - bool result = detail::is_luabind_function(obj.interpreter(), -1); - lua_pop(obj.interpreter(), 1); - return result; - } + inline bool is_luabind_function(object const& obj) + { + obj.push(obj.interpreter()); + bool result = detail::is_luabind_function(obj.interpreter(), -1); + lua_pop(obj.interpreter(), 1); + return result; + } -} // namespace unnamed + } // namespace unnamed -LUABIND_API void add_overload( - object const& context, char const* name, object const& fn) -{ - function_object* f = *touserdata(getupvalue(fn, 1)); - f->name = name; + LUABIND_API void add_overload( + object const& context, char const* name, object const& fn) + { + function_object* f = *touserdata(std::get<1>(getupvalue(fn, 1))); + f->name = name; - if (object overloads = context[name]) - { - if (is_luabind_function(overloads) && is_luabind_function(fn)) - { - f->next = *touserdata(getupvalue(overloads, 1)); - f->keepalive = overloads; - } - } + if(object overloads = context[name]) + { + if(is_luabind_function(overloads) && is_luabind_function(fn)) + { + f->next = *touserdata(std::get<1>(getupvalue(overloads, 1))); + f->keepalive = overloads; + } + } - context[name] = fn; -} + context[name] = fn; + } -LUABIND_API object make_function_aux(lua_State* L, function_object* impl) -{ - void* storage = lua_newuserdata(L, sizeof(function_object*)); - push_function_metatable(L); - *(function_object**)storage = impl; - lua_setmetatable(L, -2); + LUABIND_API object make_function_aux(lua_State* L, function_object* impl) + { + void* storage = lua_newuserdata(L, sizeof(function_object*)); + push_function_metatable(L); + *(function_object**)storage = impl; + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &function_tag); - lua_pushcclosure(L, impl->entry, 2); - stack_pop pop(L, 1); + lua_pushlightuserdata(L, &function_tag); + lua_pushcclosure(L, impl->entry, 2); + stack_pop pop(L, 1); - return object(from_stack(L, -1)); -} + return object(from_stack(L, -1)); + } -void invoke_context::format_error( - lua_State* L, function_object const* overloads) const -{ - char const* function_name = - overloads->name.empty() ? "" : overloads->name.c_str(); + void invoke_context::format_error( + lua_State* L, function_object const* overloads) const + { + char const* function_name = + overloads->name.empty() ? "" : overloads->name.c_str(); - if (candidate_index == 0) - { - lua_pushstring(L, "No matching overload found, candidates:\n"); - int count = 0; - for (function_object const* f = overloads; f != 0; f = f->next) - { - if (count != 0) - lua_pushstring(L, "\n"); - f->format_signature(L, function_name); - ++count; - } - lua_concat(L, count * 2); - } - else - { - // Ambiguous - lua_pushstring(L, "Ambiguous, candidates:\n"); - for (int i = 0; i < candidate_index; ++i) - { - if (i != 0) - lua_pushstring(L, "\n"); - candidates[i]->format_signature(L, function_name); - } - lua_concat(L, candidate_index * 2); - } -} + if(candidate_index == 0) + { + int stacksize = lua_gettop(L); + lua_pushstring(L, "No matching overload found, candidates:\n"); + int count = 0; + for(function_object const* f = overloads; f != 0; f = f->next) + { + if(count != 0) + lua_pushstring(L, "\n"); + f->format_signature(L, function_name); + ++count; + } + lua_concat(L, lua_gettop(L) - stacksize); + } + else + { + // Ambiguous + int stacksize = lua_gettop(L); + lua_pushstring(L, "Ambiguous, candidates:\n"); + for(int i = 0; i < candidate_index; ++i) + { + if(i != 0) + lua_pushstring(L, "\n"); + candidates[i]->format_signature(L, function_name); + } + lua_concat(L, lua_gettop(L) - stacksize); + } + } -}} // namespace luabind::detail + } // namespace detail +} // namespace luabind diff --git a/libs/luabind/src/function_introspection.cpp b/libs/luabind/src/function_introspection.cpp new file mode 100644 index 000000000..aed60e40e --- /dev/null +++ b/libs/luabind/src/function_introspection.cpp @@ -0,0 +1,117 @@ +/** + @file + @brief Implementation + + @date 2012 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2012. +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#define LUABIND_BUILDING + +// Internal Includes +#include +#include // for LUABIND_API + +#include +#include + +#include // for stack_pop +#include // for def, is_luabind_function +#include // for function_object +#include // for argument, object, etc +#include // for from_stack +#include // for module, module_, scope +#include +#include + +// Library/third-party includes +// - none + +// Standard includes +#include // for string +#include // for NULL + +namespace luabind { + + namespace { + detail::function_object* get_function_object(argument const& fn) { + lua_State * L = fn.interpreter(); + { + fn.push(L); + detail::stack_pop pop(L, 1); + if(!detail::is_luabind_function(L, -1)) { + return NULL; + } + } + return *touserdata(std::get<1>(getupvalue(fn, 1))); + } + + std::string get_function_name(argument const& fn) { + detail::function_object * f = get_function_object(fn); + if(!f) { + return ""; + } + return f->name; + } + + object get_function_overloads(argument const& fn) { + lua_State * L = fn.interpreter(); + detail::function_object * fobj = get_function_object(fn); + if(!fobj) { + return object(); + } + object overloadTable(newtable(L)); + int count = 1; + const char* function_name = fobj->name.c_str(); + for(detail::function_object const* f = fobj; f != 0; f = f->next) + { + f->format_signature(L, function_name); + detail::stack_pop pop(L, 1); + overloadTable[count] = object(from_stack(L, -1)); + + ++count; + } + /// @todo + + return overloadTable; + } + + } + + LUABIND_API int bind_function_introspection(lua_State * L) { + module(L, "function_info")[ + def("get_function_overloads", &get_function_overloads), + def("get_function_name", &get_function_name) + ]; + return 0; + } + +} // end of namespace luabind + diff --git a/libs/luabind/src/headertest.cpp b/libs/luabind/src/headertest.cpp new file mode 100644 index 000000000..2061691f6 --- /dev/null +++ b/libs/luabind/src/headertest.cpp @@ -0,0 +1 @@ +#include diff --git a/libs/luabind/src/inheritance.cpp b/libs/luabind/src/inheritance.cpp index 2e2ec902a..a3de45859 100644 --- a/libs/luabind/src/inheritance.cpp +++ b/libs/luabind/src/inheritance.cpp @@ -8,251 +8,224 @@ #include #include #include -#include -#include -#include -#include +#include #include #include -namespace luabind { namespace detail { +namespace luabind { + namespace detail { -class_id const class_id_map::local_id_base = - std::numeric_limits::max() / 2; + class_id const class_id_map::local_id_base = std::numeric_limits::max() / 2; -namespace -{ + namespace + { - struct edge - { - edge(class_id target, cast_function cast) - : target(target) - , cast(cast) - {} + struct edge + { + edge(class_id target, cast_function cast) + : target(target), cast(cast) + {} - class_id target; - cast_function cast; - }; + class_id target; + cast_function cast; + }; - bool operator<(edge const& x, edge const& y) - { - return x.target < y.target; - } + bool operator<(edge const& x, edge const& y) + { + return x.target < y.target; + } - struct vertex - { - vertex(class_id id) - : id(id) - {} + struct vertex + { + vertex(class_id id) + : id(id) + {} - class_id id; - std::vector edges; - }; + class_id id; + std::vector edges; + }; - typedef std::pair cache_entry; + using cache_entry = std::pair; - class cache - { - public: - static std::ptrdiff_t const unknown; - static std::ptrdiff_t const invalid; + class cache + { + public: + static constexpr std::ptrdiff_t unknown = std::numeric_limits::max(); + static constexpr std::ptrdiff_t invalid = unknown - 1; - cache_entry get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const; + cache_entry get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const; - void put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset - , std::size_t distance, std::ptrdiff_t offset); + void put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance); + void invalidate(); - void invalidate(); + private: + using key_type = std::tuple; + using map_type = std::map; + map_type m_cache; + }; - private: - typedef boost::tuple< - class_id, class_id, class_id, std::ptrdiff_t> key_type; - typedef std::map map_type; - map_type m_cache; - }; + constexpr std::ptrdiff_t cache::unknown; + constexpr std::ptrdiff_t cache::invalid; - std::ptrdiff_t const cache::unknown = - std::numeric_limits::max(); - std::ptrdiff_t const cache::invalid = cache::unknown - 1; + cache_entry cache::get(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset) const + { + map_type::const_iterator i = m_cache.find( + key_type(src, target, dynamic_id, object_offset)); + return i != m_cache.end() ? i->second : cache_entry(unknown, -1); + } - cache_entry cache::get( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset) const - { - map_type::const_iterator i = m_cache.find( - key_type(src, target, dynamic_id, object_offset)); - return i != m_cache.end() ? i->second : cache_entry(unknown, -1); - } + void cache::put(class_id src, class_id target, class_id dynamic_id, std::ptrdiff_t object_offset, std::ptrdiff_t offset, int distance) + { + m_cache.insert(std::make_pair(key_type(src, target, dynamic_id, object_offset), cache_entry(offset, distance))); + } - void cache::put( - class_id src, class_id target, class_id dynamic_id - , std::ptrdiff_t object_offset, std::size_t distance, std::ptrdiff_t offset) - { - m_cache.insert(std::make_pair( - key_type(src, target, dynamic_id, object_offset) - , cache_entry(offset, distance) - )); - } + void cache::invalidate() + { + m_cache.clear(); + } - void cache::invalidate() - { - m_cache.clear(); - } + } // namespace anonymous -} // namespace unnamed + class cast_graph::impl + { + public: + std::pair cast( + void* p, class_id src, class_id target + , class_id dynamic_id, void const* dynamic_ptr) const; + void insert(class_id src, class_id target, cast_function cast); -class cast_graph::impl -{ -public: - std::pair cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const; - void insert(class_id src, class_id target, cast_function cast); + private: + std::vector m_vertices; + mutable cache m_cache; + }; -private: - std::vector m_vertices; - mutable cache m_cache; -}; + namespace + { -namespace -{ + struct queue_entry + { + queue_entry(void* p, class_id vertex_id, int distance) + : p(p) + , vertex_id(vertex_id) + , distance(distance) + {} - struct queue_entry - { - queue_entry(void* p, class_id vertex_id, int distance) - : p(p) - , vertex_id(vertex_id) - , distance(distance) - {} + void* p; + class_id vertex_id; + int distance; + }; - void* p; - class_id vertex_id; - int distance; - }; + } // namespace anonymous -} // namespace unnamed + std::pair cast_graph::impl::cast(void* const p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const + { + if(src == target) return std::make_pair(p, 0); + if(src >= m_vertices.size() || target >= m_vertices.size()) return std::pair((void*)0, -1); -std::pair cast_graph::impl::cast( - void* const p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - if (src == target) - return std::make_pair(p, 0); + std::ptrdiff_t const object_offset = (char const*)dynamic_ptr - (char const*)p; + cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); - if (src >= m_vertices.size() || target >= m_vertices.size()) - return std::pair((void*)0, -1); + if(cached.first != cache::unknown) + { + if(cached.first == cache::invalid) + return std::pair((void*)0, -1); + return std::make_pair((char*)p + cached.first, cached.second); + } - std::ptrdiff_t const object_offset = - (char const*)dynamic_ptr - (char const*)p; + std::queue q; + q.push(queue_entry(p, src, 0)); - cache_entry cached = m_cache.get(src, target, dynamic_id, object_offset); + // Original source used boost::dynamic_bitset but didn't make use + // of its advanced capability of set operations, that's why I think + // it's safe to use a std::vector here. - if (cached.first != cache::unknown) - { - if (cached.first == cache::invalid) - return std::pair((void*)0, -1); - return std::make_pair((char*)p + cached.first, cached.second); - } + std::vector visited(m_vertices.size(), false); - std::queue q; - q.push(queue_entry(p, src, 0)); + while(!q.empty()) + { + queue_entry const qe = q.front(); + q.pop(); - boost::dynamic_bitset<> visited(m_vertices.size()); + visited[qe.vertex_id] = true; + vertex const& v = m_vertices[qe.vertex_id]; - while (!q.empty()) - { - queue_entry const qe = q.front(); - q.pop(); + if(v.id == target) + { + m_cache.put( + src, target, dynamic_id, object_offset + , (char*)qe.p - (char*)p, qe.distance + ); - visited[qe.vertex_id] = true; - vertex const& v = m_vertices[qe.vertex_id]; + return std::make_pair(qe.p, qe.distance); + } - if (v.id == target) - { - m_cache.put( - src, target, dynamic_id, object_offset - , qe.distance, (char*)qe.p - (char*)p - ); + for(auto const& e : v.edges) { + if(visited[e.target]) + continue; + if(void* casted = e.cast(qe.p)) + q.push(queue_entry(casted, e.target, qe.distance + 1)); + } + } - return std::make_pair(qe.p, qe.distance); - } + m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); - BOOST_FOREACH(edge const& e, v.edges) - { - if (visited[e.target]) - continue; - if (void* casted = e.cast(qe.p)) - q.push(queue_entry(casted, e.target, qe.distance + 1)); - } - } + return std::pair((void*)0, -1); + } - m_cache.put(src, target, dynamic_id, object_offset, cache::invalid, -1); + void cast_graph::impl::insert(class_id src, class_id target, cast_function cast) + { + class_id const max_id = std::max(src, target); - return std::pair((void*)0, -1); -} + if(max_id >= m_vertices.size()) + { + m_vertices.reserve(max_id + 1); + for(class_id i = m_vertices.size(); i < max_id + 1; ++i) + m_vertices.push_back(vertex(i)); + } -void cast_graph::impl::insert( - class_id src, class_id target, cast_function cast) -{ - class_id const max_id = std::max(src, target); + std::vector& edges = m_vertices[src].edges; - if (max_id >= m_vertices.size()) - { - m_vertices.reserve(max_id + 1); - for (class_id i = m_vertices.size(); i < max_id + 1; ++i) - m_vertices.push_back(vertex(i)); - } + std::vector::iterator i = std::lower_bound( + edges.begin(), edges.end(), edge(target, 0) + ); - std::vector& edges = m_vertices[src].edges; + if(i == edges.end() || i->target != target) + { + edges.insert(i, edge(target, cast)); + m_cache.invalidate(); + } + } - std::vector::iterator i = std::lower_bound( - edges.begin(), edges.end(), edge(target, 0) - ); + std::pair cast_graph::cast(void* p, class_id src, class_id target, class_id dynamic_id, void const* dynamic_ptr) const + { + return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); + } - if (i == edges.end() || i->target != target) - { - edges.insert(i, edge(target, cast)); - m_cache.invalidate(); - } -} + void cast_graph::insert(class_id src, class_id target, cast_function cast) + { + m_impl->insert(src, target, cast); + } -std::pair cast_graph::cast( - void* p, class_id src, class_id target - , class_id dynamic_id, void const* dynamic_ptr) const -{ - return m_impl->cast(p, src, target, dynamic_id, dynamic_ptr); -} + cast_graph::cast_graph() + : m_impl(new impl) + {} -void cast_graph::insert(class_id src, class_id target, cast_function cast) -{ - m_impl->insert(src, target, cast); -} + cast_graph::~cast_graph() + {} -cast_graph::cast_graph() - : m_impl(new impl) -{} + LUABIND_API class_id allocate_class_id(type_id const& cls) + { + using map_type = std::map; -cast_graph::~cast_graph() -{} + static map_type registered; + static class_id id = 0; -LUABIND_API class_id allocate_class_id(type_id const& cls) -{ - typedef std::map map_type; + std::pair inserted = registered.insert(std::make_pair(cls, id)); + if(inserted.second) ++id; - static map_type registered; - static class_id id = 0; + return inserted.first->second; + } - std::pair inserted = registered.insert( - std::make_pair(cls, id)); + } // namespace detail +} // namespace luabind - if (inserted.second) - ++id; - - return inserted.first->second; -} - -}} // namespace luabind::detail diff --git a/libs/luabind/src/link_compatibility.cpp b/libs/luabind/src/link_compatibility.cpp index 515e0e392..60a02f1c6 100644 --- a/libs/luabind/src/link_compatibility.cpp +++ b/libs/luabind/src/link_compatibility.cpp @@ -24,20 +24,21 @@ #include -namespace luabind { namespace detail -{ +namespace luabind { + namespace detail { #ifdef LUABIND_NOT_THREADSAFE - void not_threadsafe_defined_conflict() {} + void not_threadsafe_defined_conflict() {} #else - void not_threadsafe_not_defined_conflict() {} + void not_threadsafe_not_defined_conflict() {} #endif #ifdef LUABIND_NO_ERROR_CHECKING - void no_error_checking_defined_conflict() {} + void no_error_checking_defined_conflict() {} #else - void no_error_checking_not_defined_conflict() {} + void no_error_checking_not_defined_conflict() {} #endif -}} + } +} diff --git a/libs/luabind/src/object_rep.cpp b/libs/luabind/src/object_rep.cpp index afc6d9800..4d5f39bdf 100644 --- a/libs/luabind/src/object_rep.cpp +++ b/libs/luabind/src/object_rep.cpp @@ -24,250 +24,243 @@ #include #include -#include -namespace luabind { namespace detail -{ +#if LUA_VERSION_NUM < 502 +# define lua_getuservalue lua_getfenv +# define lua_setuservalue lua_setfenv +#endif - // dest is a function that is called to delete the c++ object this struct holds - object_rep::object_rep(instance_holder* instance, class_rep* crep) - : m_instance(instance) - , m_classrep(crep) - , m_dependency_cnt(0) - {} +namespace luabind { + namespace detail { + + // dest is a function that is called to delete the c++ object this struct holds + object_rep::object_rep(instance_holder* instance, class_rep* crep) + : m_instance(instance) + , m_classrep(crep) + { + } + + object_rep::~object_rep() + { + if(!m_instance) + return; + m_instance->~instance_holder(); + deallocate(m_instance); + } + + void object_rep::add_dependency(lua_State* L, int index) + { + if(!m_dependency_ref.is_valid()) + { + lua_newtable(L); + m_dependency_ref.set(L); + } + m_dependency_ref.get(L); + + lua_pushvalue(L, index); + lua_pushnumber(L, 0); + lua_rawset(L, -3); + lua_pop(L, 1); + } + + int destroy_instance(lua_State* L) + { + object_rep* instance = static_cast(lua_touserdata(L, 1)); + + lua_pushstring(L, "__finalize"); + lua_gettable(L, 1); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + } + else + { + lua_pushvalue(L, 1); + lua_call(L, 1, 0); + } + + instance->~object_rep(); + + lua_pushnil(L); + lua_setmetatable(L, 1); + return 0; + } + + namespace + { + + int set_instance_value(lua_State* L) + { + lua_getuservalue(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + lua_replace(L, -3); + lua_pop(L, 1); + } + + if(lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "set" function and call it. + lua_getupvalue(L, -1, 2); + + if(lua_isnil(L, -1)) + { + lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); + lua_error(L); + } + + lua_pushvalue(L, 1); + lua_pushvalue(L, 3); + lua_call(L, 2, 0); + return 0; + } + + lua_pop(L, 1); + + if(!lua_getmetatable(L, 4)) + { + lua_newtable(L); + lua_pushvalue(L, -1); + lua_setuservalue(L, 1); + lua_pushvalue(L, 4); + lua_setmetatable(L, -2); + } + else + { + lua_pop(L, 1); + } + + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_rawset(L, -3); + + return 0; + } + + int get_instance_value(lua_State* L) + { + lua_getuservalue(L, 1); + lua_pushvalue(L, 2); + lua_rawget(L, -2); + + if(lua_isnil(L, -1) && lua_getmetatable(L, -2)) + { + lua_pushvalue(L, 2); + lua_rawget(L, -2); + } + + if(lua_tocfunction(L, -1) == &property_tag) + { + // this member is a property, extract the "get" function and call it. + lua_getupvalue(L, -1, 1); + lua_pushvalue(L, 1); + lua_call(L, 1, 1); + } + + return 1; + } + + int dispatch_operator(lua_State* L) + { + for(int i = 0; i < 2; ++i) + { + if(get_instance(L, 1 + i)) + { + int nargs = lua_gettop(L); + + lua_pushvalue(L, lua_upvalueindex(1)); + lua_gettable(L, 1 + i); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + continue; + } + + lua_insert(L, 1); // move the function to the bottom + + nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; + + if(lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil + lua_remove(L, 3); + + lua_call(L, nargs, 1); + return 1; + } + } + + lua_pop(L, lua_gettop(L)); + lua_pushstring(L, "No such operator defined"); + lua_error(L); + + return 0; + } + + } // namespace unnamed + + LUABIND_API void push_instance_metatable(lua_State* L) + { + lua_newtable(L); + + // This is used as a tag to determine if a userdata is a luabind + // instance. We use a numeric key and a cclosure for fast comparison. + lua_pushnumber(L, 1); + lua_pushcclosure(L, get_instance_value, 0); + lua_rawset(L, -3); + + lua_pushcclosure(L, destroy_instance, 0); + lua_setfield(L, -2, "__gc"); + + lua_pushcclosure(L, get_instance_value, 0); + lua_setfield(L, -2, "__index"); + + lua_pushcclosure(L, set_instance_value, 0); + lua_setfield(L, -2, "__newindex"); + + for(int op = 0; op < number_of_operators; ++op) + { + lua_pushstring(L, get_operator_name(op)); + lua_pushvalue(L, -1); + lua_pushboolean(L, op == op_unm || op == op_len); + lua_pushcclosure(L, &dispatch_operator, 2); + lua_settable(L, -3); + } + } + + LUABIND_API object_rep* get_instance(lua_State* L, int index) + { + object_rep* result = static_cast(lua_touserdata(L, index)); + + if(!result || !lua_getmetatable(L, index)) + return 0; + + lua_rawgeti(L, -1, 1); + + if(lua_tocfunction(L, -1) != &get_instance_value) + result = 0; + + lua_pop(L, 2); + + return result; + } + + LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) + { + void* storage = lua_newuserdata(L, sizeof(object_rep)); + object_rep* result = new (storage) object_rep(0, cls); + cls->get_table(L); + lua_setuservalue(L, -2); + lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); + lua_setmetatable(L, -2); + return result; + } - object_rep::~object_rep() - { - if (!m_instance) - return; - m_instance->~instance_holder(); - deallocate(m_instance); } - - void object_rep::add_dependency(lua_State* L, int index) - { - assert(m_dependency_cnt < sizeof(object_rep)); - - void* key = (char*)this + m_dependency_cnt; - - lua_pushlightuserdata(L, key); - lua_pushvalue(L, index); - lua_rawset(L, LUA_REGISTRYINDEX); - - ++m_dependency_cnt; - } - - void object_rep::release_dependency_refs(lua_State* L) - { - for (std::size_t i = 0; i < m_dependency_cnt; ++i) - { - void* key = (char*)this + i; - lua_pushlightuserdata(L, key); - lua_pushnil(L); - lua_rawset(L, LUA_REGISTRYINDEX); - } - } - - int destroy_instance(lua_State* L) - { - object_rep* instance = static_cast(lua_touserdata(L, 1)); - - lua_pushstring(L, "__finalize"); - lua_gettable(L, 1); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - } - else - { - lua_pushvalue(L, 1); - lua_call(L, 1, 0); - } - - instance->release_dependency_refs(L); - instance->~object_rep(); - return 0; - } - - namespace - { - - int set_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - lua_replace(L, -3); - lua_pop(L, 1); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "set" function and call it. - lua_getupvalue(L, -1, 2); - - if (lua_isnil(L, -1)) - { - lua_pushfstring(L, "property '%s' is read only", lua_tostring(L, 2)); - lua_error(L); - } - - lua_pushvalue(L, 1); - lua_pushvalue(L, 3); - lua_call(L, 2, 0); - return 0; - } - - lua_pop(L, 1); - - if (!lua_getmetatable(L, 4)) - { - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setfenv(L, 1); - lua_pushvalue(L, 4); - lua_setmetatable(L, -2); - } - else - { - lua_pop(L, 1); - } - - lua_pushvalue(L, 2); - lua_pushvalue(L, 3); - lua_rawset(L, -3); - - return 0; - } - - int get_instance_value(lua_State* L) - { - lua_getfenv(L, 1); - lua_pushvalue(L, 2); - lua_rawget(L, -2); - - if (lua_isnil(L, -1) && lua_getmetatable(L, -2)) - { - lua_pushvalue(L, 2); - lua_rawget(L, -2); - } - - if (lua_tocfunction(L, -1) == &property_tag) - { - // this member is a property, extract the "get" function and call it. - lua_getupvalue(L, -1, 1); - lua_pushvalue(L, 1); - lua_call(L, 1, 1); - } - - return 1; - } - - int dispatch_operator(lua_State* L) - { - for (int i = 0; i < 2; ++i) - { - if (get_instance(L, 1 + i)) - { - int nargs = lua_gettop(L); - - lua_pushvalue(L, lua_upvalueindex(1)); - lua_gettable(L, 1 + i); - - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - continue; - } - - lua_insert(L, 1); // move the function to the bottom - - nargs = lua_toboolean(L, lua_upvalueindex(2)) ? 1 : nargs; - - if (lua_toboolean(L, lua_upvalueindex(2))) // remove trailing nil - lua_remove(L, 3); - - lua_call(L, nargs, 1); - return 1; - } - } - - lua_pop(L, lua_gettop(L)); - lua_pushstring(L, "No such operator defined"); - lua_error(L); - - return 0; - } - - } // namespace unnamed - - LUABIND_API void push_instance_metatable(lua_State* L) - { - lua_newtable(L); - - // just indicate that this really is a class and not just - // any user data - lua_pushboolean(L, 1); - lua_setfield(L, -2, "__luabind_class"); - - // This is used as a tag to determine if a userdata is a luabind - // instance. We use a numeric key and a cclosure for fast comparision. - lua_pushnumber(L, 1); - lua_pushcclosure(L, get_instance_value, 0); - lua_rawset(L, -3); - - lua_pushcclosure(L, destroy_instance, 0); - lua_setfield(L, -2, "__gc"); - - lua_pushcclosure(L, get_instance_value, 0); - lua_setfield(L, -2, "__index"); - - lua_pushcclosure(L, set_instance_value, 0); - lua_setfield(L, -2, "__newindex"); - - for (int op = 0; op < number_of_operators; ++op) - { - lua_pushstring(L, get_operator_name(op)); - lua_pushvalue(L, -1); - lua_pushboolean(L, op == op_unm || op == op_len); - lua_pushcclosure(L, &dispatch_operator, 2); - lua_settable(L, -3); - } - } - - LUABIND_API object_rep* get_instance(lua_State* L, int index) - { - object_rep* result = static_cast(lua_touserdata(L, index)); - - if (!result || !lua_getmetatable(L, index)) - return 0; - - lua_rawgeti(L, -1, 1); - - if (lua_tocfunction(L, -1) != &get_instance_value) - result = 0; - - lua_pop(L, 2); - - return result; - } - - LUABIND_API object_rep* push_new_instance(lua_State* L, class_rep* cls) - { - void* storage = lua_newuserdata(L, sizeof(object_rep)); - object_rep* result = new (storage) object_rep(0, cls); - cls->get_table(L); - lua_setfenv(L, -2); - lua_rawgeti(L, LUA_REGISTRYINDEX, cls->metatable_ref()); - lua_setmetatable(L, -2); - return result; - } - -}} +} diff --git a/libs/luabind/src/open.cpp b/libs/luabind/src/open.cpp index ec8e4ff64..bfdcbb8ec 100644 --- a/libs/luabind/src/open.cpp +++ b/libs/luabind/src/open.cpp @@ -24,173 +24,129 @@ #include -#include -#include +#include #include +#include +#include +#include namespace luabind { -namespace -{ + namespace + { - int make_property(lua_State* L) - { - int args = lua_gettop(L); + int make_property(lua_State* L) + { + int args = lua_gettop(L); - if (args == 0 || args > 2) - { - lua_pushstring(L, "make_property() called with wrong number of arguments."); - lua_error(L); - } + if(args == 0 || args > 2) + { + lua_pushstring(L, "make_property() called with wrong number of arguments."); + lua_error(L); + } - if (args == 1) - lua_pushnil(L); + if(args == 1) + lua_pushnil(L); - lua_pushcclosure(L, &detail::property_tag, 2); - return 1; - } + lua_pushcclosure(L, &detail::property_tag, 2); + return 1; + } - int main_thread_tag; + int main_thread_tag; - int deprecated_super(lua_State* L) - { - lua_pushstring(L, - "DEPRECATION: 'super' has been deprecated in favor of " - "directly calling the base class __init() function. " - "This error can be disabled by calling 'luabind::disable_super_deprecation()'." - ); - lua_error(L); + int deprecated_super(lua_State* L) + { + lua_pushstring(L, + "DEPRECATION: 'super' has been deprecated in favor of " + "directly calling the base class __init() function. " + "This error can be disabled by calling 'luabind::disable_super_deprecation()'." + ); + lua_error(L); - return 0; - } + return 0; + } - int destroy_class_id_map(lua_State* L) - { - detail::class_id_map* m = - (detail::class_id_map*)lua_touserdata(L, 1); - m->~class_id_map(); - return 0; - } + } // namespace unnamed - int destroy_cast_graph(lua_State* L) - { - detail::cast_graph* g = - (detail::cast_graph*)lua_touserdata(L, 1); - g->~cast_graph(); - return 0; - } + LUABIND_API lua_State* get_main_thread(lua_State* L) + { + lua_pushlightuserdata(L, &main_thread_tag); + lua_rawget(L, LUA_REGISTRYINDEX); + lua_State* result = static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); - int destroy_class_map(lua_State* L) - { - detail::class_map* m = - (detail::class_map*)lua_touserdata(L, 1); - m->~class_map(); - return 0; - } + if(!result) + throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); -} // namespace unnamed + return result; + } - LUABIND_API lua_State* get_main_thread(lua_State* L) - { - lua_pushlightuserdata(L, &main_thread_tag); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_State* result = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); + namespace { - if (!result) - throw std::runtime_error("Unable to get main thread, luabind::open() not called?"); + template + inline void * shared_create_userdata(lua_State* L, const char * name) { + lua_pushstring(L, name); + void* storage = lua_newuserdata(L, sizeof(T)); - return result; - } + // set gc metatable + lua_newtable(L); + lua_pushcclosure(L, &detail::garbage_collector, 0); + lua_setfield(L, -2, "__gc"); + lua_setmetatable(L, -2); - LUABIND_API void open(lua_State* L) - { - bool is_main_thread = lua_pushthread(L) == 1; - lua_pop(L, 1); + lua_settable(L, LUA_REGISTRYINDEX); + return storage; + } - if (!is_main_thread) - { - throw std::runtime_error( - "luabind::open() must be called with the main thread " - "lua_State*" - ); - } + template + inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name) { + void * storage = shared_create_userdata(L, name); + // placement "new" + new (storage) T; + } - if (detail::class_registry::get_registry(L)) - return; + template + inline void createGarbageCollectedRegistryUserdata(lua_State* L, const char * name, A1 constructorArg) { + void * storage = shared_create_userdata(L, name); - lua_pushstring(L, "__luabind_classes"); - detail::class_registry* r = static_cast( - lua_newuserdata(L, sizeof(detail::class_registry))); + // placement "new" + new (storage) T(constructorArg); + } - // set gc metatable - lua_newtable(L); - lua_pushstring(L, "__gc"); - lua_pushcclosure( - L - , detail::garbage_collector_s< - detail::class_registry - >::apply - , 0); + } // namespace anonymous - lua_settable(L, -3); - lua_setmetatable(L, -2); + LUABIND_API void open(lua_State* L) + { + bool is_main_thread = lua_pushthread(L) == 1; + lua_pop(L, 1); - new(r) detail::class_registry(L); - lua_settable(L, LUA_REGISTRYINDEX); + if(!is_main_thread) + { + throw std::runtime_error( + "luabind::open() must be called with the main thread " + "lua_State*" + ); + } - lua_pushstring(L, "__luabind_class_id_map"); - void* classes_storage = lua_newuserdata(L, sizeof(detail::class_id_map)); - detail::class_id_map* class_ids = new (classes_storage) detail::class_id_map; - (void)class_ids; + createGarbageCollectedRegistryUserdata(L, "__luabind_classes", L); + createGarbageCollectedRegistryUserdata(L, "__luabind_class_id_map"); + createGarbageCollectedRegistryUserdata(L, "__luabind_cast_graph"); + createGarbageCollectedRegistryUserdata(L, "__luabind_class_map"); - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_id_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); + // add functions (class, cast etc...) + lua_pushcclosure(L, detail::create_class::stage1, 0); + lua_setglobal(L, "class"); - lua_settable(L, LUA_REGISTRYINDEX); + lua_pushcclosure(L, &make_property, 0); + lua_setglobal(L, "property"); - lua_pushstring(L, "__luabind_cast_graph"); - void* cast_graph_storage = lua_newuserdata( - L, sizeof(detail::cast_graph)); - detail::cast_graph* graph = new (cast_graph_storage) detail::cast_graph; - (void)graph; + lua_pushlightuserdata(L, &main_thread_tag); + lua_pushlightuserdata(L, L); + lua_rawset(L, LUA_REGISTRYINDEX); - lua_newtable(L); - lua_pushcclosure(L, &destroy_cast_graph, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - lua_pushstring(L, "__luabind_class_map"); - void* class_map_storage = lua_newuserdata( - L, sizeof(detail::class_map)); - detail::class_map* classes = new (class_map_storage) detail::class_map; - (void)classes; - - lua_newtable(L); - lua_pushcclosure(L, &destroy_class_map, 0); - lua_setfield(L, -2, "__gc"); - lua_setmetatable(L, -2); - - lua_settable(L, LUA_REGISTRYINDEX); - - // add functions (class, cast etc...) - lua_pushcclosure(L, detail::create_class::stage1, 0); - lua_setglobal(L, "class"); - - lua_pushcclosure(L, &make_property, 0); - lua_setglobal(L, "property"); - - lua_pushlightuserdata(L, &main_thread_tag); - lua_pushlightuserdata(L, L); - lua_rawset(L, LUA_REGISTRYINDEX); - - lua_pushcclosure(L, &deprecated_super, 0); - lua_setglobal(L, "super"); - } + lua_pushcclosure(L, &deprecated_super, 0); + lua_setglobal(L, "super"); + } } // namespace luabind diff --git a/libs/luabind/luabind/detail/yes_no.hpp b/libs/luabind/src/operator.cpp similarity index 81% rename from libs/luabind/luabind/detail/yes_no.hpp rename to libs/luabind/src/operator.cpp index 931847c60..db64ce862 100644 --- a/libs/luabind/luabind/detail/yes_no.hpp +++ b/libs/luabind/src/operator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2004 Daniel Wallin +// Copyright (c) 2004 Daniel Wallin and Arvid Norberg // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -20,15 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. -#ifndef YES_NO_040211_HPP -#define YES_NO_040211_HPP +#define LUABIND_BUILDING -namespace luabind { namespace detail { +#include - typedef char(&yes_t)[1]; - typedef char(&no_t)[2]; - -}} // namespace luabind::detail - -#endif // YES_NO_040211_HPP +namespace luabind +{ + LUABIND_API self_type self; + LUABIND_API const_self_type const_self; +} diff --git a/libs/luabind/src/pcall.cpp b/libs/luabind/src/pcall.cpp index 1bf642531..07b3d9241 100644 --- a/libs/luabind/src/pcall.cpp +++ b/libs/luabind/src/pcall.cpp @@ -26,40 +26,38 @@ #include #include -namespace luabind { namespace detail -{ - int pcall(lua_State *L, int nargs, int nresults) - { - pcall_callback_fun e = get_pcall_callback(); - int en = 0; - if ( e ) +namespace luabind { + namespace detail { + + int pcall(lua_State *L, int nargs, int nresults) { - int base = lua_gettop(L) - nargs; - lua_pushcfunction(L, e); - lua_insert(L, base); // push pcall_callback under chunk and args - en = base; - } - int result = lua_pcall(L, nargs, nresults, en); - if ( en ) - lua_remove(L, en); // remove pcall_callback - return result; - } + pcall_callback_fun e = get_pcall_callback(); + int en = 0; + if(e) + { + int base = lua_gettop(L) - nargs; + e(L); + lua_insert(L, base); // push pcall_callback under chunk and args + en = base; + } + int result = lua_pcall(L, nargs, nresults, en); + if(en) + lua_remove(L, en); // remove pcall_callback + return result; + } - int resume_impl(lua_State *L, int nargs, int) - { + int resume_impl(lua_State *L, int nargs, int) + { #if LUA_VERSION_NUM >= 502 - int res = lua_resume(L, NULL, nargs); + int res = lua_resume(L, NULL, nargs); #else - int res = lua_resume(L, nargs); + int res = lua_resume(L, nargs); #endif + // Lua 5.1 added LUA_YIELD as a possible return value, + // this was causing crashes, because the caller expects 0 on success. + return (res == LUA_YIELD) ? 0 : res; + } -#if LUA_VERSION_NUM >= 501 - // Lua 5.1 added LUA_YIELD as a possible return value, - // this was causing crashes, because the caller expects 0 on success. - return (res == LUA_YIELD) ? 0 : res; -#else - return res; -#endif } +} -}} diff --git a/libs/luabind/src/scope.cpp b/libs/luabind/src/scope.cpp index 52bd132f9..0137af674 100644 --- a/libs/luabind/src/scope.cpp +++ b/libs/luabind/src/scope.cpp @@ -27,182 +27,182 @@ #include #include #include -#include #include -namespace luabind { namespace detail { - - registration::registration() - : m_next(0) - { - } - - registration::~registration() - { - delete m_next; - } - - } // namespace detail - - scope::scope() - : m_chain(0) - { - } - - scope::scope(std::auto_ptr reg) - : m_chain(reg.release()) - { - } - - scope::scope(scope const& other) - : m_chain(other.m_chain) - { - const_cast(other).m_chain = 0; - } - - scope& scope::operator=(scope const& other_) - { - delete m_chain; - m_chain = other_.m_chain; - const_cast(other_).m_chain = 0; - return *this; - } - - scope::~scope() - { - delete m_chain; - } - - scope& scope::operator,(scope s) - { - if (!m_chain) - { - m_chain = s.m_chain; - s.m_chain = 0; - return *this; - } - - for (detail::registration* c = m_chain;; c = c->m_next) - { - if (!c->m_next) - { - c->m_next = s.m_chain; - s.m_chain = 0; - break; - } - } - - return *this; - } - - void scope::register_(lua_State* L) const - { - for (detail::registration* r = m_chain; r != 0; r = r->m_next) - { - LUABIND_CHECK_STACK(L); - r->register_(L); - } - } - -} // namespace luabind +#if LUA_VERSION_NUM < 502 +# define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX) +#endif namespace luabind { + namespace detail { - namespace { + registration::registration() + : m_next(0) + { + } - struct lua_pop_stack - { - lua_pop_stack(lua_State* L) - : m_state(L) - { - } + registration::~registration() + { + delete m_next; + } - ~lua_pop_stack() - { - lua_pop(m_state, 1); - } + } // namespace detail - lua_State* m_state; - }; + scope::scope() + : m_chain(0) + { + } - } // namespace unnamed - - module_::module_(lua_State* L, char const* name = 0) - : m_state(L) - , m_name(name) - { - } + scope::scope(std::unique_ptr reg) + : m_chain(reg.release()) + { + } - void module_::operator[](scope s) - { - if (m_name) - { - lua_getglobal(m_state, m_name); + scope::scope(scope const& other) + : m_chain(other.m_chain) + { + const_cast(other).m_chain = 0; + } - if (!lua_istable(m_state, -1)) - { - lua_pop(m_state, 1); + scope& scope::operator=(scope const& other_) + { + delete m_chain; + m_chain = other_.m_chain; + const_cast(other_).m_chain = 0; + return *this; + } - lua_newtable(m_state); - lua_pushvalue(m_state, -1); - lua_setglobal(m_state, m_name); - } - } - else - { - lua_pushglobaltable(m_state); - } + scope::~scope() + { + delete m_chain; + } - lua_pop_stack guard(m_state); + scope& scope::operator,(scope s) + { + if(!m_chain) + { + m_chain = s.m_chain; + s.m_chain = 0; + return *this; + } - s.register_(m_state); - } + for(detail::registration* c = m_chain;; c = c->m_next) + { + if(!c->m_next) + { + c->m_next = s.m_chain; + s.m_chain = 0; + break; + } + } - struct namespace_::registration_ : detail::registration - { - registration_(char const* name) - : m_name(name) - { - } + return *this; + } - void register_(lua_State* L) const - { + void scope::register_(lua_State* L) const + { + for(detail::registration* r = m_chain; r != 0; r = r->m_next) + { LUABIND_CHECK_STACK(L); - assert(lua_gettop(L) >= 1); + r->register_(L); + } + } - lua_pushstring(L, m_name); - lua_gettable(L, -2); + namespace { + + struct lua_pop_stack + { + lua_pop_stack(lua_State* L) + : m_state(L) + { + } + + ~lua_pop_stack() + { + lua_pop(m_state, 1); + } + + lua_State* m_state; + }; + + } // namespace unnamed + + module_::module_(lua_State* L, char const* name = 0) + : m_state(L) + , m_name(name) + { + } + + void module_::operator[](scope s) + { + if(m_name) + { + lua_getglobal(m_state, m_name); + + if(!lua_istable(m_state, -1)) + { + lua_pop(m_state, 1); + + lua_newtable(m_state); + lua_pushvalue(m_state, -1); + lua_setglobal(m_state, m_name); + } + } + else + { + lua_pushglobaltable(m_state); + } + + lua_pop_stack guard(m_state); + + s.register_(m_state); + } + + struct namespace_::registration_ : detail::registration + { + registration_(char const* name) + : m_name(name) + { + } + + void register_(lua_State* L) const + { + LUABIND_CHECK_STACK(L); + assert(lua_gettop(L) >= 1); + + lua_pushstring(L, m_name); + lua_gettable(L, -2); detail::stack_pop p(L, 1); // pops the table on exit - if (!lua_istable(L, -1)) - { - lua_pop(L, 1); + if(!lua_istable(L, -1)) + { + lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, m_name); - lua_pushvalue(L, -2); - lua_settable(L, -4); - } + lua_newtable(L); + lua_pushstring(L, m_name); + lua_pushvalue(L, -2); + lua_settable(L, -4); + } - m_scope.register_(L); - } + m_scope.register_(L); + } - char const* m_name; - scope m_scope; - }; + char const* m_name; + scope m_scope; + }; - namespace_::namespace_(char const* name) - : scope(std::auto_ptr( - m_registration = new registration_(name))) - { - } + namespace_::namespace_(char const* name) + : scope(std::unique_ptr( + m_registration = new registration_(name))) + { + } - namespace_& namespace_::operator[](scope s) - { - m_registration->m_scope.operator,(s); - return *this; - } + namespace_& namespace_::operator[](scope s) + { + m_registration->m_scope.operator,(s); + return *this; + } } // namespace luabind diff --git a/libs/luabind/src/set_package_preload.cpp b/libs/luabind/src/set_package_preload.cpp new file mode 100644 index 000000000..166835c66 --- /dev/null +++ b/libs/luabind/src/set_package_preload.cpp @@ -0,0 +1,60 @@ +/** + @file + @brief Implementation + + @date 2012 + + @author + Ryan Pavlik + and + http://academic.cleardefinition.com/ + Iowa State University Virtual Reality Applications Center + Human-Computer Interaction Graduate Program +*/ + +// Copyright Iowa State University 2012. +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +// OR OTHER DEALINGS IN THE SOFTWARE. + +#define LUABIND_BUILDING + +// Internal Includes +#include +#include // for LUABIND_API +#include // for object, rawget, globals +#include + +// Library/third-party includes +#include // for lua_pushstring, lua_rawset, etc + +// Standard includes +// - none + + +namespace luabind { + LUABIND_API void set_package_preload(lua_State * L, const char * modulename, int(*loader) (lua_State *)) { + rawget(rawget(globals(L), "package"), "preload").push(L); + lua_pushcclosure(L, loader, 0); + lua_setfield(L, -2, modulename); + lua_pop(L, 1); + } + +} // namespace luabind + diff --git a/libs/luabind/src/stack_content_by_name.cpp b/libs/luabind/src/stack_content_by_name.cpp index 38b5c691d..e141c4054 100644 --- a/libs/luabind/src/stack_content_by_name.cpp +++ b/libs/luabind/src/stack_content_by_name.cpp @@ -22,9 +22,12 @@ #define LUABIND_BUILDING -#include +#include // for lua_gettop, lua_touserdata, etc -#include +#include // for class_rep, is_class_rep +#include // for get_instance, object_rep + +#include // for string using namespace luabind::detail; @@ -32,27 +35,27 @@ std::string luabind::detail::stack_content_by_name(lua_State* L, int start_index { std::string ret; int top = lua_gettop(L); - for (int i = start_index; i <= top; ++i) + for(int i = start_index; i <= top; ++i) { object_rep* obj = get_instance(L, i); - class_rep* crep = is_class_rep(L, i)?(class_rep*)lua_touserdata(L, i):0; - if (obj == 0 && crep == 0) + class_rep* crep = is_class_rep(L, i) ? (class_rep*)lua_touserdata(L, i) : 0; + if(obj == 0 && crep == 0) { int type = lua_type(L, i); ret += lua_typename(L, type); } - else if (obj) + else if(obj) { - if (obj->is_const()) ret += "const "; + if(obj->is_const()) ret += "const "; ret += obj->crep()->name(); } - else if (crep) + else if(crep) { ret += "<"; ret += crep->name(); ret += ">"; } - if (i < top) ret += ", "; + if(i < top) ret += ", "; } return ret; } diff --git a/libs/luabind/src/weak_ref.cpp b/libs/luabind/src/weak_ref.cpp index 245b26c2e..b73ba3876 100644 --- a/libs/luabind/src/weak_ref.cpp +++ b/libs/luabind/src/weak_ref.cpp @@ -32,126 +32,155 @@ namespace luabind { -namespace -{ + namespace + { - int weak_table_tag; + int weak_table_tag; + int impl_table_tag; -} // namespace unnamed + } // namespace unnamed -LUABIND_API void get_weak_table(lua_State* L) -{ - lua_pushlightuserdata(L, &weak_table_tag); - lua_rawget(L, LUA_REGISTRYINDEX); + LUABIND_API void get_weak_table(lua_State* L) + { + lua_pushlightuserdata(L, &weak_table_tag); + lua_rawget(L, LUA_REGISTRYINDEX); - if (lua_isnil(L, -1)) - { - lua_pop(L, 1); - lua_newtable(L); - // metatable - lua_newtable(L); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "v"); - lua_rawset(L, -3); - // set metatable - lua_setmetatable(L, -2); + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + lua_newtable(L); + // metatable + lua_createtable(L, 0, 1); // One non-sequence entry for __mode. + lua_pushliteral(L, "__mode"); + lua_pushliteral(L, "v"); + lua_rawset(L, -3); + // set metatable + lua_setmetatable(L, -2); - lua_pushlightuserdata(L, &weak_table_tag); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); - } -} + lua_pushlightuserdata(L, &weak_table_tag); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + + } + + } + + LUABIND_API void get_impl_table(lua_State* L) + { + + lua_pushlightuserdata(L, &impl_table_tag); + lua_rawget(L, LUA_REGISTRYINDEX); + + if(lua_isnil(L, -1)) + { + lua_pop(L, 1); + + lua_newtable(L); + lua_pushlightuserdata(L, &impl_table_tag); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + + } + + } } // namespace luabind namespace luabind { - struct weak_ref::impl - { - impl(lua_State* main, lua_State* s, int index) - : count(0) - , state(main) - , ref(0) - { - get_weak_table(s); - lua_pushvalue(s, index); - ref = luaL_ref(s, -2); - lua_pop(s, 1); - } + struct weak_ref::impl + { + impl(lua_State* main, lua_State* s, int index) + : count(0) + , state(main) + , ref(0) + { - ~impl() - { - get_weak_table(state); - luaL_unref(state, -1, ref); - lua_pop(state, 1); - } + get_impl_table(s); + lua_pushlightuserdata(s, this); + ref = luaL_ref(s, -2); + lua_pop(s, 1); - int count; - lua_State* state; - int ref; - }; + get_weak_table(s); + lua_pushvalue(s, index); + lua_rawseti(s, -2, ref); + lua_pop(s, 1); - weak_ref::weak_ref() - : m_impl(0) - { - } - - weak_ref::weak_ref(lua_State* main, lua_State* L, int index) - : m_impl(new impl(main, L, index)) - { - m_impl->count = 1; - } + } - weak_ref::weak_ref(weak_ref const& other) - : m_impl(other.m_impl) - { - if (m_impl) ++m_impl->count; - } + ~impl() + { + get_impl_table(state); + luaL_unref(state, -1, ref); + lua_pop(state, 1); + } - weak_ref::~weak_ref() - { - if (m_impl && --m_impl->count == 0) - { - delete m_impl; - } - } + int count; + lua_State* state; + int ref; + }; - weak_ref& weak_ref::operator=(weak_ref const& other) - { - weak_ref(other).swap(*this); - return *this; - } + weak_ref::weak_ref() + : m_impl(0) + { + } - void weak_ref::swap(weak_ref& other) - { - std::swap(m_impl, other.m_impl); - } + weak_ref::weak_ref(lua_State* main, lua_State* L, int index) + : m_impl(new impl(main, L, index)) + { + m_impl->count = 1; + } - int weak_ref::id() const - { - assert(m_impl); + weak_ref::weak_ref(weak_ref const& other) + : m_impl(other.m_impl) + { + if(m_impl) ++m_impl->count; + } + + weak_ref::~weak_ref() + { + if(m_impl && --m_impl->count == 0) + { + delete m_impl; + } + } + + weak_ref& weak_ref::operator=(weak_ref const& other) + { + weak_ref(other).swap(*this); + return *this; + } + + void weak_ref::swap(weak_ref& other) + { + std::swap(m_impl, other.m_impl); + } + + int weak_ref::id() const + { + assert(m_impl); return m_impl->ref; - } + } // L may not be the same pointer as // was used when creating this reference // since it may be a thread that shares // the same globals table. - void weak_ref::get(lua_State* L) const - { - assert(m_impl); + void weak_ref::get(lua_State* L) const + { + assert(m_impl); assert(L); - get_weak_table(L); - lua_rawgeti(L, -1, m_impl->ref); - lua_remove(L, -2); - } + get_weak_table(L); + lua_rawgeti(L, -1, m_impl->ref); + lua_remove(L, -2); + } + + lua_State* weak_ref::state() const + { + assert(m_impl); + return m_impl->state; + } - lua_State* weak_ref::state() const - { - assert(m_impl); - return m_impl->state; - } - } // namespace luabind diff --git a/libs/luabind/src/wrapper_base.cpp b/libs/luabind/src/wrapper_base.cpp index 9fb54a5db..d09dfe983 100644 --- a/libs/luabind/src/wrapper_base.cpp +++ b/libs/luabind/src/wrapper_base.cpp @@ -29,27 +29,29 @@ #include #include -namespace luabind { namespace detail -{ - LUABIND_API void do_call_member_selection(lua_State* L, char const* name) - { - object_rep* obj = static_cast(lua_touserdata(L, -1)); - lua_pop(L, 1); // pop self +namespace luabind { + namespace detail { - obj->crep()->get_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table + LUABIND_API void do_call_member_selection(lua_State* L, char const* name) + { + object_rep* obj = static_cast(lua_touserdata(L, -1)); + assert(obj); - if (!is_luabind_function(L, -1)) - return; + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_replace(L, -2); - // this (usually) means the function has not been - // overridden by lua, call the default implementation - lua_pop(L, 1); - obj->crep()->get_default_table(L); // push the crep table - lua_pushstring(L, name); - lua_gettable(L, -2); - lua_remove(L, -2); // remove the crep table + if(!is_luabind_function(L, -1)) + return; + + // this (usually) means the function has not been + // overridden by lua, call the default implementation + lua_pop(L, 1); + obj->crep()->get_default_table(L); // push the crep table + lua_pushstring(L, name); + lua_gettable(L, -2); + lua_remove(L, -2); // remove the crep table + } } -}} +} + From 5f23a72a16c4a932a2227471b0044878a49e81cd Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:08:39 -0600 Subject: [PATCH 012/491] Removed unused boost header, fixed compiling with new luabind Fixed TryFinishingBlow attempting to return by parameter reference. The new luabind fails with a by_reference to by_value check. Using a pointer accomplishes the same goal, but bypasses this issue. --- zone/attack.cpp | 1 - zone/lua_entity_list.cpp | 14 +++++++------- zone/lua_hate_list.cpp | 2 +- zone/lua_mob.cpp | 6 +++--- zone/lua_mob.h | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 483cce368..f5fc34a2c 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -39,7 +39,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include -#include #ifdef BOTS #include "bot.h" diff --git a/zone/lua_entity_list.cpp b/zone/lua_entity_list.cpp index abfc020d6..3d53b6166 100644 --- a/zone/lua_entity_list.cpp +++ b/zone/lua_entity_list.cpp @@ -508,37 +508,37 @@ luabind::scope lua_register_entity_list() { luabind::scope lua_register_mob_list() { return luabind::class_("MobList") - .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Mob_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_client_list() { return luabind::class_("ClientList") - .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Client_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_npc_list() { return luabind::class_("NPCList") - .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_NPC_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_corpse_list() { return luabind::class_("CorpseList") - .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Corpse_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_object_list() { return luabind::class_("ObjectList") - .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Object_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_door_list() { return luabind::class_("DoorList") - .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Doors_List::entries, luabind::return_stl_iterator()); } luabind::scope lua_register_spawn_list() { return luabind::class_("SpawnList") - .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_Spawn_List::entries, luabind::return_stl_iterator()); } #endif diff --git a/zone/lua_hate_list.cpp b/zone/lua_hate_list.cpp index e8c6a52df..82d79f977 100644 --- a/zone/lua_hate_list.cpp +++ b/zone/lua_hate_list.cpp @@ -63,7 +63,7 @@ luabind::scope lua_register_hate_entry() { luabind::scope lua_register_hate_list() { return luabind::class_("HateList") - .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator); + .def_readwrite("entries", &Lua_HateList::entries, luabind::return_stl_iterator()); } #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 59d50508e..c09cc8b0d 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -2141,9 +2141,9 @@ bool Lua_Mob::IsBerserk() { return self->IsBerserk(); } -bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int &damage) { +bool Lua_Mob::TryFinishingBlow(Lua_Mob defender, int *damage) { Lua_Safe_Call_Bool(); - return self->TryFinishingBlow(defender, damage); + return self->TryFinishingBlow(defender, *damage); } int Lua_Mob::GetBodyType() @@ -2540,7 +2540,7 @@ luabind::scope lua_register_mob() { .def("AttackAnimation", &Lua_Mob::AttackAnimation) .def("GetWeaponDamage", &Lua_Mob::GetWeaponDamage) .def("IsBerserk", &Lua_Mob::IsBerserk) - .def("TryFinishingBlow", &Lua_Mob::TryFinishingBlow) + .def("TryFinishingBlow", (bool(Lua_Mob::*)(int*))&Lua_Mob::TryFinishingBlow) .def("GetBodyType", &Lua_Mob::GetBodyType) .def("GetOrigBodyType", &Lua_Mob::GetOrigBodyType) .def("CheckNumHitsRemaining", &Lua_Mob::CheckNumHitsRemaining); diff --git a/zone/lua_mob.h b/zone/lua_mob.h index fc58af6d5..993556ae3 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -411,7 +411,7 @@ public: int AttackAnimation(int Hand, Lua_ItemInst weapon); int GetWeaponDamage(Lua_Mob against, Lua_ItemInst weapon); bool IsBerserk(); - bool TryFinishingBlow(Lua_Mob defender, int &damage); + bool TryFinishingBlow(Lua_Mob defender, int *damage); int GetBodyType(); int GetOrigBodyType(); void CheckNumHitsRemaining(int type, int32 buff_slot, uint16 spell_id); From f6c8d9532e9116d88c904a0b014b49d4b291674a Mon Sep 17 00:00:00 2001 From: Adam Martin Date: Sat, 2 Feb 2019 00:32:41 -0600 Subject: [PATCH 013/491] Applied changes proposed in https://github.com/decimad/luabind-deboostified/pull/38/ These changes claim to fix GCC 7 compilation. --- .../conversion_policies/function_converter.hpp | 12 +++++------- libs/luabind/luabind/detail/push_to_lua.hpp | 1 + libs/luabind/luabind/lua_index_proxy.hpp | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp index 13c27da09..905784730 100644 --- a/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp +++ b/libs/luabind/luabind/detail/conversion_policies/function_converter.hpp @@ -39,15 +39,13 @@ namespace luabind { template< typename T > struct is_function< std::function< T > > : public std::true_type {}; - - template< typename R, typename... Args, typename WrappedType > - struct deduce_signature , WrappedType > - { - using type = meta::type_list< R, Args... >; - }; - } + template< typename R, typename... Args, typename WrappedType > + struct deduce_signature , WrappedType > + { + using type = meta::type_list< R, Args... >; + }; template struct default_converter>::value>::type> diff --git a/libs/luabind/luabind/detail/push_to_lua.hpp b/libs/luabind/luabind/detail/push_to_lua.hpp index 22ad8534f..8bb2e646a 100644 --- a/libs/luabind/luabind/detail/push_to_lua.hpp +++ b/libs/luabind/luabind/detail/push_to_lua.hpp @@ -26,6 +26,7 @@ #include #include +#include namespace luabind { diff --git a/libs/luabind/luabind/lua_index_proxy.hpp b/libs/luabind/luabind/lua_index_proxy.hpp index f8c726de1..c62314f91 100644 --- a/libs/luabind/luabind/lua_index_proxy.hpp +++ b/libs/luabind/luabind/lua_index_proxy.hpp @@ -72,7 +72,7 @@ namespace luabind { detail::stack_pop pop(m_interpreter, 1); lua_pushvalue(m_interpreter, m_key_index); - detail::push(m_interpreter, value); + detail::push_to_lua(m_interpreter, value); lua_settable(m_interpreter, -3); return *this; } From 1aab23098a7910c27e2b70a8bad059e0975eda84 Mon Sep 17 00:00:00 2001 From: Trust Date: Tue, 18 Jun 2019 23:59:37 +0000 Subject: [PATCH 014/491] Container lock inconsistent state fix --- zone/object.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/zone/object.cpp b/zone/object.cpp index 4306c6642..df143085c 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -443,6 +443,14 @@ bool Object::Process(){ if(m_ground_spawn && respawn_timer.Check()){ RandomSpawn(true); } + + if (user != nullptr && !entity_list.GetClientByCharID(user->CharacterID())) { + m_inuse = false; + last_user = user; + user->SetTradeskillObject(nullptr); + user = nullptr; + } + return true; } @@ -554,7 +562,6 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) ClickObjectAction_Struct* coa = (ClickObjectAction_Struct*)outapp->pBuffer; //TODO: there is prolly a better way to do this. - m_inuse = true; coa->type = m_type; coa->unknown16 = 0x0a; @@ -576,12 +583,6 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) } } - if(sender->IsLooting()) - { - coa->open = 0x00; - user = sender; - } - sender->QueuePacket(outapp); safe_delete(outapp); @@ -590,6 +591,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) return(false); // Starting to use this object + m_inuse = true; sender->SetTradeskillObject(this); user = sender; From 682054970cfb0295ea6905d05d170fa5b59e1ad8 Mon Sep 17 00:00:00 2001 From: Justin Wienckowski Date: Mon, 15 Apr 2019 02:06:48 -0700 Subject: [PATCH 015/491] Zone::IsSpellBlocked should correctly handle spellid 0 (all spells) blocked in a region (type 2). --- zone/zone.cpp | 55 +++++++++++++++++++++------------------------------ 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/zone/zone.cpp b/zone/zone.cpp index 923e37a39..90e7fafc7 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1952,46 +1952,37 @@ bool Zone::IsSpellBlocked(uint32 spell_id, const glm::vec3& location) } } + // If all spells are blocked and this is an exception, it is not blocked + if (block_all && exception) + { + return false; + } + for (int x = 0; x < totalBS; x++) { - // If spellid is 0, block all spells in the zone - if (block_all) + // Spellid of 0 matches all spells + if (0 != blocked_spells[x].spellid && spell_id != blocked_spells[x].spellid) { - // If the same zone has entries other than spellid 0, they act as exceptions and are allowed - if (exception) - { - return false; - } - else + continue; + } + + switch (blocked_spells[x].type) + { + case 1: { return true; + break; } - } - else - { - if (spell_id != blocked_spells[x].spellid) + case 2: + { + if (IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference)) + return true; + break; + } + default: { continue; - } - - switch (blocked_spells[x].type) - { - case 1: - { - return true; - break; - } - case 2: - { - if (IsWithinAxisAlignedBox(location, blocked_spells[x].m_Location - blocked_spells[x].m_Difference, blocked_spells[x].m_Location + blocked_spells[x].m_Difference)) - return true; - break; - } - default: - { - continue; - break; - } + break; } } } From ea02042ace78e406cb491ac02a890776ce04fd94 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 01:40:36 -0500 Subject: [PATCH 016/491] Merge fixes --- loginserver/client_manager.cpp | 4 +- world/console.cpp | 292 +++++++++++++++++++++++++++------ world/login_server.cpp | 18 +- world/login_server.h | 2 - zone/api_service.cpp | 23 ++- 5 files changed, 268 insertions(+), 71 deletions(-) diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index d487e971e..9c8e3de09 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -27,7 +27,7 @@ extern bool run_server; ClientManager::ClientManager() { int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); - EQ::Net::EQStreamManagerOptions titanium_opts(titanium_port, false, false); + EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); titanium_ops = new RegularOpcodeManager; if (!titanium_ops->LoadOpcodes(server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str())) @@ -45,7 +45,7 @@ ClientManager::ClientManager() }); int sod_port = server.config.GetVariableInt("SoD", "port", 5999); - EQ::Net::EQStreamManagerOptions sod_opts(sod_port, false, false); + EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false); sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) diff --git a/world/console.cpp b/world/console.cpp index b14bbfff8..e5643e5b1 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -44,7 +44,8 @@ extern LoginServerList loginserverlist; struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string &username, const std::string &password) { struct EQ::Net::ConsoleLoginStatus ret; - std::string prefix = "eqemu"; + + std::string prefix = "eqemu"; std::string raw_user = ""; ParseAccountString(username, raw_user, prefix); @@ -54,10 +55,10 @@ struct EQ::Net::ConsoleLoginStatus CheckLogin(const std::string &username, const if (ret.account_id == 0) { return ret; } - + char account_name[64]; database.GetAccountName(ret.account_id, account_name); - + ret.account_name = account_name; ret.status = database.CheckStatus(ret.account_id); return ret; @@ -717,25 +718,17 @@ void ConsoleSetPass( connection->SendLine("Format: setpass accountname password"); } else { - std::string prefix = "eqemu"; + std::string prefix = "eqemu"; std::string raw_user = ""; ParseAccountString(args[0], raw_user, prefix); - int16 tmpstatus = 0; - uint32 tmpid = database.GetAccountIDByName(raw_user.c_str(), prefix.c_str(), &tmpstatus); - if (!tmpid) + int16 tmpstatus = 0; + uint32 tmpid = database.GetAccountIDByName(raw_user.c_str(), prefix.c_str(), &tmpstatus); + + if (!tmpid) { connection->SendLine("Error: Account not found"); } - else if (tmpstatus > connection->Admin()) { - connection->SendLine("Cannot change password: Account's status is higher than yours"); - } - else if (database.SetLocalPassword(tmpid, args[1].c_str())) { - connection->SendLine("Password changed."); - } - else { - connection->SendLine("Error changing password."); - } } } @@ -879,37 +872,242 @@ void ConsoleQuit( /** * @param console */ -void RegisterConsoleFunctions(std::unique_ptr& console) +void RegisterConsoleFunctions(std::unique_ptr &console) { console->RegisterLogin(std::bind(CheckLogin, std::placeholders::_1, std::placeholders::_2)); - console->RegisterCall("acceptmessages", 50, "acceptmessages [on/off]", std::bind(ConsoleAcceptMessages, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("api", 200, "api", std::bind(ConsoleApi, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("auction", 50, "auction [message]", std::bind(ConsoleAuction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("broadcast", 50, "broadcast [message]", std::bind(ConsoleBroadcast, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("echo", 50, "echo [on/off]", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("emote", 50, "emote [zonename or charname or world] [type] [message]", std::bind(ConsoleEmote, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("flag", 200, "flag [status] [accountname]", std::bind(ConsoleFlag, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("gmsay", 50, "gmsay [message]", std::bind(ConsoleGMSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("iplookup", 50, "IPLookup [name]", std::bind(ConsoleIpLookup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("kick", 150, "kick [charname]", std::bind(ConsoleKick, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("lock", 150, "lock", std::bind(ConsoleLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("lsreconnect", 50, "LSReconnect", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("md5", 50, "md5", std::bind(ConsoleMd5, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("ooc", 50, "ooc [message]", std::bind(ConsoleOOC, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("reloadworld", 200, "reloadworld", std::bind(ConsoleReloadWorld, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("setpass", 200, "setpass [accountname] [newpass]", std::bind(ConsoleSetPass, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("signalcharbyname", 50, "signalcharbyname charname ID", std::bind(ConsoleSignalCharByName, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("tell", 50, "tell [name] [message]", std::bind(ConsoleTell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("unlock", 150, "unlock", std::bind(ConsoleUnlock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("uptime", 50, "uptime [zoneID#]", std::bind(ConsoleUptime, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("version", 50, "version", std::bind(ConsoleVersion, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("who", 50, "who", std::bind(ConsoleWho, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("whoami", 50, "whoami", std::bind(ConsoleWhoami, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("worldshutdown", 200, "worldshutdown", std::bind(ConsoleWorldShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("zonebootup", 150, "zonebootup [ZoneServerID] [zonename]", std::bind(ConsoleZoneBootup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("zonelock", 150, "zonelock [list|lock|unlock] [zonename]", std::bind(ConsoleZoneLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("zoneshutdown", 150, "zoneshutdown [zonename or ZoneServerID]", std::bind(ConsoleZoneShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("zonestatus", 50, "zonestatus", std::bind(ConsoleZoneStatus, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));console->RegisterCall("ping", 50, "ping", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("quit", 50, "quit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall("exit", 50, "exit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "acceptmessages", + 50, + "acceptmessages [on/off]", + std::bind( + ConsoleAcceptMessages, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "api", + 200, + "api", + std::bind(ConsoleApi, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "auction", + 50, + "auction [message]", + std::bind( + ConsoleAuction, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "broadcast", + 50, + "broadcast [message]", + std::bind( + ConsoleBroadcast, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "echo", + 50, + "echo [on/off]", + std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "emote", + 50, + "emote [zonename or charname or world] [type] [message]", + std::bind(ConsoleEmote, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "flag", + 200, + "flag [status] [accountname]", + std::bind(ConsoleFlag, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "gmsay", + 50, + "gmsay [message]", + std::bind(ConsoleGMSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "iplookup", + 50, + "IPLookup [name]", + std::bind( + ConsoleIpLookup, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "kick", + 150, + "kick [charname]", + std::bind(ConsoleKick, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "lock", + 150, + "lock", + std::bind(ConsoleLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "lsreconnect", + 50, + "LSReconnect", + std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "md5", + 50, + "md5", + std::bind(ConsoleMd5, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "ooc", + 50, + "ooc [message]", + std::bind(ConsoleOOC, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "reloadworld", + 200, + "reloadworld", + std::bind( + ConsoleReloadWorld, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "setpass", + 200, + "setpass [accountname] [newpass]", + std::bind( + ConsoleSetPass, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "signalcharbyname", + 50, + "signalcharbyname charname ID", + std::bind( + ConsoleSignalCharByName, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "tell", + 50, + "tell [name] [message]", + std::bind(ConsoleTell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "unlock", + 150, + "unlock", + std::bind( + ConsoleUnlock, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "uptime", + 50, + "uptime [zoneID#]", + std::bind( + ConsoleUptime, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "version", + 50, + "version", + std::bind( + ConsoleVersion, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "who", + 50, + "who", + std::bind(ConsoleWho, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "whoami", + 50, + "whoami", + std::bind( + ConsoleWhoami, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "worldshutdown", + 200, + "worldshutdown", + std::bind( + ConsoleWorldShutdown, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "zonebootup", + 150, + "zonebootup [ZoneServerID] [zonename]", + std::bind( + ConsoleZoneBootup, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "zonelock", + 150, + "zonelock [list|lock|unlock] [zonename]", + std::bind( + ConsoleZoneLock, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "zoneshutdown", + 150, + "zoneshutdown [zonename or ZoneServerID]", + std::bind( + ConsoleZoneShutdown, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "zonestatus", + 50, + "zonestatus", + std::bind( + ConsoleZoneStatus, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + console->RegisterCall( + "ping", + 50, + "ping", + std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "quit", + 50, + "quit", + std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall( + "exit", + 50, + "exit", + std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } diff --git a/world/login_server.cpp b/world/login_server.cpp index 69778d34a..0043a15a5 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -360,20 +360,4 @@ void LoginServer::SendAccountUpdate(ServerPacket* pack) { strn0cpy(s->worldpassword, LoginPassword.c_str(), 30); SendPacket(pack); } -} - -bool LoginServer::Connected() -{ - if (IsLegacy) { - if (legacy_client) { - return legacy_client->Connected(); - } - } - else { - if (client) { - return client->Connected(); - } - } - - return false; -} +} \ No newline at end of file diff --git a/world/login_server.h b/world/login_server.h index 161c1388f..9134f4654 100644 --- a/world/login_server.h +++ b/world/login_server.h @@ -35,14 +35,12 @@ public: ~LoginServer(); bool Connect(); - void SendInfo(); void SendStatus(); void SendPacket(ServerPacket* pack); void SendAccountUpdate(ServerPacket* pack); bool Connected() { return IsLegacy ? legacy_client->Connected() : client->Connected(); } - bool MiniLogin() { return minilogin; } bool CanUpdate() { return CanAccountUpdate; } private: diff --git a/zone/api_service.cpp b/zone/api_service.cpp index 957d2b012..5be7a7927 100644 --- a/zone/api_service.cpp +++ b/zone/api_service.cpp @@ -34,13 +34,25 @@ extern Zone *zone; -EQ::Net::WebsocketLoginStatus -CheckLogin(EQ::Net::WebsocketServerConnection *connection, const std::string &username, const std::string &password) +/** + * @param connection + * @param username + * @param password + * @return + */ +EQ::Net::WebsocketLoginStatus CheckLogin( + EQ::Net::WebsocketServerConnection *connection, + const std::string &username, + const std::string &password +) { EQ::Net::WebsocketLoginStatus ret; ret.logged_in = false; - ret.account_id = database.CheckLogin(username.c_str(), password.c_str()); + + std::string prefix = "eqemu"; + + ret.account_id = database.CheckLogin(username.c_str(), password.c_str(), prefix.c_str()); if (ret.account_id == 0) { return ret; @@ -54,6 +66,11 @@ CheckLogin(EQ::Net::WebsocketServerConnection *connection, const std::string &us return ret; } +/** + * @param connection + * @param params + * @return + */ Json::Value ApiGetPacketStatistics(EQ::Net::WebsocketServerConnection *connection, Json::Value params) { if (zone->GetZoneID() == 0) { From 6638b9ade522f2571ada349d9cba33422151f6ee Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 02:16:16 -0500 Subject: [PATCH 017/491] Cleanup --- loginserver/database_mysql.cpp | 296 ++++++++++++++++++--------------- loginserver/database_mysql.h | 158 ++++++++++-------- loginserver/main.cpp | 117 ++++++++----- 3 files changed, 337 insertions(+), 234 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index e0b10e4d9..0f1c6b7cf 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -1,24 +1,29 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "../common/global_define.h" #include "database.h" #ifdef EQEMU_MYSQL_ENABLED + #include "database_mysql.h" #include "login_server.h" #include "../common/eqemu_logsys.h" @@ -27,7 +32,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA extern LoginServer server; -DatabaseMySQL::DatabaseMySQL(std::string user, std::string pass, std::string host, std::string port, std::string name) +DatabaseMySQL::DatabaseMySQL( + std::string user, + std::string pass, + std::string host, + std::string port, + std::string name +) { this->user = user; this->pass = pass; @@ -35,60 +46,67 @@ DatabaseMySQL::DatabaseMySQL(std::string user, std::string pass, std::string hos this->name = name; database = mysql_init(nullptr); - if (database) - { + if (database) { char r = 1; mysql_options(database, MYSQL_OPT_RECONNECT, &r); - if (!mysql_real_connect(database, host.c_str(), user.c_str(), pass.c_str(), name.c_str(), atoi(port.c_str()), nullptr, 0)) - { + if (!mysql_real_connect( + database, + host.c_str(), + user.c_str(), + pass.c_str(), + name.c_str(), + atoi(port.c_str()), + nullptr, + 0 + )) { mysql_close(database); Log(Logs::General, Logs::Error, "Failed to connect to MySQL database. Error: %s", mysql_error(database)); exit(1); } } - else - { + else { Log(Logs::General, Logs::Error, "Failed to create db object in MySQL database."); } } DatabaseMySQL::~DatabaseMySQL() { - if (database) - { + if (database) { mysql_close(database); } } -bool DatabaseMySQL::GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) +bool DatabaseMySQL::GetLoginDataFromAccountInfo( + const std::string &name, + const std::string &loginserver, + std::string &password, + unsigned int &id +) { - if (!database) - { + if (!database) { return false; } MYSQL_RES *res; MYSQL_ROW row; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() << " WHERE AccountName = '"; + query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() + << " WHERE AccountName = '"; query << EscapeString(name); query << "' AND AccountLoginserver='"; query << EscapeString(loginserver); query << "'"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { LogF(Logs::General, Logs::Error, "Mysql query failed: {0}", query.str()); return false; } res = mysql_use_result(database); - if (res) - { - while ((row = mysql_fetch_row(res)) != nullptr) - { - id = atoi(row[0]); + if (res) { + while ((row = mysql_fetch_row(res)) != nullptr) { + id = atoi(row[0]); password = row[1]; mysql_free_result(res); return true; @@ -99,49 +117,53 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo(const std::string &name, const s return false; } -bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) +bool DatabaseMySQL::GetLoginTokenDataFromToken( + const std::string &token, + const std::string &ip, + unsigned int &db_account_id, + std::string &db_loginserver, + std::string &user +) { - if (!database) - { + if (!database) { return false; } MYSQL_RES *res; MYSQL_ROW row; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT tbllogintokens.Id, tbllogintokens.IpAddress, tbllogintokenclaims.Name, tbllogintokenclaims.Value FROM tbllogintokens "; - query << "JOIN tbllogintokenclaims ON tbllogintokens.Id = tbllogintokenclaims.TokenId WHERE tbllogintokens.Expires > NOW() AND tbllogintokens.Id='"; + query + << "SELECT tbllogintokens.Id, tbllogintokens.IpAddress, tbllogintokenclaims.Name, tbllogintokenclaims.Value FROM tbllogintokens "; + query + << "JOIN tbllogintokenclaims ON tbllogintokens.Id = tbllogintokenclaims.TokenId WHERE tbllogintokens.Expires > NOW() AND tbllogintokens.Id='"; query << EscapeString(token) << "' AND tbllogintokens.IpAddress='" << EscapeString(ip) << "'"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } res = mysql_use_result(database); - bool found_username = false; - bool found_login_id = false; + bool found_username = false; + bool found_login_id = false; bool found_login_server_name = false; - if (res) - { - while ((row = mysql_fetch_row(res)) != nullptr) - { + if (res) { + while ((row = mysql_fetch_row(res)) != nullptr) { if (strcmp(row[2], "username") == 0) { - user = row[3]; + user = row[3]; found_username = true; continue; } if (strcmp(row[2], "login_server_id") == 0) { - db_account_id = atoi(row[3]); + db_account_id = atoi(row[3]); found_login_id = true; continue; } if (strcmp(row[2], "login_server_name") == 0) { - db_loginserver = row[3]; + db_loginserver = row[3]; found_login_server_name = true; continue; } @@ -155,8 +177,7 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken(const std::string &token, const s unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) { - if (!database) - { + if (!database) { return false; } @@ -166,18 +187,15 @@ unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) query << "SELECT MAX(LoginServerID) + 1 FROM " << server.options.GetAccountTable() << " WHERE AccountLoginServer='"; query << EscapeString(loginserver) << "'"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return 0; } res = mysql_use_result(database); - if (res) - { - while ((row = mysql_fetch_row(res)) != nullptr) - { + if (res) { + while ((row = mysql_fetch_row(res)) != nullptr) { if (row[0] == nullptr) { mysql_free_result(res); return 1; @@ -194,12 +212,22 @@ unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) return 1; } -bool DatabaseMySQL::CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) +bool DatabaseMySQL::CreateLoginData( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int &id +) { return CreateLoginDataWithID(name, password, loginserver, GetFreeID(loginserver)); } -bool DatabaseMySQL::CreateLoginDataWithID(const std::string & name, const std::string & password, const std::string & loginserver, unsigned int id) +bool DatabaseMySQL::CreateLoginDataWithID( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id +) { if (!database) { return false; @@ -213,8 +241,10 @@ bool DatabaseMySQL::CreateLoginDataWithID(const std::string & name, const std::s MYSQL_ROW row; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "INSERT INTO " << server.options.GetAccountTable() << " (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; - query << " VALUES(" << id << ", '" << EscapeString(loginserver) << "', '" << EscapeString(name) << "', '" << EscapeString(password) << "', 'local_creation', NOW(), '127.0.0.1'); "; + query << "INSERT INTO " << server.options.GetAccountTable() + << " (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; + query << " VALUES(" << id << ", '" << EscapeString(loginserver) << "', '" << EscapeString(name) << "', '" + << EscapeString(password) << "', 'local_creation', NOW(), '127.0.0.1'); "; if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); @@ -226,82 +256,82 @@ bool DatabaseMySQL::CreateLoginDataWithID(const std::string & name, const std::s void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { - if (!database) - { + if (!database) { return; } - auto query = fmt::format("UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", + auto query = fmt::format( + "UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", server.options.GetAccountTable(), hash, EscapeString(name), EscapeString(loginserver)); - if (mysql_query(database, query.c_str()) != 0) - { + if (mysql_query(database, query.c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.c_str()); } } -bool DatabaseMySQL::GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, - unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) +bool DatabaseMySQL::GetWorldRegistration( + std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, + unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password +) { - if (!database) - { + if (!database) { return false; } - MYSQL_RES *res; - MYSQL_ROW row; - char escaped_short_name[101]; + MYSQL_RES *res; + MYSQL_ROW row; + char escaped_short_name[101]; unsigned long length; - length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length()); + length = mysql_real_escape_string( + database, + escaped_short_name, + short_name.substr(0, 100).c_str(), + short_name.substr(0, 100).length()); escaped_short_name[length + 1] = 0; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, "; - query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " << server.options.GetWorldRegistrationTable(); - query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID"; + query + << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, "; + query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " + << server.options.GetWorldRegistrationTable(); + query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() + << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID"; query << " WHERE WSR.ServerShortName = '"; query << escaped_short_name; query << "'"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } res = mysql_use_result(database); - if (res) - { - if ((row = mysql_fetch_row(res)) != nullptr) - { - id = atoi(row[0]); - desc = row[1]; - trusted = atoi(row[2]); - list_id = atoi(row[3]); + if (res) { + if ((row = mysql_fetch_row(res)) != nullptr) { + id = atoi(row[0]); + desc = row[1]; + trusted = atoi(row[2]); + list_id = atoi(row[3]); list_desc = row[4]; int db_account_id = atoi(row[5]); mysql_free_result(res); - if (db_account_id > 0) - { + if (db_account_id > 0) { std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT AccountName, AccountPassword FROM " << server.options.GetWorldAdminRegistrationTable(); query << " WHERE ServerAdminID = " << db_account_id; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } res = mysql_use_result(database); - if (res) - { - if ((row = mysql_fetch_row(res)) != nullptr) - { - account = row[0]; + if (res) { + if ((row = mysql_fetch_row(res)) != nullptr) { + account = row[0]; password = row[1]; mysql_free_result(res); return true; @@ -321,8 +351,7 @@ bool DatabaseMySQL::GetWorldRegistration(std::string long_name, std::string shor void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) { - if (!database) - { + if (!database) { return; } @@ -332,16 +361,14 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) query << "', LastLoginDate = now() where LoginServerID = "; query << id; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); } } void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { - if (!database) - { + if (!database) { return; } @@ -351,67 +378,73 @@ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std:: query << password << "'), AccountCreateDate = now(), AccountEmail = '" << email; query << "', LastIPAddress = '0.0.0.0', LastLoginDate = now()"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); } } void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { - if (!database) - { + if (!database) { return; } - char escaped_long_name[101]; + char escaped_long_name[101]; unsigned long length; - length = mysql_real_escape_string(database, escaped_long_name, long_name.substr(0, 100).c_str(), long_name.substr(0, 100).length()); + length = mysql_real_escape_string( + database, + escaped_long_name, + long_name.substr(0, 100).c_str(), + long_name.substr(0, 100).length()); escaped_long_name[length + 1] = 0; std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "UPDATE " << server.options.GetWorldRegistrationTable() << " SET ServerLastLoginDate = now(), ServerLastIPAddr = '"; + query << "UPDATE " << server.options.GetWorldRegistrationTable() + << " SET ServerLastLoginDate = now(), ServerLastIPAddr = '"; query << ip_address; query << "', ServerLongName = '"; query << escaped_long_name; query << "' WHERE ServerID = "; query << id; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); } } bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { - if (!database) - { + if (!database) { return false; } - MYSQL_RES *res; - MYSQL_ROW row; - char escaped_long_name[201]; - char escaped_short_name[101]; + MYSQL_RES *res; + MYSQL_ROW row; + char escaped_long_name[201]; + char escaped_short_name[101]; unsigned long length; - length = mysql_real_escape_string(database, escaped_long_name, long_name.substr(0, 100).c_str(), long_name.substr(0, 100).length()); + length = mysql_real_escape_string( + database, + escaped_long_name, + long_name.substr(0, 100).c_str(), + long_name.substr(0, 100).length()); escaped_long_name[length + 1] = 0; - length = mysql_real_escape_string(database, escaped_short_name, short_name.substr(0, 100).c_str(), short_name.substr(0, 100).length()); + length = mysql_real_escape_string( + database, + escaped_short_name, + short_name.substr(0, 100).c_str(), + short_name.substr(0, 100).length()); escaped_short_name[length + 1] = 0; std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT ifnull(max(ServerID),0) FROM " << server.options.GetWorldRegistrationTable(); - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } res = mysql_use_result(database); - if (res) - { - if ((row = mysql_fetch_row(res)) != nullptr) - { + if (res) { + if ((row = mysql_fetch_row(res)) != nullptr) { id = atoi(row[0]) + 1; mysql_free_result(res); @@ -420,15 +453,18 @@ bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string s query << ", ServerLongName = '" << escaped_long_name << "', ServerShortName = '" << escaped_short_name; query << "', ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''"; - if (mysql_query(database, query.str().c_str()) != 0) - { + if (mysql_query(database, query.str().c_str()) != 0) { Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } return true; } } - Log(Logs::General, Logs::Error, "World registration did not exist in the database for %s %s", long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::Error, + "World registration did not exist in the database for %s %s", + long_name.c_str(), + short_name.c_str()); return false; } diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 60e8290cf..1a59d40cf 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -1,24 +1,28 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_DATABASEMYSQL_H #define EQEMU_DATABASEMYSQL_H #include "database.h" + #ifdef EQEMU_MYSQL_ENABLED #include @@ -26,79 +30,99 @@ #include #include -/** -* Mysql Database class -*/ -class DatabaseMySQL : public Database -{ +class DatabaseMySQL : public Database { public: - /** - * Constructor, sets our database to null. - */ + DatabaseMySQL() { database = nullptr; } /** - * Constructor, tries to set our database to connect to the supplied options. - */ + * Constructor, tries to set our database to connect to the supplied options. + * + * @param user + * @param pass + * @param host + * @param port + * @param name + */ DatabaseMySQL(std::string user, std::string pass, std::string host, std::string port, std::string name); /** - * Destructor, frees our database if needed. - */ + * Destructor, frees our database if needed. + */ virtual ~DatabaseMySQL(); - - /** - * @return Returns true if the database successfully connected. - */ virtual bool IsConnected() { return (database != nullptr); } /** - * Retrieves the login data (password hash and account id) from the account name provided - * Needed for client login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id); - - virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user); - + * Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure. + * @param name + * @param loginserver + * @param password + * @param id + * @return + */ + virtual bool GetLoginDataFromAccountInfo( + const std::string &name, + const std::string &loginserver, + std::string &password, + unsigned int &id + ); + virtual bool GetLoginTokenDataFromToken( + const std::string &token, + const std::string &ip, + unsigned int &db_account_id, + std::string &db_loginserver, + std::string &user + ); virtual unsigned int GetFreeID(const std::string &loginserver); - - virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id); - - virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id); - + virtual bool CreateLoginData( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int &id + ); + virtual bool CreateLoginDataWithID( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id + ); virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); /** - * Retrieves the world registration from the long and short names provided. - * Needed for world login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, - unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password); + * Retrieves the world registration from the long and short names provided + * Needed for world login procedure + * Returns true if the record was found, false otherwise. + * + * @param long_name + * @param short_name + * @param id + * @param desc + * @param list_id + * @param trusted + * @param list_desc + * @param account + * @param password + * @return + */ + virtual bool GetWorldRegistration( + std::string long_name, + std::string short_name, + unsigned int &id, + std::string &desc, + unsigned int &list_id, + unsigned int &trusted, + std::string &list_desc, + std::string &account, + std::string &password + ); - /** - * Updates the ip address of the client with account id = id - */ virtual void UpdateLSAccountData(unsigned int id, std::string ip_address); - - /** - * Updates or creates the login server account with info from world server - */ virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email); - - /** - * Updates the ip address of the world with account id = id - */ virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); - - /** - * Creates new world registration for unregistered servers and returns new id - */ virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); protected: std::string user, pass, host, port, name; - MYSQL *database; + MYSQL *database; }; #endif diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 85f2bde4a..199b65889 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "../common/global_define.h" #include "../common/types.h" #include "../common/opcodemgr.h" @@ -31,7 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA LoginServer server; EQEmuLogSys LogSys; -bool run_server = true; +bool run_server = true; void CatchSignal(int sig_num) { @@ -41,9 +44,10 @@ int main() { RegisterExecutablePlatform(ExePlatformLogin); set_exception_handler(); + LogSys.LoadLogSettingsDefaults(); - LogSys.log_settings[Logs::Error].log_to_console = Logs::General; + LogSys.log_settings[Logs::Error].log_to_console = Logs::General; LogSys.log_settings[Logs::Error].is_category_enabled = 1; Log(Logs::General, Logs::Login_Server, "Logging System Init."); @@ -59,8 +63,22 @@ int main() server.options.RejectDuplicateServers(server.config.GetVariableBool("general", "reject_duplicate_servers", false)); server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", true)); - server.options.EQEmuLoginServerAddress(server.config.GetVariableString("general", "eqemu_loginserver_address", "login.eqemulator.net:5999")); - server.options.DefaultLoginServerName(server.config.GetVariableString("general", "default_loginserver_name", "peq")); + + server.options.EQEmuLoginServerAddress( + server.config.GetVariableString( + "general", + "eqemu_loginserver_address", + "login.eqemulator.net:5999" + ) + ); + + server.options.DefaultLoginServerName( + server.config.GetVariableString( + "general", + "default_loginserver_name", + "peq" + ) + ); #ifdef ENABLE_SECURITY server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13)); @@ -70,49 +88,74 @@ int main() server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true)); server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false)); server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true)); - server.options.UpdateInsecurePasswords(server.config.GetVariableBool("security", "update_insecure_passwords", true)); + server.options.UpdateInsecurePasswords( + server.config.GetVariableBool( + "security", + "update_insecure_passwords", + true + )); server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); - server.options.WorldRegistrationTable(server.config.GetVariableString("schema", "world_registration_table", "tblWorldServerRegistration")); - server.options.WorldAdminRegistrationTable(server.config.GetVariableString("schema", "world_admin_registration_table", "tblServerAdminRegistration")); - server.options.WorldServerTypeTable(server.config.GetVariableString("schema", "world_server_type_table", "tblServerListType")); + server.options.WorldRegistrationTable( + server.config.GetVariableString( + "schema", + "world_registration_table", + "tblWorldServerRegistration" + )); + server.options.WorldAdminRegistrationTable( + server.config.GetVariableString( + "schema", + "world_admin_registration_table", + "tblServerAdminRegistration" + )); + server.options.WorldServerTypeTable( + server.config.GetVariableString( + "schema", + "world_server_type_table", + "tblServerListType" + )); - /* Create database connection */ + /** + * mysql connect + */ if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) { -#ifdef EQEMU_MYSQL_ENABLED Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); - server.db = (Database*)new DatabaseMySQL( + server.db = (Database *) new DatabaseMySQL( server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "password", ""), server.config.GetVariableString("database", "host", "localhost"), server.config.GetVariableString("database", "port", "3306"), - server.config.GetVariableString("database", "db", "peq")); -#endif + server.config.GetVariableString("database", "db", "peq") + ); } - /* Make sure our database got created okay, otherwise cleanup and exit. */ + /** + * Make sure our database got created okay, otherwise cleanup and exit + */ if (!server.db) { Log(Logs::General, Logs::Error, "Database Initialization Failure."); Log(Logs::General, Logs::Login_Server, "Log System Shutdown."); return 1; } - //create our server manager. + /** + * create server manager + */ Log(Logs::General, Logs::Login_Server, "Server Manager Initialize."); server.server_manager = new ServerManager(); - if (!server.server_manager) { - //We can't run without a server manager, cleanup and exit. + if (!server.server_manager) Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); delete server.db; return 1; } - //create our client manager. + /** + * create client manager + */ Log(Logs::General, Logs::Login_Server, "Client Manager Initialize."); server.client_manager = new ClientManager(); if (!server.client_manager) { - //We can't run without a client manager, cleanup and exit. Log(Logs::General, Logs::Error, "Client Manager Failed to Start."); Log(Logs::General, Logs::Login_Server, "Server Manager Shutdown."); delete server.server_manager; @@ -124,9 +167,9 @@ int main() #ifdef WIN32 #ifdef UNICODE - SetConsoleTitle(L"EQEmu Login Server"); + SetConsoleTitle(L"EQEmu Login Server"); #else - SetConsoleTitle("EQEmu Login Server"); + SetConsoleTitle("EQEmu Login Server"); #endif #endif From 9e0f44010652f2cc1a5b184466d2a1dde667a890 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 02:16:30 -0500 Subject: [PATCH 018/491] Remove postgres --- loginserver/database_postgresql.cpp | 234 ------------------ loginserver/database_postgresql.h | 91 ------- .../EQEmuLoginServerPostgreDBInstall.sql | 57 ----- 3 files changed, 382 deletions(-) delete mode 100644 loginserver/database_postgresql.cpp delete mode 100644 loginserver/database_postgresql.h delete mode 100644 loginserver/login_util/EQEmuLoginServerPostgreDBInstall.sql diff --git a/loginserver/database_postgresql.cpp b/loginserver/database_postgresql.cpp deleted file mode 100644 index e67e47467..000000000 --- a/loginserver/database_postgresql.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "../common/global_define.h" -#include "database.h" - -#ifdef EQEMU_POSTGRESQL_ENABLED -#include "database_postgresql.h" -#include "error_log.h" -#include "login_server.h" - - -extern LoginServer server; - -#pragma comment(lib, "libpq.lib") - -DatabasePostgreSQL::DatabasePostgreSQL(string user, string pass, string host, string port, string name) -{ - db = nullptr; - db = PQsetdbLogin(host.c_str(), port.c_str(), nullptr, nullptr, name.c_str(), user.c_str(), pass.c_str()); - if(!db) - { - Log(Logs::General, Logs::Error, "Failed to connect to PostgreSQL Database."); - } - - if(PQstatus(db) != CONNECTION_OK) - { - Log(Logs::General, Logs::Error, "Failed to connect to PostgreSQL Database."); - PQfinish(db); - db = nullptr; - } -} - -DatabasePostgreSQL::~DatabasePostgreSQL() -{ - if(db) - { - PQfinish(db); - } -} - -bool DatabasePostgreSQL::GetLoginDataFromAccountName(string name, string &password, unsigned int &id, std::string &loginserver) -{ - if(!db) - { - return false; - } - - /** - * PostgreSQL doesn't have automatic reconnection option like mysql - * but it's easy to check and reconnect - */ - if(PQstatus(db) != CONNECTION_OK) - { - PQreset(db); - if(PQstatus(db) != CONNECTION_OK) - { - return false; - } - } - - stringstream query(stringstream::in | stringstream::out); - query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() << " WHERE AccountName = '"; - query << name; - query << "'"; - - PGresult *res = PQexec(db, query.str().c_str()); - - char *error = PQresultErrorMessage(res); - if(strlen(error) > 0) - { - Log(Logs::General, Logs::Error, "Database error in DatabasePostgreSQL::GetLoginDataFromAccountName(): %s", error); - PQclear(res); - return false; - } - - if(PQntuples(res) > 0) - { - id = atoi(PQgetvalue(res, 0, 0)); - password = PQgetvalue(res, 0, 1); - PQclear(res); - return true; - } - - PQclear(res); - return false; -} - -bool DatabasePostgreSQL::GetWorldRegistration(string long_name, string short_name, unsigned int &id, string &desc, unsigned int &list_id, - unsigned int &trusted, string &list_desc, string &account, string &password) -{ - if(!db) - { - return false; - } - - /** - * PostgreSQL doesn't have automatic reconnection option like mysql - * but it's easy to check and reconnect - */ - if(PQstatus(db) != CONNECTION_OK) - { - PQreset(db); - if(PQstatus(db) != CONNECTION_OK) - { - return false; - } - } - - stringstream query(stringstream::in | stringstream::out); - query << "SELECT WSR.ServerID, WSR.ServerTagDescription, WSR.ServerTrusted, SLT.ServerListTypeID, "; - query << "SLT.ServerListTypeDescription, SAR.AccountName, SAR.AccountPassword FROM " << server.options.GetWorldRegistrationTable(); - query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID JOIN "; - query << server.options.GetWorldAdminRegistrationTable() << " AS SAR ON WSR.ServerAdminID = SAR.ServerAdminID WHERE WSR.ServerShortName"; - query << " = '"; - query << short_name; - query << "'"; - - PGresult *res = PQexec(db, query.str().c_str()); - - char *error = PQresultErrorMessage(res); - if(strlen(error) > 0) - { - Log(Logs::General, Logs::Error, "Database error in DatabasePostgreSQL::GetWorldRegistration(): %s", error); - PQclear(res); - return false; - } - - if(PQntuples(res) > 0) - { - id = atoi(PQgetvalue(res, 0, 0)); - desc = PQgetvalue(res, 0, 1); - trusted = atoi(PQgetvalue(res, 0, 2)); - list_id = atoi(PQgetvalue(res, 0, 3)); - list_desc = PQgetvalue(res, 0, 4); - account = PQgetvalue(res, 0, 5); - password = PQgetvalue(res, 0, 6); - - PQclear(res); - return true; - } - - PQclear(res); - return false; -} - -void DatabasePostgreSQL::UpdateLSAccountData(unsigned int id, string ip_address) -{ - if(!db) - { - return; - } - - /** - * PostgreSQL doesn't have automatic reconnection option like mysql - * but it's easy to check and reconnect - */ - if(PQstatus(db) != CONNECTION_OK) - { - PQreset(db); - if(PQstatus(db) != CONNECTION_OK) - { - return; - } - } - - stringstream query(stringstream::in | stringstream::out); - query << "UPDATE " << server.options.GetAccountTable() << " SET LastIPAddress = '"; - query << ip_address; - query << "', LastLoginDate = current_date where LoginServerID = "; - query << id; - PGresult *res = PQexec(db, query.str().c_str()); - - char *error = PQresultErrorMessage(res); - if(strlen(error) > 0) - { - Log(Logs::General, Logs::Error, "Database error in DatabasePostgreSQL::GetLoginDataFromAccountName(): %s", error); - } - PQclear(res); -} - -void DatabasePostgreSQL::UpdateWorldRegistration(unsigned int id, string long_name, string ip_address) -{ - if(!db) - { - return; - } - - /** - * PostgreSQL doesn't have automatic reconnection option like mysql - * but it's easy to check and reconnect - */ - if(PQstatus(db) != CONNECTION_OK) - { - PQreset(db); - if(PQstatus(db) != CONNECTION_OK) - { - return; - } - } - - stringstream query(stringstream::in | stringstream::out); - query << "UPDATE " << server.options.GetWorldRegistrationTable() << " SET ServerLastLoginDate = current_date, ServerLastIPAddr = '"; - query << ip_address; - query << "', ServerLongName = '"; - query << long_name; - query << "' where ServerID = "; - query << id; - PGresult *res = PQexec(db, query.str().c_str()); - - char *error = PQresultErrorMessage(res); - if(strlen(error) > 0) - { - Log(Logs::General, Logs::Error, "Database error in DatabasePostgreSQL::GetLoginDataFromAccountName(): %s", error); - } - PQclear(res); -} - -#endif - diff --git a/loginserver/database_postgresql.h b/loginserver/database_postgresql.h deleted file mode 100644 index 9d195920e..000000000 --- a/loginserver/database_postgresql.h +++ /dev/null @@ -1,91 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef EQEMU_DATABASEPOSTGRESQL_H -#define EQEMU_DATABASEPOSTGRESQL_H - -#include "database.h" -#ifdef EQEMU_POSTGRESQL_ENABLED - -#include -#include -#include -#include - -/** - * PostgreSQL Database class - */ -class DatabasePostgreSQL : public Database -{ -public: - /** - * Constructor, sets our database to null. - */ - DatabasePostgreSQL() { db = nullptr; } - - /** - * Constructor, tries to set our database to connect to the supplied options. - */ - DatabasePostgreSQL(std::string user, std::string pass, std::string host, std::string port, std::string name); - - /** - * Destructor, frees our database if needed. - */ - virtual ~DatabasePostgreSQL(); - - /** - * Returns true if the database successfully connected. - */ - virtual bool IsConnected() { return (db != nullptr); } - - /** - * Retrieves the login data (password hash and account id) from the account name provided - * Needed for client login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetLoginDataFromAccountName(std::string name, std::string &password, unsigned int &id, std::string &loginserver); - - /** - * Retrieves the world registration from the long and short names provided. - * Needed for world login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, - unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password); - - /** - * Updates the ip address of the client with account id = id - */ - virtual void UpdateLSAccountData(unsigned int id, std::string ip_address); - - /** - * Updates the ip address of the world with account id = id - */ - virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); - - /** - * Creates new world registration for unregistered servers and returns new id - */ - virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); -protected: - std::string user, pass, host, port, name; - PGconn *db; -}; - -#endif -#endif - diff --git a/loginserver/login_util/EQEmuLoginServerPostgreDBInstall.sql b/loginserver/login_util/EQEmuLoginServerPostgreDBInstall.sql deleted file mode 100644 index bedfbe20d..000000000 --- a/loginserver/login_util/EQEmuLoginServerPostgreDBInstall.sql +++ /dev/null @@ -1,57 +0,0 @@ -DROP TABLE IF EXISTS tblLoginServerAccounts; -CREATE TABLE tblLoginServerAccounts ( - LoginServerID SERIAL, - AccountName text NOT NULL, - AccountPassword text NOT NULL, - AccountCreateDate date NOT NULL, - AccountEmail text NOT NULL, - LastLoginDate date NOT NULL, - LastIPAddress text NOT NULL, - PRIMARY KEY(LoginServerID, AccountName) -); - -insert into tblLoginServerAccounts (AccountName, AccountPassword, AccountEmail, AccountCreateDate, LastLoginDate, LastIPAddress) values('Admin', '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', 'admin@somewhere.com', current_date, current_date, '127.0.0.1'); - -DROP TABLE IF EXISTS tblServerListType; -CREATE TABLE tblServerListType ( - ServerListTypeID integer NOT NULL, - CHECK (ServerListTypeID >= 0), - ServerListTypeDescription text NOT NULL, - PRIMARY KEY (ServerListTypeID) -); - -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (1, 'Legends'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (2, 'Preferred'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (3, 'Standard'); - -DROP TABLE IF EXISTS tblServerAdminRegistration; -CREATE TABLE tblServerAdminRegistration ( - ServerAdminID SERIAL, - AccountName text NOT NULL, - AccountPassword text NOT NULL, - FirstName text NOT NULL, - LastName text NOT NULL, - Email text NOT NULL, - RegistrationDate date NOT NULL, - RegistrationIPAddr text NOT NULL, - PRIMARY KEY (ServerAdminID, Email) -); - -INSERT INTO tblServerAdminRegistration (AccountName, AccountPassword, FirstName, LastName, Email, RegistrationDate, RegistrationIPAddr) VALUES ('Admin', 'Password', 'Tom', 'Wilson', 'Tom.Wilson@gmail.com', current_date, '0.0.0.0'); - -DROP TABLE IF EXISTS tblWorldServerRegistration; -CREATE TABLE tblWorldServerRegistration ( - ServerID SERIAL, - ServerLongName text NOT NULL, - ServerTagDescription text NOT NULL, - ServerShortName text NOT NULL, - ServerListTypeID integer NOT NULL, - ServerLastLoginDate date NULL, - ServerLastIPAddr text NOT NULL, - ServerAdminID integer NOT NULL, - ServerTrusted integer NOT NULL, - Note text NOT NULL, - PRIMARY KEY (ServerID, ServerLongName) -); - -INSERT INTO tblWorldServerRegistration (ServerLongName, ServerTagDescription, ServerShortName, ServerListTypeID, ServerLastLoginDate, ServerLastIPAddr, ServerAdminID, ServerTrusted, Note) VALUES ('My Test Server', 'A test server', 'MTST', 1, current_date, '0.0.0.0', 1, 0, 'This is a note for the test server'); \ No newline at end of file From 217c9751a8c027d7136f21149cf55f22be8d5e87 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 02:50:16 -0500 Subject: [PATCH 019/491] Tons of cleanup / formatting --- loginserver/client.cpp | 481 ++++++++++++++---------- loginserver/client.h | 223 ++++++----- loginserver/client_manager.cpp | 141 +++---- loginserver/client_manager.h | 75 ++-- loginserver/config.cpp | 168 ++++----- loginserver/config.h | 35 +- loginserver/database.h | 157 +++++--- loginserver/database_mysql.cpp | 1 - loginserver/encryption.cpp | 20 + loginserver/encryption.h | 20 + loginserver/eq_crypto_api.h | 35 +- loginserver/login_server.h | 40 +- loginserver/login_structures.h | 94 ++--- loginserver/main.cpp | 39 +- loginserver/options.h | 69 ++-- loginserver/server_manager.cpp | 161 ++++---- loginserver/server_manager.h | 101 +++-- loginserver/world_server.cpp | 658 +++++++++++++++++++-------------- loginserver/world_server.h | 126 +++---- 19 files changed, 1515 insertions(+), 1129 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 4687e917f..0b1243a30 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "client.h" #include "login_server.h" #include "../common/misc_functions.h" @@ -25,28 +28,29 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA extern LoginServer server; +/** + * @param c + * @param v + */ Client::Client(std::shared_ptr c, LSClientVersion v) { - connection = c; - version = v; - status = cs_not_sent_session_ready; - account_id = 0; - play_server_id = 0; + connection = c; + version = v; + status = cs_not_sent_session_ready; + account_id = 0; + play_server_id = 0; play_sequence_id = 0; } bool Client::Process() { EQApplicationPacket *app = connection->PopPacket(); - while (app) - { - if (server.options.IsTraceOn()) - { + while (app) { + if (server.options.IsTraceOn()) { Log(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(app); } @@ -56,67 +60,56 @@ bool Client::Process() continue; } - switch (app->GetOpcode()) - { - case OP_SessionReady: - { - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Login_Server, "Session ready received from client."); - } - Handle_SessionReady((const char*)app->pBuffer, app->Size()); - break; - } - case OP_Login: - { - if (app->Size() < 20) - { - Log(Logs::General, Logs::Error, "Login received but it is too small, discarding."); + switch (app->GetOpcode()) { + case OP_SessionReady: { + if (server.options.IsTraceOn()) { + Log(Logs::General, Logs::Login_Server, "Session ready received from client."); + } + Handle_SessionReady((const char *) app->pBuffer, app->Size()); break; } + case OP_Login: { + if (app->Size() < 20) { + Log(Logs::General, Logs::Error, "Login received but it is too small, discarding."); + break; + } - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Login_Server, "Login received from client."); - } + if (server.options.IsTraceOn()) { + Log(Logs::General, Logs::Login_Server, "Login received from client."); + } - Handle_Login((const char*)app->pBuffer, app->Size()); - break; - } - case OP_ServerListRequest: - { - if (app->Size() < 4) { - Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding."); + Handle_Login((const char *) app->pBuffer, app->Size()); break; } + case OP_ServerListRequest: { + if (app->Size() < 4) { + Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding."); + break; + } - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Login_Server, "Server list request received from client."); - } + if (server.options.IsTraceOn()) { + Log(Logs::General, Logs::Login_Server, "Server list request received from client."); + } - SendServerListPacket(*(uint32_t*)app->pBuffer); - break; - } - case OP_PlayEverquestRequest: - { - if (app->Size() < sizeof(PlayEverquestRequest_Struct)) - { - Log(Logs::General, Logs::Error, "Play received but it is too small, discarding."); + SendServerListPacket(*(uint32_t *) app->pBuffer); break; } + case OP_PlayEverquestRequest: { + if (app->Size() < sizeof(PlayEverquestRequest_Struct)) { + Log(Logs::General, Logs::Error, "Play received but it is too small, discarding."); + break; + } - Handle_Play((const char*)app->pBuffer); - break; - } - default: - { - if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) { - char dump[64]; - app->build_header_dump(dump); - Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump); + Handle_Play((const char *) app->pBuffer); + break; + } + default: { + if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) { + char dump[64]; + app->build_header_dump(dump); + Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump); + } } - } } delete app; @@ -126,16 +119,20 @@ bool Client::Process() return true; } -void Client::Handle_SessionReady(const char* data, unsigned int size) +/** + * Sends our reply to session ready packet + * + * @param data + * @param size + */ +void Client::Handle_SessionReady(const char *data, unsigned int size) { - if (status != cs_not_sent_session_ready) - { + if (status != cs_not_sent_session_ready) { Log(Logs::General, Logs::Error, "Session ready received again after already being received."); return; } - if (size < sizeof(unsigned int)) - { + if (size < sizeof(unsigned int)) { Log(Logs::General, Logs::Error, "Session ready was too small."); return; } @@ -145,32 +142,28 @@ void Client::Handle_SessionReady(const char* data, unsigned int size) /** * The packets are mostly the same but slightly different between the two versions. */ - if (version == cv_sod) - { + if (version == cv_sod) { EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 17); - outapp->pBuffer[0] = 0x02; + outapp->pBuffer[0] = 0x02; outapp->pBuffer[10] = 0x01; outapp->pBuffer[11] = 0x65; - if (server.options.IsDumpOutPacketsOn()) - { + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } connection->QueuePacket(outapp); delete outapp; } - else - { - const char *msg = "ChatMessage"; + else { + const char *msg = "ChatMessage"; EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg)); - outapp->pBuffer[0] = 0x02; + outapp->pBuffer[0] = 0x02; outapp->pBuffer[10] = 0x01; outapp->pBuffer[11] = 0x65; - strcpy((char*)(outapp->pBuffer + 15), msg); + strcpy((char *) (outapp->pBuffer + 15), msg); - if (server.options.IsDumpOutPacketsOn()) - { + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } @@ -179,7 +172,13 @@ void Client::Handle_SessionReady(const char* data, unsigned int size) } } -void Client::Handle_Login(const char* data, unsigned int size) +/** + * Verifies login and send a reply + * + * @param data + * @param size + */ +void Client::Handle_Login(const char *data, unsigned int size) { if (status != cs_waiting_for_login) { Log(Logs::General, Logs::Error, "Login received after already having logged in."); @@ -187,20 +186,26 @@ void Client::Handle_Login(const char* data, unsigned int size) } if ((size - 12) % 8 != 0) { - Log(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a block corruption, discarding.", size); + Log(Logs::General, + Logs::Error, + "Login received packet of size: %u, this would cause a block corruption, discarding.", + size); return; } if (size < sizeof(LoginLoginRequest_Struct)) { - Log(Logs::General, Logs::Error, "Login received packet of size: %u, this would cause a buffer overflow, discarding.", size); + Log(Logs::General, + Logs::Error, + "Login received packet of size: %u, this would cause a buffer overflow, discarding.", + size); return; } char *login_packet_buffer = nullptr; - unsigned int db_account_id = 0; - std::string db_loginserver = "eqemu"; - std::string db_account_password_hash; + unsigned int db_account_id = 0; + std::string db_loginserver = "eqemu"; + std::string db_account_password_hash; std::string outbuffer; outbuffer.resize(size - 12); @@ -228,22 +233,29 @@ void Client::Handle_Login(const char* data, unsigned int size) bool result = false; if (outbuffer[0] == 0 && outbuffer[1] == 0) { if (server.options.IsTokenLoginAllowed()) { - cred = (&outbuffer[2 + user.length()]); - result = server.db->GetLoginTokenDataFromToken(cred, connection->GetRemoteAddr(), db_account_id, db_loginserver, user); + cred = (&outbuffer[2 + user.length()]); + result = server.db->GetLoginTokenDataFromToken( + cred, + connection->GetRemoteAddr(), + db_account_id, + db_loginserver, + user + ); } } else { if (server.options.IsPasswordLoginAllowed()) { - cred = (&outbuffer[1 + user.length()]); + cred = (&outbuffer[1 + user.length()]); auto components = SplitString(user, '.'); if (components.size() == 2) { db_loginserver = components[0]; - user = components[1]; + user = components[1]; } ParseAccountString(user, user, db_loginserver); - - if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == false) { + + if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == + false) { status = cs_creating_account; AttemptLoginAccountCreation(user, cred, db_loginserver); return; @@ -263,35 +275,44 @@ void Client::Handle_Login(const char* data, unsigned int size) } } -void Client::Handle_Play(const char* data) +/** + * Sends a packet to the requested server to see if the client is allowed or not + * + * @param data + */ +void Client::Handle_Play(const char *data) { - if (status != cs_logged_in) - { + if (status != cs_logged_in) { Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding."); return; } - const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct*)data; - unsigned int server_id_in = (unsigned int)play->ServerNumber; - unsigned int sequence_in = (unsigned int)play->Sequence; + const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct *) data; + unsigned int server_id_in = (unsigned int) play->ServerNumber; + unsigned int sequence_in = (unsigned int) play->Sequence; - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Login_Server, "Play received from client, server number %u sequence %u.", server_id_in, sequence_in); + if (server.options.IsTraceOn()) { + Log(Logs::General, + Logs::Login_Server, + "Play received from client, server number %u sequence %u.", + server_id_in, + sequence_in); } - this->play_server_id = (unsigned int)play->ServerNumber; + this->play_server_id = (unsigned int) play->ServerNumber; play_sequence_id = sequence_in; - play_server_id = server_id_in; + play_server_id = server_id_in; server.server_manager->SendUserToWorldRequest(server_id_in, account_id, loginserver_name); } +/** + * @param seq + */ void Client::SendServerListPacket(uint32 seq) { EQApplicationPacket *outapp = server.server_manager->CreateServerListPacket(this, seq); - if (server.options.IsDumpOutPacketsOn()) - { + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } @@ -301,8 +322,7 @@ void Client::SendServerListPacket(uint32 seq) void Client::SendPlayResponse(EQApplicationPacket *outapp) { - if (server.options.IsTraceOn()) - { + if (server.options.IsTraceOn()) { Log(Logs::General, Logs::Netcode, "Sending play response for %s.", GetAccountName().c_str()); // server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size); } @@ -313,23 +333,26 @@ void Client::GenerateKey() { key.clear(); int count = 0; - while (count < 10) - { + while (count < 10) { static const char key_selection[] = - { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '0', '1', '2', '3', '4', '5', - '6', '7', '8', '9' - }; + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9' + }; - key.append((const char*)&key_selection[random.Int(0, 35)], 1); + key.append((const char *) &key_selection[random.Int(0, 35)], 1); count++; } } -void Client::AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver) +void Client::AttemptLoginAccountCreation( + const std::string &user, + const std::string &pass, + const std::string &loginserver +) { if (loginserver == "eqemu") { if (!server.options.CanAutoLinkAccounts()) { @@ -341,7 +364,7 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str DoFailedLogin(); return; } - + auto addr_components = SplitString(server.options.GetEQEmuLoginServerAddress(), ':'); if (addr_components.size() != 2) { DoFailedLogin(); @@ -350,22 +373,42 @@ void Client::AttemptLoginAccountCreation(const std::string &user, const std::str stored_user = user; stored_pass = pass; - + auto address = addr_components[0]; - auto port = std::stoi(addr_components[1]); - EQ::Net::DNSLookup(address, port, false, [=](const std::string &addr) { - if (addr.empty()) { - DoFailedLogin(); - return; + auto port = std::stoi(addr_components[1]); + EQ::Net::DNSLookup( + address, port, false, [=](const std::string &addr) { + if (addr.empty()) { + DoFailedLogin(); + return; + } + + login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager()); + login_connection_manager->OnNewConnection( + std::bind( + &Client::LoginOnNewConnection, + this, + std::placeholders::_1 + )); + login_connection_manager->OnConnectionStateChange( + std::bind( + &Client::LoginOnStatusChange, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); + login_connection_manager->OnPacketRecv( + std::bind( + &Client::LoginOnPacketRecv, + this, + std::placeholders::_1, + std::placeholders::_2 + )); + + login_connection_manager->Connect(addr, port); } - - login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager()); - login_connection_manager->OnNewConnection(std::bind(&Client::LoginOnNewConnection, this, std::placeholders::_1)); - login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - login_connection_manager->OnPacketRecv(std::bind(&Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2)); - - login_connection_manager->Connect(addr, port); - }); + ); } else { if (!server.options.CanAutoCreateAccounts()) { @@ -382,8 +425,8 @@ void Client::DoFailedLogin() stored_user.clear(); stored_pass.clear(); - EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); - LoginLoginFailed_Struct* llas = (LoginLoginFailed_Struct *)outapp.pBuffer; + EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); + LoginLoginFailed_Struct *llas = (LoginLoginFailed_Struct *) outapp.pBuffer; llas->unknown1 = llrs.unknown1; llas->unknown2 = llrs.unknown2; llas->unknown3 = llrs.unknown3; @@ -399,7 +442,21 @@ void Client::DoFailedLogin() status = cs_failed_to_login; } -bool Client::VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash) +/** + * Verifies a login hash, will also attempt to update a login hash if needed + * + * @param user + * @param loginserver + * @param cred + * @param hash + * @return + */ +bool Client::VerifyLoginHash( + const std::string &user, + const std::string &loginserver, + const std::string &cred, + const std::string &hash +) { auto mode = server.options.GetEncryptionMode(); if (eqcrypt_verify_hash(user, cred, hash, mode)) { @@ -443,6 +500,11 @@ bool Client::VerifyLoginHash(const std::string &user, const std::string &loginse return false; } +/** + * @param user + * @param db_account_id + * @param db_loginserver + */ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver) { stored_user.clear(); @@ -456,43 +518,43 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); GenerateKey(); - account_id = db_account_id; - account_name = user; + account_id = db_account_id; + account_name = user; loginserver_name = db_loginserver; - EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); - LoginAccepted_Struct* login_accepted = (LoginAccepted_Struct *)outapp->pBuffer; + EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); + LoginAccepted_Struct *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer; login_accepted->unknown1 = llrs.unknown1; login_accepted->unknown2 = llrs.unknown2; login_accepted->unknown3 = llrs.unknown3; login_accepted->unknown4 = llrs.unknown4; login_accepted->unknown5 = llrs.unknown5; - LoginFailedAttempts_Struct * login_failed_attempts = new LoginFailedAttempts_Struct; + LoginFailedAttempts_Struct *login_failed_attempts = new LoginFailedAttempts_Struct; memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct)); login_failed_attempts->failed_attempts = 0; - login_failed_attempts->message = 0x01; - login_failed_attempts->lsid = db_account_id; - login_failed_attempts->unknown3[3] = 0x03; - login_failed_attempts->unknown4[3] = 0x02; - login_failed_attempts->unknown5[0] = 0xe7; - login_failed_attempts->unknown5[1] = 0x03; - login_failed_attempts->unknown6[0] = 0xff; - login_failed_attempts->unknown6[1] = 0xff; - login_failed_attempts->unknown6[2] = 0xff; - login_failed_attempts->unknown6[3] = 0xff; - login_failed_attempts->unknown7[0] = 0xa0; - login_failed_attempts->unknown7[1] = 0x05; - login_failed_attempts->unknown8[3] = 0x02; - login_failed_attempts->unknown9[0] = 0xff; - login_failed_attempts->unknown9[1] = 0x03; + login_failed_attempts->message = 0x01; + login_failed_attempts->lsid = db_account_id; + login_failed_attempts->unknown3[3] = 0x03; + login_failed_attempts->unknown4[3] = 0x02; + login_failed_attempts->unknown5[0] = 0xe7; + login_failed_attempts->unknown5[1] = 0x03; + login_failed_attempts->unknown6[0] = 0xff; + login_failed_attempts->unknown6[1] = 0xff; + login_failed_attempts->unknown6[2] = 0xff; + login_failed_attempts->unknown6[3] = 0xff; + login_failed_attempts->unknown7[0] = 0xa0; + login_failed_attempts->unknown7[1] = 0x05; + login_failed_attempts->unknown8[3] = 0x02; + login_failed_attempts->unknown9[0] = 0xff; + login_failed_attempts->unknown9[1] = 0x03; login_failed_attempts->unknown11[0] = 0x63; login_failed_attempts->unknown12[0] = 0x01; memcpy(login_failed_attempts->key, key.c_str(), key.size()); - char encrypted_buffer[80] = { 0 }; - auto rc = eqcrypt_block((const char*)login_failed_attempts, 75, encrypted_buffer, 1); + char encrypted_buffer[80] = {0}; + auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1); if (rc == nullptr) { LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block"); } @@ -509,13 +571,17 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const status = cs_logged_in; } +/** + * @param user + * @param pass + */ void Client::CreateLocalAccount(const std::string &user, const std::string &pass) { auto mode = server.options.GetEncryptionMode(); auto hash = eqcrypt_hash(user, pass, mode); - unsigned int db_id = 0; - std::string db_login = server.options.GetDefaultLoginServerName(); + unsigned int db_id = 0; + std::string db_login = server.options.GetDefaultLoginServerName(); if (!server.db->CreateLoginData(user, hash, db_login, db_id)) { DoFailedLogin(); } @@ -524,6 +590,11 @@ void Client::CreateLocalAccount(const std::string &user, const std::string &pass } } +/** + * @param user + * @param pass + * @param id + */ void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id) { auto mode = server.options.GetEncryptionMode(); @@ -537,12 +608,24 @@ void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass } } +/** + * @param connection + */ void Client::LoginOnNewConnection(std::shared_ptr connection) { login_connection = connection; } -void Client::LoginOnStatusChange(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) +/** + * @param conn + * @param from + * @param to + */ +void Client::LoginOnStatusChange( + std::shared_ptr conn, + EQ::Net::DbProtocolStatus from, + EQ::Net::DbProtocolStatus to +) { if (to == EQ::Net::StatusConnected) { LoginSendSessionReady(); @@ -553,20 +636,33 @@ void Client::LoginOnStatusChange(std::shared_ptr co } } -void Client::LoginOnStatusChangeIgnored(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) +/** + * @param conn + * @param from + * @param to + */ +void Client::LoginOnStatusChangeIgnored( + std::shared_ptr conn, + EQ::Net::DbProtocolStatus from, + EQ::Net::DbProtocolStatus to +) { } -void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet & p) +/** + * @param conn + * @param p + */ +void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p) { auto opcode = p.GetUInt16(0); switch (opcode) { - case 0x0017: //OP_ChatMessage - LoginSendLogin(); - break; - case 0x0018: - LoginProcessLoginResponse(p); - break; + case 0x0017: //OP_ChatMessage + LoginSendLogin(); + break; + case 0x0018: + LoginProcessLoginResponse(p); + break; } } @@ -581,7 +677,7 @@ void Client::LoginSendSessionReady() void Client::LoginSendLogin() { - size_t buffer_len = stored_user.length() + stored_pass.length() + 2; + size_t buffer_len = stored_user.length() + stored_pass.length() + 2; std::unique_ptr buffer(new char[buffer_len]); strcpy(&buffer[0], stored_user.c_str()); @@ -598,26 +694,33 @@ void Client::LoginSendLogin() p.PutUInt16(0, 2); //OP_Login p.PutUInt32(2, 3); - eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true); + eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true); login_connection->QueuePacket(p); } -void Client::LoginProcessLoginResponse(const EQ::Net::Packet & p) +void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) { - auto encrypt_size = p.Length() - 12; + auto encrypt_size = p.Length() - 12; if (encrypt_size % 8 > 0) { encrypt_size = (encrypt_size / 8) * 8; } std::unique_ptr decrypted(new char[encrypt_size]); - eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false); + eqcrypt_block((char *) p.Data() + 12, encrypt_size, &decrypted[0], false); EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); - auto response_error = sp.GetUInt16(1); + auto response_error = sp.GetUInt16(1); - login_connection_manager->OnConnectionStateChange(std::bind(&Client::LoginOnStatusChangeIgnored, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + login_connection_manager->OnConnectionStateChange( + std::bind( + &Client::LoginOnStatusChangeIgnored, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3 + )); if (response_error > 101) { DoFailedLogin(); diff --git a/loginserver/client.h b/loginserver/client.h index 8225dc90a..57440be5a 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_CLIENT_H #define EQEMU_CLIENT_H @@ -24,19 +27,15 @@ #include "../common/eq_stream_intf.h" #include "../common/net/dns.h" #include "../common/net/daybreak_connection.h" - #include "login_structures.h" - #include -enum LSClientVersion -{ +enum LSClientVersion { cv_titanium, cv_sod }; -enum LSClientStatus -{ +enum LSClientStatus { cs_not_sent_session_ready, cs_waiting_for_login, cs_creating_account, @@ -45,144 +44,186 @@ enum LSClientStatus }; /** -* Client class, controls a single client and it's -* connection to the login server. -*/ -class Client -{ + * Client class, controls a single client and it's connection to the login server + */ +class Client { public: + /** - * Constructor, sets our connection to c and version to v - */ + * Constructor, sets our connection to c and version to v + * + * @param c + * @param v + */ Client(std::shared_ptr c, LSClientVersion v); /** - * Destructor. - */ - ~Client() { } + * Destructor + */ + ~Client() {} /** - * Processes the client's connection and does various actions. - */ + * Processes the client's connection and does various actions + * + * @return + */ bool Process(); /** - * Sends our reply to session ready packet. - */ - void Handle_SessionReady(const char* data, unsigned int size); + * Sends our reply to session ready packet + * + * @param data + * @param size + */ + void Handle_SessionReady(const char *data, unsigned int size); /** - * Verifies login and send a reply. - */ - void Handle_Login(const char* data, unsigned int size); + * Verifies login and send a reply + * + * @param data + * @param size + */ + void Handle_Login(const char *data, unsigned int size); /** - * Sends a packet to the requested server to see if the client is allowed or not. - */ - void Handle_Play(const char* data); + * Sends a packet to the requested server to see if the client is allowed or not + * + * @param data + */ + void Handle_Play(const char *data); /** - * Sends a server list packet to the client. - */ + * Sends a server list packet to the client + * + * @param seq + */ void SendServerListPacket(uint32 seq); /** - * Sends the input packet to the client and clears our play response states. - */ + * Sends the input packet to the client and clears our play response states + * + * @param outapp + */ void SendPlayResponse(EQApplicationPacket *outapp); /** - * Generates a random login key for the client during login. - */ + * Generates a random login key for the client during login + */ void GenerateKey(); /** - * Gets the account id of this client. - */ + * Gets the account id of this client + * + * @return + */ unsigned int GetAccountID() const { return account_id; } /** - * Gets the loginserver name of this client. - */ + * Gets the loginserver name of this client + * + * @return + */ std::string GetLoginServerName() const { return loginserver_name; } /** - * Gets the account name of this client. - */ + * Gets the account name of this client + * + * @return + */ std::string GetAccountName() const { return account_name; } /** - * Gets the key generated at login for this client. - */ + * Gets the key generated at login for this client + * + * @return + */ std::string GetKey() const { return key; } /** - * Gets the server selected to be played on for this client. - */ + * Gets the server selected to be played on for this client + * + * @return + */ unsigned int GetPlayServerID() const { return play_server_id; } /** - * Gets the play sequence state for this client. - */ + * Gets the play sequence state for this client + * + * @return + */ unsigned int GetPlaySequence() const { return play_sequence_id; } /** - * Gets the connection for this client. - */ + * Gets the connection for this client + * + * @return + */ std::shared_ptr GetConnection() { return connection; } /** - * Attempts to create a login account - */ + * Attempts to create a login account + * + * @param user + * @param pass + * @param loginserver + */ void AttemptLoginAccountCreation(const std::string &user, const std::string &pass, const std::string &loginserver); /** - * Does a failed login - */ + * Does a failed login + */ void DoFailedLogin(); /** - * Verifies a login hash, will also attempt to update a login hash if needed. - */ - bool VerifyLoginHash(const std::string &user, const std::string &loginserver, const std::string &cred, const std::string &hash); + * Verifies a login hash, will also attempt to update a login hash if needed + * + * @param user + * @param loginserver + * @param cred + * @param hash + * @return + */ + bool VerifyLoginHash( + const std::string &user, + const std::string &loginserver, + const std::string &cred, + const std::string &hash + ); - /** - * Does a successful login - */ void DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver); - - /** - * Creates a local account - */ void CreateLocalAccount(const std::string &user, const std::string &pass); - - /** - * Creates an eqemu account - */ void CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id); private: - EQEmu::Random random; + EQEmu::Random random; std::shared_ptr connection; - LSClientVersion version; - LSClientStatus status; + LSClientVersion version; + LSClientStatus status; - std::string account_name; + std::string account_name; unsigned int account_id; - std::string loginserver_name; + std::string loginserver_name; unsigned int play_server_id; unsigned int play_sequence_id; - std::string key; + std::string key; std::unique_ptr login_connection_manager; - std::shared_ptr login_connection; - LoginLoginRequest_Struct llrs; + std::shared_ptr login_connection; + LoginLoginRequest_Struct llrs; std::string stored_user; std::string stored_pass; void LoginOnNewConnection(std::shared_ptr connection); - void LoginOnStatusChange(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); - void LoginOnStatusChangeIgnored(std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to); + void LoginOnStatusChange( + std::shared_ptr conn, + EQ::Net::DbProtocolStatus from, + EQ::Net::DbProtocolStatus to + ); + void LoginOnStatusChangeIgnored( + std::shared_ptr conn, + EQ::Net::DbProtocolStatus from, + EQ::Net::DbProtocolStatus to + ); void LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p); void LoginSendSessionReady(); void LoginSendLogin(); diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 9c8e3de09..210cf5824 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -1,87 +1,101 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "client_manager.h" #include "login_server.h" extern LoginServer server; -extern bool run_server; +extern bool run_server; #include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys_fmt.h" ClientManager::ClientManager() { - int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); + int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); - titanium_ops = new RegularOpcodeManager; - if (!titanium_ops->LoadOpcodes(server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str())) - { + titanium_ops = new RegularOpcodeManager; + if (!titanium_ops->LoadOpcodes( + server.config.GetVariableString( + "Titanium", + "opcodes", + "login_opcodes.conf" + ).c_str())) { Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for Titanium file %s.", server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str()); run_server = false; } - titanium_stream->OnNewConnection([this](std::shared_ptr stream) { - LogF(Logs::General, Logs::Login_Server, "New Titanium client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort()); - stream->SetOpcodeManager(&titanium_ops); - Client *c = new Client(stream, cv_titanium); - clients.push_back(c); - }); + titanium_stream->OnNewConnection( + [this](std::shared_ptr stream) { + LogF(Logs::General, + Logs::Login_Server, + "New Titanium client connection from {0}:{1}", + stream->GetRemoteIP(), + stream->GetRemotePort()); + stream->SetOpcodeManager(&titanium_ops); + Client *c = new Client(stream, cv_titanium); + clients.push_back(c); + } + ); - int sod_port = server.config.GetVariableInt("SoD", "port", 5999); + int sod_port = server.config.GetVariableInt("SoD", "port", 5999); EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false); sod_stream = new EQ::Net::EQStreamManager(sod_opts); - sod_ops = new RegularOpcodeManager; - if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) - { + sod_ops = new RegularOpcodeManager; + if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) { Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for SoD file %s.", server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str()); run_server = false; } - sod_stream->OnNewConnection([this](std::shared_ptr stream) { - LogF(Logs::General, Logs::Login_Server, "New SoD client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort()); - stream->SetOpcodeManager(&sod_ops); - Client *c = new Client(stream, cv_sod); - clients.push_back(c); - }); + sod_stream->OnNewConnection( + [this](std::shared_ptr stream) { + LogF(Logs::General, + Logs::Login_Server, + "New SoD client connection from {0}:{1}", + stream->GetRemoteIP(), + stream->GetRemotePort()); + stream->SetOpcodeManager(&sod_ops); + Client *c = new Client(stream, cv_sod); + clients.push_back(c); + } + ); } ClientManager::~ClientManager() { - if (titanium_stream) - { + if (titanium_stream) { delete titanium_stream; } - if (titanium_ops) - { + if (titanium_ops) { delete titanium_ops; } - if (sod_stream) - { + if (sod_stream) { delete sod_stream; } - if (sod_ops) - { + if (sod_ops) { delete sod_ops; } } @@ -91,16 +105,13 @@ void ClientManager::Process() ProcessDisconnect(); auto iter = clients.begin(); - while (iter != clients.end()) - { - if ((*iter)->Process() == false) - { + while (iter != clients.end()) { + if ((*iter)->Process() == false) { Log(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login."); delete (*iter); iter = clients.erase(iter); } - else - { + else { ++iter; } } @@ -109,17 +120,14 @@ void ClientManager::Process() void ClientManager::ProcessDisconnect() { auto iter = clients.begin(); - while (iter != clients.end()) - { + while (iter != clients.end()) { std::shared_ptr c = (*iter)->GetConnection(); - if (c->CheckState(CLOSED)) - { + if (c->CheckState(CLOSED)) { Log(Logs::General, Logs::Login_Server, "Client disconnected from the server, removing client."); delete (*iter); iter = clients.erase(iter); } - else - { + else { ++iter; } } @@ -128,16 +136,15 @@ void ClientManager::ProcessDisconnect() void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver) { auto iter = clients.begin(); - while (iter != clients.end()) - { - if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) - { - Log(Logs::General, Logs::Login_Server, "Client attempting to log in and existing client already logged in, removing existing client."); + while (iter != clients.end()) { + if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { + Log(Logs::General, + Logs::Login_Server, + "Client attempting to log in and existing client already logged in, removing existing client."); delete (*iter); iter = clients.erase(iter); } - else - { + else { ++iter; } } @@ -146,10 +153,8 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver) { auto iter = clients.begin(); - while (iter != clients.end()) - { - if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) - { + while (iter != clients.end()) { + if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { return (*iter); } ++iter; diff --git a/loginserver/client_manager.h b/loginserver/client_manager.h index 08b1f1b98..4de290210 100644 --- a/loginserver/client_manager.h +++ b/loginserver/client_manager.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_CLIENTMANAGER_H #define EQEMU_CLIENTMANAGER_H @@ -27,44 +30,50 @@ /** * Client manager class, holds all the client objects and does basic processing. */ -class ClientManager -{ +class ClientManager { public: /** - * Constructor, sets up the stream factories and opcode managers. - */ + * Constructor: sets up the stream factories and opcode managers + */ ClientManager(); /** - * Destructor, shuts down the streams and opcode managers. - */ + * Destructor: shuts down the streams and opcode managers + */ ~ClientManager(); /** - * Processes every client in the internal list, removes them if necessary. - */ + * Processes every client in the internal list, removes them if necessary. + */ void Process(); /** - * Removes a client with a certain account id. - */ + * Removes a client with a certain account id + * + * @param account_id + * @param loginserver + */ void RemoveExistingClient(unsigned int account_id, const std::string &loginserver); /** - * Gets a client (if exists) by their account id. - */ + * Gets a client (if exists) by their account id + * + * @param account_id + * @param loginserver + * @return + */ Client *GetClient(unsigned int account_id, const std::string &loginserver); private: /** - * Processes disconnected clients, removes them if necessary. - */ + * Processes disconnected clients, removes them if necessary + */ void ProcessDisconnect(); - std::list clients; - OpcodeManager *titanium_ops; + std::list clients; + OpcodeManager *titanium_ops; EQ::Net::EQStreamManager *titanium_stream; - OpcodeManager *sod_ops; + OpcodeManager *sod_ops; EQ::Net::EQStreamManager *sod_stream; }; diff --git a/loginserver/config.cpp b/loginserver/config.cpp index 72d44efa0..f9dc32fba 100644 --- a/loginserver/config.cpp +++ b/loginserver/config.cpp @@ -1,37 +1,41 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" #include "config.h" /** -* Retrieves the variable we want from our title or theme -* First gets the map from the title -* Then gets the argument from the map we got from title -*/ + * Retrieves the variable we want from our title or theme + * First gets the map from the title, then gets the argument from the map we got from title + * + * @param title + * @param parameter + * @return + */ std::string Config::GetVariable(std::string title, std::string parameter) { std::map >::iterator iter = vars.find(title); - if(iter != vars.end()) - { + if (iter != vars.end()) { std::map::iterator arg_iter = iter->second.find(parameter); - if(arg_iter != iter->second.end()) - { + if (arg_iter != iter->second.end()) { return arg_iter->second; } } @@ -40,50 +44,44 @@ std::string Config::GetVariable(std::string title, std::string parameter) } /** -* Opens a file and passes it to the tokenizer -* Then it parses the tokens returned and puts them into titles and variables. -*/ + * Opens a file and passes it to the tokenizer + * Then it parses the tokens returned and puts them into titles and variables + * + * @param file_name + */ void Config::Parse(const char *file_name) { - if(file_name == nullptr) - { + if (file_name == nullptr) { Log(Logs::General, Logs::Error, "Config::Parse(), file_name passed was null."); return; } vars.clear(); FILE *input = fopen(file_name, "r"); - if(input) - { + if (input) { std::list tokens; Tokenize(input, tokens); - char mode = 0; - std::string title, param, arg; + char mode = 0; + std::string title, param, arg; std::list::iterator iter = tokens.begin(); - while(iter != tokens.end()) - { - if((*iter).compare("[") == 0) - { + while (iter != tokens.end()) { + if ((*iter).compare("[") == 0) { title.clear(); bool first = true; ++iter; - if(iter == tokens.end()) - { + if (iter == tokens.end()) { Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing."); fclose(input); vars.clear(); return; } - while((*iter).compare("]") != 0 && iter != tokens.end()) - { - if(!first) - { + while ((*iter).compare("]") != 0 && iter != tokens.end()) { + if (!first) { title += " "; } - else - { + else { first = false; } @@ -93,65 +91,58 @@ void Config::Parse(const char *file_name) ++iter; } - if(mode == 0) - { + if (mode == 0) { param = (*iter); mode++; } - else if(mode == 1) - { + else if (mode == 1) { mode++; - if((*iter).compare("=") != 0) - { + if ((*iter).compare("=") != 0) { Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be."); fclose(input); vars.clear(); return; } } - else - { - arg = (*iter); + else { + arg = (*iter); mode = 0; std::map >::iterator map_iter = vars.find(title); - if(map_iter != vars.end()) - { + if (map_iter != vars.end()) { map_iter->second[param] = arg; - vars[title] = map_iter->second; + vars[title] = map_iter->second; } - else - { + else { std::map var_map; var_map[param] = arg; - vars[title] = var_map; + vars[title] = var_map; } } ++iter; } fclose(input); } - else - { + else { Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing."); } } /** -* Pretty basic lexical analyzer -* Breaks up the input character stream into tokens and puts them into the list provided. -* Ignores # as a line comment -*/ + * Pretty basic lexical analyzer + * Breaks up the input character stream into tokens and puts them into the list provided + * Ignores # as a line comment + * + * @param input + * @param tokens + */ void Config::Tokenize(FILE *input, std::list &tokens) { - auto c = fgetc(input); + auto c = fgetc(input); std::string lexeme; - while(c != EOF) - { - if(isspace(c)) - { - if(lexeme.size() > 0) - { + while (c != EOF) { + if (isspace(c)) { + if (lexeme.size() > 0) { tokens.push_back(lexeme); lexeme.clear(); } @@ -159,35 +150,28 @@ void Config::Tokenize(FILE *input, std::list &tokens) continue; } - if(isalnum(c)) - { + if (isalnum(c)) { lexeme += c; c = fgetc(input); continue; } - switch(c) - { - case '#': - { - if(lexeme.size() > 0) - { + switch (c) { + case '#': { + if (lexeme.size() > 0) { tokens.push_back(lexeme); lexeme.clear(); } - while(c != '\n' && c != EOF) - { + while (c != '\n' && c != EOF) { c = fgetc(input); } break; } - case '[': - case ']': - case '=': - { - if(lexeme.size() > 0) - { + case '[': + case ']': + case '=': { + if (lexeme.size() > 0) { tokens.push_back(lexeme); lexeme.clear(); } @@ -197,8 +181,7 @@ void Config::Tokenize(FILE *input, std::list &tokens) lexeme.clear(); break; } - default: - { + default: { lexeme += c; } } @@ -206,8 +189,7 @@ void Config::Tokenize(FILE *input, std::list &tokens) c = fgetc(input); } - if(lexeme.size() > 0) - { + if (lexeme.size() > 0) { tokens.push_back(lexeme); } } diff --git a/loginserver/config.h b/loginserver/config.h index 36d1feebe..549b32693 100644 --- a/loginserver/config.h +++ b/loginserver/config.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_CONFIG_H #define EQEMU_CONFIG_H diff --git a/loginserver/database.h b/loginserver/database.h index 00a76b099..b1651fae7 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_DATABASE_H #define EQEMU_DATABASE_H @@ -25,58 +28,110 @@ /** * Base database class, intended to be extended. */ -class Database -{ +class Database { public: - Database() : user(""), pass(""), host(""), port(""), name("") { } - virtual ~Database() { } + Database() : user(""), pass(""), host(""), port(""), name("") {} + virtual ~Database() {} - /** - * Returns true if the database successfully connected. - */ virtual bool IsConnected() { return false; } /** - * Retrieves the login data (password hash and account id) from the account name provided - * Needed for client login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetLoginDataFromAccountInfo(const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id) { return false; } + * Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure + * + * @param name + * @param loginserver + * @param password + * @param id + * @return + */ + virtual bool GetLoginDataFromAccountInfo( + const std::string &name, + const std::string &loginserver, + std::string &password, + unsigned int &id + ) { return false; } - virtual bool GetLoginTokenDataFromToken(const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user) { return false; } + virtual bool GetLoginTokenDataFromToken( + const std::string &token, + const std::string &ip, + unsigned int &db_account_id, + std::string &db_loginserver, + std::string &user + ) { return false; } - virtual bool CreateLoginData(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id) { return false; } + virtual bool CreateLoginData( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int &id + ) { return false; } - virtual bool CreateLoginDataWithID(const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id) { return false; } + virtual bool CreateLoginDataWithID( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id + ) { return false; } - virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { } + virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) {} /** - * Retrieves the world registration from the long and short names provided. - * Needed for world login procedure. - * Returns true if the record was found, false otherwise. - */ - virtual bool GetWorldRegistration(std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, - unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password) { return false; } + * Retrieves the world registration from the long and short names provided + * Needed for world login procedure + * Returns true if the record was found, false otherwise + * + * @param long_name + * @param short_name + * @param id + * @param desc + * @param list_id + * @param trusted + * @param list_desc + * @param account + * @param password + * @return + */ + virtual bool GetWorldRegistration( + std::string long_name, + std::string short_name, + unsigned int &id, + std::string &desc, + unsigned int &list_id, + unsigned int &trusted, + std::string &list_desc, + std::string &account, + std::string &password + ) { return false; } + + virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {} /** - * Updates the ip address of the client with account id = id - */ - virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) { } + * Updates or creates the login server account with info from world server + * + * @param id + * @param name + * @param password + * @param email + */ + virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) {} /** - * Updates or creates the login server account with info from world server - */ - virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { } + * Updates the ip address of the world with account id = id + * + * @param id + * @param long_name + * @param ip_address + */ + virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) {} /** - * Updates the ip address of the world with account id = id - */ - virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { } - - /** - * Creates new world registration for unregistered servers and returns new id - */ + * Creates new world registration for unregistered servers and returns new id + * + * @param long_name + * @param short_name + * @param id + * @return + */ virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { return false; } protected: std::string user, pass, host, port, name; diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 0f1c6b7cf..7c3eda074 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -18,7 +18,6 @@ * */ - #include "../common/global_define.h" #include "database.h" diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index 43d6ae694..0a635b081 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -1,3 +1,23 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include #include #include diff --git a/loginserver/encryption.h b/loginserver/encryption.h index 3ec9c2743..a6e79292f 100644 --- a/loginserver/encryption.h +++ b/loginserver/encryption.h @@ -1,3 +1,23 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #pragma once #include diff --git a/loginserver/eq_crypto_api.h b/loginserver/eq_crypto_api.h index d722bcb53..bff7b8444 100644 --- a/loginserver/eq_crypto_api.h +++ b/loginserver/eq_crypto_api.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMUCAPI__H #define EQEMUCAPI__H diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 111565dbb..4efb05265 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_LOGINSERVER_H #define EQEMU_LOGINSERVER_H @@ -27,9 +30,8 @@ #include "client_manager.h" /** -* Login server struct, contains every variable for the server that needs to exist -* outside the scope of main(). -*/ + * Login server struct, contains every variable for the server that needs to exist outside the scope of main() + */ struct LoginServer { public: diff --git a/loginserver/login_structures.h b/loginserver/login_structures.h index 6e3f290e9..099b4b4f0 100644 --- a/loginserver/login_structures.h +++ b/loginserver/login_structures.h @@ -1,32 +1,35 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_LOGINSTRUCTURES_H #define EQEMU_LOGINSTRUCTURES_H #pragma pack(1) struct LoginChatMessage_Struct { - short Unknown0; + short Unknown0; uint32 Unknown1; uint32 Unknown2; uint32 Unknown3; - uint8 Unknown4; - char ChatMessage[1]; + uint8 Unknown4; + char ChatMessage[1]; }; struct LoginLoginRequest_Struct { @@ -35,7 +38,7 @@ struct LoginLoginRequest_Struct { short unknown3; short unknown4; short unknown5; - char unknown6[16]; + char unknown6[16]; }; struct LoginAccepted_Struct { @@ -44,28 +47,27 @@ struct LoginAccepted_Struct { short unknown3; short unknown4; short unknown5; - char encrypt[80]; + char encrypt[80]; }; -struct LoginFailedAttempts_Struct -{ - char message; //0x01 - char unknown2[7]; //0x00 +struct LoginFailedAttempts_Struct { + char message; //0x01 + char unknown2[7]; //0x00 uint32 lsid; - char key[11]; //10 char + null term; + char key[11]; //10 char + null term; uint32 failed_attempts; - char unknown3[4]; //0x00, 0x00, 0x00, 0x03 - char unknown4[4]; //0x00, 0x00, 0x00, 0x02 - char unknown5[4]; //0xe7, 0x03, 0x00, 0x00 - char unknown6[4]; //0xff, 0xff, 0xff, 0xff - char unknown7[4]; //0xa0, 0x05, 0x00, 0x00 - char unknown8[4]; //0x00, 0x00, 0x00, 0x02 - char unknown9[4]; //0xff, 0x03, 0x00, 0x00 - char unknown10[4]; //0x00, 0x00, 0x00, 0x00 - char unknown11[4]; //0x63, 0x00, 0x00, 0x00 - char unknown12[4]; //0x01, 0x00, 0x00, 0x00 - char unknown13[4]; //0x00, 0x00, 0x00, 0x00 - char unknown14[4]; //0x00, 0x00, 0x00, 0x00 + char unknown3[4]; //0x00, 0x00, 0x00, 0x03 + char unknown4[4]; //0x00, 0x00, 0x00, 0x02 + char unknown5[4]; //0xe7, 0x03, 0x00, 0x00 + char unknown6[4]; //0xff, 0xff, 0xff, 0xff + char unknown7[4]; //0xa0, 0x05, 0x00, 0x00 + char unknown8[4]; //0x00, 0x00, 0x00, 0x02 + char unknown9[4]; //0xff, 0x03, 0x00, 0x00 + char unknown10[4]; //0x00, 0x00, 0x00, 0x00 + char unknown11[4]; //0x63, 0x00, 0x00, 0x00 + char unknown12[4]; //0x01, 0x00, 0x00, 0x00 + char unknown13[4]; //0x00, 0x00, 0x00, 0x00 + char unknown14[4]; //0x00, 0x00, 0x00, 0x00 }; struct LoginLoginFailed_Struct { @@ -74,7 +76,7 @@ struct LoginLoginFailed_Struct { short unknown3; short unknown4; short unknown5; - char unknown6[74]; + char unknown6[74]; }; struct ServerListHeader_Struct { @@ -86,8 +88,7 @@ struct ServerListHeader_Struct { uint32 NumberOfServers; }; -struct PlayEverquestRequest_Struct -{ +struct PlayEverquestRequest_Struct { uint16 Sequence; uint32 Unknown1; uint32 Unknown2; @@ -95,18 +96,19 @@ struct PlayEverquestRequest_Struct }; struct PlayEverquestResponse_Struct { - uint8 Sequence; - uint8 Unknown1[9]; - uint8 Allowed; + uint8 Sequence; + uint8 Unknown1[9]; + uint8 Allowed; uint16 Message; - uint8 Unknown2[3]; + uint8 Unknown2[3]; uint32 ServerNumber; }; static const unsigned char FailedLoginResponseData[] = { 0xf6, 0x85, 0x9c, 0x23, 0x57, 0x7e, 0x3e, 0x55, 0xb3, 0x4c, 0xf8, 0xc8, 0xcb, 0x77, 0xd5, 0x16, 0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3, 0x4c, 0xf8, 0xc8, 0xcb, 0x77, 0xd5, 0x16, - 0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3 }; + 0x09, 0x7a, 0x63, 0xdc, 0x57, 0x7e, 0x3e, 0x55, 0xb3 +}; #pragma pack() diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 199b65889..4f28cf1e1 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -80,11 +80,13 @@ int main() ) ); + #ifdef ENABLE_SECURITY server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13)); #else server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6)); #endif + server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true)); server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false)); server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true)); @@ -93,44 +95,47 @@ int main() "security", "update_insecure_passwords", true - )); - + ) + ); server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); server.options.WorldRegistrationTable( server.config.GetVariableString( "schema", "world_registration_table", "tblWorldServerRegistration" - )); + ) + ); server.options.WorldAdminRegistrationTable( server.config.GetVariableString( "schema", "world_admin_registration_table", "tblServerAdminRegistration" - )); + ) + ); server.options.WorldServerTypeTable( server.config.GetVariableString( "schema", "world_server_type_table", "tblServerListType" - )); + ) + ); /** * mysql connect */ - if (server.config.GetVariableString("database", "subsystem", "MySQL").compare("MySQL") == 0) { - Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); - server.db = (Database *) new DatabaseMySQL( - server.config.GetVariableString("database", "user", "root"), - server.config.GetVariableString("database", "password", ""), - server.config.GetVariableString("database", "host", "localhost"), - server.config.GetVariableString("database", "port", "3306"), - server.config.GetVariableString("database", "db", "peq") - ); - } + Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); + + server.db = (Database *) new DatabaseMySQL( + server.config.GetVariableString("database", "user", "root"), + server.config.GetVariableString("database", "password", ""), + server.config.GetVariableString("database", "host", "localhost"), + server.config.GetVariableString("database", "port", "3306"), + server.config.GetVariableString("database", "db", "peq") + ); + /** - * Make sure our database got created okay, otherwise cleanup and exit + * make sure our database got created okay, otherwise cleanup and exit */ if (!server.db) { Log(Logs::General, Logs::Error, "Database Initialization Failure."); @@ -143,7 +148,7 @@ int main() */ Log(Logs::General, Logs::Login_Server, "Server Manager Initialize."); server.server_manager = new ServerManager(); - if (!server.server_manager) + if (!server.server_manager) { Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); delete server.db; diff --git a/loginserver/options.h b/loginserver/options.h index 6f4425a88..aeeed6731 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_OPTIONS_H #define EQEMU_OPTIONS_H @@ -22,12 +25,12 @@ * Collects options on one object, because having a bunch of global variables floating around is * really ugly and just a little dangerous. */ -class Options -{ +class Options { public: + /** - * Constructor, sets the default options. - */ + * Constructor: Default options + */ Options() : allow_unregistered(true), trace(false), @@ -38,7 +41,7 @@ public: reject_duplicate_servers(false), allow_password_login(true), allow_token_login(false), - auto_create_accounts(false) { } + auto_create_accounts(false) {} /** * Sets allow_unregistered. @@ -182,18 +185,18 @@ public: inline bool IsUpdatingInsecurePasswords() const { return update_insecure_passwords; } private: - bool allow_unregistered; - bool trace; - bool world_trace; - bool dump_in_packets; - bool dump_out_packets; - bool reject_duplicate_servers; - bool allow_token_login; - bool allow_password_login; - bool auto_create_accounts; - bool auto_link_accounts; - bool update_insecure_passwords; - int encryption_mode; + bool allow_unregistered; + bool trace; + bool world_trace; + bool dump_in_packets; + bool dump_out_packets; + bool reject_duplicate_servers; + bool allow_token_login; + bool allow_password_login; + bool auto_create_accounts; + bool auto_link_accounts; + bool update_insecure_passwords; + int encryption_mode; std::string local_network; std::string account_table; std::string world_registration_table; diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 616119231..533a87c58 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "server_manager.h" #include "login_server.h" #include "login_structures.h" @@ -24,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/eqemu_logsys_fmt.h" extern LoginServer server; -extern bool run_server; +extern bool run_server; ServerManager::ServerManager() { @@ -36,38 +39,52 @@ ServerManager::ServerManager() opts.ipv6 = false; server_connection->Listen(opts); - server_connection->OnConnectionIdentified("World", [this](std::shared_ptr c) { - LogF(Logs::General, Logs::Login_Server, "New world server connection from {0}:{1}", c->Handle()->RemoteIP(), c->Handle()->RemotePort()); + server_connection->OnConnectionIdentified( + "World", [this](std::shared_ptr c) { + LogF(Logs::General, + Logs::Login_Server, + "New world server connection from {0}:{1}", + c->Handle()->RemoteIP(), + c->Handle()->RemotePort()); - auto iter = world_servers.begin(); - while (iter != world_servers.end()) { - if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 && - (*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) { - LogF(Logs::General, Logs::Login_Server, "World server already existed for {0}:{1}, removing existing connection.", - c->Handle()->RemoteIP(), c->Handle()->RemotePort()); + auto iter = world_servers.begin(); + while (iter != world_servers.end()) { + if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 && + (*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) { + LogF(Logs::General, + Logs::Login_Server, + "World server already existed for {0}:{1}, removing existing connection.", + c->Handle()->RemoteIP(), + c->Handle()->RemotePort()); - world_servers.erase(iter); - break; + world_servers.erase(iter); + break; + } + + ++iter; } - ++iter; + world_servers.push_back(std::unique_ptr(new WorldServer(c))); } + ); - world_servers.push_back(std::unique_ptr(new WorldServer(c))); - }); + server_connection->OnConnectionRemoved( + "World", [this](std::shared_ptr c) { + auto iter = world_servers.begin(); + while (iter != world_servers.end()) { + if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) { + LogF(Logs::General, + Logs::World_Server, + "World server {0} has been disconnected, removing.", + (*iter)->GetLongName().c_str()); + world_servers.erase(iter); + return; + } - server_connection->OnConnectionRemoved("World", [this](std::shared_ptr c) { - auto iter = world_servers.begin(); - while (iter != world_servers.end()) { - if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) { - LogF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", (*iter)->GetLongName().c_str()); - world_servers.erase(iter); - return; + ++iter; } - - ++iter; } - }); + ); } ServerManager::~ServerManager() @@ -75,11 +92,12 @@ ServerManager::~ServerManager() } -WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port) +WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { - if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && (*iter)->GetConnection()->Handle()->RemotePort()) { + if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && + (*iter)->GetConnection()->Handle()->RemotePort()) { return (*iter).get(); } ++iter; @@ -90,9 +108,9 @@ WorldServer* ServerManager::GetServerByAddress(const std::string &addr, int port EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq) { - unsigned int packet_size = sizeof(ServerListHeader_Struct); + unsigned int packet_size = sizeof(ServerListHeader_Struct); unsigned int server_count = 0; - in_addr in; + in_addr in; in.s_addr = c->GetConnection()->GetRemoteIP(); std::string client_ip = inet_ntoa(in); @@ -119,8 +137,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq ++iter; } - EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); - ServerListHeader_Struct *server_list = (ServerListHeader_Struct*)outapp->pBuffer; + EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); + ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer; server_list->Unknown1 = seq; server_list->Unknown2 = 0x00000000; server_list->Unknown3 = 0x01650000; @@ -129,7 +147,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq * Not sure what this is but it should be noted setting it to * 0xFFFFFFFF crashes the client so: don't do that. */ - server_list->Unknown4 = 0x00000000; + server_list->Unknown4 = 0x00000000; server_list->NumberOfServers = server_count; unsigned char *data_pointer = outapp->pBuffer; @@ -157,22 +175,22 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq } switch ((*iter)->GetServerListID()) { - case 1: { - *(unsigned int*)data_pointer = 0x00000030; - break; - } - case 2: { - *(unsigned int*)data_pointer = 0x00000009; - break; - } - default: { - *(unsigned int*)data_pointer = 0x00000001; - } + case 1: { + *(unsigned int *) data_pointer = 0x00000030; + break; + } + case 2: { + *(unsigned int *) data_pointer = 0x00000009; + break; + } + default: { + *(unsigned int *) data_pointer = 0x00000001; + } } data_pointer += 4; - *(unsigned int*)data_pointer = (*iter)->GetRuntimeID(); + *(unsigned int *) data_pointer = (*iter)->GetRuntimeID(); data_pointer += 4; memcpy(data_pointer, (*iter)->GetLongName().c_str(), (*iter)->GetLongName().size()); @@ -187,18 +205,18 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq // 0 = Up, 1 = Down, 2 = Up, 3 = down, 4 = locked, 5 = locked(down) if ((*iter)->GetStatus() < 0) { if ((*iter)->GetZonesBooted() == 0) { - *(uint32*)data_pointer = 0x01; + *(uint32 *) data_pointer = 0x01; } else { - *(uint32*)data_pointer = 0x04; + *(uint32 *) data_pointer = 0x04; } } else { - *(uint32*)data_pointer = 0x02; + *(uint32 *) data_pointer = 0x02; } data_pointer += 4; - *(uint32*)data_pointer = (*iter)->GetPlayersOnline(); + *(uint32 *) data_pointer = (*iter)->GetPlayersOnline(); data_pointer += 4; ++iter; @@ -207,16 +225,20 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq return outapp; } -void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver) +void ServerManager::SendUserToWorldRequest( + unsigned int server_id, + unsigned int client_account_id, + const std::string &client_loginserver +) { - auto iter = world_servers.begin(); + auto iter = world_servers.begin(); bool found = false; while (iter != world_servers.end()) { if ((*iter)->GetRuntimeID() == server_id) { EQ::Net::DynamicPacket outapp; outapp.Resize(sizeof(UsertoWorldRequest_Struct)); - UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct*)outapp.Data(); - utwr->worldid = server_id; + UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) outapp.Data(); + utwr->worldid = server_id; utwr->lsaccountid = client_account_id; strncpy(utwr->login, &client_loginserver[0], 64); (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp); @@ -230,7 +252,10 @@ void ServerManager::SendUserToWorldRequest(unsigned int server_id, unsigned int } if (!found && server.options.IsTraceOn()) { - Log(Logs::General, Logs::Error, "Client requested a user to world but supplied an invalid id of %u.", server_id); + Log(Logs::General, + Logs::Error, + "Client requested a user to world but supplied an invalid id of %u.", + server_id); } } diff --git a/loginserver/server_manager.h b/loginserver/server_manager.h index 220f40be3..5c3390b09 100644 --- a/loginserver/server_manager.h +++ b/loginserver/server_manager.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_SERVERMANAGER_H #define EQEMU_SERVERMANAGER_H @@ -27,14 +30,14 @@ #include /** -* Server manager class, deals with management of the world servers. -*/ -class ServerManager -{ + * Server manager class, deals with management of the world servers + */ +class ServerManager { public: + /** - * Constructor, sets up the TCP server and starts listening. - */ + * Constructor, sets up the TCP server and starts listening + */ ServerManager(); /** @@ -43,34 +46,60 @@ public: ~ServerManager(); /** - * Sends a request to world to see if the client is banned or suspended. - */ - void SendUserToWorldRequest(unsigned int server_id, unsigned int client_account_id, const std::string &client_loginserver); + * Sends a request to world to see if the client is banned or suspended + * + * @param server_id + * @param client_account_id + * @param client_loginserver + */ + void SendUserToWorldRequest( + unsigned int server_id, + unsigned int client_account_id, + const std::string &client_loginserver + ); /** - * Creates a server list packet for the client. - */ + * Creates a server list packet for the client + * + * @param c + * @param seq + * @return + */ EQApplicationPacket *CreateServerListPacket(Client *c, uint32 seq); /** - * Checks to see if there is a server exists with this name, ignoring option. - */ + * Checks to see if there is a server exists with this name, ignoring option + * + * @param l_name + * @param s_name + * @param ignore + * @return + */ bool ServerExists(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); /** - * Destroys a server with this name, ignoring option. - */ + * Destroys a server with this name, ignoring option + * + * @param l_name + * @param s_name + * @param ignore + */ void DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); private: + /** - * Retrieves a server(if exists) by ip address - * Useful utility for the reconnect process. - */ - WorldServer* GetServerByAddress(const std::string &address, int port); + * Retrieves a server(if exists) by ip address + * Useful utility for the reconnect process + * + * @param address + * @param port + * @return + */ + WorldServer *GetServerByAddress(const std::string &address, int port); std::unique_ptr server_connection; - std::list> world_servers; + std::list> world_servers; }; #endif diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 5561b1964..5942063f4 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -1,47 +1,73 @@ -/* EQEMu: Everquest Server Emulator -Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY except by those people which sell it, which -are required to give you total support for your newly bought product; -without even the implied warranty of MERCHANTABILITY or FITNESS FOR -A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #include "world_server.h" #include "login_server.h" #include "login_structures.h" #include "config.h" - #include "../common/eqemu_logsys.h" extern LoginServer server; WorldServer::WorldServer(std::shared_ptr c) { - connection = c; - zones_booted = 0; - players_online = 0; - server_status = 0; - runtime_id = 0; - server_list_id = 0; - server_type = 0; + connection = c; + zones_booted = 0; + players_online = 0; + server_status = 0; + runtime_id = 0; + server_list_id = 0; + server_type = 0; is_server_authorized = false; - is_server_trusted = false; - is_server_logged_in = false; + is_server_trusted = false; + is_server_logged_in = false; - c->OnMessage(ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_UsertoWorldRespLeg, std::bind(&WorldServer::ProcessUsertoWorldRespLeg, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_UsertoWorldResp, std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2)); - c->OnMessage(ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); + c->OnMessage( + ServerOP_NewLSInfo, + std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2) + ); + + c->OnMessage( + ServerOP_LSStatus, + std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2) + ); + + c->OnMessage( + ServerOP_UsertoWorldRespLeg, + std::bind( + &WorldServer::ProcessUsertoWorldRespLeg, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + + c->OnMessage( + ServerOP_UsertoWorldResp, + std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2) + ); + + c->OnMessage( + ServerOP_LSAccountUpdate, + std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2) + ); } WorldServer::~WorldServer() @@ -51,87 +77,92 @@ WorldServer::~WorldServer() void WorldServer::Reset() { - zones_booted = 0; + zones_booted = 0; players_online = 0; - server_status = 0; + server_status = 0; runtime_id; - server_list_id = 0; - server_type = 0; + server_list_id = 0; + server_type = 0; is_server_authorized = false; - is_server_logged_in = false; + is_server_logged_in = false; } void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } - if (p.Length() < sizeof(ServerNewLSInfo_Struct)) - { - Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " + if (p.Length() < sizeof(ServerNewLSInfo_Struct)) { + Log(Logs::General, Logs::Error, + "Received application packet from server that had opcode ServerOP_NewLSInfo, " "but was too small. Discarded to avoid buffer overrun."); return; } - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "New Login Info Recieved."); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, Logs::Netcode, "New Login Info Received."); } - ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct*)p.Data(); + ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data(); Handle_NewLSInfo(info); } void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } - if (p.Length() < sizeof(ServerLSStatus_Struct)) - { - Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_LSStatus, " - "but was too small. Discarded to avoid buffer overrun."); + if (p.Length() < sizeof(ServerLSStatus_Struct)) { + Log(Logs::General, + Logs::Error, + "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun"); return; } - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "World Server Status Recieved."); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, Logs::Netcode, "World Server Status Received."); } - ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct*)p.Data(); + ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data(); Handle_LSStatus(ls_status); } void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } - if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) - { - Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " + if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { + Log(Logs::General, + Logs::Error, + "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun."); return; } @@ -139,86 +170,101 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack //I don't use world trace for this and here is why: //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. - if (server.options.IsTraceOn()) - { + if (server.options.IsTraceOn()) { Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct*)p.Data(); + UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct *) p.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); Client *c = server.client_manager->GetClient(utwr->lsaccountid, "eqemu"); - if (c) - { - Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); - EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; - per->Sequence = c->GetPlaySequence(); + if (c) { + Log(Logs::General, + Logs::Debug, + "Found client with user id of %u and account name of %s.", + utwr->lsaccountid, + c->GetAccountName().c_str()); + EQApplicationPacket *outapp = new EQApplicationPacket( + OP_PlayEverquestResponse, + sizeof(PlayEverquestResponse_Struct)); + PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; + per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - if (utwr->response > 0) - { + if (utwr->response > 0) { per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName()); + SendClientAuth( + c->GetConnection()->GetRemoteAddr(), + c->GetAccountName(), + c->GetKey(), + c->GetAccountID(), + c->GetLoginServerName()); } - switch (utwr->response) - { - case 1: - per->Message = 101; - break; - case 0: - per->Message = 326; - break; - case -1: - per->Message = 337; - break; - case -2: - per->Message = 338; - break; - case -3: - per->Message = 303; - break; + switch (utwr->response) { + case 1: + per->Message = 101; + break; + case 0: + per->Message = 326; + break; + case -1: + per->Message = 337; + break; + case -2: + per->Message = 338; + break; + case -3: + per->Message = 303; + break; } - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", - per->Allowed, per->Sequence, per->ServerNumber, per->Message); + if (server.options.IsTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", + per->Allowed, + per->Sequence, + per->ServerNumber, + per->Message); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); } - if (server.options.IsDumpOutPacketsOn()) - { + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } c->SendPlayResponse(outapp); delete outapp; } - else - { - Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); + else { + Log(Logs::General, + Logs::Error, + "Received User-To-World Response for %u but could not find the client referenced!.", + utwr->lsaccountid); } } void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } - if (p.Length() < sizeof(UsertoWorldResponse_Struct)) - { - Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerOP_UsertoWorldResp, " + if (p.Length() < sizeof(UsertoWorldResponse_Struct)) { + Log(Logs::General, + Logs::Error, + "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun."); return; } @@ -226,94 +272,112 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet //I don't use world trace for this and here is why: //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. - if (server.options.IsTraceOn()) - { + if (server.options.IsTraceOn()) { Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct*)p.Data(); + UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) p.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); - if (c) - { - Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", utwr->lsaccountid, c->GetAccountName().c_str()); - EQApplicationPacket *outapp = new EQApplicationPacket(OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct)); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct*)outapp->pBuffer; - per->Sequence = c->GetPlaySequence(); + if (c) { + Log(Logs::General, + Logs::Debug, + "Found client with user id of %u and account name of %s.", + utwr->lsaccountid, + c->GetAccountName().c_str()); + EQApplicationPacket *outapp = new EQApplicationPacket( + OP_PlayEverquestResponse, + sizeof(PlayEverquestResponse_Struct)); + PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; + per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - if (utwr->response > 0) - { + if (utwr->response > 0) { per->Allowed = 1; - SendClientAuth(c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), c->GetLoginServerName()); + SendClientAuth( + c->GetConnection()->GetRemoteAddr(), + c->GetAccountName(), + c->GetKey(), + c->GetAccountID(), + c->GetLoginServerName()); } - switch (utwr->response) - { - case 1: - per->Message = 101; - break; - case 0: - per->Message = 326; - break; - case -1: - per->Message = 337; - break; - case -2: - per->Message = 338; - break; - case -3: - per->Message = 303; - break; + switch (utwr->response) { + case 1: + per->Message = 101; + break; + case 0: + per->Message = 326; + break; + case -1: + per->Message = 337; + break; + case -2: + per->Message = 338; + break; + case -3: + per->Message = 303; + break; } - if (server.options.IsTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", - per->Allowed, per->Sequence, per->ServerNumber, per->Message); + if (server.options.IsTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", + per->Allowed, + per->Sequence, + per->ServerNumber, + per->Message); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); } - if (server.options.IsDumpOutPacketsOn()) - { + if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); } c->SendPlayResponse(outapp); delete outapp; } - else - { - Log(Logs::General, Logs::Error, "Recieved User-To-World Response for %u but could not find the client referenced!.", utwr->lsaccountid); + else { + Log(Logs::General, + Logs::Error, + "Received User-To-World Response for %u but could not find the client referenced!.", + utwr->lsaccountid); } } +/** + * @param opcode + * @param p + */ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) - { - Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, p.Length()); + if (server.options.IsWorldTraceOn()) { + Log(Logs::General, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length()); } - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } - if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) - { - Log(Logs::General, Logs::Error, "Recieved application packet from server that had opcode ServerLSAccountUpdate_Struct, " + if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) { + Log(Logs::General, + Logs::Error, + "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " "but was too small. Discarded to avoid buffer overrun."); return; } Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); - ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct*)p.Data(); - if (is_server_trusted) - { + ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data(); + if (is_server_trusted) { Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); std::string name; std::string password; @@ -325,160 +389,155 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } } -void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) +void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) { - if (is_server_logged_in) - { - Log(Logs::General, Logs::Error, "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); + if (is_server_logged_in) { + Log(Logs::General, + Logs::Error, + "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); return; } - if (strlen(i->account) <= 30) - { + if (strlen(i->account) <= 30) { account_name = i->account; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long."); return; } - if (strlen(i->password) <= 30) - { + if (strlen(i->password) <= 30) { account_password = i->password; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long."); return; } - if (strlen(i->name) <= 200) - { + if (strlen(i->name) <= 200) { long_name = i->name; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long."); return; } - if (strlen(i->shortname) <= 50) - { + if (strlen(i->shortname) <= 50) { short_name = i->shortname; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long."); return; } - if (strlen(i->local_address) <= 125) - { - if (strlen(i->local_address) == 0) - { + if (strlen(i->local_address) <= 125) { + if (strlen(i->local_address) == 0) { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost"); local_ip = "127.0.0.1"; } - else - { + else { local_ip = i->local_address; } } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long."); return; } - if (strlen(i->remote_address) <= 125) - { - if (strlen(i->remote_address) == 0) - { + if (strlen(i->remote_address) <= 125) { + if (strlen(i->remote_address) == 0) { remote_ip = GetConnection()->Handle()->RemoteIP(); - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", remote_ip.c_str()); + Log(Logs::General, + Logs::Error, + "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", + remote_ip.c_str()); } - else - { + else { remote_ip = i->remote_address; } } - else - { + else { remote_ip = GetConnection()->Handle()->RemoteIP(); - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", remote_ip.c_str()); + Log(Logs::General, + Logs::Error, + "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", + remote_ip.c_str()); } - if (strlen(i->serverversion) <= 64) - { + if (strlen(i->serverversion) <= 64) { version = i->serverversion; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long."); return; } - if (strlen(i->protocolversion) <= 25) - { + if (strlen(i->protocolversion) <= 25) { protocol = i->protocolversion; } - else - { + else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long."); return; } - server_type = i->servertype; + server_type = i->servertype; is_server_logged_in = true; - if (server.options.IsRejectingDuplicateServers()) - { - if (server.server_manager->ServerExists(long_name, short_name, this)) - { - Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name."); + if (server.options.IsRejectingDuplicateServers()) { + if (server.server_manager->ServerExists(long_name, short_name, this)) { + Log(Logs::General, + Logs::Error, + "World tried to login but there already exists a server that has that name."); return; } } - else - { - if (server.server_manager->ServerExists(long_name, short_name, this)) - { - Log(Logs::General, Logs::Error, "World tried to login but there already exists a server that has that name."); + else { + if (server.server_manager->ServerExists(long_name, short_name, this)) { + Log(Logs::General, + Logs::Error, + "World tried to login but there already exists a server that has that name."); server.server_manager->DestroyServerByName(long_name, short_name, this); } } - if (!server.options.IsUnregisteredAllowed()) - { - if (account_name.size() > 0 && account_password.size() > 0) - { - unsigned int s_id = 0; + if (!server.options.IsUnregisteredAllowed()) { + if (account_name.size() > 0 && account_password.size() > 0) { + unsigned int s_id = 0; unsigned int s_list_type = 0; - unsigned int s_trusted = 0; - std::string s_desc; - std::string s_list_desc; - std::string s_acct_name; - std::string s_acct_pass; - if (server.db->GetWorldRegistration(long_name, short_name, s_id, s_desc, s_list_type, s_trusted, s_list_desc, s_acct_name, s_acct_pass)) - { - if (s_acct_name.size() == 0 || s_acct_pass.size() == 0) - { - Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged into account that had no user/password requirement.", - long_name.c_str(), short_name.c_str()); + unsigned int s_trusted = 0; + std::string s_desc; + std::string s_list_desc; + std::string s_acct_name; + std::string s_acct_pass; + if (server.db->GetWorldRegistration( + long_name, + short_name, + s_id, + s_desc, + s_list_type, + s_trusted, + s_list_desc, + s_acct_name, + s_acct_pass + )) { + if (s_acct_name.size() == 0 || s_acct_pass.size() == 0) { + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) successfully logged into account that had no user/password requirement.", + long_name.c_str(), + short_name.c_str()); is_server_authorized = true; SetRuntimeID(s_id); server_list_id = s_list_type; - desc = s_desc; + desc = s_desc; } - else if (s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0) - { + else if (s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0) { Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.", long_name.c_str(), short_name.c_str()); is_server_authorized = true; SetRuntimeID(s_id); server_list_id = s_list_type; - desc = s_desc; + desc = s_desc; if (s_trusted) { Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); is_server_trusted = true; @@ -488,31 +547,41 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) } } else { - Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only" - " registered servers are allowed.", long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only" + " registered servers are allowed.", + long_name.c_str(), + short_name.c_str()); return; } } else { - Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.", - long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.", + long_name.c_str(), + short_name.c_str()); return; } } else { - Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but only registered servers are allowed.", - long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) did not attempt to log in but only registered servers are allowed.", + long_name.c_str(), + short_name.c_str()); return; } } else { - unsigned int server_id = 0; - unsigned int server_list_type = 0; + unsigned int server_id = 0; + unsigned int server_list_type = 0; unsigned int is_server_trusted = 0; - std::string server_description; - std::string server_list_description; - std::string server_account_name; - std::string server_account_password; + std::string server_description; + std::string server_list_description; + std::string server_account_name; + std::string server_account_password; if (server.db->GetWorldRegistration( @@ -524,17 +593,18 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) is_server_trusted, server_list_description, server_account_name, - server_account_password)) - { + server_account_password + )) { if (account_name.size() > 0 && account_password.size() > 0) { - if (server_account_name.compare(account_name) == 0 && server_account_password.compare(account_password) == 0) { + if (server_account_name.compare(account_name) == 0 && + server_account_password.compare(account_password) == 0) { Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.", long_name.c_str(), short_name.c_str()); is_server_authorized = true; SetRuntimeID(server_id); server_list_id = server_list_type; - desc = server_description; + desc = server_description; if (is_server_trusted) { Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); @@ -543,31 +613,50 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) connection->Send(ServerOP_LSAccountUpdate, outapp); } } + + /** + * this is the first of two cases where we should deny access even if unregistered is allowed + */ else { - // this is the first of two cases where we should deny access even if unregistered is allowed - Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but account and password did not match the entry in the database.", - long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) attempted to log in but account and password did not match the entry in the database.", + long_name.c_str(), + short_name.c_str()); } } else { + + /** + * this is the second of two cases where we should deny access even if unregistered is allowed + */ if (server_account_name.size() > 0 || server_account_password.size() > 0) { - // this is the second of two cases where we should deny access even if unregistered is allowed - Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but this server requires a password.", - long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) did not attempt to log in but this server requires a password.", + long_name.c_str(), + short_name.c_str()); } else { - Log(Logs::General, Logs::World_Server, "Server %s(%s) did not attempt to log in but unregistered servers are allowed.", - long_name.c_str(), short_name.c_str()); + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) did not attempt to log in but unregistered servers are allowed.", + long_name.c_str(), + short_name.c_str()); + is_server_authorized = true; SetRuntimeID(server_id); server_list_id = 3; } } } - else - { - Log(Logs::General, Logs::World_Server, "Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.", - long_name.c_str(), short_name.c_str()); + else { + Log(Logs::General, + Logs::World_Server, + "Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.", + long_name.c_str(), + short_name.c_str()); + if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) { is_server_authorized = true; SetRuntimeID(server_id); @@ -579,23 +668,39 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct* i) server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, GetConnection()->Handle()->RemoteIP()); } +/** + * @param s + */ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) { players_online = s->num_players; - zones_booted = s->num_zones; - server_status = s->status; + zones_booted = s->num_zones; + server_status = s->status; } -void WorldServer::SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name) +/** + * @param ip + * @param account + * @param key + * @param account_id + * @param loginserver_name + */ +void WorldServer::SendClientAuth( + std::string ip, + std::string account, + std::string key, + unsigned int account_id, + const std::string &loginserver_name +) { EQ::Net::DynamicPacket outapp; - ClientAuth_Struct client_auth; + ClientAuth_Struct client_auth; client_auth.lsaccount_id = account_id; strncpy(client_auth.name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); - client_auth.lsadmin = 0; + client_auth.lsadmin = 0; client_auth.worldadmin = 0; - client_auth.ip = inet_addr(ip.c_str()); + client_auth.ip = inet_addr(ip.c_str()); strncpy(client_auth.lsname, &loginserver_name[0], 64); std::string client_address(ip); @@ -614,8 +719,7 @@ void WorldServer::SendClientAuth(std::string ip, std::string account, std::strin outapp.PutSerialize(0, client_auth); connection->Send(ServerOP_LSClientAuth, outapp); - if (server.options.IsDumpInPacketsOn()) - { + if (server.options.IsDumpInPacketsOn()) { DumpPacket(ServerOP_LSClientAuth, outapp); } } diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 9e295a5fd..60eb7baae 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -1,20 +1,23 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2010 EQEMu Development Team (http://eqemulator.net) +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ #ifndef EQEMU_WORLDSERVER_H #define EQEMU_WORLDSERVER_H @@ -31,106 +34,79 @@ class WorldServer { public: - /** - * Constructor, sets our connection to c. - */ WorldServer(std::shared_ptr c); /** - * Destructor, frees our connection if it exists. - */ + * Destructor, frees our connection if it exists + */ ~WorldServer(); /** - * Resets the basic stats of this server. - */ + * Resets the basic stats of this server. + */ void Reset(); /** * Accesses connection, it is intentional that this is not const (trust me). */ std::shared_ptr GetConnection() { return connection; } - - /** - * Sets the connection to c. - */ void SetConnection(std::shared_ptr c) { connection = c; } - - /** - * Gets the runtime id of this server. - */ unsigned int GetRuntimeID() const { return runtime_id; } - - /** - * Sets the runtime id of this server. - */ void SetRuntimeID(unsigned int id) { runtime_id = id; } - - /** - * Gets the long name of the server. - */ std::string GetLongName() const { return long_name; } - - /** - * Gets the short name of the server. - */ std::string GetShortName() const { return short_name; } /** - * Gets whether the server is authorized to show up on the server list or not. - */ + * Gets whether the server is authorized to show up on the server list or not + * @return + */ bool IsAuthorized() const { return is_server_authorized; } - - /** - * Gets the local ip of the server. - */ std::string GetLocalIP() const { return local_ip; } - - /** - * Gets the remote ip of the server. - */ std::string GetRemoteIP() const { return remote_ip; } /** - * Gets what kind of server this server is (legends, preferred, normal) - */ + * Gets what kind of server this server is (legends, preferred, normal) + * + * @return + */ unsigned int GetServerListID() const { return server_list_id; } - - /** - * Gets the status of the server. - */ int GetStatus() const { return server_status; } - - /** - * Gets the number of zones online on the server. - */ unsigned int GetZonesBooted() const { return zones_booted; } - - /** - * Gets the number of players on the server. - */ unsigned int GetPlayersOnline() const { return players_online; } /** - * Takes the info struct we received from world and processes it. - */ + * Takes the info struct we received from world and processes it + * + * @param i + */ void Handle_NewLSInfo(ServerNewLSInfo_Struct* i); /** - * Takes the status struct we received from world and processes it. - */ + * Takes the status struct we received from world and processes it + * + * @param s + */ void Handle_LSStatus(ServerLSStatus_Struct *s); /** - * Informs world that there is a client incoming with the following data. - */ + * Informs world that there is a client incoming with the following data. + * + * @param ip + * @param account + * @param key + * @param account_id + * @param loginserver_name + */ void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name); private: /** - * Packet processing functions: - */ + * Packet processing functions + * + * @param opcode + * @param p + */ void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p); From fbebec03aed508e696269c6079ca26e074b5499d Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 02:57:03 -0500 Subject: [PATCH 020/491] Update database_mysql.cpp --- loginserver/database_mysql.cpp | 94 +++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 7c3eda074..15827a38b 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -31,6 +31,15 @@ extern LoginServer server; +/** + * Initial connect + * + * @param user + * @param pass + * @param host + * @param port + * @param name + */ DatabaseMySQL::DatabaseMySQL( std::string user, std::string pass, @@ -68,6 +77,9 @@ DatabaseMySQL::DatabaseMySQL( } } +/** + * Deconstructor + */ DatabaseMySQL::~DatabaseMySQL() { if (database) { @@ -75,6 +87,13 @@ DatabaseMySQL::~DatabaseMySQL() } } +/** + * @param name + * @param loginserver + * @param password + * @param id + * @return + */ bool DatabaseMySQL::GetLoginDataFromAccountInfo( const std::string &name, const std::string &loginserver, @@ -116,6 +135,14 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( return false; } +/** + * @param token + * @param ip + * @param db_account_id + * @param db_loginserver + * @param user + * @return + */ bool DatabaseMySQL::GetLoginTokenDataFromToken( const std::string &token, const std::string &ip, @@ -174,6 +201,10 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken( return found_username && found_login_id && found_login_server_name; } +/** + * @param loginserver + * @return + */ unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) { if (!database) { @@ -211,6 +242,13 @@ unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) return 1; } +/** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ bool DatabaseMySQL::CreateLoginData( const std::string &name, const std::string &password, @@ -221,6 +259,13 @@ bool DatabaseMySQL::CreateLoginData( return CreateLoginDataWithID(name, password, loginserver, GetFreeID(loginserver)); } +/** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ bool DatabaseMySQL::CreateLoginDataWithID( const std::string &name, const std::string &password, @@ -253,6 +298,11 @@ bool DatabaseMySQL::CreateLoginDataWithID( return true; } +/** + * @param name + * @param loginserver + * @param hash + */ void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { if (!database) { @@ -271,9 +321,28 @@ void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string & } } +/** + * @param long_name + * @param short_name + * @param id + * @param desc + * @param list_id + * @param trusted + * @param list_desc + * @param account + * @param password + * @return + */ bool DatabaseMySQL::GetWorldRegistration( - std::string long_name, std::string short_name, unsigned int &id, std::string &desc, unsigned int &list_id, - unsigned int &trusted, std::string &list_desc, std::string &account, std::string &password + std::string long_name, + std::string short_name, + unsigned int &id, + std::string &desc, + unsigned int &list_id, + unsigned int &trusted, + std::string &list_desc, + std::string &account, + std::string &password ) { if (!database) { @@ -348,6 +417,10 @@ bool DatabaseMySQL::GetWorldRegistration( return false; } +/** + * @param id + * @param ip_address + */ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) { if (!database) { @@ -365,6 +438,12 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) } } +/** + * @param id + * @param name + * @param password + * @param email + */ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) { if (!database) { @@ -382,6 +461,11 @@ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std:: } } +/** + * @param id + * @param long_name + * @param ip_address + */ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { if (!database) { @@ -410,6 +494,12 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_na } } +/** + * @param long_name + * @param short_name + * @param id + * @return + */ bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { if (!database) { From b04d71ff45cf04973761a2bce9496c6aa7f5bb48 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 03:09:03 -0500 Subject: [PATCH 021/491] Update json_config.cpp --- common/json_config.cpp | 66 +++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/common/json_config.cpp b/common/json_config.cpp index c9599b99d..9f4688a71 100644 --- a/common/json_config.cpp +++ b/common/json_config.cpp @@ -1,20 +1,20 @@ #include "json_config.h" #include +#include -EQ::JsonConfigFile::JsonConfigFile() -{ - -} +EQ::JsonConfigFile::JsonConfigFile() = default; EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value) { m_root = value; } -EQ::JsonConfigFile::~JsonConfigFile() -{ -} +EQ::JsonConfigFile::~JsonConfigFile() = default; +/** + * @param filename + * @return + */ EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename) { JsonConfigFile ret; @@ -37,7 +37,18 @@ EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename) return ret; } -std::string EQ::JsonConfigFile::GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value) { +/** + * @param title + * @param parameter + * @param default_value + * @return + */ +std::string EQ::JsonConfigFile::GetVariableString( + const std::string &title, + const std::string ¶meter, + const std::string &default_value +) +{ try { if (m_root.isMember(title) && m_root[title].isMember(parameter)) { return m_root[title][parameter].asString(); @@ -50,7 +61,18 @@ std::string EQ::JsonConfigFile::GetVariableString(const std::string &title, cons return default_value; } -int EQ::JsonConfigFile::GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value) { +/** + * @param title + * @param parameter + * @param default_value + * @return + */ +int EQ::JsonConfigFile::GetVariableInt( + const std::string &title, + const std::string ¶meter, + const int default_value +) +{ try { if (m_root.isMember(title) && m_root[title].isMember(parameter)) { return m_root[title][parameter].asInt(); @@ -63,7 +85,18 @@ int EQ::JsonConfigFile::GetVariableInt(const std::string &title, const std::stri return default_value; } -bool EQ::JsonConfigFile::GetVariableBool(const std::string &title, const std::string ¶meter, const bool default_value) { +/** + * @param title + * @param parameter + * @param default_value + * @return + */ +bool EQ::JsonConfigFile::GetVariableBool( + const std::string &title, + const std::string ¶meter, + const bool default_value +) +{ try { if (m_root.isMember(title) && m_root[title].isMember(parameter)) { return m_root[title][parameter].asBool(); @@ -76,7 +109,18 @@ bool EQ::JsonConfigFile::GetVariableBool(const std::string &title, const std::st return default_value; } -double EQ::JsonConfigFile::GetVariableDouble(const std::string &title, const std::string ¶meter, const double default_value) { +/** + * @param title + * @param parameter + * @param default_value + * @return + */ +double EQ::JsonConfigFile::GetVariableDouble( + const std::string &title, + const std::string ¶meter, + const double default_value +) +{ try { if (m_root.isMember(title) && m_root[title].isMember(parameter)) { return m_root[title][parameter].asDouble(); From daec42c4d9eef650b13eb5927ab1d40c8b778fee Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 04:03:54 -0500 Subject: [PATCH 022/491] Migrate quite a few database calls to dbcore and fmt --- loginserver/database_mysql.cpp | 135 ++++++++++++++++----------------- loginserver/database_mysql.h | 3 +- loginserver/login_server.h | 1 + loginserver/main.cpp | 9 ++- loginserver/world_server.cpp | 18 +++-- 5 files changed, 85 insertions(+), 81 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 15827a38b..445f048ec 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -71,6 +71,26 @@ DatabaseMySQL::DatabaseMySQL( Log(Logs::General, Logs::Error, "Failed to connect to MySQL database. Error: %s", mysql_error(database)); exit(1); } + + uint32 errnum = 0; + char errbuf[MYSQL_ERRMSG_SIZE]; + if (!Open( + host.c_str(), + user.c_str(), + pass.c_str(), + name.c_str(), + atoi(port.c_str()), + &errnum, + errbuf + ) + ) { + Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); + exit(1); + } + else { + Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host, port); + } + } else { Log(Logs::General, Logs::Error, "Failed to create db object in MySQL database."); @@ -273,25 +293,22 @@ bool DatabaseMySQL::CreateLoginDataWithID( unsigned int id ) { - if (!database) { - return false; - } - if (id == 0) { return false; } - MYSQL_RES *result; - MYSQL_ROW row; - std::stringstream query(std::stringstream::in | std::stringstream::out); + auto query = fmt::format( + "INSERT INTO {0} (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) " + "VALUES ({1}, '{2}', '{3}', '{4}', 'local_creation', NOW(), '127.0.0.1')", + server.options.GetAccountTable(), + id, + EscapeString(loginserver), + EscapeString(name), + EscapeString(password) + ); - query << "INSERT INTO " << server.options.GetAccountTable() - << " (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) "; - query << " VALUES(" << id << ", '" << EscapeString(loginserver) << "', '" << EscapeString(name) << "', '" - << EscapeString(password) << "', 'local_creation', NOW(), '127.0.0.1'); "; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); + auto results = QueryDatabase(query); + if (!results.Success()) { return false; } @@ -305,20 +322,15 @@ bool DatabaseMySQL::CreateLoginDataWithID( */ void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) { - if (!database) { - return; - } - auto query = fmt::format( "UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", server.options.GetAccountTable(), hash, EscapeString(name), - EscapeString(loginserver)); + EscapeString(loginserver) + ); - if (mysql_query(database, query.c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.c_str()); - } + QueryDatabase(query); } /** @@ -423,19 +435,14 @@ bool DatabaseMySQL::GetWorldRegistration( */ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) { - if (!database) { - return; - } + auto query = fmt::format( + "UPDATE {0} SET LastIPAddress = '{2}', LastLoginDate = now() where LoginServerId = {3}", + server.options.GetAccountTable(), + ip_address, + id + ); - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "UPDATE " << server.options.GetAccountTable() << " SET LastIPAddress = '"; - query << ip_address; - query << "', LastLoginDate = now() where LoginServerID = "; - query << id; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - } + QueryDatabase(query); } /** @@ -444,21 +451,24 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) * @param password * @param email */ -void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) +void DatabaseMySQL::UpdateLSAccountInfo( + unsigned int id, + std::string name, + std::string password, + std::string email +) { - if (!database) { - return; - } + auto query = fmt::format( + "REPLACE {0} SET LoginServerID = {1}, AccountName = '{2}', AccountPassword = sha('{3}'), AccountCreateDate = now(), " + "AccountEmail = '{4}', LastIPAddress = '0.0.0.0', LastLoginDate = now()", + server.options.GetAccountTable(), + id, + EscapeString(name), + EscapeString(password), + EscapeString(email) + ); - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "REPLACE " << server.options.GetAccountTable() << " SET LoginServerID = "; - query << id << ", AccountName = '" << name << "', AccountPassword = sha('"; - query << password << "'), AccountCreateDate = now(), AccountEmail = '" << email; - query << "', LastIPAddress = '0.0.0.0', LastLoginDate = now()"; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - } + QueryDatabase(query); } /** @@ -468,30 +478,15 @@ void DatabaseMySQL::UpdateLSAccountInfo(unsigned int id, std::string name, std:: */ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { - if (!database) { - return; - } + auto query = fmt::format( + "UPDATE {0} SET ServerLastLoginDate = NOW(), ServerLastIPAddr = '{1}', ServerLongName = '{2}' WHERE ServerID = {3}", + server.options.GetWorldRegistrationTable(), + ip_address, + EscapeString(long_name), + id + ); - char escaped_long_name[101]; - unsigned long length; - length = mysql_real_escape_string( - database, - escaped_long_name, - long_name.substr(0, 100).c_str(), - long_name.substr(0, 100).length()); - escaped_long_name[length + 1] = 0; - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "UPDATE " << server.options.GetWorldRegistrationTable() - << " SET ServerLastLoginDate = now(), ServerLastIPAddr = '"; - query << ip_address; - query << "', ServerLongName = '"; - query << escaped_long_name; - query << "' WHERE ServerID = "; - query << id; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - } + QueryDatabase(query); } /** diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 1a59d40cf..b45ee9c2f 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -22,6 +22,7 @@ #define EQEMU_DATABASEMYSQL_H #include "database.h" +#include "../common/dbcore.h" #ifdef EQEMU_MYSQL_ENABLED @@ -30,7 +31,7 @@ #include #include -class DatabaseMySQL : public Database { +class DatabaseMySQL : public DBcore { public: DatabaseMySQL() { database = nullptr; } diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 4efb05265..ba03bfd52 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -18,6 +18,7 @@ * */ + #ifndef EQEMU_LOGINSERVER_H #define EQEMU_LOGINSERVER_H diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 4f28cf1e1..391ec48d4 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -47,8 +47,12 @@ int main() LogSys.LoadLogSettingsDefaults(); - LogSys.log_settings[Logs::Error].log_to_console = Logs::General; - LogSys.log_settings[Logs::Error].is_category_enabled = 1; + LogSys.log_settings[Logs::Error].log_to_console = Logs::General; + LogSys.log_settings[Logs::Error].is_category_enabled = Logs::General; + LogSys.log_settings[Logs::MySQLError].is_category_enabled = Logs::General; + LogSys.log_settings[Logs::MySQLError].log_to_console = Logs::General; + LogSys.log_settings[Logs::Netcode].is_category_enabled = Logs::General; + LogSys.log_settings[Logs::Netcode].log_to_console = Logs::General; Log(Logs::General, Logs::Login_Server, "Logging System Init."); @@ -133,7 +137,6 @@ int main() server.config.GetVariableString("database", "db", "peq") ); - /** * make sure our database got created okay, otherwise cleanup and exit */ diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 5942063f4..7509297eb 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -379,12 +379,16 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data(); if (is_server_trusted) { Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); - std::string name; - std::string password; - std::string email; + std::string name = ""; + std::string password = ""; + std::string email = ""; name.assign(lsau->useraccount); password.assign(lsau->userpassword); - email.assign(lsau->useremail); + + if (lsau->useremail) { + email.assign(lsau->useremail); + } + server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); } } @@ -614,9 +618,9 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) } } - /** - * this is the first of two cases where we should deny access even if unregistered is allowed - */ + /** + * this is the first of two cases where we should deny access even if unregistered is allowed + */ else { Log(Logs::General, Logs::World_Server, From c7e196e26d15e12cc4a593617fa6fd5cddfc5201 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 04:27:51 -0500 Subject: [PATCH 023/491] Update client.cpp --- loginserver/client.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 0b1243a30..d526d85d4 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -245,28 +245,38 @@ void Client::Handle_Login(const char *data, unsigned int size) } else { if (server.options.IsPasswordLoginAllowed()) { - cred = (&outbuffer[1 + user.length()]); + cred = (&outbuffer[1 + user.length()]); auto components = SplitString(user, '.'); if (components.size() == 2) { db_loginserver = components[0]; user = components[1]; } + LogF( + Logs::General, + Logs::Login_Server, + "Attempting password based login [{0}] login [{1}] user [{2}]", + user, + db_loginserver, + user + ); + ParseAccountString(user, user, db_loginserver); - if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id) == - false) { + if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id)) { + result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); + } + else { status = cs_creating_account; AttemptLoginAccountCreation(user, cred, db_loginserver); return; } - else { - result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); - } } } - /* Login Accepted */ + /** + * Login accepted + */ if (result) { DoSuccessfulLogin(user, db_account_id, db_loginserver); } @@ -355,7 +365,11 @@ void Client::AttemptLoginAccountCreation( ) { if (loginserver == "eqemu") { + + LogF(Logs::General, Logs::Login_Server, "Attempting login account creation via '{0}'", loginserver); + if (!server.options.CanAutoLinkAccounts()) { + LogF(Logs::General, Logs::Login_Server, "CanAutoLinkAccounts disabled - sending failed login"); DoFailedLogin(); return; } @@ -411,6 +425,7 @@ void Client::AttemptLoginAccountCreation( ); } else { + if (!server.options.CanAutoCreateAccounts()) { DoFailedLogin(); return; From bb7cae46c56ce5a0209b5c4666c4ba2405f3e84f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 14:53:24 -0500 Subject: [PATCH 024/491] Update console.cpp --- world/console.cpp | 273 ++++++---------------------------------------- 1 file changed, 35 insertions(+), 238 deletions(-) diff --git a/world/console.cpp b/world/console.cpp index e5643e5b1..12b287653 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -236,6 +236,7 @@ void ConsoleMd5( uint8 md5[16]; MD5::Generate((const uchar *) args[0].c_str(), strlen(args[0].c_str()), md5); + connection->SendLine( StringFormat( "MD5: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", @@ -255,7 +256,8 @@ void ConsoleMd5( md5[13], md5[14], md5[15] - )); + ) + ); } /** @@ -872,242 +874,37 @@ void ConsoleQuit( /** * @param console */ -void RegisterConsoleFunctions(std::unique_ptr &console) +void RegisterConsoleFunctions(std::unique_ptr& console) { console->RegisterLogin(std::bind(CheckLogin, std::placeholders::_1, std::placeholders::_2)); - console->RegisterCall( - "acceptmessages", - 50, - "acceptmessages [on/off]", - std::bind( - ConsoleAcceptMessages, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "api", - 200, - "api", - std::bind(ConsoleApi, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "auction", - 50, - "auction [message]", - std::bind( - ConsoleAuction, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "broadcast", - 50, - "broadcast [message]", - std::bind( - ConsoleBroadcast, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "echo", - 50, - "echo [on/off]", - std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "emote", - 50, - "emote [zonename or charname or world] [type] [message]", - std::bind(ConsoleEmote, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "flag", - 200, - "flag [status] [accountname]", - std::bind(ConsoleFlag, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "gmsay", - 50, - "gmsay [message]", - std::bind(ConsoleGMSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "iplookup", - 50, - "IPLookup [name]", - std::bind( - ConsoleIpLookup, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "kick", - 150, - "kick [charname]", - std::bind(ConsoleKick, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "lock", - 150, - "lock", - std::bind(ConsoleLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "lsreconnect", - 50, - "LSReconnect", - std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "md5", - 50, - "md5", - std::bind(ConsoleMd5, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "ooc", - 50, - "ooc [message]", - std::bind(ConsoleOOC, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "reloadworld", - 200, - "reloadworld", - std::bind( - ConsoleReloadWorld, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "setpass", - 200, - "setpass [accountname] [newpass]", - std::bind( - ConsoleSetPass, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "signalcharbyname", - 50, - "signalcharbyname charname ID", - std::bind( - ConsoleSignalCharByName, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "tell", - 50, - "tell [name] [message]", - std::bind(ConsoleTell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "unlock", - 150, - "unlock", - std::bind( - ConsoleUnlock, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "uptime", - 50, - "uptime [zoneID#]", - std::bind( - ConsoleUptime, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "version", - 50, - "version", - std::bind( - ConsoleVersion, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "who", - 50, - "who", - std::bind(ConsoleWho, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "whoami", - 50, - "whoami", - std::bind( - ConsoleWhoami, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "worldshutdown", - 200, - "worldshutdown", - std::bind( - ConsoleWorldShutdown, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "zonebootup", - 150, - "zonebootup [ZoneServerID] [zonename]", - std::bind( - ConsoleZoneBootup, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "zonelock", - 150, - "zonelock [list|lock|unlock] [zonename]", - std::bind( - ConsoleZoneLock, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "zoneshutdown", - 150, - "zoneshutdown [zonename or ZoneServerID]", - std::bind( - ConsoleZoneShutdown, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "zonestatus", - 50, - "zonestatus", - std::bind( - ConsoleZoneStatus, - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 - )); - console->RegisterCall( - "ping", - 50, - "ping", - std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "quit", - 50, - "quit", - std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - console->RegisterCall( - "exit", - 50, - "exit", - std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); -} + console->RegisterCall("acceptmessages", 50, "acceptmessages [on/off]", std::bind(ConsoleAcceptMessages, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("api", 200, "api", std::bind(ConsoleApi, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("auction", 50, "auction [message]", std::bind(ConsoleAuction, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("broadcast", 50, "broadcast [message]", std::bind(ConsoleBroadcast, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("echo", 50, "echo [on/off]", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("emote", 50, "emote [zonename or charname or world] [type] [message]", std::bind(ConsoleEmote, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("flag", 200, "flag [status] [accountname]", std::bind(ConsoleFlag, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("gmsay", 50, "gmsay [message]", std::bind(ConsoleGMSay, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("iplookup", 50, "IPLookup [name]", std::bind(ConsoleIpLookup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("kick", 150, "kick [charname]", std::bind(ConsoleKick, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("lock", 150, "lock", std::bind(ConsoleLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("lsreconnect", 50, "LSReconnect", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("md5", 50, "md5", std::bind(ConsoleMd5, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("ooc", 50, "ooc [message]", std::bind(ConsoleOOC, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("reloadworld", 200, "reloadworld", std::bind(ConsoleReloadWorld, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("setpass", 200, "setpass [accountname] [newpass]", std::bind(ConsoleSetPass, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("signalcharbyname", 50, "signalcharbyname charname ID", std::bind(ConsoleSignalCharByName, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("tell", 50, "tell [name] [message]", std::bind(ConsoleTell, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("unlock", 150, "unlock", std::bind(ConsoleUnlock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("uptime", 50, "uptime [zoneID#]", std::bind(ConsoleUptime, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("version", 50, "version", std::bind(ConsoleVersion, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("who", 50, "who", std::bind(ConsoleWho, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("whoami", 50, "whoami", std::bind(ConsoleWhoami, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("worldshutdown", 200, "worldshutdown", std::bind(ConsoleWorldShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("zonebootup", 150, "zonebootup [ZoneServerID] [zonename]", std::bind(ConsoleZoneBootup, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("zonelock", 150, "zonelock [list|lock|unlock] [zonename]", std::bind(ConsoleZoneLock, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("zoneshutdown", 150, "zoneshutdown [zonename or ZoneServerID]", std::bind(ConsoleZoneShutdown, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("zonestatus", 50, "zonestatus", std::bind(ConsoleZoneStatus, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));console->RegisterCall("ping", 50, "ping", std::bind(ConsoleNull, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("quit", 50, "quit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + console->RegisterCall("exit", 50, "exit", std::bind(ConsoleQuit, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); +} \ No newline at end of file From cdfd473476b065402c09ee84bc06c834d199215f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 16:01:44 -0500 Subject: [PATCH 025/491] Add more logging --- loginserver/client.cpp | 79 ++++++++++++++++++++++++++++------ loginserver/database_mysql.cpp | 52 ++++++++++++---------- loginserver/main.cpp | 19 ++++++-- 3 files changed, 112 insertions(+), 38 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index d526d85d4..5953471ec 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -180,24 +180,38 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) */ void Client::Handle_Login(const char *data, unsigned int size) { + std::string logging_function_prefix = "[Client::Handle_Login]"; + if (status != cs_waiting_for_login) { - Log(Logs::General, Logs::Error, "Login received after already having logged in."); + LogF( + Logs::General, + Logs::Error, + "{0} Login received after already having logged in", + logging_function_prefix + ); return; } if ((size - 12) % 8 != 0) { - Log(Logs::General, + LogF( + Logs::General, Logs::Error, - "Login received packet of size: %u, this would cause a block corruption, discarding.", - size); + "{0} Login received packet of size: {1}, this would cause a block corruption, discarding.", + logging_function_prefix, + size + ); return; } if (size < sizeof(LoginLoginRequest_Struct)) { - Log(Logs::General, + LogF( + Logs::General, Logs::Error, - "Login received packet of size: %u, this would cause a buffer overflow, discarding.", - size); + "{0} Login received packet of size: %u, this would cause a buffer overflow, discarding.", + logging_function_prefix, + size + ); + return; } @@ -224,7 +238,12 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string user(&outbuffer[0]); if (user.length() >= outbuffer.length()) { - LogF(Logs::General, Logs::Debug, "Corrupt buffer sent to server, preventing buffer overflow."); + LogF( + Logs::General, + Logs::Debug, + "{0} Corrupt buffer sent to server, preventing buffer overflow.", + logging_function_prefix + ); return; } @@ -245,7 +264,7 @@ void Client::Handle_Login(const char *data, unsigned int size) } else { if (server.options.IsPasswordLoginAllowed()) { - cred = (&outbuffer[1 + user.length()]); + cred = (&outbuffer[1 + user.length()]); auto components = SplitString(user, '.'); if (components.size() == 2) { db_loginserver = components[0]; @@ -255,7 +274,8 @@ void Client::Handle_Login(const char *data, unsigned int size) LogF( Logs::General, Logs::Login_Server, - "Attempting password based login [{0}] login [{1}] user [{2}]", + "{0} Attempting password based login [{1}] login [{2}] user [{3}]", + logging_function_prefix, user, db_loginserver, user @@ -265,10 +285,19 @@ void Client::Handle_Login(const char *data, unsigned int size) if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id)) { result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); + + LogF( + Logs::Detail, + Logs::Login_Server, + "{0} [VerifyLoginHash] Success [{1}]", + logging_function_prefix, + (result ? "true" : "false") + ); } else { status = cs_creating_account; AttemptLoginAccountCreation(user, cred, db_loginserver); + return; } } @@ -278,9 +307,25 @@ void Client::Handle_Login(const char *data, unsigned int size) * Login accepted */ if (result) { + LogF( + Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login succeeded", + logging_function_prefix, + user, + db_loginserver, + user + ); + DoSuccessfulLogin(user, db_account_id, db_loginserver); } else { + LogF( + Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login failed", + logging_function_prefix, + user, + db_loginserver, + user + ); + DoFailedLogin(); } } @@ -358,6 +403,11 @@ void Client::GenerateKey() } } +/** + * @param user + * @param pass + * @param loginserver + */ void Client::AttemptLoginAccountCreation( const std::string &user, const std::string &pass, @@ -403,7 +453,8 @@ void Client::AttemptLoginAccountCreation( &Client::LoginOnNewConnection, this, std::placeholders::_1 - )); + ) + ); login_connection_manager->OnConnectionStateChange( std::bind( &Client::LoginOnStatusChange, @@ -411,14 +462,16 @@ void Client::AttemptLoginAccountCreation( std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 - )); + ) + ); login_connection_manager->OnPacketRecv( std::bind( &Client::LoginOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2 - )); + ) + ); login_connection_manager->Connect(addr, port); } diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 445f048ec..d42f46d9c 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -121,37 +121,45 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( unsigned int &id ) { - if (!database) { + auto query = fmt::format( + "SELECT LoginServerID, AccountPassword FROM {0} WHERE AccountName = '{1}' AND AccountLoginserver = '{2}' LIMIT 1", + server.options.GetAccountTable(), + EscapeString(name), + EscapeString(loginserver) + ); + + auto results = QueryDatabase(query); + + if (results.RowCount() != 1) { + LogF( + Logs::Detail, + Logs::Login_Server, + "Database::GetLoginDataFromAccountInfo could not find account for name [{0}] login [{1}]", + name, + loginserver + ); + return false; } - MYSQL_RES *res; - MYSQL_ROW row; - std::stringstream query(std::stringstream::in | std::stringstream::out); query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() - << " WHERE AccountName = '"; - query << EscapeString(name); - query << "' AND AccountLoginserver='"; - query << EscapeString(loginserver); - query << "'"; - - if (mysql_query(database, query.str().c_str()) != 0) { - LogF(Logs::General, Logs::Error, "Mysql query failed: {0}", query.str()); + if (!results.Success()) { return false; } - res = mysql_use_result(database); + auto row = results.begin(); - if (res) { - while ((row = mysql_fetch_row(res)) != nullptr) { - id = atoi(row[0]); - password = row[1]; - mysql_free_result(res); - return true; - } - } + id = atoi(row[0]); + password = row[1]; + + LogF( + Logs::Detail, + Logs::Login_Server, + "Database::GetLoginDataFromAccountInfo found account for name [{0}] login [{1}]", + name, + loginserver + ); - Log(Logs::General, Logs::Error, "Mysql query returned no result: %s", query.str().c_str()); return false; } diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 391ec48d4..04d61d702 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -48,11 +48,15 @@ int main() LogSys.LoadLogSettingsDefaults(); LogSys.log_settings[Logs::Error].log_to_console = Logs::General; - LogSys.log_settings[Logs::Error].is_category_enabled = Logs::General; - LogSys.log_settings[Logs::MySQLError].is_category_enabled = Logs::General; + LogSys.log_settings[Logs::Error].is_category_enabled = 1; LogSys.log_settings[Logs::MySQLError].log_to_console = Logs::General; - LogSys.log_settings[Logs::Netcode].is_category_enabled = Logs::General; + LogSys.log_settings[Logs::MySQLError].is_category_enabled = 1; + LogSys.log_settings[Logs::MySQLQuery].log_to_console = Logs::General; + LogSys.log_settings[Logs::MySQLQuery].is_category_enabled = 1; LogSys.log_settings[Logs::Netcode].log_to_console = Logs::General; + LogSys.log_settings[Logs::Netcode].is_category_enabled = Logs::General; + + LogSys.log_settings[Logs::Login_Server].log_to_console = Logs::Detail; Log(Logs::General, Logs::Login_Server, "Logging System Init."); @@ -182,6 +186,15 @@ int main() #endif Log(Logs::General, Logs::Login_Server, "Server Started."); + + if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) { + Log( + Logs::General, + Logs::Login_Server, + "Loginserver logging set to level [1] for more debugging, enable detail [3]" + ); + } + while (run_server) { Timer::SetCurrentTime(); server.client_manager->Process(); From 11bc21f99f5b7ff7024762ca5e7e4f64f3f84b41 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 16:26:32 -0500 Subject: [PATCH 026/491] Update more logging --- loginserver/client.cpp | 47 ++++++++++++++++++++++++++-------- loginserver/database_mysql.cpp | 7 ++--- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 5953471ec..4b6c00be3 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -180,14 +180,12 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) */ void Client::Handle_Login(const char *data, unsigned int size) { - std::string logging_function_prefix = "[Client::Handle_Login]"; - if (status != cs_waiting_for_login) { LogF( Logs::General, Logs::Error, "{0} Login received after already having logged in", - logging_function_prefix + __func__ ); return; } @@ -197,7 +195,7 @@ void Client::Handle_Login(const char *data, unsigned int size) Logs::General, Logs::Error, "{0} Login received packet of size: {1}, this would cause a block corruption, discarding.", - logging_function_prefix, + __func__, size ); return; @@ -208,7 +206,7 @@ void Client::Handle_Login(const char *data, unsigned int size) Logs::General, Logs::Error, "{0} Login received packet of size: %u, this would cause a buffer overflow, discarding.", - logging_function_prefix, + __func__, size ); @@ -242,7 +240,7 @@ void Client::Handle_Login(const char *data, unsigned int size) Logs::General, Logs::Debug, "{0} Corrupt buffer sent to server, preventing buffer overflow.", - logging_function_prefix + __func__ ); return; } @@ -275,7 +273,7 @@ void Client::Handle_Login(const char *data, unsigned int size) Logs::General, Logs::Login_Server, "{0} Attempting password based login [{1}] login [{2}] user [{3}]", - logging_function_prefix, + __func__, user, db_loginserver, user @@ -290,7 +288,7 @@ void Client::Handle_Login(const char *data, unsigned int size) Logs::Detail, Logs::Login_Server, "{0} [VerifyLoginHash] Success [{1}]", - logging_function_prefix, + __func__, (result ? "true" : "false") ); } @@ -309,7 +307,7 @@ void Client::Handle_Login(const char *data, unsigned int size) if (result) { LogF( Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login succeeded", - logging_function_prefix, + __func__, user, db_loginserver, user @@ -320,7 +318,7 @@ void Client::Handle_Login(const char *data, unsigned int size) else { LogF( Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login failed", - logging_function_prefix, + __func__, user, db_loginserver, user @@ -696,10 +694,22 @@ void Client::LoginOnStatusChange( ) { if (to == EQ::Net::StatusConnected) { + LogF( + Logs::Detail, + Logs::Login_Server, + "[{0}] == EQ::Net::StatusConnected", + __func__ + ); LoginSendSessionReady(); } if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) { + LogF( + Logs::Detail, + Logs::Login_Server, + "[{0}] == EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected", + __func__ + ); DoFailedLogin(); } } @@ -724,6 +734,7 @@ void Client::LoginOnStatusChangeIgnored( void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p) { auto opcode = p.GetUInt16(0); + LogF(Logs::Detail, Logs::Login_Server, "[{0}] [{1}]", __func__, opcode); switch (opcode) { case 0x0017: //OP_ChatMessage LoginSendLogin(); @@ -767,6 +778,9 @@ void Client::LoginSendLogin() login_connection->QueuePacket(p); } +/** + * @param p + */ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) { auto encrypt_size = p.Length() - 12; @@ -788,13 +802,24 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) std::placeholders::_1, std::placeholders::_2, std::placeholders::_3 - )); + ) + ); if (response_error > 101) { + LogF(Logs::Detail, Logs::Login_Server, "[{0}] response [{1}] failed login", __func__, response_error); DoFailedLogin(); login_connection->Close(); } else { + LogF( + Logs::Detail, + Logs::Login_Server, + "[{0}] response [{1}] login succeeded user [{2}]", + __func__, + response_error, + stored_user + ); + auto m_dbid = sp.GetUInt32(8); CreateEQEmuAccount(stored_user, stored_pass, m_dbid); diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index d42f46d9c..4f4d59ac2 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -134,7 +134,8 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( LogF( Logs::Detail, Logs::Login_Server, - "Database::GetLoginDataFromAccountInfo could not find account for name [{0}] login [{1}]", + "[{0}] could not find account for name [{1}] login [{2}]", + __func__, name, loginserver ); @@ -142,7 +143,6 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( return false; } - query << "SELECT LoginServerID, AccountPassword FROM " << server.options.GetAccountTable() if (!results.Success()) { return false; } @@ -155,7 +155,8 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( LogF( Logs::Detail, Logs::Login_Server, - "Database::GetLoginDataFromAccountInfo found account for name [{0}] login [{1}]", + "[{0}] found account for name [{1}] login [{2}]", + __func__, name, loginserver ); From 9613d128ae3ccbfe0764171a48cbd591c283858f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 18:49:53 -0500 Subject: [PATCH 027/491] More logging updates --- common/eqemu_logsys.cpp | 56 ++++++++++++++++++----- common/eqemu_logsys.h | 21 ++++++--- common/eqemu_logsys_fmt.h | 17 +++++-- common/ruletypes.h | 4 ++ loginserver/client.cpp | 82 +++++++++++++++++----------------- loginserver/database_mysql.cpp | 22 ++++++--- loginserver/world_server.cpp | 1 - zone/net.cpp | 2 +- 8 files changed, 134 insertions(+), 71 deletions(-) diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index d614415ea..abf700642 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -19,6 +19,7 @@ */ #include "eqemu_logsys.h" +#include "rulesys.h" #include "platform.h" #include "string_util.h" #include "database.h" @@ -96,16 +97,12 @@ EQEmuLogSys::EQEmuLogSys() { on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {}; - bool file_logs_enabled = false; - int log_platform = 0; } /** * EQEmuLogSys Deconstructor */ -EQEmuLogSys::~EQEmuLogSys() -{ -} +EQEmuLogSys::~EQEmuLogSys() = default; void EQEmuLogSys::LoadLogSettingsDefaults() { @@ -113,7 +110,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults() * Get Executable platform currently running this code (Zone/World/etc) */ log_platform = GetExecutablePlatformInt(); - + for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) { log_settings[log_category_id].log_to_console = 0; log_settings[log_category_id].log_to_file = 0; @@ -351,6 +348,25 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, on_log_console_hook(debug_level, log_category, message); } +constexpr const char *str_end(const char *str) +{ + return *str ? str_end(str + 1) : str; +} + +constexpr bool str_slant(const char *str) +{ + return *str == '/' ? true : (*str ? str_slant(str + 1) : false); +} + +constexpr const char *r_slant(const char *str) +{ + return *str == '/' ? (str + 1) : r_slant(str - 1); +} +constexpr const char *file_name(const char *str) +{ + return str_slant(str) ? r_slant(str_end(str)) : str; +} + /** * Core logging function * @@ -359,7 +375,15 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, * @param message * @param ... */ -void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...) +void EQEmuLogSys::Out( + Logs::DebugLevel debug_level, + uint16 log_category, + const char *file, + const char *func, + int line, + const std::string &message, + ... +) { bool log_to_console = true; if (log_settings[log_category].log_to_console < debug_level) { @@ -381,12 +405,18 @@ void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::st return; } + std::string prefix; + + if (RuleB(Logging, PrintFileFunctionAndLine)) { + prefix = fmt::format("[{0}::{1}:{2}] ", file_name(file), func, line); + } + va_list args; va_start(args, message); std::string output_message = vStringFormat(message.c_str(), args); va_end(args); - std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message); + std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message); if (log_to_console) { EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message); @@ -463,12 +493,13 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) return; } - EQEmuLogSys::Out( + Log( Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), - getpid()); + getpid() + ); /** * Make directory if not exists @@ -493,12 +524,13 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) return; } - EQEmuLogSys::Out( + Log( Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), - getpid()); + getpid() + ); /** * Open file pointer diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 05f4a5fee..c9ecc8b0c 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -21,6 +21,7 @@ #ifndef EQEMU_LOGSYS_H #define EQEMU_LOGSYS_H +#include #include #include #include @@ -158,12 +159,12 @@ namespace Logs { #define Log(debug_level, log_category, message, ...) do {\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\ - LogSys.Out(debug_level, log_category, message, ##__VA_ARGS__);\ + LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) #define LogF(debug_level, log_category, message, ...) do {\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\ - OutF(LogSys, debug_level, log_category, message, ##__VA_ARGS__);\ + OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) class EQEmuLogSys { @@ -188,7 +189,15 @@ public: * - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would * be checked against to see if that piped output is set to actually process it for the category and debug level */ - void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...); + void Out( + Logs::DebugLevel debug_level, + uint16 log_category, + const char *file, + const char *func, + int line, + const std::string &message, + ... + ); /** * Used in file logs to prepend a timestamp entry for logs @@ -218,14 +227,14 @@ public: * These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults * Database loaded via Database::LoadLogSettings(log_settings) */ - LogSettings log_settings[Logs::LogCategory::MaxCategoryID]; + LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{}; - bool file_logs_enabled; + bool file_logs_enabled{}; /** * Sets Executable platform (Zone/World/UCS) etc. */ - int log_platform; + int log_platform{}; /** * File name used in writing logs diff --git a/common/eqemu_logsys_fmt.h b/common/eqemu_logsys_fmt.h index 3a6a9f67d..2874d5766 100644 --- a/common/eqemu_logsys_fmt.h +++ b/common/eqemu_logsys_fmt.h @@ -22,9 +22,18 @@ #include -template -void OutF(EQEmuLogSys &ls, Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args) +template +void OutF( + EQEmuLogSys &ls, + Logs::DebugLevel debug_level, + uint16 log_category, + const char *file, + const char *func, + int line, + const char *fmt, + const Args &... args +) { std::string log_str = fmt::format(fmt, args...); - ls.Out(debug_level, log_category, log_str); -} + ls.Out(debug_level, log_category, file, func, line, log_str); +} \ No newline at end of file diff --git a/common/ruletypes.h b/common/ruletypes.h index 3c9e5d677..5800619eb 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -746,6 +746,10 @@ RULE_INT(Faction, DubiouslyFactionMinimum, -500) RULE_INT(Faction, ThreateninglyFactionMinimum, -750) RULE_CATEGORY_END() +RULE_CATEGORY(Logging) +RULE_BOOL(Logging, PrintFileFunctionAndLine, true) // Ex: [World Server] [net.cpp::main:309] Loading variables... +RULE_CATEGORY_END() + #undef RULE_CATEGORY #undef RULE_INT #undef RULE_REAL diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 4b6c00be3..44d1fcbc0 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -181,12 +181,7 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) void Client::Handle_Login(const char *data, unsigned int size) { if (status != cs_waiting_for_login) { - LogF( - Logs::General, - Logs::Error, - "{0} Login received after already having logged in", - __func__ - ); + LogF(Logs::General, Logs::Error, "Login received after already having logged in"); return; } @@ -194,8 +189,7 @@ void Client::Handle_Login(const char *data, unsigned int size) LogF( Logs::General, Logs::Error, - "{0} Login received packet of size: {1}, this would cause a block corruption, discarding.", - __func__, + "Login received packet of size: {0}, this would cause a block corruption, discarding.", size ); return; @@ -205,8 +199,7 @@ void Client::Handle_Login(const char *data, unsigned int size) LogF( Logs::General, Logs::Error, - "{0} Login received packet of size: %u, this would cause a buffer overflow, discarding.", - __func__, + "Login received packet of size: {0}, this would cause a buffer overflow, discarding.", size ); @@ -236,12 +229,7 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string user(&outbuffer[0]); if (user.length() >= outbuffer.length()) { - LogF( - Logs::General, - Logs::Debug, - "{0} Corrupt buffer sent to server, preventing buffer overflow.", - __func__ - ); + LogF(Logs::General, Logs::Debug,"Corrupt buffer sent to server, preventing buffer overflow."); return; } @@ -272,8 +260,7 @@ void Client::Handle_Login(const char *data, unsigned int size) LogF( Logs::General, Logs::Login_Server, - "{0} Attempting password based login [{1}] login [{2}] user [{3}]", - __func__, + "Attempting password based login [{0}] login [{1}] user [{2}]", user, db_loginserver, user @@ -287,8 +274,7 @@ void Client::Handle_Login(const char *data, unsigned int size) LogF( Logs::Detail, Logs::Login_Server, - "{0} [VerifyLoginHash] Success [{1}]", - __func__, + "[VerifyLoginHash] Success [{0}]", (result ? "true" : "false") ); } @@ -306,9 +292,7 @@ void Client::Handle_Login(const char *data, unsigned int size) */ if (result) { LogF( - Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login succeeded", - __func__, - user, + Logs::Detail, Logs::Login_Server, "lgoin [{0}] user [{2}] Login succeeded", db_loginserver, user ); @@ -317,9 +301,7 @@ void Client::Handle_Login(const char *data, unsigned int size) } else { LogF( - Logs::Detail, Logs::Login_Server, "{0} [{1}] login [{2}] user [{3}] Login failed", - __func__, - user, + Logs::Detail, Logs::Login_Server, "lgoin [{0}] user [{2}] Login failed", db_loginserver, user ); @@ -537,6 +519,14 @@ bool Client::VerifyLoginHash( if (hash.length() == 32) { //md5 is insecure for (int i = EncryptionModeMD5; i <= EncryptionModeMD5Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + LogF( + Logs::Detail, + Logs::Login_Server, + "user [{0}] loginserver [{1}] mode [{2}]", + user, + loginserver, + mode + ); server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); return true; } @@ -545,6 +535,15 @@ bool Client::VerifyLoginHash( else if (hash.length() == 40) { //sha1 is insecure for (int i = EncryptionModeSHA; i <= EncryptionModeSHATriple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + LogF( + Logs::Detail, + Logs::Login_Server, + "user [{0}] loginserver [{1}] mode [{2}]", + user, + loginserver, + mode + ); + server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); return true; } @@ -553,6 +552,15 @@ bool Client::VerifyLoginHash( else if (hash.length() == 128) { //sha2-512 is insecure for (int i = EncryptionModeSHA512; i <= EncryptionModeSHA512Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + LogF( + Logs::Detail, + Logs::Login_Server, + "user [{0}] loginserver [{1}] mode [{2}]", + user, + loginserver, + mode + ); + server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); return true; } @@ -694,22 +702,13 @@ void Client::LoginOnStatusChange( ) { if (to == EQ::Net::StatusConnected) { - LogF( - Logs::Detail, - Logs::Login_Server, - "[{0}] == EQ::Net::StatusConnected", - __func__ - ); + LogF(Logs::Detail, Logs::Login_Server, "EQ::Net::StatusConnected"); LoginSendSessionReady(); } if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) { - LogF( - Logs::Detail, - Logs::Login_Server, - "[{0}] == EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected", - __func__ - ); + LogF(Logs::Detail, Logs::Login_Server, "EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected"); + DoFailedLogin(); } } @@ -734,7 +733,7 @@ void Client::LoginOnStatusChangeIgnored( void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p) { auto opcode = p.GetUInt16(0); - LogF(Logs::Detail, Logs::Login_Server, "[{0}] [{1}]", __func__, opcode); + LogF(Logs::Detail, Logs::Login_Server, "[{0}]", opcode); switch (opcode) { case 0x0017: //OP_ChatMessage LoginSendLogin(); @@ -806,7 +805,7 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) ); if (response_error > 101) { - LogF(Logs::Detail, Logs::Login_Server, "[{0}] response [{1}] failed login", __func__, response_error); + LogF(Logs::Detail, Logs::Login_Server, "response [{0}] failed login", response_error); DoFailedLogin(); login_connection->Close(); } @@ -814,8 +813,7 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) LogF( Logs::Detail, Logs::Login_Server, - "[{0}] response [{1}] login succeeded user [{2}]", - __func__, + "response [{0}] login succeeded user [{1}]", response_error, stored_user ); diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 4f4d59ac2..c8696c019 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -134,8 +134,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( LogF( Logs::Detail, Logs::Login_Server, - "[{0}] could not find account for name [{1}] login [{2}]", - __func__, + "Could not find account for name [{0}] login [{1}]", name, loginserver ); @@ -155,8 +154,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( LogF( Logs::Detail, Logs::Login_Server, - "[{0}] found account for name [{1}] login [{2}]", - __func__, + "Found account for name [{0}] login [{1}]", name, loginserver ); @@ -329,8 +327,21 @@ bool DatabaseMySQL::CreateLoginDataWithID( * @param loginserver * @param hash */ -void DatabaseMySQL::UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) +void DatabaseMySQL::UpdateLoginHash( + const std::string &name, + const std::string &loginserver, + const std::string &hash +) { + LogF( + Logs::Detail, + Logs::Login_Server, + "name [{0}] loginserver [{1}] hash [{2}]", + name, + loginserver, + hash + ); + auto query = fmt::format( "UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", server.options.GetAccountTable(), @@ -366,6 +377,7 @@ bool DatabaseMySQL::GetWorldRegistration( std::string &password ) { + if (!database) { return false; } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 7509297eb..cd1bd2abb 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -587,7 +587,6 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) std::string server_account_name; std::string server_account_password; - if (server.db->GetWorldRegistration( long_name, short_name, diff --git a/zone/net.cpp b/zone/net.cpp index 9fe8a7d50..0b692e481 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -226,7 +226,7 @@ int main(int argc, char** argv) { worldserver.SetLauncherName("NONE"); } - Log(Logs::General, Logs::Zone_Server, "Connecting to MySQL..."); + Log(Logs::General, Logs::Zone_Server, "Connecting to MySQL... "); if (!database.Connect( Config->DatabaseHost.c_str(), Config->DatabaseUsername.c_str(), From 8c254861124dbc13bbb0f8bb1e036a16307b4c1f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 18:54:08 -0500 Subject: [PATCH 028/491] Few tweaks --- common/eqemu_logsys.h | 4 ++-- loginserver/client.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index c9ecc8b0c..5ec81d526 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -229,12 +229,12 @@ public: */ LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{}; - bool file_logs_enabled{}; + bool file_logs_enabled = false; /** * Sets Executable platform (Zone/World/UCS) etc. */ - int log_platform{}; + int log_platform = 0; /** * File name used in writing logs diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 44d1fcbc0..2c2f3ae2b 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -292,7 +292,7 @@ void Client::Handle_Login(const char *data, unsigned int size) */ if (result) { LogF( - Logs::Detail, Logs::Login_Server, "lgoin [{0}] user [{2}] Login succeeded", + Logs::Detail, Logs::Login_Server, "login [{0}] user [{2}] Login succeeded", db_loginserver, user ); @@ -301,7 +301,7 @@ void Client::Handle_Login(const char *data, unsigned int size) } else { LogF( - Logs::Detail, Logs::Login_Server, "lgoin [{0}] user [{2}] Login failed", + Logs::Detail, Logs::Login_Server, "login [{0}] user [{2}] Login failed", db_loginserver, user ); From dc9e4e8260870d47e301c58e8a294c9197b41916 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 19:10:34 -0500 Subject: [PATCH 029/491] Received New Login Server Info log --- loginserver/world_server.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index cd1bd2abb..576280a2d 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -23,6 +23,7 @@ #include "login_structures.h" #include "config.h" #include "../common/eqemu_logsys.h" +#include "../common/eqemu_logsys_fmt.h" extern LoginServer server; @@ -108,11 +109,33 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) return; } - if (server.options.IsWorldTraceOn()) { - Log(Logs::General, Logs::Netcode, "New Login Info Received."); - } ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data(); + + LogF( + Logs::General, + Logs::Login_Server, + "Received New Login Server Info \n" + " - name [{0}]\n" + " - shortname [{1}]\n" + " - remote_address [{2}]\n" + " - local_address [{3}]\n" + " - account [{4}]\n" + " - password [{5}]\n" + " - protocolversion [{6}]\n" + " - server_version [{7}]\n" + " - server_type [{8}]", + info->name, + info->shortname, + info->remote_address, + info->local_address, + info->account, + info->password, + info->protocolversion, + info->serverversion, + info->servertype + ); + Handle_NewLSInfo(info); } From d40b95f2e84ed781b81db705ac42a4022533098e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 19:22:06 -0500 Subject: [PATCH 030/491] ProcessLSStatus logging --- loginserver/world_server.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 576280a2d..b1abfa2a5 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -141,30 +141,40 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) { - if (server.options.IsWorldTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Application packet received from server: 0x%.4X, (size %u)", - opcode, - p.Length()); - } + Log( + Logs::Detail, + Logs::Netcode, + "Application packet received from server: 0x%.4X, (size %u)", + opcode, + p.Length() + ); if (server.options.IsDumpInPacketsOn()) { DumpPacket(opcode, p); } if (p.Length() < sizeof(ServerLSStatus_Struct)) { - Log(Logs::General, + Log( + Logs::General, Logs::Error, - "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun"); + "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" + ); + return; } - if (server.options.IsWorldTraceOn()) { - Log(Logs::General, Logs::Netcode, "World Server Status Received."); - } - ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data(); + + LogF( + Logs::Detail, + Logs::Login_Server, + "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", + this->GetLongName(), + ls_status->status, + ls_status->num_players, + ls_status->num_zones + ); + Handle_LSStatus(ls_status); } From eea3965d02b92867323bbfbe719713b30aa447bf Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 21:35:36 -0500 Subject: [PATCH 031/491] Add DatabaseMySQL::DoesLoginServerAccountExist --- loginserver/client.cpp | 6 ++++++ loginserver/database_mysql.cpp | 33 +++++++++++++++++++++++++++++++++ loginserver/database_mysql.h | 8 ++++++++ loginserver/login_server.h | 2 +- loginserver/main.cpp | 2 +- loginserver/world_server.cpp | 2 +- 6 files changed, 50 insertions(+), 3 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 2c2f3ae2b..b5ae59b48 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -590,6 +590,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const in.s_addr = connection->GetRemoteIP(); server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); + GenerateKey(); account_id = db_account_id; @@ -674,6 +675,11 @@ void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass auto mode = server.options.GetEncryptionMode(); auto hash = eqcrypt_hash(user, pass, mode); + if (server.db->DoesLoginServerAccountExist(user, hash, "eqemu", id)) { + DoSuccessfulLogin(user, id, "eqemu"); + return; + } + if (!server.db->CreateLoginDataWithID(user, hash, "eqemu", id)) { DoFailedLogin(); } diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index c8696c019..c961d9b6f 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -322,6 +322,39 @@ bool DatabaseMySQL::CreateLoginDataWithID( return true; } +/** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ +bool DatabaseMySQL::DoesLoginServerAccountExist( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id +) +{ + if (id == 0) { + return false; + } + + auto query = fmt::format( + "SELECT AccountName FROM {0} WHERE AccountName = '{1}' AND AccountLoginserver = '{2}'", + server.options.GetAccountTable(), + EscapeString(name), + EscapeString(loginserver) + ); + + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() != 1) { + return false; + } + + return true; +} + /** * @param name * @param loginserver diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index b45ee9c2f..5f1c31779 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -87,8 +87,16 @@ public: const std::string &loginserver, unsigned int id ); + virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + virtual bool DoesLoginServerAccountExist( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id + ); + /** * Retrieves the world registration from the long and short names provided * Needed for world login procedure diff --git a/loginserver/login_server.h b/loginserver/login_server.h index ba03bfd52..bc257ddef 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -39,7 +39,7 @@ public: LoginServer() : db(nullptr), server_manager(nullptr) { } EQ::JsonConfigFile config; - Database *db; + DatabaseMySQL *db; Options options; ServerManager *server_manager; ClientManager *client_manager; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 04d61d702..70b48ca54 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -133,7 +133,7 @@ int main() */ Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); - server.db = (Database *) new DatabaseMySQL( + server.db = new DatabaseMySQL( server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "password", ""), server.config.GetVariableString("database", "host", "localhost"), diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index b1abfa2a5..1d6c0d2d3 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -159,7 +159,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) Logs::Error, "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" ); - + return; } From 7fcf6b51d8cd9f730f71e1d1fce1c47b846591ab Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 21:35:39 -0500 Subject: [PATCH 032/491] Update database.h --- loginserver/database.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/loginserver/database.h b/loginserver/database.h index b1651fae7..6b0e1fa68 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -75,6 +75,13 @@ public: virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) {} + virtual bool DoesLoginServerAccountExist( + const std::string &name, + const std::string &password, + const std::string &loginserver, + unsigned int id + ) { return false; } + /** * Retrieves the world registration from the long and short names provided * Needed for world login procedure From ff5783965a530453c7c74d007ba3280f9fb9d0a7 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 21:56:24 -0500 Subject: [PATCH 033/491] Use one database class --- loginserver/CMakeLists.txt | 1 - loginserver/database.h | 148 --------------------------------- loginserver/database_mysql.cpp | 5 -- loginserver/database_mysql.h | 32 ++++--- loginserver/login_server.h | 1 - 5 files changed, 14 insertions(+), 173 deletions(-) delete mode 100644 loginserver/database.h diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 3af0c7e66..a0ed71a91 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -13,7 +13,6 @@ SET(eqlogin_sources SET(eqlogin_headers client.h client_manager.h - database.h database_mysql.h encryption.h login_server.h diff --git a/loginserver/database.h b/loginserver/database.h deleted file mode 100644 index 6b0e1fa68..000000000 --- a/loginserver/database.h +++ /dev/null @@ -1,148 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef EQEMU_DATABASE_H -#define EQEMU_DATABASE_H - -#include - -#define EQEMU_MYSQL_ENABLED - -/** -* Base database class, intended to be extended. -*/ -class Database { -public: - Database() : user(""), pass(""), host(""), port(""), name("") {} - virtual ~Database() {} - - virtual bool IsConnected() { return false; } - - /** - * Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure - * - * @param name - * @param loginserver - * @param password - * @param id - * @return - */ - virtual bool GetLoginDataFromAccountInfo( - const std::string &name, - const std::string &loginserver, - std::string &password, - unsigned int &id - ) { return false; } - - virtual bool GetLoginTokenDataFromToken( - const std::string &token, - const std::string &ip, - unsigned int &db_account_id, - std::string &db_loginserver, - std::string &user - ) { return false; } - - virtual bool CreateLoginData( - const std::string &name, - const std::string &password, - const std::string &loginserver, - unsigned int &id - ) { return false; } - - virtual bool CreateLoginDataWithID( - const std::string &name, - const std::string &password, - const std::string &loginserver, - unsigned int id - ) { return false; } - - virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash) {} - - virtual bool DoesLoginServerAccountExist( - const std::string &name, - const std::string &password, - const std::string &loginserver, - unsigned int id - ) { return false; } - - /** - * Retrieves the world registration from the long and short names provided - * Needed for world login procedure - * Returns true if the record was found, false otherwise - * - * @param long_name - * @param short_name - * @param id - * @param desc - * @param list_id - * @param trusted - * @param list_desc - * @param account - * @param password - * @return - */ - virtual bool GetWorldRegistration( - std::string long_name, - std::string short_name, - unsigned int &id, - std::string &desc, - unsigned int &list_id, - unsigned int &trusted, - std::string &list_desc, - std::string &account, - std::string &password - ) { return false; } - - virtual void UpdateLSAccountData(unsigned int id, std::string ip_address) {} - - /** - * Updates or creates the login server account with info from world server - * - * @param id - * @param name - * @param password - * @param email - */ - virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email) {} - - /** - * Updates the ip address of the world with account id = id - * - * @param id - * @param long_name - * @param ip_address - */ - virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) {} - - /** - * Creates new world registration for unregistered servers and returns new id - * - * @param long_name - * @param short_name - * @param id - * @return - */ - virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { return false; } -protected: - std::string user, pass, host, port, name; -}; - -#endif - diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index c961d9b6f..62f75d0af 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -19,9 +19,6 @@ */ #include "../common/global_define.h" -#include "database.h" - -#ifdef EQEMU_MYSQL_ENABLED #include "database_mysql.h" #include "login_server.h" @@ -605,5 +602,3 @@ bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string s short_name.c_str()); return false; } - -#endif diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 5f1c31779..3b4c5c0cc 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -21,11 +21,8 @@ #ifndef EQEMU_DATABASEMYSQL_H #define EQEMU_DATABASEMYSQL_H -#include "database.h" #include "../common/dbcore.h" -#ifdef EQEMU_MYSQL_ENABLED - #include #include #include @@ -50,8 +47,8 @@ public: /** * Destructor, frees our database if needed. */ - virtual ~DatabaseMySQL(); - virtual bool IsConnected() { return (database != nullptr); } + ~DatabaseMySQL(); + bool IsConnected() { return (database != nullptr); } /** * Retrieves the login data (password hash and account id) from the account name provided needed for client login procedure. @@ -61,36 +58,36 @@ public: * @param id * @return */ - virtual bool GetLoginDataFromAccountInfo( + bool GetLoginDataFromAccountInfo( const std::string &name, const std::string &loginserver, std::string &password, unsigned int &id ); - virtual bool GetLoginTokenDataFromToken( + bool GetLoginTokenDataFromToken( const std::string &token, const std::string &ip, unsigned int &db_account_id, std::string &db_loginserver, std::string &user ); - virtual unsigned int GetFreeID(const std::string &loginserver); - virtual bool CreateLoginData( + unsigned int GetFreeID(const std::string &loginserver); + bool CreateLoginData( const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id ); - virtual bool CreateLoginDataWithID( + bool CreateLoginDataWithID( const std::string &name, const std::string &password, const std::string &loginserver, unsigned int id ); - virtual void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); - virtual bool DoesLoginServerAccountExist( + bool DoesLoginServerAccountExist( const std::string &name, const std::string &password, const std::string &loginserver, @@ -113,7 +110,7 @@ public: * @param password * @return */ - virtual bool GetWorldRegistration( + bool GetWorldRegistration( std::string long_name, std::string short_name, unsigned int &id, @@ -125,15 +122,14 @@ public: std::string &password ); - virtual void UpdateLSAccountData(unsigned int id, std::string ip_address); - virtual void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email); - virtual void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); - virtual bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); + void UpdateLSAccountData(unsigned int id, std::string ip_address); + void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email); + void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); + bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); protected: std::string user, pass, host, port, name; MYSQL *database; }; #endif -#endif diff --git a/loginserver/login_server.h b/loginserver/login_server.h index bc257ddef..4696e8120 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -23,7 +23,6 @@ #define EQEMU_LOGINSERVER_H #include "../common/json_config.h" -#include "database.h" #include "database_mysql.h" #include "encryption.h" #include "options.h" From bd2836db61ecae8aabad2493a60fb33f5a8f74e1 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 21:58:39 -0500 Subject: [PATCH 034/491] DatabaseMySQL -> Database --- loginserver/database_mysql.cpp | 28 ++++++++++++++-------------- loginserver/database_mysql.h | 8 ++++---- loginserver/login_server.h | 2 +- loginserver/main.cpp | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 62f75d0af..e49795459 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -37,7 +37,7 @@ extern LoginServer server; * @param port * @param name */ -DatabaseMySQL::DatabaseMySQL( +Database::Database( std::string user, std::string pass, std::string host, @@ -97,7 +97,7 @@ DatabaseMySQL::DatabaseMySQL( /** * Deconstructor */ -DatabaseMySQL::~DatabaseMySQL() +Database::~Database() { if (database) { mysql_close(database); @@ -111,7 +111,7 @@ DatabaseMySQL::~DatabaseMySQL() * @param id * @return */ -bool DatabaseMySQL::GetLoginDataFromAccountInfo( +bool Database::GetLoginDataFromAccountInfo( const std::string &name, const std::string &loginserver, std::string &password, @@ -167,7 +167,7 @@ bool DatabaseMySQL::GetLoginDataFromAccountInfo( * @param user * @return */ -bool DatabaseMySQL::GetLoginTokenDataFromToken( +bool Database::GetLoginTokenDataFromToken( const std::string &token, const std::string &ip, unsigned int &db_account_id, @@ -229,7 +229,7 @@ bool DatabaseMySQL::GetLoginTokenDataFromToken( * @param loginserver * @return */ -unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) +unsigned int Database::GetFreeID(const std::string &loginserver) { if (!database) { return false; @@ -273,7 +273,7 @@ unsigned int DatabaseMySQL::GetFreeID(const std::string &loginserver) * @param id * @return */ -bool DatabaseMySQL::CreateLoginData( +bool Database::CreateLoginData( const std::string &name, const std::string &password, const std::string &loginserver, @@ -290,7 +290,7 @@ bool DatabaseMySQL::CreateLoginData( * @param id * @return */ -bool DatabaseMySQL::CreateLoginDataWithID( +bool Database::CreateLoginDataWithID( const std::string &name, const std::string &password, const std::string &loginserver, @@ -326,7 +326,7 @@ bool DatabaseMySQL::CreateLoginDataWithID( * @param id * @return */ -bool DatabaseMySQL::DoesLoginServerAccountExist( +bool Database::DoesLoginServerAccountExist( const std::string &name, const std::string &password, const std::string &loginserver, @@ -357,7 +357,7 @@ bool DatabaseMySQL::DoesLoginServerAccountExist( * @param loginserver * @param hash */ -void DatabaseMySQL::UpdateLoginHash( +void Database::UpdateLoginHash( const std::string &name, const std::string &loginserver, const std::string &hash @@ -395,7 +395,7 @@ void DatabaseMySQL::UpdateLoginHash( * @param password * @return */ -bool DatabaseMySQL::GetWorldRegistration( +bool Database::GetWorldRegistration( std::string long_name, std::string short_name, unsigned int &id, @@ -484,7 +484,7 @@ bool DatabaseMySQL::GetWorldRegistration( * @param id * @param ip_address */ -void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) +void Database::UpdateLSAccountData(unsigned int id, std::string ip_address) { auto query = fmt::format( "UPDATE {0} SET LastIPAddress = '{2}', LastLoginDate = now() where LoginServerId = {3}", @@ -502,7 +502,7 @@ void DatabaseMySQL::UpdateLSAccountData(unsigned int id, std::string ip_address) * @param password * @param email */ -void DatabaseMySQL::UpdateLSAccountInfo( +void Database::UpdateLSAccountInfo( unsigned int id, std::string name, std::string password, @@ -527,7 +527,7 @@ void DatabaseMySQL::UpdateLSAccountInfo( * @param long_name * @param ip_address */ -void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) +void Database::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { auto query = fmt::format( "UPDATE {0} SET ServerLastLoginDate = NOW(), ServerLastIPAddr = '{1}', ServerLongName = '{2}' WHERE ServerID = {3}", @@ -546,7 +546,7 @@ void DatabaseMySQL::UpdateWorldRegistration(unsigned int id, std::string long_na * @param id * @return */ -bool DatabaseMySQL::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) +bool Database::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { if (!database) { return false; diff --git a/loginserver/database_mysql.h b/loginserver/database_mysql.h index 3b4c5c0cc..dab6de6ef 100644 --- a/loginserver/database_mysql.h +++ b/loginserver/database_mysql.h @@ -28,10 +28,10 @@ #include #include -class DatabaseMySQL : public DBcore { +class Database : public DBcore { public: - DatabaseMySQL() { database = nullptr; } + Database() { database = nullptr; } /** * Constructor, tries to set our database to connect to the supplied options. @@ -42,12 +42,12 @@ public: * @param port * @param name */ - DatabaseMySQL(std::string user, std::string pass, std::string host, std::string port, std::string name); + Database(std::string user, std::string pass, std::string host, std::string port, std::string name); /** * Destructor, frees our database if needed. */ - ~DatabaseMySQL(); + ~Database(); bool IsConnected() { return (database != nullptr); } /** diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 4696e8120..9d3553ce1 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -38,7 +38,7 @@ public: LoginServer() : db(nullptr), server_manager(nullptr) { } EQ::JsonConfigFile config; - DatabaseMySQL *db; + Database *db; Options options; ServerManager *server_manager; ClientManager *client_manager; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 70b48ca54..217db1a2f 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -133,7 +133,7 @@ int main() */ Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); - server.db = new DatabaseMySQL( + server.db = new Database( server.config.GetVariableString("database", "user", "root"), server.config.GetVariableString("database", "password", ""), server.config.GetVariableString("database", "host", "localhost"), From 1a5ce7a9de517b188b7640152a4e8196d5c40b7a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 22:47:28 -0500 Subject: [PATCH 035/491] Cleanup query Database::GetWorldRegistration --- loginserver/database_mysql.cpp | 101 +++++++++++++-------------------- 1 file changed, 41 insertions(+), 60 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index e49795459..6603d63e7 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -407,77 +407,58 @@ bool Database::GetWorldRegistration( std::string &password ) { + auto query = fmt::format( + "SELECT\n" + " ifnull(WSR.ServerID, 999999) AS ServerID,\n" + " WSR.ServerTagDescription,\n" + " ifnull(WSR.ServerTrusted, 0) AS ServerTrusted,\n" + " ifnull(SLT.ServerListTypeID, 3) AS ServerListTypeID,\n" + " SLT.ServerListTypeDescription,\n" + " ifnull(WSR.ServerAdminID, 0) AS ServerAdminID\n" + "FROM\n" + " {0} AS WSR\n" + " JOIN {1} AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID\n" + "WHERE\n" + " WSR.ServerShortName = '{2}' LIMIT 1", + server.options.GetWorldRegistrationTable(), + server.options.GetWorldServerTypeTable(), + EscapeString(short_name) + ); - if (!database) { + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() != 1) { return false; } - MYSQL_RES *res; - MYSQL_ROW row; - char escaped_short_name[101]; - unsigned long length; - length = mysql_real_escape_string( - database, - escaped_short_name, - short_name.substr(0, 100).c_str(), - short_name.substr(0, 100).length()); - escaped_short_name[length + 1] = 0; - std::stringstream query(std::stringstream::in | std::stringstream::out); - query - << "SELECT ifnull(WSR.ServerID,999999) AS ServerID, WSR.ServerTagDescription, ifnull(WSR.ServerTrusted,0) AS ServerTrusted, ifnull(SLT.ServerListTypeID,3) AS ServerListTypeID, "; - query << "SLT.ServerListTypeDescription, ifnull(WSR.ServerAdminID,0) AS ServerAdminID FROM " - << server.options.GetWorldRegistrationTable(); - query << " AS WSR JOIN " << server.options.GetWorldServerTypeTable() - << " AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID"; - query << " WHERE WSR.ServerShortName = '"; - query << escaped_short_name; - query << "'"; + auto row = results.begin(); - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - return false; - } + id = atoi(row[0]); + desc = row[1]; + trusted = atoi(row[2]); + list_id = atoi(row[3]); + list_desc = row[4]; - res = mysql_use_result(database); - if (res) { - if ((row = mysql_fetch_row(res)) != nullptr) { - id = atoi(row[0]); - desc = row[1]; - trusted = atoi(row[2]); - list_id = atoi(row[3]); - list_desc = row[4]; - int db_account_id = atoi(row[5]); - mysql_free_result(res); + int db_account_id = atoi(row[5]); + if (db_account_id > 0) { - if (db_account_id > 0) { - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT AccountName, AccountPassword FROM " << server.options.GetWorldAdminRegistrationTable(); - query << " WHERE ServerAdminID = " << db_account_id; + auto world_registration_query = fmt::format( + "SELECT AccountName, AccountPassword FROM {0} WHERE ServerAdminID = {1} LIMIT 1", + server.options.GetWorldAdminRegistrationTable(), + db_account_id + ); - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - return false; - } - - res = mysql_use_result(database); - if (res) { - if ((row = mysql_fetch_row(res)) != nullptr) { - account = row[0]; - password = row[1]; - mysql_free_result(res); - return true; - } - } - - Log(Logs::General, Logs::Error, "Mysql query returned no result: %s", query.str().c_str()); - return false; - } - return true; + auto world_registration_results = QueryDatabase(world_registration_query); + if (!world_registration_results.Success() || world_registration_results.RowCount() != 1) { + return false; } + + auto world_registration_row = world_registration_results.begin(); + + account = world_registration_row[0]; + password = world_registration_row[1]; } - Log(Logs::General, Logs::Error, "Mysql query returned no result: %s", query.str().c_str()); - return false; + return true; } /** From d17cfff8fe7f9a953d6deadc1057654fe7c08929 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 22:54:22 -0500 Subject: [PATCH 036/491] Migrate query Database::GetFreeID --- loginserver/database_mysql.cpp | 37 +++++++++------------------------- loginserver/world_server.cpp | 27 ++++++++++++++++--------- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 6603d63e7..15f33c5bc 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -231,39 +231,20 @@ bool Database::GetLoginTokenDataFromToken( */ unsigned int Database::GetFreeID(const std::string &loginserver) { - if (!database) { - return false; - } + auto query = fmt::format( + "SELECT MAX(LoginServerID) + 1 FROM {0} WHERE AccountLoginServer='{1}'", + server.options.GetAccountTable(), + EscapeString(loginserver) + ); - MYSQL_RES *res; - MYSQL_ROW row; - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT MAX(LoginServerID) + 1 FROM " << server.options.GetAccountTable() << " WHERE AccountLoginServer='"; - query << EscapeString(loginserver) << "'"; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() != 1) { return 0; } - res = mysql_use_result(database); + auto row = results.begin(); - if (res) { - while ((row = mysql_fetch_row(res)) != nullptr) { - if (row[0] == nullptr) { - mysql_free_result(res); - return 1; - } - - auto ret = atol(row[0]); - mysql_free_result(res); - return ret; - } - - mysql_free_result(res); - } - - return 1; + return atol(row[0]); } /** diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 1d6c0d2d3..241ba8413 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -478,16 +478,19 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) } else { Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long."); + return; } if (strlen(i->remote_address) <= 125) { if (strlen(i->remote_address) == 0) { remote_ip = GetConnection()->Handle()->RemoteIP(); - Log(Logs::General, + Log( + Logs::General, Logs::Error, - "Handle_NewLSInfo error, remote address was null, defaulting to stream address %s.", - remote_ip.c_str()); + "Remote address was null, defaulting to stream address %s.", + remote_ip.c_str() + ); } else { remote_ip = i->remote_address; @@ -495,10 +498,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) } else { remote_ip = GetConnection()->Handle()->RemoteIP(); - Log(Logs::General, + + Log( + Logs::General, Logs::Error, "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", - remote_ip.c_str()); + remote_ip.c_str() + ); } if (strlen(i->serverversion) <= 64) { @@ -687,11 +693,12 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) } } else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) attempted to log in but database couldn't find an entry but unregistered servers are allowed.", - long_name.c_str(), - short_name.c_str()); + LogF(Logs::General, + Logs::World_Server, + "Server [{0}] ({1}) is not registered but unregistered servers are allowed", + long_name, + short_name + ); if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) { is_server_authorized = true; From 126d8edc57b82ac152e4cfbf183575af7a581d76 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 23:13:13 -0500 Subject: [PATCH 037/491] Convert Database::CreateWorldRegistration --- loginserver/database_mysql.cpp | 76 ++++++++++++++-------------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 15f33c5bc..72b97e087 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -510,57 +510,41 @@ void Database::UpdateWorldRegistration(unsigned int id, std::string long_name, s */ bool Database::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) { - if (!database) { + auto query = fmt::format( + "SELECT ifnull(max(ServerID),0) + 1 FROM {0}", + server.options.GetWorldRegistrationTable() + ); + + auto results = QueryDatabase(query); + if (!results.Success() || results.RowCount() != 1) { return false; } - MYSQL_RES *res; - MYSQL_ROW row; - char escaped_long_name[201]; - char escaped_short_name[101]; - unsigned long length; - length = mysql_real_escape_string( - database, - escaped_long_name, - long_name.substr(0, 100).c_str(), - long_name.substr(0, 100).length()); - escaped_long_name[length + 1] = 0; - length = mysql_real_escape_string( - database, - escaped_short_name, - short_name.substr(0, 100).c_str(), - short_name.substr(0, 100).length()); - escaped_short_name[length + 1] = 0; - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "SELECT ifnull(max(ServerID),0) FROM " << server.options.GetWorldRegistrationTable(); + auto row = results.begin(); + + id = atoi(row[0]); + + auto insert_query = fmt::format( + "INSERT INTO {0} SET ServerID = {1}, ServerLongName = '{2}', ServerShortName = '{3}', \n" + "ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''", + server.options.GetWorldRegistrationTable(), + id, + long_name, + short_name + ); + + auto insert_results = QueryDatabase(insert_query); + if (!insert_results.Success()) { + LogF( + Logs::General, + Logs::Error, + "World registration did not exist in the database for {0} - {1}", + long_name, + short_name + ); - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); return false; } - res = mysql_use_result(database); - if (res) { - if ((row = mysql_fetch_row(res)) != nullptr) { - id = atoi(row[0]) + 1; - mysql_free_result(res); - - std::stringstream query(std::stringstream::in | std::stringstream::out); - query << "INSERT INTO " << server.options.GetWorldRegistrationTable() << " SET ServerID = " << id; - query << ", ServerLongName = '" << escaped_long_name << "', ServerShortName = '" << escaped_short_name; - query << "', ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''"; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - return false; - } - return true; - } - } - Log(Logs::General, - Logs::Error, - "World registration did not exist in the database for %s %s", - long_name.c_str(), - short_name.c_str()); - return false; + return true; } From a914e97c29171e49bf9f1089e61c9a8d67772644 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 23:26:03 -0500 Subject: [PATCH 038/491] Convert Database::GetLoginTokenDataFromToken --- loginserver/database_mysql.cpp | 63 ++++++++++++++-------------------- 1 file changed, 26 insertions(+), 37 deletions(-) diff --git a/loginserver/database_mysql.cpp b/loginserver/database_mysql.cpp index 72b97e087..360ef2229 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database_mysql.cpp @@ -175,51 +175,40 @@ bool Database::GetLoginTokenDataFromToken( std::string &user ) { - if (!database) { + auto query = fmt::format( + "SELECT tbllogintokens.Id, tbllogintokens.IpAddress, tbllogintokenclaims.Name, tbllogintokenclaims.Value FROM tbllogintokens " + "JOIN tbllogintokenclaims ON tbllogintokens.Id = tbllogintokenclaims.TokenId WHERE tbllogintokens.Expires > NOW() " + "AND tbllogintokens.Id='{0}' AND tbllogintokens.IpAddress='{1}'", + EscapeString(token), + EscapeString(ip) + ); + + auto results = QueryDatabase(query); + if (results.RowCount() == 0 || !results.Success()) { return false; } - MYSQL_RES *res; - MYSQL_ROW row; - std::stringstream query(std::stringstream::in | std::stringstream::out); - query - << "SELECT tbllogintokens.Id, tbllogintokens.IpAddress, tbllogintokenclaims.Name, tbllogintokenclaims.Value FROM tbllogintokens "; - query - << "JOIN tbllogintokenclaims ON tbllogintokens.Id = tbllogintokenclaims.TokenId WHERE tbllogintokens.Expires > NOW() AND tbllogintokens.Id='"; - query << EscapeString(token) << "' AND tbllogintokens.IpAddress='" << EscapeString(ip) << "'"; - - if (mysql_query(database, query.str().c_str()) != 0) { - Log(Logs::General, Logs::Error, "Mysql query failed: %s", query.str().c_str()); - return false; - } - - res = mysql_use_result(database); - bool found_username = false; bool found_login_id = false; bool found_login_server_name = false; - if (res) { - while ((row = mysql_fetch_row(res)) != nullptr) { - if (strcmp(row[2], "username") == 0) { - user = row[3]; - found_username = true; - continue; - } - - if (strcmp(row[2], "login_server_id") == 0) { - db_account_id = atoi(row[3]); - found_login_id = true; - continue; - } - - if (strcmp(row[2], "login_server_name") == 0) { - db_loginserver = row[3]; - found_login_server_name = true; - continue; - } + for (auto row = results.begin(); row != results.end(); ++row) { + if (strcmp(row[2], "username") == 0) { + user = row[3]; + found_username = true; + continue; } - mysql_free_result(res); + if (strcmp(row[2], "login_server_id") == 0) { + db_account_id = atoi(row[3]); + found_login_id = true; + continue; + } + + if (strcmp(row[2], "login_server_name") == 0) { + db_loginserver = row[3]; + found_login_server_name = true; + continue; + } } return found_username && found_login_id && found_login_server_name; From 8ad4ef503bfb8b0293d112a1c31de40afb6798a8 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 3 Jul 2019 23:27:45 -0500 Subject: [PATCH 039/491] database_mysql -> database --- loginserver/CMakeLists.txt | 4 ++-- loginserver/{database_mysql.cpp => database.cpp} | 2 +- loginserver/{database_mysql.h => database.h} | 0 loginserver/login_server.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename loginserver/{database_mysql.cpp => database.cpp} (99%) rename loginserver/{database_mysql.h => database.h} (100%) diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index a0ed71a91..cb3c36874 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -3,7 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(eqlogin_sources client.cpp client_manager.cpp - database_mysql.cpp + database.cpp encryption.cpp main.cpp server_manager.cpp @@ -13,7 +13,7 @@ SET(eqlogin_sources SET(eqlogin_headers client.h client_manager.h - database_mysql.h + database.h encryption.h login_server.h login_structures.h diff --git a/loginserver/database_mysql.cpp b/loginserver/database.cpp similarity index 99% rename from loginserver/database_mysql.cpp rename to loginserver/database.cpp index 360ef2229..534ce2328 100644 --- a/loginserver/database_mysql.cpp +++ b/loginserver/database.cpp @@ -20,7 +20,7 @@ #include "../common/global_define.h" -#include "database_mysql.h" +#include "database.h" #include "login_server.h" #include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys_fmt.h" diff --git a/loginserver/database_mysql.h b/loginserver/database.h similarity index 100% rename from loginserver/database_mysql.h rename to loginserver/database.h diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 9d3553ce1..36ce7460c 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -23,7 +23,7 @@ #define EQEMU_LOGINSERVER_H #include "../common/json_config.h" -#include "database_mysql.h" +#include "database.h" #include "encryption.h" #include "options.h" #include "server_manager.h" From d5eb0155337493e2e43c6ab66043778e881f185d Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 4 Jul 2019 23:29:54 -0500 Subject: [PATCH 040/491] Remove old DB connector --- loginserver/client.cpp | 1 - loginserver/database.cpp | 56 ++++++++++++---------------------------- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index b5ae59b48..a4e7b4f89 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -590,7 +590,6 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const in.s_addr = connection->GetRemoteIP(); server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); - GenerateKey(); account_id = db_account_id; diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 534ce2328..11a0aace0 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -50,47 +50,23 @@ Database::Database( this->host = host; this->name = name; - database = mysql_init(nullptr); - if (database) { - char r = 1; - mysql_options(database, MYSQL_OPT_RECONNECT, &r); - if (!mysql_real_connect( - database, - host.c_str(), - user.c_str(), - pass.c_str(), - name.c_str(), - atoi(port.c_str()), - nullptr, - 0 - )) { - mysql_close(database); - Log(Logs::General, Logs::Error, "Failed to connect to MySQL database. Error: %s", mysql_error(database)); - exit(1); - } - - uint32 errnum = 0; - char errbuf[MYSQL_ERRMSG_SIZE]; - if (!Open( - host.c_str(), - user.c_str(), - pass.c_str(), - name.c_str(), - atoi(port.c_str()), - &errnum, - errbuf - ) - ) { - Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); - exit(1); - } - else { - Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host, port); - } - + uint32 errnum = 0; + char errbuf[MYSQL_ERRMSG_SIZE]; + if (!Open( + host.c_str(), + user.c_str(), + pass.c_str(), + name.c_str(), + atoi(port.c_str()), + &errnum, + errbuf + ) + ) { + Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); + exit(1); } else { - Log(Logs::General, Logs::Error, "Failed to create db object in MySQL database."); + Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host, port); } } @@ -438,7 +414,7 @@ bool Database::GetWorldRegistration( void Database::UpdateLSAccountData(unsigned int id, std::string ip_address) { auto query = fmt::format( - "UPDATE {0} SET LastIPAddress = '{2}', LastLoginDate = now() where LoginServerId = {3}", + "UPDATE {0} SET LastIPAddress = '{1}', LastLoginDate = NOW() where LoginServerId = {2}", server.options.GetAccountTable(), ip_address, id From 8b582730a8714c8f96100b9f44eb6762f1e0fb8c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 00:44:42 -0500 Subject: [PATCH 041/491] Small refactorings --- common/eqemu_logsys.h | 10 +++++ loginserver/world_server.cpp | 82 ++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 27 deletions(-) diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 5ec81d526..83bf689d8 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -167,6 +167,16 @@ namespace Logs { OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) +#define LogLoginserver(message, ...) do {\ + if (LogSys.log_settings[Logs::Login_Server].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Login_Server, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogLoginserverDetail(message, ...) do {\ + if (LogSys.log_settings[Logs::Login_Server].is_category_enabled == 1)\ + OutF(LogSys, Logs::Detail, Logs::Login_Server, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + class EQEmuLogSys { public: EQEmuLogSys(); diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 241ba8413..57b0f18a2 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -207,36 +207,39 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponseLegacy_Struct *utwr = (UsertoWorldResponseLegacy_Struct *) p.Data(); - Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); - Client *c = server.client_manager->GetClient(utwr->lsaccountid, "eqemu"); + UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) p.Data(); + Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); + Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); if (c) { + Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", - utwr->lsaccountid, - c->GetAccountName().c_str()); - EQApplicationPacket *outapp = new EQApplicationPacket( + user_to_world_response->lsaccountid, + c->GetAccountName().c_str() + ); + + EQApplicationPacket *outapp = new EQApplicationPacket( OP_PlayEverquestResponse, - sizeof(PlayEverquestResponse_Struct)); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; + sizeof(PlayEverquestResponse_Struct) + ); + + PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); - Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); - Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - - if (utwr->response > 0) { + if (user_to_world_response->response > 0) { per->Allowed = 1; SendClientAuth( c->GetConnection()->GetRemoteAddr(), c->GetAccountName(), c->GetKey(), c->GetAccountID(), - c->GetLoginServerName()); + c->GetLoginServerName() + ); } - switch (utwr->response) { + switch (user_to_world_response->response) { case 1: per->Message = 101; break; @@ -254,16 +257,16 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack break; } - if (server.options.IsTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", - per->Allowed, - per->Sequence, - per->ServerNumber, - per->Message); - Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - } + LogF(Logs::General, + Logs::Netcode, + "Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]", + per->Allowed, + per->Sequence, + per->ServerNumber, + per->Message + ); + + Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); @@ -276,7 +279,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack Log(Logs::General, Logs::Error, "Received User-To-World Response for %u but could not find the client referenced!.", - utwr->lsaccountid); + user_to_world_response->lsaccountid); } } @@ -737,16 +740,19 @@ void WorldServer::SendClientAuth( ) { EQ::Net::DynamicPacket outapp; - ClientAuth_Struct client_auth; + ClientAuth_Struct client_auth{}; + client_auth.lsaccount_id = account_id; + strncpy(client_auth.name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); + client_auth.lsadmin = 0; client_auth.worldadmin = 0; client_auth.ip = inet_addr(ip.c_str()); strncpy(client_auth.lsname, &loginserver_name[0], 64); - std::string client_address(ip); + const std::string& client_address(ip); std::string world_address(connection->Handle()->RemoteIP()); if (client_address.compare(world_address) == 0) { @@ -759,6 +765,28 @@ void WorldServer::SendClientAuth( client_auth.local = 0; } + struct in_addr ip_addr{}; + ip_addr.s_addr = client_auth.ip; + + LogLoginserver( + "Client authentication response: world_address [{0}] client_address [{1}]", + world_address, + client_address + ); + + LogLoginserver( + "Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] " + " world_admin [{5}] ip [{6}] local [{7}]", + client_auth.lsaccount_id, + client_auth.lsname, + client_auth.name, + client_auth.key, + client_auth.lsadmin, + client_auth.worldadmin, + inet_ntoa(ip_addr), + client_auth.local + ); + outapp.PutSerialize(0, client_auth); connection->Send(ServerOP_LSClientAuth, outapp); From b41e58fd1094c0b4b9bb8853bcd0d60391bcb689 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 02:33:31 -0500 Subject: [PATCH 042/491] More loginserver refactorings and cleanup --- common/eqemu_logsys.h | 5 + loginserver/database.cpp | 9 +- loginserver/encryption.cpp | 184 ++++++++++++++++++++------------ loginserver/main.cpp | 41 ++++--- loginserver/server_manager.cpp | 89 +++++++++++----- loginserver/server_manager.h | 22 ++-- loginserver/world_server.cpp | 188 +++++++++++++++++---------------- loginserver/world_server.h | 22 ++-- 8 files changed, 328 insertions(+), 232 deletions(-) diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 83bf689d8..48873a6cc 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -157,6 +157,11 @@ namespace Logs { }; } +#define Error(message, ...) do {\ + if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + #define Log(debug_level, log_category, message, ...) do {\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\ LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 11a0aace0..8709fe365 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -258,11 +258,8 @@ bool Database::CreateLoginDataWithID( ); auto results = QueryDatabase(query); - if (!results.Success()) { - return false; - } - return true; + return results.Success(); } /** @@ -309,9 +306,7 @@ void Database::UpdateLoginHash( const std::string &hash ) { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "name [{0}] loginserver [{1}] hash [{2}]", name, loginserver, diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index 0a635b081..bf15bd796 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -23,15 +23,26 @@ #include #include #include + #ifdef ENABLE_SECURITY + #include + #endif #include "encryption.h" -const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc) { +/** + * @param buffer_in + * @param buffer_in_sz + * @param buffer_out + * @param enc + * @return + */ +const char *eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char *buffer_out, bool enc) +{ DES_key_schedule k; - DES_cblock v; + DES_cblock v; memset(&k, 0, sizeof(DES_key_schedule)); memset(&v, 0, sizeof(DES_cblock)); @@ -40,16 +51,21 @@ const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buff return nullptr; } - DES_ncbc_encrypt((const unsigned char*)buffer_in, (unsigned char*)buffer_out, (long)buffer_in_sz, &k, &v, enc); + DES_ncbc_encrypt((const unsigned char *) buffer_in, (unsigned char *) buffer_out, (long) buffer_in_sz, &k, &v, enc); return buffer_out; } -std::string eqcrypt_md5(const std::string &msg) { - std::string ret; +/** + * @param msg + * @return + */ +std::string eqcrypt_md5(const std::string &msg) +{ + std::string ret; unsigned char md5_digest[16]; - char tmp[4]; + char tmp[4]; - MD5((const unsigned char*)msg.c_str(), msg.length(), md5_digest); + MD5((const unsigned char *) msg.c_str(), msg.length(), md5_digest); for (int i = 0; i < 16; ++i) { sprintf(&tmp[0], "%02x", md5_digest[i]); @@ -60,12 +76,17 @@ std::string eqcrypt_md5(const std::string &msg) { return ret; } -std::string eqcrypt_sha1(const std::string &msg) { - std::string ret; +/** + * @param msg + * @return + */ +std::string eqcrypt_sha1(const std::string &msg) +{ + std::string ret; unsigned char sha_digest[20]; - char tmp[4]; + char tmp[4]; - SHA1((const unsigned char*)msg.c_str(), msg.length(), sha_digest); + SHA1((const unsigned char *) msg.c_str(), msg.length(), sha_digest); for (int i = 0; i < 20; ++i) { sprintf(&tmp[0], "%02x", sha_digest[i]); @@ -76,12 +97,17 @@ std::string eqcrypt_sha1(const std::string &msg) { return ret; } -std::string eqcrypt_sha512(const std::string &msg) { - std::string ret; +/** + * @param msg + * @return + */ +std::string eqcrypt_sha512(const std::string &msg) +{ + std::string ret; unsigned char sha_digest[64]; - char tmp[4]; + char tmp[4]; - SHA512((const unsigned char*)msg.c_str(), msg.length(), sha_digest); + SHA512((const unsigned char *) msg.c_str(), msg.length(), sha_digest); for (int i = 0; i < 64; ++i) { sprintf(&tmp[0], "%02x", sha_digest[i]); @@ -94,23 +120,39 @@ std::string eqcrypt_sha512(const std::string &msg) { #ifdef ENABLE_SECURITY +/** + * @param msg + * @return + */ std::string eqcrypt_argon2(const std::string &msg) { char buffer[crypto_pwhash_STRBYTES]; - if (crypto_pwhash_str(&buffer[0], &msg[0], msg.length(), crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE) != 0) { + if (crypto_pwhash_str( + &buffer[0], + &msg[0], + msg.length(), + crypto_pwhash_OPSLIMIT_INTERACTIVE, + crypto_pwhash_MEMLIMIT_INTERACTIVE + ) != 0) { return ""; } return buffer; } +/** + * @param msg + * @return + */ std::string eqcrypt_scrypt(const std::string &msg) { char buffer[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; - if (crypto_pwhash_scryptsalsa208sha256_str(&buffer[0], &msg[0], msg.length(), - crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE) != 0) { + if (crypto_pwhash_scryptsalsa208sha256_str( + &buffer[0], &msg[0], msg.length(), + crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE, crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE + ) != 0) { return ""; } @@ -119,60 +161,72 @@ std::string eqcrypt_scrypt(const std::string &msg) #endif -std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) { - switch (mode) - { - case EncryptionModeMD5: - return eqcrypt_md5(password); - case EncryptionModeMD5PassUser: - return eqcrypt_md5(password + ":" + username); - case EncryptionModeMD5UserPass: - return eqcrypt_md5(username + ":" + password); - case EncryptionModeMD5Triple: - return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); - case EncryptionModeSHA: - return eqcrypt_sha1(password); - case EncryptionModeSHAPassUser: - return eqcrypt_sha1(password + ":" + username); - case EncryptionModeSHAUserPass: - return eqcrypt_sha1(username + ":" + password); - case EncryptionModeSHATriple: - return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); - case EncryptionModeSHA512: - return eqcrypt_sha512(password); - case EncryptionModeSHA512PassUser: - return eqcrypt_sha512(password + ":" + username); - case EncryptionModeSHA512UserPass: - return eqcrypt_sha512(username + ":" + password); - case EncryptionModeSHA512Triple: - return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); +/** + * @param username + * @param password + * @param mode + * @return + */ +std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode) +{ + switch (mode) { + case EncryptionModeMD5: + return eqcrypt_md5(password); + case EncryptionModeMD5PassUser: + return eqcrypt_md5(password + ":" + username); + case EncryptionModeMD5UserPass: + return eqcrypt_md5(username + ":" + password); + case EncryptionModeMD5Triple: + return eqcrypt_md5(eqcrypt_md5(username) + eqcrypt_md5(password)); + case EncryptionModeSHA: + return eqcrypt_sha1(password); + case EncryptionModeSHAPassUser: + return eqcrypt_sha1(password + ":" + username); + case EncryptionModeSHAUserPass: + return eqcrypt_sha1(username + ":" + password); + case EncryptionModeSHATriple: + return eqcrypt_sha1(eqcrypt_sha1(username) + eqcrypt_sha1(password)); + case EncryptionModeSHA512: + return eqcrypt_sha512(password); + case EncryptionModeSHA512PassUser: + return eqcrypt_sha512(password + ":" + username); + case EncryptionModeSHA512UserPass: + return eqcrypt_sha512(username + ":" + password); + case EncryptionModeSHA512Triple: + return eqcrypt_sha512(eqcrypt_sha512(username) + eqcrypt_sha512(password)); #ifdef ENABLE_SECURITY - case EncryptionModeArgon2: - return eqcrypt_argon2(password); - case EncryptionModeSCrypt: - return eqcrypt_scrypt(password); + case EncryptionModeArgon2: + return eqcrypt_argon2(password); + case EncryptionModeSCrypt: + return eqcrypt_scrypt(password); #endif - //todo bcrypt? pbkdf2? - default: - return ""; - break; + //todo bcrypt? pbkdf2? + default: + return ""; + break; } } -bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode) { - switch (mode) - { +/** + * @param username + * @param password + * @param pwhash + * @param mode + * @return + */ +bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode) +{ + switch (mode) { #ifdef ENABLE_SECURITY - case 13: - return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0; - case 14: - return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0; + case 13: + return crypto_pwhash_str_verify(&pwhash[0], &password[0], password.length()) == 0; + case 14: + return crypto_pwhash_scryptsalsa208sha256_str_verify(&pwhash[0], &password[0], password.length()) == 0; #endif - default: - { - auto hash = eqcrypt_hash(username, password, mode); - return hash.compare(pwhash) == 0; - } + default: { + auto hash = eqcrypt_hash(username, password, mode); + return hash.compare(pwhash) == 0; + } } return false; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 217db1a2f..04c9b0735 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -26,6 +26,7 @@ #include "../common/platform.h" #include "../common/crash.h" #include "../common/eqemu_logsys.h" +#include "../common/eqemu_logsys_fmt.h" #include "login_server.h" #include #include @@ -58,10 +59,10 @@ int main() LogSys.log_settings[Logs::Login_Server].log_to_console = Logs::Detail; - Log(Logs::General, Logs::Login_Server, "Logging System Init."); + LogLoginserver("Logging System Init"); server.config = EQ::JsonConfigFile::Load("login.json"); - Log(Logs::General, Logs::Login_Server, "Config System Init."); + LogLoginserver("Config System Init"); server.options.Trace(server.config.GetVariableBool("general", "trace", false)); server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); @@ -131,7 +132,7 @@ int main() /** * mysql connect */ - Log(Logs::General, Logs::Login_Server, "MySQL Database Init."); + LogLoginserver("MySQL Database Init"); server.db = new Database( server.config.GetVariableString("database", "user", "root"), @@ -145,19 +146,19 @@ int main() * make sure our database got created okay, otherwise cleanup and exit */ if (!server.db) { - Log(Logs::General, Logs::Error, "Database Initialization Failure."); - Log(Logs::General, Logs::Login_Server, "Log System Shutdown."); + Error("Database Initialization Failure"); + LogLoginserver("Log System Shutdown"); return 1; } /** * create server manager */ - Log(Logs::General, Logs::Login_Server, "Server Manager Initialize."); + LogLoginserver("Server Manager Init"); server.server_manager = new ServerManager(); if (!server.server_manager) { - Log(Logs::General, Logs::Error, "Server Manager Failed to Start."); - Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); + Error("Server Manager Failed to Start"); + LogLoginserver("Database System Shutdown"); delete server.db; return 1; } @@ -165,14 +166,14 @@ int main() /** * create client manager */ - Log(Logs::General, Logs::Login_Server, "Client Manager Initialize."); + LogLoginserver("Client Manager Init"); server.client_manager = new ClientManager(); if (!server.client_manager) { - Log(Logs::General, Logs::Error, "Client Manager Failed to Start."); - Log(Logs::General, Logs::Login_Server, "Server Manager Shutdown."); + Error("Client Manager Failed to Start"); + LogLoginserver("Server Manager Shutdown"); delete server.server_manager; - Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); + LogLoginserver("Database System Shutdown"); delete server.db; return 1; } @@ -185,14 +186,10 @@ int main() #endif #endif - Log(Logs::General, Logs::Login_Server, "Server Started."); + LogLoginserver("Server Started"); if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) { - Log( - Logs::General, - Logs::Login_Server, - "Loginserver logging set to level [1] for more debugging, enable detail [3]" - ); + LogLoginserver("Loginserver logging set to level [1] for more debugging, enable detail [3]"); } while (run_server) { @@ -202,13 +199,13 @@ int main() Sleep(5); } - Log(Logs::General, Logs::Login_Server, "Server Shutdown."); - Log(Logs::General, Logs::Login_Server, "Client Manager Shutdown."); + LogLoginserver("Server Shutdown"); + LogLoginserver("Client Manager Shutdown"); delete server.client_manager; - Log(Logs::General, Logs::Login_Server, "Server Manager Shutdown."); + LogLoginserver("Server Manager Shutdown"); delete server.server_manager; - Log(Logs::General, Logs::Login_Server, "Database System Shutdown."); + LogLoginserver("Database System Shutdown"); delete server.db; return 0; } diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 533a87c58..61b61a933 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -39,23 +39,27 @@ ServerManager::ServerManager() opts.ipv6 = false; server_connection->Listen(opts); + LogLoginserver("Loginserver now listening on port [{0}]", listen_port); + server_connection->OnConnectionIdentified( - "World", [this](std::shared_ptr c) { - LogF(Logs::General, - Logs::Login_Server, - "New world server connection from {0}:{1}", - c->Handle()->RemoteIP(), - c->Handle()->RemotePort()); + "World", [this](std::shared_ptr world_connection) { + LogLoginserver( + "New world server connection from {0}:{1}", + world_connection->Handle()->RemoteIP(), + world_connection->Handle()->RemotePort() + ); auto iter = world_servers.begin(); while (iter != world_servers.end()) { - if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(c->Handle()->RemoteIP()) == 0 && - (*iter)->GetConnection()->Handle()->RemotePort() == c->Handle()->RemotePort()) { - LogF(Logs::General, - Logs::Login_Server, - "World server already existed for {0}:{1}, removing existing connection.", - c->Handle()->RemoteIP(), - c->Handle()->RemotePort()); + if ((*iter)->GetConnection()->Handle()->RemoteIP().compare(world_connection->Handle()->RemoteIP()) == + 0 && + (*iter)->GetConnection()->Handle()->RemotePort() == world_connection->Handle()->RemotePort()) { + + LogLoginserver( + "World server already existed for {0}:{1}, removing existing connection.", + world_connection->Handle()->RemoteIP(), + world_connection->Handle()->RemotePort() + ); world_servers.erase(iter); break; @@ -64,7 +68,7 @@ ServerManager::ServerManager() ++iter; } - world_servers.push_back(std::unique_ptr(new WorldServer(c))); + world_servers.push_back(std::unique_ptr(new WorldServer(world_connection))); } ); @@ -87,16 +91,18 @@ ServerManager::ServerManager() ); } -ServerManager::~ServerManager() -{ +ServerManager::~ServerManager() = default; -} - -WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port) +/** + * @param ip_address + * @param port + * @return + */ +WorldServer *ServerManager::GetServerByAddress(const std::string &ip_address, int port) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { - if ((*iter)->GetConnection()->Handle()->RemoteIP() == addr && + if ((*iter)->GetConnection()->Handle()->RemoteIP() == ip_address && (*iter)->GetConnection()->Handle()->RemotePort()) { return (*iter).get(); } @@ -106,12 +112,17 @@ WorldServer *ServerManager::GetServerByAddress(const std::string &addr, int port return nullptr; } -EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq) +/** + * @param client + * @param sequence + * @return + */ +EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint32 sequence) { unsigned int packet_size = sizeof(ServerListHeader_Struct); unsigned int server_count = 0; in_addr in; - in.s_addr = c->GetConnection()->GetRemoteIP(); + in.s_addr = client->GetConnection()->GetRemoteIP(); std::string client_ip = inet_ntoa(in); auto iter = world_servers.begin(); @@ -139,7 +150,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer; - server_list->Unknown1 = seq; + server_list->Unknown1 = sequence; server_list->Unknown2 = 0x00000000; server_list->Unknown3 = 0x01650000; @@ -225,6 +236,11 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *c, uint32 seq return outapp; } +/** + * @param server_id + * @param client_account_id + * @param client_loginserver + */ void ServerManager::SendUserToWorldRequest( unsigned int server_id, unsigned int client_account_id, @@ -259,7 +275,17 @@ void ServerManager::SendUserToWorldRequest( } } -bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldServer *ignore) +/** + * @param server_long_name + * @param server_short_name + * @param ignore + * @return + */ +bool ServerManager::ServerExists( + std::string server_long_name, + std::string server_short_name, + WorldServer *ignore +) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { @@ -268,7 +294,7 @@ bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldSe continue; } - if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) { + if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) { return true; } @@ -277,7 +303,16 @@ bool ServerManager::ServerExists(std::string l_name, std::string s_name, WorldSe return false; } -void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore) +/** + * @param server_long_name + * @param server_short_name + * @param ignore + */ +void ServerManager::DestroyServerByName( + std::string server_long_name, + std::string server_short_name, + WorldServer *ignore +) { auto iter = world_servers.begin(); while (iter != world_servers.end()) { @@ -286,7 +321,7 @@ void ServerManager::DestroyServerByName(std::string l_name, std::string s_name, continue; } - if ((*iter)->GetLongName().compare(l_name) == 0 && (*iter)->GetShortName().compare(s_name) == 0) { + if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) { (*iter)->GetConnection()->Handle()->Disconnect(); iter = world_servers.erase(iter); continue; diff --git a/loginserver/server_manager.h b/loginserver/server_manager.h index 5c3390b09..a05590316 100644 --- a/loginserver/server_manager.h +++ b/loginserver/server_manager.h @@ -61,30 +61,30 @@ public: /** * Creates a server list packet for the client * - * @param c - * @param seq + * @param client + * @param sequence * @return */ - EQApplicationPacket *CreateServerListPacket(Client *c, uint32 seq); + EQApplicationPacket *CreateServerListPacket(Client *client, uint32 sequence); /** * Checks to see if there is a server exists with this name, ignoring option * - * @param l_name - * @param s_name + * @param server_long_name + * @param server_short_name * @param ignore * @return */ - bool ServerExists(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); + bool ServerExists(std::string server_long_name, std::string server_short_name, WorldServer *ignore = nullptr); /** * Destroys a server with this name, ignoring option * - * @param l_name - * @param s_name + * @param server_long_name + * @param server_short_name * @param ignore */ - void DestroyServerByName(std::string l_name, std::string s_name, WorldServer *ignore = nullptr); + void DestroyServerByName(std::string server_long_name, std::string server_short_name, WorldServer *ignore = nullptr); private: @@ -92,11 +92,11 @@ private: * Retrieves a server(if exists) by ip address * Useful utility for the reconnect process * - * @param address + * @param ip_address * @param port * @return */ - WorldServer *GetServerByAddress(const std::string &address, int port); + WorldServer *GetServerByAddress(const std::string &ip_address, int port); std::unique_ptr server_connection; std::list> world_servers; diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 57b0f18a2..1c5e01b4e 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -27,9 +27,12 @@ extern LoginServer server; -WorldServer::WorldServer(std::shared_ptr c) +/** + * @param worldserver_connection + */ +WorldServer::WorldServer(std::shared_ptr worldserver_connection) { - connection = c; + connection = worldserver_connection; zones_booted = 0; players_online = 0; server_status = 0; @@ -40,17 +43,17 @@ WorldServer::WorldServer(std::shared_ptr c) is_server_trusted = false; is_server_logged_in = false; - c->OnMessage( + worldserver_connection->OnMessage( ServerOP_NewLSInfo, std::bind(&WorldServer::ProcessNewLSInfo, this, std::placeholders::_1, std::placeholders::_2) ); - c->OnMessage( + worldserver_connection->OnMessage( ServerOP_LSStatus, std::bind(&WorldServer::ProcessLSStatus, this, std::placeholders::_1, std::placeholders::_2) ); - c->OnMessage( + worldserver_connection->OnMessage( ServerOP_UsertoWorldRespLeg, std::bind( &WorldServer::ProcessUsertoWorldRespLeg, @@ -60,49 +63,50 @@ WorldServer::WorldServer(std::shared_ptr c) ) ); - c->OnMessage( + worldserver_connection->OnMessage( ServerOP_UsertoWorldResp, - std::bind(&WorldServer::ProcessUsertoWorldResp, this, std::placeholders::_1, std::placeholders::_2) + std::bind(&WorldServer::ProcessUserToWorldResponse, this, std::placeholders::_1, std::placeholders::_2) ); - c->OnMessage( + worldserver_connection->OnMessage( ServerOP_LSAccountUpdate, std::bind(&WorldServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2) ); } -WorldServer::~WorldServer() -{ - -} +WorldServer::~WorldServer() = default; void WorldServer::Reset() { - zones_booted = 0; - players_online = 0; - server_status = 0; runtime_id; + zones_booted = 0; + players_online = 0; + server_status = 0; server_list_id = 0; server_type = 0; is_server_authorized = false; is_server_logged_in = false; } -void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) +/** + * @param opcode + * @param packet + */ +void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, - p.Length()); + packet.Length()); } if (server.options.IsDumpInPacketsOn()) { - DumpPacket(opcode, p); + DumpPacket(opcode, packet); } - if (p.Length() < sizeof(ServerNewLSInfo_Struct)) { + if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) { Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_NewLSInfo, " "but was too small. Discarded to avoid buffer overrun."); @@ -110,7 +114,7 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) } - ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) p.Data(); + ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) packet.Data(); LogF( Logs::General, @@ -139,21 +143,25 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p) Handle_NewLSInfo(info); } -void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) +/** + * @param opcode + * @param packet + */ +void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet) { Log( Logs::Detail, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, - p.Length() + packet.Length() ); if (server.options.IsDumpInPacketsOn()) { - DumpPacket(opcode, p); + DumpPacket(opcode, packet); } - if (p.Length() < sizeof(ServerLSStatus_Struct)) { + if (packet.Length() < sizeof(ServerLSStatus_Struct)) { Log( Logs::General, Logs::Error, @@ -163,11 +171,9 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) return; } - ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) p.Data(); + ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) packet.Data(); - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", this->GetLongName(), ls_status->status, @@ -178,21 +184,25 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p) Handle_LSStatus(ls_status); } -void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p) +/** + * @param opcode + * @param packet + */ +void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, - p.Length()); + packet.Length()); } if (server.options.IsDumpInPacketsOn()) { - DumpPacket(opcode, p); + DumpPacket(opcode, packet); } - if (p.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { + if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " @@ -207,7 +217,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) p.Data(); + UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); if (c) { @@ -276,28 +286,32 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack delete outapp; } else { - Log(Logs::General, - Logs::Error, - "Received User-To-World Response for %u but could not find the client referenced!.", - user_to_world_response->lsaccountid); + Error( + "Received User-To-World Response for {0} but could not find the client referenced!", + user_to_world_response->lsaccountid + ); } } -void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p) +/** + * @param opcode + * @param packet + */ +void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, - p.Length()); + packet.Length()); } if (server.options.IsDumpInPacketsOn()) { - DumpPacket(opcode, p); + DumpPacket(opcode, packet); } - if (p.Length() < sizeof(UsertoWorldResponse_Struct)) { + if (packet.Length() < sizeof(UsertoWorldResponse_Struct)) { Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " @@ -312,7 +326,7 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) p.Data(); + UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) packet.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); if (c) { @@ -387,23 +401,23 @@ void WorldServer::ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet /** * @param opcode - * @param p + * @param packet */ -void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p) +void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { Log(Logs::General, Logs::Netcode, "Application packet received from server: 0x%.4X, (size %u)", opcode, - p.Length()); + packet.Length()); } if (server.options.IsDumpInPacketsOn()) { - DumpPacket(opcode, p); + DumpPacket(opcode, packet); } - if (p.Length() < sizeof(ServerLSAccountUpdate_Struct)) { + if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) { Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " @@ -412,7 +426,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); - ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) p.Data(); + ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) packet.Data(); if (is_server_trusted) { Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); std::string name = ""; @@ -429,74 +443,70 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } } -void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) +void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_packet) { if (is_server_logged_in) { - Log(Logs::General, - Logs::Error, - "WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); + Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); return; } - if (strlen(i->account) <= 30) { - account_name = i->account; + if (strlen(new_worldserver_info_packet->account) <= 30) { + account_name = new_worldserver_info_packet->account; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account name was too long."); + Error("Handle_NewLSInfo error, account name was too long."); return; } - if (strlen(i->password) <= 30) { - account_password = i->password; + if (strlen(new_worldserver_info_packet->password) <= 30) { + account_password = new_worldserver_info_packet->password; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, account password was too long."); + Error("Handle_NewLSInfo error, account password was too long."); return; } - if (strlen(i->name) <= 200) { - long_name = i->name; + if (strlen(new_worldserver_info_packet->name) <= 200) { + long_name = new_worldserver_info_packet->name; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, long name was too long."); + Error("Handle_NewLSInfo error, long name was too long."); return; } - if (strlen(i->shortname) <= 50) { - short_name = i->shortname; + if (strlen(new_worldserver_info_packet->shortname) <= 50) { + short_name = new_worldserver_info_packet->shortname; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, short name was too long."); + Error("Handle_NewLSInfo error, short name was too long."); return; } - if (strlen(i->local_address) <= 125) { - if (strlen(i->local_address) == 0) { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was null, defaulting to localhost"); + if (strlen(new_worldserver_info_packet->local_address) <= 125) { + if (strlen(new_worldserver_info_packet->local_address) == 0) { + Error("Handle_NewLSInfo error, local address was null, defaulting to localhost"); local_ip = "127.0.0.1"; } else { - local_ip = i->local_address; + local_ip = new_worldserver_info_packet->local_address; } } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, local address was too long."); + Error("Handle_NewLSInfo error, local address was too long."); return; } - if (strlen(i->remote_address) <= 125) { - if (strlen(i->remote_address) == 0) { + if (strlen(new_worldserver_info_packet->remote_address) <= 125) { + if (strlen(new_worldserver_info_packet->remote_address) == 0) { remote_ip = GetConnection()->Handle()->RemoteIP(); - Log( - Logs::General, - Logs::Error, + Error( "Remote address was null, defaulting to stream address %s.", remote_ip.c_str() ); } else { - remote_ip = i->remote_address; + remote_ip = new_worldserver_info_packet->remote_address; } } else { @@ -510,23 +520,23 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) ); } - if (strlen(i->serverversion) <= 64) { - version = i->serverversion; + if (strlen(new_worldserver_info_packet->serverversion) <= 64) { + version = new_worldserver_info_packet->serverversion; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, server version was too long."); + Error("Handle_NewLSInfo error, server version was too long."); return; } - if (strlen(i->protocolversion) <= 25) { - protocol = i->protocolversion; + if (strlen(new_worldserver_info_packet->protocolversion) <= 25) { + protocol = new_worldserver_info_packet->protocolversion; } else { - Log(Logs::General, Logs::Error, "Handle_NewLSInfo error, protocol version was too long."); + Error("Handle_NewLSInfo error, protocol version was too long."); return; } - server_type = i->servertype; + server_type = new_worldserver_info_packet->servertype; is_server_logged_in = true; if (server.options.IsRejectingDuplicateServers()) { @@ -715,13 +725,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *i) } /** - * @param s + * @param server_login_status */ -void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *s) +void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *server_login_status) { - players_online = s->num_players; - zones_booted = s->num_zones; - server_status = s->status; + players_online = server_login_status->num_players; + zones_booted = server_login_status->num_zones; + server_status = server_login_status->status; } /** @@ -752,8 +762,8 @@ void WorldServer::SendClientAuth( client_auth.ip = inet_addr(ip.c_str()); strncpy(client_auth.lsname, &loginserver_name[0], 64); - const std::string& client_address(ip); - std::string world_address(connection->Handle()->RemoteIP()); + const std::string &client_address(ip); + std::string world_address(connection->Handle()->RemoteIP()); if (client_address.compare(world_address) == 0) { client_auth.local = 1; diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 60eb7baae..35c187ae0 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -34,7 +34,7 @@ class WorldServer { public: - WorldServer(std::shared_ptr c); + WorldServer(std::shared_ptr worldserver_connection); /** * Destructor, frees our connection if it exists @@ -77,16 +77,16 @@ public: /** * Takes the info struct we received from world and processes it * - * @param i + * @param new_worldserver_info_packet */ - void Handle_NewLSInfo(ServerNewLSInfo_Struct* i); + void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_worldserver_info_packet); /** * Takes the status struct we received from world and processes it * - * @param s + * @param server_login_status */ - void Handle_LSStatus(ServerLSStatus_Struct *s); + void Handle_LSStatus(ServerLSStatus_Struct *server_login_status); /** * Informs world that there is a client incoming with the following data. @@ -105,13 +105,13 @@ private: * Packet processing functions * * @param opcode - * @param p + * @param packet */ - void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &p); - void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &p); - void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &p); - void ProcessUsertoWorldResp(uint16_t opcode, const EQ::Net::Packet &p); - void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &p); + void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet); + void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet); + void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet); + void ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet); + void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet); std::shared_ptr connection; unsigned int zones_booted; From 2c922876a9e474a19553d0a7a8e14e1238106b9a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 02:49:55 -0500 Subject: [PATCH 043/491] More loginserver refactorings and cleanup --- loginserver/client_manager.cpp | 35 +++++--- loginserver/config.cpp | 14 ++-- loginserver/login_server.h | 2 +- loginserver/main.cpp | 2 +- loginserver/server_manager.cpp | 20 +++-- loginserver/world_server.cpp | 143 ++++++++++++++++++--------------- loginserver/world_server.h | 4 +- 7 files changed, 129 insertions(+), 91 deletions(-) diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 210cf5824..d6cc6f5eb 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -29,8 +29,10 @@ extern bool run_server; ClientManager::ClientManager() { - int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); + int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); + EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); + titanium_stream = new EQ::Net::EQStreamManager(titanium_opts); titanium_ops = new RegularOpcodeManager; if (!titanium_ops->LoadOpcodes( @@ -39,8 +41,12 @@ ClientManager::ClientManager() "opcodes", "login_opcodes.conf" ).c_str())) { - Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for Titanium file %s.", - server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf").c_str()); + + Error( + "ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]", + server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf") + ); + run_server = false; } @@ -57,7 +63,8 @@ ClientManager::ClientManager() } ); - int sod_port = server.config.GetVariableInt("SoD", "port", 5999); + int sod_port = server.config.GetVariableInt("SoD", "port", 5999); + EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false); sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; @@ -69,11 +76,12 @@ ClientManager::ClientManager() sod_stream->OnNewConnection( [this](std::shared_ptr stream) { - LogF(Logs::General, - Logs::Login_Server, - "New SoD client connection from {0}:{1}", - stream->GetRemoteIP(), - stream->GetRemotePort()); + LogLoginserver( + "New SoD client connection from {0}:{1}", + stream->GetRemoteIP(), + stream->GetRemotePort() + ); + stream->SetOpcodeManager(&sod_ops); Client *c = new Client(stream, cv_sod); clients.push_back(c); @@ -133,6 +141,10 @@ void ClientManager::ProcessDisconnect() } } +/** + * @param account_id + * @param loginserver + */ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::string &loginserver) { auto iter = clients.begin(); @@ -150,6 +162,11 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str } } +/** + * @param account_id + * @param loginserver + * @return + */ Client *ClientManager::GetClient(unsigned int account_id, const std::string &loginserver) { auto iter = clients.begin(); diff --git a/loginserver/config.cpp b/loginserver/config.cpp index f9dc32fba..6964c13ff 100644 --- a/loginserver/config.cpp +++ b/loginserver/config.cpp @@ -20,6 +20,7 @@ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" +#include "../common/eqemu_logsys_fmt.h" #include "config.h" /** @@ -52,7 +53,7 @@ std::string Config::GetVariable(std::string title, std::string parameter) void Config::Parse(const char *file_name) { if (file_name == nullptr) { - Log(Logs::General, Logs::Error, "Config::Parse(), file_name passed was null."); + Error("Config::Parse(), file_name passed was null"); return; } @@ -62,8 +63,9 @@ void Config::Parse(const char *file_name) std::list tokens; Tokenize(input, tokens); - char mode = 0; - std::string title, param, arg; + char mode = 0; + std::string title, param, arg; + std::list::iterator iter = tokens.begin(); while (iter != tokens.end()) { if ((*iter).compare("[") == 0) { @@ -71,7 +73,7 @@ void Config::Parse(const char *file_name) bool first = true; ++iter; if (iter == tokens.end()) { - Log(Logs::General, Logs::Error, "Config::Parse(), EOF before title done parsing."); + Error("Config::Parse(), EOF before title done parsing"); fclose(input); vars.clear(); return; @@ -98,7 +100,7 @@ void Config::Parse(const char *file_name) else if (mode == 1) { mode++; if ((*iter).compare("=") != 0) { - Log(Logs::General, Logs::Error, "Config::Parse(), invalid parse token where = should be."); + Error("Config::Parse(), invalid parse token where = should be"); fclose(input); vars.clear(); return; @@ -123,7 +125,7 @@ void Config::Parse(const char *file_name) fclose(input); } else { - Log(Logs::General, Logs::Error, "Config::Parse(), file was unable to be opened for parsing."); + Error("Config::Parse(), file was unable to be opened for parsing"); } } diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 36ce7460c..1ab0fee76 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -41,7 +41,7 @@ public: Database *db; Options options; ServerManager *server_manager; - ClientManager *client_manager; + ClientManager *client_manager{}; }; #endif diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 04c9b0735..26a32578f 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -196,7 +196,7 @@ int main() Timer::SetCurrentTime(); server.client_manager->Process(); EQ::EventLoop::Get().Process(); - Sleep(5); + Sleep(50); } LogLoginserver("Server Shutdown"); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 61b61a933..df0428feb 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -148,8 +148,9 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 ++iter; } - EQApplicationPacket *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); - ServerListHeader_Struct *server_list = (ServerListHeader_Struct *) outapp->pBuffer; + auto *outapp = new EQApplicationPacket(OP_ServerListResponse, packet_size); + auto *server_list = (ServerListHeader_Struct *) outapp->pBuffer; + server_list->Unknown1 = sequence; server_list->Unknown2 = 0x00000000; server_list->Unknown3 = 0x01650000; @@ -253,10 +254,11 @@ void ServerManager::SendUserToWorldRequest( if ((*iter)->GetRuntimeID() == server_id) { EQ::Net::DynamicPacket outapp; outapp.Resize(sizeof(UsertoWorldRequest_Struct)); - UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) outapp.Data(); - utwr->worldid = server_id; - utwr->lsaccountid = client_account_id; - strncpy(utwr->login, &client_loginserver[0], 64); + + auto *user_to_world_request = (UsertoWorldRequest_Struct *) outapp.Data(); + user_to_world_request->worldid = server_id; + user_to_world_request->lsaccountid = client_account_id; + strncpy(user_to_world_request->login, &client_loginserver[0], 64); (*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp); found = true; @@ -294,7 +296,8 @@ bool ServerManager::ServerExists( continue; } - if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) { + if ((*iter)->GetLongName().compare(server_long_name) == 0 && + (*iter)->GetShortName().compare(server_short_name) == 0) { return true; } @@ -321,7 +324,8 @@ void ServerManager::DestroyServerByName( continue; } - if ((*iter)->GetLongName().compare(server_long_name) == 0 && (*iter)->GetShortName().compare(server_short_name) == 0) { + if ((*iter)->GetLongName().compare(server_long_name) == 0 && + (*iter)->GetShortName().compare(server_short_name) == 0) { (*iter)->GetConnection()->Handle()->Disconnect(); iter = world_servers.erase(iter); continue; diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 1c5e01b4e..f8c848123 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -162,16 +162,14 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet } if (packet.Length() < sizeof(ServerLSStatus_Struct)) { - Log( - Logs::General, - Logs::Error, + Error( "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" ); return; } - ServerLSStatus_Struct *ls_status = (ServerLSStatus_Struct *) packet.Data(); + auto *ls_status = (ServerLSStatus_Struct *) packet.Data(); LogLoginserverDetail( "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", @@ -203,10 +201,10 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack } if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { - Log(Logs::General, - Logs::Error, + Error( "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " - "but was too small. Discarded to avoid buffer overrun."); + "but was too small. Discarded to avoid buffer overrun" + ); return; } @@ -217,7 +215,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponseLegacy_Struct *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); + auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); if (c) { @@ -229,12 +227,12 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack c->GetAccountName().c_str() ); - EQApplicationPacket *outapp = new EQApplicationPacket( + auto *outapp = new EQApplicationPacket( OP_PlayEverquestResponse, sizeof(PlayEverquestResponse_Struct) ); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; + auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; per->Sequence = c->GetPlaySequence(); per->ServerNumber = c->GetPlayServerID(); @@ -326,36 +324,49 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac Log(Logs::General, Logs::Netcode, "User-To-World Response received."); } - UsertoWorldResponse_Struct *utwr = (UsertoWorldResponse_Struct *) packet.Data(); - Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", utwr->lsaccountid); - Client *c = server.client_manager->GetClient(utwr->lsaccountid, utwr->login); - if (c) { + auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data(); + Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); + Client *client = server.client_manager->GetClient( + user_to_world_response->lsaccountid, + user_to_world_response->login + ); + if (client) { Log(Logs::General, Logs::Debug, "Found client with user id of %u and account name of %s.", - utwr->lsaccountid, - c->GetAccountName().c_str()); - EQApplicationPacket *outapp = new EQApplicationPacket( + user_to_world_response->lsaccountid, + client->GetAccountName().c_str() + ); + + auto *outapp = new EQApplicationPacket( OP_PlayEverquestResponse, - sizeof(PlayEverquestResponse_Struct)); - PlayEverquestResponse_Struct *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; - per->Sequence = c->GetPlaySequence(); - per->ServerNumber = c->GetPlayServerID(); - Log(Logs::General, Logs::Debug, "Found sequence and play of %u %u", c->GetPlaySequence(), c->GetPlayServerID()); + sizeof(PlayEverquestResponse_Struct) + ); + + auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; + per->Sequence = client->GetPlaySequence(); + per->ServerNumber = client->GetPlayServerID(); + Log(Logs::General, + Logs::Debug, + "Found sequence and play of %u %u", + client->GetPlaySequence(), + client->GetPlayServerID() + ); Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); - if (utwr->response > 0) { + if (user_to_world_response->response > 0) { per->Allowed = 1; SendClientAuth( - c->GetConnection()->GetRemoteAddr(), - c->GetAccountName(), - c->GetKey(), - c->GetAccountID(), - c->GetLoginServerName()); + client->GetConnection()->GetRemoteAddr(), + client->GetAccountName(), + client->GetKey(), + client->GetAccountID(), + client->GetLoginServerName() + ); } - switch (utwr->response) { + switch (user_to_world_response->response) { case 1: per->Message = 101; break; @@ -388,14 +399,12 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac DumpPacket(outapp); } - c->SendPlayResponse(outapp); + client->SendPlayResponse(outapp); delete outapp; } else { - Log(Logs::General, - Logs::Error, - "Received User-To-World Response for %u but could not find the client referenced!.", - utwr->lsaccountid); + Error("Received User-To-World Response for {0} but could not find the client referenced!.", + user_to_world_response->lsaccountid); } } @@ -418,77 +427,83 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) { - Log(Logs::General, - Logs::Error, + Error( "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " - "but was too small. Discarded to avoid buffer overrun."); + "but was too small. Discarded to avoid buffer overrun" + ); + return; } Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); - ServerLSAccountUpdate_Struct *lsau = (ServerLSAccountUpdate_Struct *) packet.Data(); + + auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data(); if (is_server_trusted) { - Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", lsau->useraccount); + Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", loginserver_update->useraccount); std::string name = ""; std::string password = ""; std::string email = ""; - name.assign(lsau->useraccount); - password.assign(lsau->userpassword); + name.assign(loginserver_update->useraccount); + password.assign(loginserver_update->userpassword); - if (lsau->useremail) { - email.assign(lsau->useremail); + if (loginserver_update->useremail) { + email.assign(loginserver_update->useremail); } - server.db->UpdateLSAccountInfo(lsau->useraccountid, name, password, email); + server.db->UpdateLSAccountInfo(loginserver_update->useraccountid, name, password, email); } } -void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_packet) +/** + * + * @param new_world_server_info_packet + */ +void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info_packet) { if (is_server_logged_in) { Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); return; } - if (strlen(new_worldserver_info_packet->account) <= 30) { - account_name = new_worldserver_info_packet->account; + if (strlen(new_world_server_info_packet->account) <= 30) { + account_name = new_world_server_info_packet->account; } else { Error("Handle_NewLSInfo error, account name was too long."); return; } - if (strlen(new_worldserver_info_packet->password) <= 30) { - account_password = new_worldserver_info_packet->password; + if (strlen(new_world_server_info_packet->password) <= 30) { + account_password = new_world_server_info_packet->password; } else { Error("Handle_NewLSInfo error, account password was too long."); return; } - if (strlen(new_worldserver_info_packet->name) <= 200) { - long_name = new_worldserver_info_packet->name; + if (strlen(new_world_server_info_packet->name) <= 200) { + long_name = new_world_server_info_packet->name; } else { Error("Handle_NewLSInfo error, long name was too long."); return; } - if (strlen(new_worldserver_info_packet->shortname) <= 50) { - short_name = new_worldserver_info_packet->shortname; + if (strlen(new_world_server_info_packet->shortname) <= 50) { + short_name = new_world_server_info_packet->shortname; } else { Error("Handle_NewLSInfo error, short name was too long."); return; } - if (strlen(new_worldserver_info_packet->local_address) <= 125) { - if (strlen(new_worldserver_info_packet->local_address) == 0) { + if (strlen(new_world_server_info_packet->local_address) <= 125) { + if (strlen(new_world_server_info_packet->local_address) == 0) { Error("Handle_NewLSInfo error, local address was null, defaulting to localhost"); local_ip = "127.0.0.1"; } else { - local_ip = new_worldserver_info_packet->local_address; + local_ip = new_world_server_info_packet->local_address; } } else { @@ -497,8 +512,8 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_ return; } - if (strlen(new_worldserver_info_packet->remote_address) <= 125) { - if (strlen(new_worldserver_info_packet->remote_address) == 0) { + if (strlen(new_world_server_info_packet->remote_address) <= 125) { + if (strlen(new_world_server_info_packet->remote_address) == 0) { remote_ip = GetConnection()->Handle()->RemoteIP(); Error( "Remote address was null, defaulting to stream address %s.", @@ -506,7 +521,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_ ); } else { - remote_ip = new_worldserver_info_packet->remote_address; + remote_ip = new_world_server_info_packet->remote_address; } } else { @@ -520,23 +535,23 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_worldserver_info_ ); } - if (strlen(new_worldserver_info_packet->serverversion) <= 64) { - version = new_worldserver_info_packet->serverversion; + if (strlen(new_world_server_info_packet->serverversion) <= 64) { + version = new_world_server_info_packet->serverversion; } else { Error("Handle_NewLSInfo error, server version was too long."); return; } - if (strlen(new_worldserver_info_packet->protocolversion) <= 25) { - protocol = new_worldserver_info_packet->protocolversion; + if (strlen(new_world_server_info_packet->protocolversion) <= 25) { + protocol = new_world_server_info_packet->protocolversion; } else { Error("Handle_NewLSInfo error, protocol version was too long."); return; } - server_type = new_worldserver_info_packet->servertype; + server_type = new_world_server_info_packet->servertype; is_server_logged_in = true; if (server.options.IsRejectingDuplicateServers()) { diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 35c187ae0..26cc2762f 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -77,9 +77,9 @@ public: /** * Takes the info struct we received from world and processes it * - * @param new_worldserver_info_packet + * @param new_world_server_info_packet */ - void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_worldserver_info_packet); + void Handle_NewLSInfo(ServerNewLSInfo_Struct* new_world_server_info_packet); /** * Takes the status struct we received from world and processes it From feea52f79ed0aec52a3d97c117568b5226f2e739 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 03:38:12 -0500 Subject: [PATCH 044/491] Make loginserver intelligently determine if the client is requesting from a RFC 1918 network instead of using a config string match --- common/CMakeLists.txt | 2 + common/data_verification.h | 68 +++++++++++++++++--------------- common/ip_util.cpp | 72 ++++++++++++++++++++++++++++++++++ common/ip_util.h | 36 +++++++++++++++++ loginserver/main.cpp | 1 - loginserver/options.h | 10 ----- loginserver/server_manager.cpp | 6 ++- loginserver/world_server.cpp | 12 +++--- 8 files changed, 155 insertions(+), 52 deletions(-) create mode 100644 common/ip_util.cpp create mode 100644 common/ip_util.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 2c94d618a..a1c2c51a2 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -35,6 +35,7 @@ SET(common_sources inventory_profile.cpp inventory_slot.cpp ipc_mutex.cpp + ip_util.cpp item_data.cpp item_instance.cpp json_config.cpp @@ -159,6 +160,7 @@ SET(common_headers inventory_profile.h inventory_slot.h ipc_mutex.h + ip_util.h item_data.h item_fieldlist.h item_instance.h diff --git a/common/data_verification.h b/common/data_verification.h index 27ad017a9..c56f3ce04 100644 --- a/common/data_verification.h +++ b/common/data_verification.h @@ -1,53 +1,57 @@ -/* EQEMu: Everquest Server Emulator - - Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ #pragma once #include #include -namespace EQEmu -{ - template - T Clamp(const T& value, const T& lower, const T& upper) { +namespace EQEmu { + template + T Clamp(const T &value, const T &lower, const T &upper) + { return std::max(lower, std::min(value, upper)); } - template - T ClampLower(const T& value, const T& lower) { + template + T ClampLower(const T &value, const T &lower) + { return std::max(lower, value); } - template - T ClampUpper(const T& value, const T& upper) { + template + T ClampUpper(const T &value, const T &upper) + { return std::min(value, upper); } - template - bool ValueWithin(const T& value, const T& lower, const T& upper) { + template + bool ValueWithin(const T &value, const T &lower, const T &upper) + { return value >= lower && value <= upper; } - template - bool ValueWithin(const T1& value, const T2& lower, const T3& upper) { - return value >= (T1)lower && value <= (T1)upper; + template + bool ValueWithin(const T1 &value, const T2 &lower, const T3 &upper) + { + return value >= (T1) lower && value <= (T1) upper; } - } /*EQEmu*/ diff --git a/common/ip_util.cpp b/common/ip_util.cpp new file mode 100644 index 000000000..e1f5d0794 --- /dev/null +++ b/common/ip_util.cpp @@ -0,0 +1,72 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "ip_util.h" + +/** + * @param ip + * @return + */ +uint32_t IpUtil::IPToUInt(const std::string &ip) +{ + int a, b, c, d; + uint32_t addr = 0; + + if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4) { + return 0; + } + + addr = a << 24; + addr |= b << 16; + addr |= c << 8; + addr |= d; + return addr; +} + +/** + * @param ip + * @param network + * @param mask + * @return + */ +bool IpUtil::IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask) +{ + uint32_t ip_addr = IpUtil::IPToUInt(ip); + uint32_t network_addr = IpUtil::IPToUInt(network); + uint32_t mask_addr = IpUtil::IPToUInt(mask); + + uint32_t net_lower = (network_addr & mask_addr); + uint32_t net_upper = (net_lower | (~mask_addr)); + + return ip_addr >= net_lower && ip_addr <= net_upper; +} + +/** + * @param ip + * @return + */ +bool IpUtil::IsIpInPrivateRfc1918(const std::string &ip) +{ + return ( + IpUtil::IsIpInRange(ip, "10.0.0.0", "255.0.0.0") || + IpUtil::IsIpInRange(ip, "172.16.0.0", "255.240.0.0") || + IpUtil::IsIpInRange(ip, "192.168.0.0", "255.255.0.0") + ); +} diff --git a/common/ip_util.h b/common/ip_util.h new file mode 100644 index 000000000..76ea33fdb --- /dev/null +++ b/common/ip_util.h @@ -0,0 +1,36 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef EQEMU_IP_UTIL_H +#define EQEMU_IP_UTIL_H + +#include "types.h" +#include "iostream" + +class IpUtil { +public: + + static uint32_t IPToUInt(const std::string &ip); + static bool IsIpInRange(const std::string &ip, const std::string &network, const std::string &mask); + static bool IsIpInPrivateRfc1918(const std::string &ip); + +}; + +#endif //EQEMU_IP_UTIL_H \ No newline at end of file diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 26a32578f..3a9accbd8 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -68,7 +68,6 @@ int main() server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); server.options.DumpInPackets(server.config.GetVariableBool("general", "dump_packets_in", false)); server.options.DumpOutPackets(server.config.GetVariableBool("general", "dump_packets_out", false)); - server.options.LocalNetwork(server.config.GetVariableString("general", "local_network", "192.168.1.")); server.options.RejectDuplicateServers(server.config.GetVariableBool("general", "reject_duplicate_servers", false)); server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", true)); diff --git a/loginserver/options.h b/loginserver/options.h index aeeed6731..00abd7abf 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -103,16 +103,6 @@ public: */ inline int GetEncryptionMode() const { return encryption_mode; } - /** - * Sets local_network. - */ - inline void LocalNetwork(std::string n) { local_network = n; } - - /** - * Return the value of local_network. - */ - inline std::string GetLocalNetwork() const { return local_network; } - /** * Sets account table. */ diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index df0428feb..9b584e2fe 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -25,6 +25,7 @@ #include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys_fmt.h" +#include "../common/ip_util.h" extern LoginServer server; extern bool run_server; @@ -137,7 +138,8 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 if (world_ip.compare(client_ip) == 0) { packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } - else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) { + else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) { + LogLoginserver("Client is requesting server list from a local address [{0}]", client_ip); packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } else { @@ -177,7 +179,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size()); data_pointer += ((*iter)->GetLocalIP().size() + 1); } - else if (client_ip.find(server.options.GetLocalNetwork()) != std::string::npos) { + else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) { memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size()); data_pointer += ((*iter)->GetLocalIP().size() + 1); } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index f8c848123..d50cf6ccc 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -24,6 +24,7 @@ #include "config.h" #include "../common/eqemu_logsys.h" #include "../common/eqemu_logsys_fmt.h" +#include "../common/ip_util.h" extern LoginServer server; @@ -556,17 +557,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info if (server.options.IsRejectingDuplicateServers()) { if (server.server_manager->ServerExists(long_name, short_name, this)) { - Log(Logs::General, - Logs::Error, - "World tried to login but there already exists a server that has that name."); + Error("World tried to login but there already exists a server that has that name"); return; } } else { if (server.server_manager->ServerExists(long_name, short_name, this)) { - Log(Logs::General, - Logs::Error, - "World tried to login but there already exists a server that has that name."); + Error("World tried to login but there already exists a server that has that name"); server.server_manager->DestroyServerByName(long_name, short_name, this); } } @@ -783,7 +780,8 @@ void WorldServer::SendClientAuth( if (client_address.compare(world_address) == 0) { client_auth.local = 1; } - else if (client_address.find(server.options.GetLocalNetwork()) != std::string::npos) { + else if (IpUtil::IsIpInPrivateRfc1918(client_address)) { + LogLoginserver("Client is authenticating from a local address [{0}]", client_address); client_auth.local = 1; } else { From ffd652a64326e33137feef4d4388b8f1b232236a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 03:50:01 -0500 Subject: [PATCH 045/491] Load log settings from the database --- common/database.cpp | 3 +- loginserver/database.cpp | 97 ++++++++++++++++++++++++++++++++++-- loginserver/database.h | 2 + loginserver/main.cpp | 13 +---- loginserver/world_server.cpp | 34 +++++++------ 5 files changed, 117 insertions(+), 32 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 7798cc812..0e5ed3ae5 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2065,7 +2065,8 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id) return atoi(row[0]); } -void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) { +void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) +{ // log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults() std::string query = diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 8709fe365..da501e783 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -164,10 +164,10 @@ bool Database::GetLoginTokenDataFromToken( return false; } - bool found_username = false; - bool found_login_id = false; - bool found_login_server_name = false; - for (auto row = results.begin(); row != results.end(); ++row) { + bool found_username = false; + bool found_login_id = false; + bool found_login_server_name = false; + for (auto row = results.begin(); row != results.end(); ++row) { if (strcmp(row[2], "username") == 0) { user = row[3]; found_username = true; @@ -508,3 +508,92 @@ bool Database::CreateWorldRegistration(std::string long_name, std::string short_ return true; } + +/** + * @param log_settings + */ +void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) +{ + std::string query = + "SELECT " + "log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay " + "FROM " + "logsys_categories " + "ORDER BY log_category_id"; + + auto results = QueryDatabase(query); + + int log_category_id = 0; + + int categories_in_database[1000] = {}; + + for (auto row = results.begin(); row != results.end(); ++row) { + log_category_id = atoi(row[0]); + if (log_category_id <= Logs::None || log_category_id >= Logs::MaxCategoryID) { + continue; + } + + log_settings[log_category_id].log_to_console = static_cast(atoi(row[2])); + log_settings[log_category_id].log_to_file = static_cast(atoi(row[3])); + log_settings[log_category_id].log_to_gmsay = static_cast(atoi(row[4])); + + /** + * Determine if any output method is enabled for the category + * and set it to 1 so it can used to check if category is enabled + */ + const bool log_to_console = log_settings[log_category_id].log_to_console > 0; + const bool log_to_file = log_settings[log_category_id].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0; + const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay; + + if (is_category_enabled) { + log_settings[log_category_id].is_category_enabled = 1; + } + + /** + * This determines whether or not the process needs to actually file log anything. + * If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open + */ + if (log_settings[log_category_id].log_to_file > 0) { + LogSys.file_logs_enabled = true; + } + + categories_in_database[log_category_id] = 1; + } + + /** + * Auto inject categories that don't exist in the database... + */ + for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { + if (!categories_in_database[log_index]) { + + Log(Logs::General, + Logs::Status, + "New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...", + Logs::LogCategoryName[log_index] + ); + + std::string inject_query = StringFormat( + "INSERT INTO logsys_categories " + "(log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay) " + "VALUES " + "(%i, '%s', %i, %i, %i)", + log_index, + EscapeString(Logs::LogCategoryName[log_index]).c_str(), + log_settings[log_category_id].log_to_console, + log_settings[log_category_id].log_to_file, + log_settings[log_category_id].log_to_gmsay + ); + + QueryDatabase(inject_query); + } + } +} \ No newline at end of file diff --git a/loginserver/database.h b/loginserver/database.h index dab6de6ef..97e80f073 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -22,6 +22,7 @@ #define EQEMU_DATABASEMYSQL_H #include "../common/dbcore.h" +#include "../common/eqemu_logsys.h" #include #include @@ -126,6 +127,7 @@ public: void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email); void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); + void LoadLogSettings(EQEmuLogSys::LogSettings *log_settings); protected: std::string user, pass, host, port, name; MYSQL *database; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 3a9accbd8..21efd91bf 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -48,17 +48,6 @@ int main() LogSys.LoadLogSettingsDefaults(); - LogSys.log_settings[Logs::Error].log_to_console = Logs::General; - LogSys.log_settings[Logs::Error].is_category_enabled = 1; - LogSys.log_settings[Logs::MySQLError].log_to_console = Logs::General; - LogSys.log_settings[Logs::MySQLError].is_category_enabled = 1; - LogSys.log_settings[Logs::MySQLQuery].log_to_console = Logs::General; - LogSys.log_settings[Logs::MySQLQuery].is_category_enabled = 1; - LogSys.log_settings[Logs::Netcode].log_to_console = Logs::General; - LogSys.log_settings[Logs::Netcode].is_category_enabled = Logs::General; - - LogSys.log_settings[Logs::Login_Server].log_to_console = Logs::Detail; - LogLoginserver("Logging System Init"); server.config = EQ::JsonConfigFile::Load("login.json"); @@ -141,6 +130,8 @@ int main() server.config.GetVariableString("database", "db", "peq") ); + server.db->LoadLogSettings(LogSys.log_settings); + /** * make sure our database got created okay, otherwise cleanup and exit */ diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index d50cf6ccc..6672800e5 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -440,7 +440,10 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data(); if (is_server_trusted) { - Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate update processed for: %s", loginserver_update->useraccount); + Log(Logs::General, + Logs::Netcode, + "ServerOP_LSAccountUpdate update processed for: %s", + loginserver_update->useraccount); std::string name = ""; std::string password = ""; std::string email = ""; @@ -698,18 +701,18 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info * this is the second of two cases where we should deny access even if unregistered is allowed */ if (server_account_name.size() > 0 || server_account_password.size() > 0) { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) did not attempt to log in but this server requires a password.", - long_name.c_str(), - short_name.c_str()); + LogLoginserver( + "Server [{0}] [{1}] did not login but this server required a password to login", + long_name, + short_name + ); } else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) did not attempt to log in but unregistered servers are allowed.", - long_name.c_str(), - short_name.c_str()); + LogLoginserver( + "Server [{0}] [{1}] did not login but unregistered servers are allowed", + long_name, + short_name + ); is_server_authorized = true; SetRuntimeID(server_id); @@ -718,11 +721,10 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info } } else { - LogF(Logs::General, - Logs::World_Server, - "Server [{0}] ({1}) is not registered but unregistered servers are allowed", - long_name, - short_name + LogLoginserver( + "Server [{0}] ({1}) is not registered but unregistered servers are allowed", + long_name, + short_name ); if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) { From f0937c396357406a7ee06b61d3673547864d786e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 04:21:22 -0500 Subject: [PATCH 046/491] More logging adjustments --- common/ruletypes.h | 2 +- loginserver/client.cpp | 127 +++++++++++++-------------------- loginserver/client_manager.cpp | 22 +++--- loginserver/database.cpp | 10 +-- loginserver/server_manager.cpp | 7 +- loginserver/world_server.cpp | 12 ++-- 6 files changed, 74 insertions(+), 106 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index 5800619eb..e3be272ca 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -747,7 +747,7 @@ RULE_INT(Faction, ThreateninglyFactionMinimum, -750) RULE_CATEGORY_END() RULE_CATEGORY(Logging) -RULE_BOOL(Logging, PrintFileFunctionAndLine, true) // Ex: [World Server] [net.cpp::main:309] Loading variables... +RULE_BOOL(Logging, PrintFileFunctionAndLine, false) // Ex: [World Server] [net.cpp::main:309] Loading variables... RULE_CATEGORY_END() #undef RULE_CATEGORY diff --git a/loginserver/client.cpp b/loginserver/client.cpp index a4e7b4f89..a6d582eef 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -47,7 +47,7 @@ bool Client::Process() EQApplicationPacket *app = connection->PopPacket(); while (app) { if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Login_Server, "Application packet received from client (size %u)", app->Size()); + Log(Logs::General, Logs::Netcode, "Application packet received from client (size %u)", app->Size()); } if (server.options.IsDumpInPacketsOn()) { @@ -63,19 +63,19 @@ bool Client::Process() switch (app->GetOpcode()) { case OP_SessionReady: { if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Login_Server, "Session ready received from client."); + LogLoginserver("Session ready received from client."); } Handle_SessionReady((const char *) app->pBuffer, app->Size()); break; } case OP_Login: { if (app->Size() < 20) { - Log(Logs::General, Logs::Error, "Login received but it is too small, discarding."); + Error("Login received but it is too small, discarding."); break; } if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Login_Server, "Login received from client."); + LogLoginserver("Login received from client."); } Handle_Login((const char *) app->pBuffer, app->Size()); @@ -83,12 +83,12 @@ bool Client::Process() } case OP_ServerListRequest: { if (app->Size() < 4) { - Log(Logs::General, Logs::Error, "Server List Request received but it is too small, discarding."); + Error("Server List Request received but it is too small, discarding."); break; } if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Login_Server, "Server list request received from client."); + LogLoginserver("Server list request received from client."); } SendServerListPacket(*(uint32_t *) app->pBuffer); @@ -96,7 +96,7 @@ bool Client::Process() } case OP_PlayEverquestRequest: { if (app->Size() < sizeof(PlayEverquestRequest_Struct)) { - Log(Logs::General, Logs::Error, "Play received but it is too small, discarding."); + Error("Play received but it is too small, discarding."); break; } @@ -107,7 +107,7 @@ bool Client::Process() if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) { char dump[64]; app->build_header_dump(dump); - Log(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump); + Error("Recieved unhandled application packet from the client: %s.", dump); } } } @@ -128,12 +128,12 @@ bool Client::Process() void Client::Handle_SessionReady(const char *data, unsigned int size) { if (status != cs_not_sent_session_ready) { - Log(Logs::General, Logs::Error, "Session ready received again after already being received."); + Error("Session ready received again after already being received."); return; } if (size < sizeof(unsigned int)) { - Log(Logs::General, Logs::Error, "Session ready was too small."); + Error("Session ready was too small."); return; } @@ -181,27 +181,18 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) void Client::Handle_Login(const char *data, unsigned int size) { if (status != cs_waiting_for_login) { - LogF(Logs::General, Logs::Error, "Login received after already having logged in"); + Error("Login received after already having logged in"); return; } if ((size - 12) % 8 != 0) { - LogF( - Logs::General, - Logs::Error, - "Login received packet of size: {0}, this would cause a block corruption, discarding.", - size - ); + Error("Login received packet of size: {0}, this would cause a block corruption, discarding", size); + return; } if (size < sizeof(LoginLoginRequest_Struct)) { - LogF( - Logs::General, - Logs::Error, - "Login received packet of size: {0}, this would cause a buffer overflow, discarding.", - size - ); + Error("Login received packet of size: {0}, this would cause a buffer overflow, discarding", size); return; } @@ -215,13 +206,13 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string outbuffer; outbuffer.resize(size - 12); if (outbuffer.length() == 0) { - LogF(Logs::General, Logs::Debug, "Corrupt buffer sent to server, no length."); + Error("Corrupt buffer sent to server, no length."); return; } auto r = eqcrypt_block(data + 10, size - 12, &outbuffer[0], 0); if (r == nullptr) { - LogF(Logs::General, Logs::Debug, "Failed to decrypt eqcrypt block"); + Error("Failed to decrypt eqcrypt block"); return; } @@ -229,7 +220,7 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string user(&outbuffer[0]); if (user.length() >= outbuffer.length()) { - LogF(Logs::General, Logs::Debug,"Corrupt buffer sent to server, preventing buffer overflow."); + Error("Corrupt buffer sent to server, preventing buffer overflow."); return; } @@ -257,9 +248,7 @@ void Client::Handle_Login(const char *data, unsigned int size) user = components[1]; } - LogF( - Logs::General, - Logs::Login_Server, + LogLoginserver( "Attempting password based login [{0}] login [{1}] user [{2}]", user, db_loginserver, @@ -271,12 +260,7 @@ void Client::Handle_Login(const char *data, unsigned int size) if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id)) { result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); - LogF( - Logs::Detail, - Logs::Login_Server, - "[VerifyLoginHash] Success [{0}]", - (result ? "true" : "false") - ); + LogLoginserverDetail("[VerifyLoginHash] Success [{0}]", (result ? "true" : "false")); } else { status = cs_creating_account; @@ -292,7 +276,7 @@ void Client::Handle_Login(const char *data, unsigned int size) */ if (result) { LogF( - Logs::Detail, Logs::Login_Server, "login [{0}] user [{2}] Login succeeded", + Logs::Detail, Logs::Login_Server, "login [{0}] user [{1}] Login succeeded", db_loginserver, user ); @@ -301,7 +285,7 @@ void Client::Handle_Login(const char *data, unsigned int size) } else { LogF( - Logs::Detail, Logs::Login_Server, "login [{0}] user [{2}] Login failed", + Logs::Detail, Logs::Login_Server, "login [{0}] user [{1}] Login failed", db_loginserver, user ); @@ -318,20 +302,16 @@ void Client::Handle_Login(const char *data, unsigned int size) void Client::Handle_Play(const char *data) { if (status != cs_logged_in) { - Log(Logs::General, Logs::Error, "Client sent a play request when they were not logged in, discarding."); + Error("Client sent a play request when they were not logged in, discarding."); return; } - const PlayEverquestRequest_Struct *play = (const PlayEverquestRequest_Struct *) data; - unsigned int server_id_in = (unsigned int) play->ServerNumber; - unsigned int sequence_in = (unsigned int) play->Sequence; + const auto *play = (const PlayEverquestRequest_Struct *) data; + auto server_id_in = (unsigned int) play->ServerNumber; + auto sequence_in = (unsigned int) play->Sequence; if (server.options.IsTraceOn()) { - Log(Logs::General, - Logs::Login_Server, - "Play received from client, server number %u sequence %u.", - server_id_in, - sequence_in); + LogLoginserver("Play received from client, server number {0} sequence {1}", server_id_in, sequence_in); } this->play_server_id = (unsigned int) play->ServerNumber; @@ -396,10 +376,10 @@ void Client::AttemptLoginAccountCreation( { if (loginserver == "eqemu") { - LogF(Logs::General, Logs::Login_Server, "Attempting login account creation via '{0}'", loginserver); + LogLoginserver("Attempting login account creation via '{0}'", loginserver); if (!server.options.CanAutoLinkAccounts()) { - LogF(Logs::General, Logs::Login_Server, "CanAutoLinkAccounts disabled - sending failed login"); + LogLoginserver("CanAutoLinkAccounts disabled - sending failed login"); DoFailedLogin(); return; } @@ -473,14 +453,16 @@ void Client::DoFailedLogin() stored_user.clear(); stored_pass.clear(); - EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); - LoginLoginFailed_Struct *llas = (LoginLoginFailed_Struct *) outapp.pBuffer; - llas->unknown1 = llrs.unknown1; - llas->unknown2 = llrs.unknown2; - llas->unknown3 = llrs.unknown3; - llas->unknown4 = llrs.unknown4; - llas->unknown5 = llrs.unknown5; - memcpy(llas->unknown6, FailedLoginResponseData, sizeof(FailedLoginResponseData)); + EQApplicationPacket outapp(OP_LoginAccepted, sizeof(LoginLoginFailed_Struct)); + auto *login_failed = (LoginLoginFailed_Struct *) outapp.pBuffer; + + login_failed->unknown1 = llrs.unknown1; + login_failed->unknown2 = llrs.unknown2; + login_failed->unknown3 = llrs.unknown3; + login_failed->unknown4 = llrs.unknown4; + login_failed->unknown5 = llrs.unknown5; + + memcpy(login_failed->unknown6, FailedLoginResponseData, sizeof(FailedLoginResponseData)); if (server.options.IsDumpOutPacketsOn()) { DumpPacket(&outapp); @@ -519,9 +501,7 @@ bool Client::VerifyLoginHash( if (hash.length() == 32) { //md5 is insecure for (int i = EncryptionModeMD5; i <= EncryptionModeMD5Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -535,9 +515,7 @@ bool Client::VerifyLoginHash( else if (hash.length() == 40) { //sha1 is insecure for (int i = EncryptionModeSHA; i <= EncryptionModeSHATriple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -552,9 +530,7 @@ bool Client::VerifyLoginHash( else if (hash.length() == 128) { //sha2-512 is insecure for (int i = EncryptionModeSHA512; i <= EncryptionModeSHA512Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -586,7 +562,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const server.client_manager->RemoveExistingClient(db_account_id, db_loginserver); - in_addr in; + in_addr in{}; in.s_addr = connection->GetRemoteIP(); server.db->UpdateLSAccountData(db_account_id, std::string(inet_ntoa(in))); @@ -596,15 +572,15 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const account_name = user; loginserver_name = db_loginserver; - EQApplicationPacket *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); - LoginAccepted_Struct *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer; + auto *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); + auto *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer; login_accepted->unknown1 = llrs.unknown1; login_accepted->unknown2 = llrs.unknown2; login_accepted->unknown3 = llrs.unknown3; login_accepted->unknown4 = llrs.unknown4; login_accepted->unknown5 = llrs.unknown5; - LoginFailedAttempts_Struct *login_failed_attempts = new LoginFailedAttempts_Struct; + auto *login_failed_attempts = new LoginFailedAttempts_Struct; memset(login_failed_attempts, 0, sizeof(LoginFailedAttempts_Struct)); login_failed_attempts->failed_attempts = 0; @@ -630,7 +606,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const char encrypted_buffer[80] = {0}; auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1); if (rc == nullptr) { - LogF(Logs::General, Logs::Debug, "Failed to encrypt eqcrypt block"); + LogLoginserverDetail("Failed to encrypt eqcrypt block"); } memcpy(login_accepted->encrypt, encrypted_buffer, 80); @@ -707,12 +683,12 @@ void Client::LoginOnStatusChange( ) { if (to == EQ::Net::StatusConnected) { - LogF(Logs::Detail, Logs::Login_Server, "EQ::Net::StatusConnected"); + LogLoginserverDetail("EQ::Net::StatusConnected"); LoginSendSessionReady(); } if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) { - LogF(Logs::Detail, Logs::Login_Server, "EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected"); + LogLoginserverDetail("EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected"); DoFailedLogin(); } @@ -738,7 +714,6 @@ void Client::LoginOnStatusChangeIgnored( void Client::LoginOnPacketRecv(std::shared_ptr conn, const EQ::Net::Packet &p) { auto opcode = p.GetUInt16(0); - LogF(Logs::Detail, Logs::Login_Server, "[{0}]", opcode); switch (opcode) { case 0x0017: //OP_ChatMessage LoginSendLogin(); @@ -810,14 +785,12 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) ); if (response_error > 101) { - LogF(Logs::Detail, Logs::Login_Server, "response [{0}] failed login", response_error); + LogLoginserverDetail("response [{0}] failed login", response_error); DoFailedLogin(); login_connection->Close(); } else { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "response [{0}] login succeeded user [{1}]", response_error, stored_user diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index d6cc6f5eb..4c7f56104 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -52,11 +52,12 @@ ClientManager::ClientManager() titanium_stream->OnNewConnection( [this](std::shared_ptr stream) { - LogF(Logs::General, - Logs::Login_Server, - "New Titanium client connection from {0}:{1}", - stream->GetRemoteIP(), - stream->GetRemotePort()); + LogLoginserver( + "New Titanium client connection from {0}:{1}", + stream->GetRemoteIP(), + stream->GetRemotePort() + ); + stream->SetOpcodeManager(&titanium_ops); Client *c = new Client(stream, cv_titanium); clients.push_back(c); @@ -69,8 +70,11 @@ ClientManager::ClientManager() sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) { - Log(Logs::General, Logs::Error, "ClientManager fatal error: couldn't load opcodes for SoD file %s.", - server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str()); + Error( + "ClientManager fatal error: couldn't load opcodes for SoD file {0}", + server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str() + ); + run_server = false; } @@ -150,9 +154,7 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str auto iter = clients.begin(); while (iter != clients.end()) { if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { - Log(Logs::General, - Logs::Login_Server, - "Client attempting to log in and existing client already logged in, removing existing client."); + LogLoginserver("Client attempting to log in existing client already logged in, removing existing client"); delete (*iter); iter = clients.erase(iter); } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index da501e783..fffcfaccc 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -104,9 +104,7 @@ bool Database::GetLoginDataFromAccountInfo( auto results = QueryDatabase(query); if (results.RowCount() != 1) { - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "Could not find account for name [{0}] login [{1}]", name, loginserver @@ -124,15 +122,13 @@ bool Database::GetLoginDataFromAccountInfo( id = atoi(row[0]); password = row[1]; - LogF( - Logs::Detail, - Logs::Login_Server, + LogLoginserverDetail( "Found account for name [{0}] login [{1}]", name, loginserver ); - return false; + return true; } /** diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 9b584e2fe..c7eb2378b 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -265,17 +265,14 @@ void ServerManager::SendUserToWorldRequest( found = true; if (server.options.IsDumpInPacketsOn()) { - LogF(Logs::General, Logs::Login_Server, "{0}", outapp.ToString()); + LogLoginserver("{0}", outapp.ToString()); } } ++iter; } if (!found && server.options.IsTraceOn()) { - Log(Logs::General, - Logs::Error, - "Client requested a user to world but supplied an invalid id of %u.", - server_id); + Error("Client requested a user to world but supplied an invalid id of {0}", server_id); } } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 6672800e5..a214620ed 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -108,18 +108,18 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe } if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) { - Log(Logs::General, Logs::Error, + Error( "Received application packet from server that had opcode ServerOP_NewLSInfo, " - "but was too small. Discarded to avoid buffer overrun."); + "but was too small. Discarded to avoid buffer overrun" + ); + return; } - ServerNewLSInfo_Struct *info = (ServerNewLSInfo_Struct *) packet.Data(); + auto *info = (ServerNewLSInfo_Struct *) packet.Data(); - LogF( - Logs::General, - Logs::Login_Server, + LogLoginserver( "Received New Login Server Info \n" " - name [{0}]\n" " - shortname [{1}]\n" From 86f9a205e52ac477d936beb8a730fd1bde27e156 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 17:20:20 -0500 Subject: [PATCH 047/491] Remove eqemu_logsys_fmt.h header, more log tweaks --- common/CMakeLists.txt | 1 - common/dbcore.cpp | 159 +++++++++++------- common/eqemu_logsys.cpp | 42 ++++- common/eqemu_logsys.h | 50 ++++++ common/net/eqstream.cpp | 1 - common/net/servertalk_client_connection.cpp | 1 - .../servertalk_legacy_client_connection.cpp | 1 - common/net/servertalk_server_connection.cpp | 1 - loginserver/client.cpp | 22 +-- loginserver/client_manager.cpp | 3 +- loginserver/config.cpp | 1 - loginserver/database.cpp | 1 - loginserver/main.cpp | 1 - loginserver/server_manager.cpp | 1 - loginserver/world_server.cpp | 1 - ucs/clientlist.cpp | 1 - world/login_server.cpp | 1 - world/net.cpp | 1 - zone/net.cpp | 1 - zone/waypoints.cpp | 1 - 20 files changed, 197 insertions(+), 94 deletions(-) diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a1c2c51a2..276a1c95a 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -139,7 +139,6 @@ SET(common_headers eqemu_config.h eqemu_config_elements.h eqemu_logsys.h - eqemu_logsys_fmt.h eq_limits.h eq_packet.h eq_stream_ident.h diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 0468bdc77..e493042d0 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -14,33 +14,37 @@ #include #ifdef _WINDOWS - #define snprintf _snprintf - #define strncasecmp _strnicmp - #define strcasecmp _stricmp - #include +#define snprintf _snprintf +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#include #else - #include "unix.h" - #include + +#include "unix.h" +#include + #endif #ifdef _EQDEBUG - #define DEBUG_MYSQL_QUERIES 0 +#define DEBUG_MYSQL_QUERIES 0 #else - #define DEBUG_MYSQL_QUERIES 0 +#define DEBUG_MYSQL_QUERIES 0 #endif -DBcore::DBcore() { +DBcore::DBcore() +{ mysql_init(&mysql); - pHost = 0; - pUser = 0; + pHost = 0; + pUser = 0; pPassword = 0; pDatabase = 0; pCompress = false; - pSSL = false; - pStatus = Closed; + pSSL = false; + pStatus = Closed; } -DBcore::~DBcore() { +DBcore::~DBcore() +{ mysql_close(&mysql); safe_delete_array(pHost); safe_delete_array(pUser); @@ -49,7 +53,8 @@ DBcore::~DBcore() { } // Sends the MySQL server a keepalive -void DBcore::ping() { +void DBcore::ping() +{ if (!MDatabase.trylock()) { // well, if's it's locked, someone's using it. If someone's using it, it doesnt need a keepalive return; @@ -63,34 +68,32 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO return QueryDatabase(query.c_str(), query.length(), retryOnFailureOnce); } -MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, bool retryOnFailureOnce) +MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce) { LockMutex lock(&MDatabase); // Reconnect if we are not connected before hand. - if (pStatus != Connected) + if (pStatus != Connected) { Open(); + } // request query. != 0 indicates some kind of error. - if (mysql_real_query(&mysql, query, querylen) != 0) - { + if (mysql_real_query(&mysql, query, querylen) != 0) { unsigned int errorNumber = mysql_errno(&mysql); - if (errorNumber == CR_SERVER_GONE_ERROR) + if (errorNumber == CR_SERVER_GONE_ERROR) { pStatus = Error; + } // error appears to be a disconnect error, may need to try again. - if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) - { + if (errorNumber == CR_SERVER_LOST || errorNumber == CR_SERVER_GONE_ERROR) { - if (retryOnFailureOnce) - { - std::cout << "Database Error: Lost connection, attempting to recover...." << std::endl; + if (retryOnFailureOnce) { + Log(Logs::General, Logs::Status, "Database Error: Lost connection, attempting to recover..."); MySQLRequestResult requestResult = QueryDatabase(query, querylen, false); - if (requestResult.Success()) - { - std::cout << "Reconnection to database successful." << std::endl; + if (requestResult.Success()) { + Log(Logs::General, Logs::Status, "Reconnection to database successful"); return requestResult; } @@ -102,109 +105,147 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); - return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer); + return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32) mysql_errno(&mysql), errorBuffer); } auto errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); /* Implement Logging at the Root */ - if (mysql_errno(&mysql) > 0 && strlen(query) > 0){ + if (mysql_errno(&mysql) > 0 && strlen(query) > 0) { if (LogSys.log_settings[Logs::MySQLError].is_category_enabled == 1) Log(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query); } - return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer); + return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql), errorBuffer); } // successful query. get results. - MYSQL_RES* res = mysql_store_result(&mysql); - uint32 rowCount = 0; + MYSQL_RES *res = mysql_store_result(&mysql); + uint32 rowCount = 0; - if (res != nullptr) - rowCount = (uint32)mysql_num_rows(res); + if (res != nullptr) { + rowCount = (uint32) mysql_num_rows(res); + } - MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); - - if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) - { + MySQLRequestResult requestResult( + res, + (uint32) mysql_affected_rows(&mysql), + rowCount, + (uint32) mysql_field_count(&mysql), + (uint32) mysql_insert_id(&mysql)); + + if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) { if ((strncasecmp(query, "select", 6) == 0)) { - Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s returned)", query, requestResult.RowCount(), requestResult.RowCount() == 1 ? "" : "s"); + Log(Logs::General, + Logs::MySQLQuery, + "%s (%u row%s returned)", + query, + requestResult.RowCount(), + requestResult.RowCount() == 1 ? "" : "s"); } else { - Log(Logs::General, Logs::MySQLQuery, "%s (%u row%s affected)", query, requestResult.RowsAffected(), requestResult.RowsAffected() == 1 ? "" : "s"); + Log(Logs::General, + Logs::MySQLQuery, + "%s (%u row%s affected)", + query, + requestResult.RowsAffected(), + requestResult.RowsAffected() == 1 ? "" : "s"); } } return requestResult; } -void DBcore::TransactionBegin() { +void DBcore::TransactionBegin() +{ QueryDatabase("START TRANSACTION"); } -void DBcore::TransactionCommit() { +void DBcore::TransactionCommit() +{ QueryDatabase("COMMIT"); } -void DBcore::TransactionRollback() { +void DBcore::TransactionRollback() +{ QueryDatabase("ROLLBACK"); } -uint32 DBcore::DoEscapeString(char* tobuf, const char* frombuf, uint32 fromlen) { +uint32 DBcore::DoEscapeString(char *tobuf, const char *frombuf, uint32 fromlen) +{ // No good reason to lock the DB, we only need it in the first place to check char encoding. // LockMutex lock(&MDatabase); return mysql_real_escape_string(&mysql, tobuf, frombuf, fromlen); } -bool DBcore::Open(const char* iHost, const char* iUser, const char* iPassword, const char* iDatabase,uint32 iPort, uint32* errnum, char* errbuf, bool iCompress, bool iSSL) { +bool DBcore::Open( + const char *iHost, + const char *iUser, + const char *iPassword, + const char *iDatabase, + uint32 iPort, + uint32 *errnum, + char *errbuf, + bool iCompress, + bool iSSL +) +{ LockMutex lock(&MDatabase); safe_delete(pHost); safe_delete(pUser); safe_delete(pPassword); safe_delete(pDatabase); - pHost = strcpy(new char[strlen(iHost) + 1], iHost); - pUser = strcpy(new char[strlen(iUser) + 1], iUser); + pHost = strcpy(new char[strlen(iHost) + 1], iHost); + pUser = strcpy(new char[strlen(iUser) + 1], iUser); pPassword = strcpy(new char[strlen(iPassword) + 1], iPassword); pDatabase = strcpy(new char[strlen(iDatabase) + 1], iDatabase); pCompress = iCompress; - pPort = iPort; - pSSL = iSSL; + pPort = iPort; + pSSL = iSSL; return Open(errnum, errbuf); } -bool DBcore::Open(uint32* errnum, char* errbuf) { - if (errbuf) +bool DBcore::Open(uint32 *errnum, char *errbuf) +{ + if (errbuf) { errbuf[0] = 0; + } LockMutex lock(&MDatabase); - if (GetStatus() == Connected) + if (GetStatus() == Connected) { return true; + } if (GetStatus() == Error) { mysql_close(&mysql); - mysql_init(&mysql); // Initialize structure again + mysql_init(&mysql); // Initialize structure again } - if (!pHost) + if (!pHost) { return false; + } /* Added CLIENT_FOUND_ROWS flag to the connect otherwise DB update calls would say 0 rows affected when the value already equalled what the function was tring to set it to, therefore the function would think it failed */ uint32 flags = CLIENT_FOUND_ROWS; - if (pCompress) + if (pCompress) { flags |= CLIENT_COMPRESS; - if (pSSL) + } + if (pSSL) { flags |= CLIENT_SSL; + } if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) { pStatus = Connected; return true; } else { - if (errnum) + if (errnum) { *errnum = mysql_errno(&mysql); - if (errbuf) + } + if (errbuf) { snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); + } pStatus = Error; return false; } diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index abf700642..c5776bf15 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -95,8 +95,8 @@ enum GameChatColor { */ EQEmuLogSys::EQEmuLogSys() { - on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; - on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {}; + on_log_gmsay_hook = [](uint16 log_type, const std::string &) {}; + on_log_console_hook = [](uint16 debug_level, uint16 log_type, const std::string &) {}; } /** @@ -177,7 +177,10 @@ void EQEmuLogSys::LoadLogSettingsDefaults() * @param in_message * @return */ -std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message) +std::string EQEmuLogSys::FormatOutMessageString( + uint16 log_category, + const std::string &in_message +) { std::string ret; ret.push_back('['); @@ -193,7 +196,11 @@ std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std:: * @param log_category * @param message */ -void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message) +void EQEmuLogSys::ProcessGMSay( + uint16 debug_level, + uint16 log_category, + const std::string &message +) { /** * Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash @@ -215,7 +222,11 @@ void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const st * @param log_category * @param message */ -void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message) +void EQEmuLogSys::ProcessLogWrite( + uint16 debug_level, + uint16 log_category, + const std::string &message +) { if (log_category == Logs::Crash) { char time_stamp[80]; @@ -348,20 +359,37 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, on_log_console_hook(debug_level, log_category, message); } +/** + * @param str + * @return + */ constexpr const char *str_end(const char *str) { return *str ? str_end(str + 1) : str; } +/** + * @param str + * @return + */ constexpr bool str_slant(const char *str) { return *str == '/' ? true : (*str ? str_slant(str + 1) : false); } +/** + * @param str + * @return + */ constexpr const char *r_slant(const char *str) { return *str == '/' ? (str + 1) : r_slant(str - 1); } + +/** + * @param str + * @return + */ constexpr const char *file_name(const char *str) { return str_slant(str) ? r_slant(str_end(str)) : str; @@ -452,7 +480,7 @@ void EQEmuLogSys::MakeDirectory(const std::string &directory_name) return; _mkdir(directory_name.c_str()); #else - struct stat st; + struct stat st{}; if (stat(directory_name.c_str(), &st) == 0) { // exists return; } @@ -540,4 +568,4 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) std::ios_base::app | std::ios_base::out ); } -} +} \ No newline at end of file diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 48873a6cc..ed5088fec 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -193,6 +193,10 @@ public: */ void CloseFileLogs(); void LoadLogSettingsDefaults(); + + /** + * @param directory_name + */ void MakeDirectory(const std::string &directory_name); /** @@ -216,8 +220,13 @@ public: /** * Used in file logs to prepend a timestamp entry for logs + * @param time_stamp */ void SetCurrentTimeStamp(char* time_stamp); + + /** + * @param log_name + */ void StartFileLogs(const std::string &log_name = ""); /** @@ -264,7 +273,14 @@ public: */ uint16 GetGMSayColorFromCategory(uint16 log_category); + /** + * @param f + */ void SetGMSayHandler(std::function f) { on_log_gmsay_hook = f; } + + /** + * @param f + */ void SetConsoleHandler(std::function f) { on_log_console_hook = f; } private: @@ -282,6 +298,7 @@ private: /** * Linux console color messages mapped by category + * * @param log_category * @return */ @@ -292,11 +309,44 @@ private: */ uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); + /** + * @param debug_level + * @param log_category + * @param message + */ void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); + + /** + * @param debug_level + * @param log_category + * @param message + */ void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); + + /** + * @param debug_level + * @param log_category + * @param message + */ void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); }; extern EQEmuLogSys LogSys; +template +void OutF( + EQEmuLogSys &ls, + Logs::DebugLevel debug_level, + uint16 log_category, + const char *file, + const char *func, + int line, + const char *fmt, + const Args &... args +) +{ + std::string log_str = fmt::format(fmt, args...); + ls.Out(debug_level, log_category, file, func, line, log_str); +} + #endif diff --git a/common/net/eqstream.cpp b/common/net/eqstream.cpp index 378b0d919..cb0bbe087 100644 --- a/common/net/eqstream.cpp +++ b/common/net/eqstream.cpp @@ -1,6 +1,5 @@ #include "eqstream.h" #include "../eqemu_logsys.h" -#include "../eqemu_logsys_fmt.h" EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options) { diff --git a/common/net/servertalk_client_connection.cpp b/common/net/servertalk_client_connection.cpp index 0b77fc073..676d9d024 100644 --- a/common/net/servertalk_client_connection.cpp +++ b/common/net/servertalk_client_connection.cpp @@ -1,7 +1,6 @@ #include "servertalk_client_connection.h" #include "dns.h" #include "../eqemu_logsys.h" -#include "../eqemu_logsys_fmt.h" EQ::Net::ServertalkClient::ServertalkClient(const std::string &addr, int port, bool ipv6, const std::string &identifier, const std::string &credentials) : m_timer(std::unique_ptr(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkClient::Connect, this)))) diff --git a/common/net/servertalk_legacy_client_connection.cpp b/common/net/servertalk_legacy_client_connection.cpp index 851ca3541..1e31f406f 100644 --- a/common/net/servertalk_legacy_client_connection.cpp +++ b/common/net/servertalk_legacy_client_connection.cpp @@ -1,7 +1,6 @@ #include "servertalk_legacy_client_connection.h" #include "dns.h" #include "../eqemu_logsys.h" -#include "../eqemu_logsys_fmt.h" EQ::Net::ServertalkLegacyClient::ServertalkLegacyClient(const std::string &addr, int port, bool ipv6) : m_timer(std::unique_ptr(new EQ::Timer(100, true, std::bind(&EQ::Net::ServertalkLegacyClient::Connect, this)))) diff --git a/common/net/servertalk_server_connection.cpp b/common/net/servertalk_server_connection.cpp index fa52d8f9e..c211545f0 100644 --- a/common/net/servertalk_server_connection.cpp +++ b/common/net/servertalk_server_connection.cpp @@ -1,7 +1,6 @@ #include "servertalk_server_connection.h" #include "servertalk_server.h" #include "../eqemu_logsys.h" -#include "../eqemu_logsys_fmt.h" #include "../util/uuid.h" EQ::Net::ServertalkServerConnection::ServertalkServerConnection(std::shared_ptr c, EQ::Net::ServertalkServer *parent, bool encrypted, bool allow_downgrade) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index a6d582eef..b08c47a27 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -24,7 +24,6 @@ #include "../common/eqemu_logsys.h" #include "../common/string_util.h" #include "encryption.h" -#include "../common/eqemu_logsys_fmt.h" extern LoginServer server; @@ -140,10 +139,10 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) status = cs_waiting_for_login; /** - * The packets are mostly the same but slightly different between the two versions. - */ + * The packets are mostly the same but slightly different between the two versions + */ if (version == cv_sod) { - EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 17); + auto *outapp = new EQApplicationPacket(OP_ChatMessage, 17); outapp->pBuffer[0] = 0x02; outapp->pBuffer[10] = 0x01; outapp->pBuffer[11] = 0x65; @@ -156,8 +155,8 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) delete outapp; } else { - const char *msg = "ChatMessage"; - EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg)); + const char *msg = "ChatMessage"; + auto *outapp = new EQApplicationPacket(OP_ChatMessage, 16 + strlen(msg)); outapp->pBuffer[0] = 0x02; outapp->pBuffer[10] = 0x01; outapp->pBuffer[11] = 0x65; @@ -275,8 +274,8 @@ void Client::Handle_Login(const char *data, unsigned int size) * Login accepted */ if (result) { - LogF( - Logs::Detail, Logs::Login_Server, "login [{0}] user [{1}] Login succeeded", + LogLoginserverDetail( + "login [{0}] user [{1}] Login succeeded", db_loginserver, user ); @@ -284,8 +283,8 @@ void Client::Handle_Login(const char *data, unsigned int size) DoSuccessfulLogin(user, db_account_id, db_loginserver); } else { - LogF( - Logs::Detail, Logs::Login_Server, "login [{0}] user [{1}] Login failed", + LogLoginserverDetail( + "login [{0}] user [{1}] Login failed", db_loginserver, user ); @@ -572,7 +571,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const account_name = user; loginserver_name = db_loginserver; - auto *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); + auto *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); auto *login_accepted = (LoginAccepted_Struct *) outapp->pBuffer; login_accepted->unknown1 = llrs.unknown1; login_accepted->unknown2 = llrs.unknown2; @@ -763,6 +762,7 @@ void Client::LoginSendLogin() void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) { auto encrypt_size = p.Length() - 12; + if (encrypt_size % 8 > 0) { encrypt_size = (encrypt_size / 8) * 8; } diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 4c7f56104..1c610c562 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -25,7 +25,6 @@ extern LoginServer server; extern bool run_server; #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" ClientManager::ClientManager() { @@ -135,7 +134,7 @@ void ClientManager::ProcessDisconnect() while (iter != clients.end()) { std::shared_ptr c = (*iter)->GetConnection(); if (c->CheckState(CLOSED)) { - Log(Logs::General, Logs::Login_Server, "Client disconnected from the server, removing client."); + LogLoginserver("Client disconnected from the server, removing client."); delete (*iter); iter = clients.erase(iter); } diff --git a/loginserver/config.cpp b/loginserver/config.cpp index 6964c13ff..59b0f2ee5 100644 --- a/loginserver/config.cpp +++ b/loginserver/config.cpp @@ -20,7 +20,6 @@ #include "../common/global_define.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "config.h" /** diff --git a/loginserver/database.cpp b/loginserver/database.cpp index fffcfaccc..4336d7656 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -23,7 +23,6 @@ #include "database.h" #include "login_server.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "../common/string_util.h" extern LoginServer server; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 21efd91bf..b95e51649 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -26,7 +26,6 @@ #include "../common/platform.h" #include "../common/crash.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "login_server.h" #include #include diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index c7eb2378b..44b323342 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -24,7 +24,6 @@ #include #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "../common/ip_util.h" extern LoginServer server; diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index a214620ed..fe4fff693 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -23,7 +23,6 @@ #include "login_structures.h" #include "config.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "../common/ip_util.h" extern LoginServer server; diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index a433705e6..b7d1f01b3 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/global_define.h" #include "../common/string_util.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "../common/misc_functions.h" #include "ucsconfig.h" diff --git a/world/login_server.cpp b/world/login_server.cpp index 0043a15a5..4fdb9dc35 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/packet_dump.h" #include "../common/string_util.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "login_server.h" #include "login_server_list.h" #include "zoneserver.h" diff --git a/world/net.cpp b/world/net.cpp index 087581a9d..515f50b66 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -25,7 +25,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/string_util.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "../common/queue.h" #include "../common/timer.h" #include "../common/eq_packet.h" diff --git a/zone/net.cpp b/zone/net.cpp index 0b692e481..9710ef7e1 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -42,7 +42,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/eqemu_exception.h" #include "../common/spdat.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "api_service.h" #include "zone_config.h" diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index fb0a85490..711ffb7d1 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -25,7 +25,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/string_util.h" #include "../common/misc_functions.h" #include "../common/eqemu_logsys.h" -#include "../common/eqemu_logsys_fmt.h" #include "map.h" #include "npc.h" From b2ed5fe47981ab9a6b9d36f3f0447ab22d2a43d6 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 18:16:09 -0500 Subject: [PATCH 048/491] Add RFC 5424 logging --- common/eqemu_logsys.cpp | 47 +++++++++++++++---- common/eqemu_logsys.h | 84 +++++++++++++++++++++++++++++----- common/eqemu_logsys_fmt.h | 39 ---------------- common/platform.cpp | 58 +++++++++++++++++++++++ common/platform.h | 23 ++++++++++ loginserver/client.cpp | 62 ++++++++++++------------- loginserver/client_manager.cpp | 12 ++--- loginserver/config.cpp | 8 ++-- loginserver/database.cpp | 6 +-- loginserver/main.cpp | 36 +++++++-------- loginserver/server_manager.cpp | 12 ++--- loginserver/world_server.cpp | 52 ++++++++++----------- 12 files changed, 286 insertions(+), 153 deletions(-) delete mode 100644 common/eqemu_logsys_fmt.h diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index c5776bf15..8c1f619f1 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -133,6 +133,17 @@ void EQEmuLogSys::LoadLogSettingsDefaults() log_settings[Logs::Headless_Client].log_to_console = Logs::General; log_settings[Logs::NPCScaling].log_to_gmsay = Logs::General; + /** + * RFC 5424 + */ + log_settings[Logs::Emergency].log_to_console = Logs::General; + log_settings[Logs::Alert].log_to_console = Logs::General; + log_settings[Logs::Critical].log_to_console = Logs::General; + log_settings[Logs::Error].log_to_console = Logs::General; + log_settings[Logs::Warning].log_to_console = Logs::General; + log_settings[Logs::Notice].log_to_console = Logs::General; + log_settings[Logs::Info].log_to_console = Logs::General; + /** * Set Category enabled status on defaults */ @@ -172,6 +183,24 @@ void EQEmuLogSys::LoadLogSettingsDefaults() } } +/** + * @param log_category + * @return + */ +bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category) +{ + return ( + log_category == Logs::Emergency || + log_category == Logs::Alert || + log_category == Logs::Critical || + log_category == Logs::Error || + log_category == Logs::Warning || + log_category == Logs::Notice || + log_category == Logs::Info || + log_category == Logs::Debug + ); +} + /** * @param log_category * @param in_message @@ -182,13 +211,13 @@ std::string EQEmuLogSys::FormatOutMessageString( const std::string &in_message ) { - std::string ret; - ret.push_back('['); - ret.append(Logs::LogCategoryName[log_category]); - ret.push_back(']'); - ret.push_back(' '); - ret.append(in_message); - return ret; + std::string return_string; + + if (IsRfc5424LogCategory(log_category)) { + return_string = "[" + GetPlatformName() + "] "; + } + + return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message; } /** @@ -390,7 +419,7 @@ constexpr const char *r_slant(const char *str) * @param str * @return */ -constexpr const char *file_name(const char *str) +constexpr const char *base_file_name(const char *str) { return str_slant(str) ? r_slant(str_end(str)) : str; } @@ -436,7 +465,7 @@ void EQEmuLogSys::Out( std::string prefix; if (RuleB(Logging, PrintFileFunctionAndLine)) { - prefix = fmt::format("[{0}::{1}:{2}] ", file_name(file), func, line); + prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line); } va_list args; diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index ed5088fec..4626b0399 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -94,6 +94,12 @@ namespace Logs { NPCRoamBox, NPCScaling, MobAppearance, + Info, + Warning, + Critical, + Emergency, + Alert, + Notice, MaxCategoryID /* Don't Remove this */ }; @@ -153,15 +159,74 @@ namespace Logs { "Traps", "NPC Roam Box", "NPC Scaling", - "Mob Appearance" + "Mob Appearance", + "Info", + "Warning", + "Critical", + "Emergency", + "Alert", + "Notice" }; } -#define Error(message, ...) do {\ +/** + * RFC 5424 + */ + +#define LogEmergency(message, ...) do {\ + if (LogSys.log_settings[Logs::Emergency].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Emergency, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogAlert(message, ...) do {\ + if (LogSys.log_settings[Logs::Alert].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Alert, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogCritical(message, ...) do {\ + if (LogSys.log_settings[Logs::Critical].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Critical, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogError(message, ...) do {\ if (LogSys.log_settings[Logs::Error].is_category_enabled == 1)\ OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) + +#define LogWarning(message, ...) do {\ + if (LogSys.log_settings[Logs::Warning].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogNotice(message, ...) do {\ + if (LogSys.log_settings[Logs::Notice].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Notice, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogInfo(message, ...) do {\ + if (LogSys.log_settings[Logs::Info].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Info, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogDebug(message, ...) do {\ + if (LogSys.log_settings[Logs::Debug].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + + + + + +/** + * Other + */ + +#define LogStatus(message, ...) do {\ + if (LogSys.log_settings[Logs::Status].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::Status, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + #define Log(debug_level, log_category, message, ...) do {\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\ LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ @@ -172,15 +237,6 @@ namespace Logs { OutF(LogSys, debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) -#define LogLoginserver(message, ...) do {\ - if (LogSys.log_settings[Logs::Login_Server].is_category_enabled == 1)\ - OutF(LogSys, Logs::General, Logs::Login_Server, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ -} while (0) - -#define LogLoginserverDetail(message, ...) do {\ - if (LogSys.log_settings[Logs::Login_Server].is_category_enabled == 1)\ - OutF(LogSys, Logs::Detail, Logs::Login_Server, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ -} while (0) class EQEmuLogSys { public: @@ -329,6 +385,12 @@ private: * @param message */ void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); + + /** + * @param log_category + * @return + */ + bool IsRfc5424LogCategory(uint16 log_category); }; extern EQEmuLogSys LogSys; diff --git a/common/eqemu_logsys_fmt.h b/common/eqemu_logsys_fmt.h deleted file mode 100644 index 2874d5766..000000000 --- a/common/eqemu_logsys_fmt.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * -*/ - -#pragma once - -#include - -template -void OutF( - EQEmuLogSys &ls, - Logs::DebugLevel debug_level, - uint16 log_category, - const char *file, - const char *func, - int line, - const char *fmt, - const Args &... args -) -{ - std::string log_str = fmt::format(fmt, args...); - ls.Out(debug_level, log_category, file, func, line, log_str); -} \ No newline at end of file diff --git a/common/platform.cpp b/common/platform.cpp index 4955d6639..b67267155 100644 --- a/common/platform.cpp +++ b/common/platform.cpp @@ -1,3 +1,23 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include "platform.h" EQEmuExePlatform exe_platform = ExePlatformNone; @@ -10,6 +30,44 @@ const EQEmuExePlatform& GetExecutablePlatform() { return exe_platform; } +/** + * @return + */ int GetExecutablePlatformInt(){ return exe_platform; +} + +/** + * Returns platform name by string + * + * @return + */ +std::string GetPlatformName() +{ + switch (GetExecutablePlatformInt()) { + case EQEmuExePlatform::ExePlatformWorld: + return "WorldServer"; + case EQEmuExePlatform::ExePlatformQueryServ: + return "QueryServer"; + case EQEmuExePlatform::ExePlatformZone: + return "ZoneServer"; + case EQEmuExePlatform::ExePlatformUCS: + return "UCS"; + case EQEmuExePlatform::ExePlatformLogin: + return "LoginServer"; + case EQEmuExePlatform::ExePlatformSocket_Server: + return "SocketServer"; + case EQEmuExePlatform::ExePlatformSharedMemory: + return "SharedMemory"; + case EQEmuExePlatform::ExePlatformClientImport: + return "ClientImport"; + case EQEmuExePlatform::ExePlatformClientExport: + return "ClientExport"; + case EQEmuExePlatform::ExePlatformLaunch: + return "Launch"; + case EQEmuExePlatform::ExePlatformHC: + return "HC"; + default: + return ""; + } } \ No newline at end of file diff --git a/common/platform.h b/common/platform.h index 8eb765257..bd24a1493 100644 --- a/common/platform.h +++ b/common/platform.h @@ -1,6 +1,28 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #ifndef EQEMU_PLATFORM_H #define EQEMU_PLATFORM_H +#include "iostream" + enum EQEmuExePlatform { ExePlatformNone = 0, @@ -20,5 +42,6 @@ enum EQEmuExePlatform void RegisterExecutablePlatform(EQEmuExePlatform p); const EQEmuExePlatform& GetExecutablePlatform(); int GetExecutablePlatformInt(); +std::string GetPlatformName(); #endif diff --git a/loginserver/client.cpp b/loginserver/client.cpp index b08c47a27..41e6c16dc 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -62,19 +62,19 @@ bool Client::Process() switch (app->GetOpcode()) { case OP_SessionReady: { if (server.options.IsTraceOn()) { - LogLoginserver("Session ready received from client."); + LogInfo("Session ready received from client."); } Handle_SessionReady((const char *) app->pBuffer, app->Size()); break; } case OP_Login: { if (app->Size() < 20) { - Error("Login received but it is too small, discarding."); + LogError("Login received but it is too small, discarding."); break; } if (server.options.IsTraceOn()) { - LogLoginserver("Login received from client."); + LogInfo("Login received from client."); } Handle_Login((const char *) app->pBuffer, app->Size()); @@ -82,12 +82,12 @@ bool Client::Process() } case OP_ServerListRequest: { if (app->Size() < 4) { - Error("Server List Request received but it is too small, discarding."); + LogError("Server List Request received but it is too small, discarding."); break; } if (server.options.IsTraceOn()) { - LogLoginserver("Server list request received from client."); + LogInfo("Server list request received from client."); } SendServerListPacket(*(uint32_t *) app->pBuffer); @@ -95,7 +95,7 @@ bool Client::Process() } case OP_PlayEverquestRequest: { if (app->Size() < sizeof(PlayEverquestRequest_Struct)) { - Error("Play received but it is too small, discarding."); + LogError("Play received but it is too small, discarding."); break; } @@ -106,7 +106,7 @@ bool Client::Process() if (LogSys.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) { char dump[64]; app->build_header_dump(dump); - Error("Recieved unhandled application packet from the client: %s.", dump); + LogError("Recieved unhandled application packet from the client: %s.", dump); } } } @@ -127,12 +127,12 @@ bool Client::Process() void Client::Handle_SessionReady(const char *data, unsigned int size) { if (status != cs_not_sent_session_ready) { - Error("Session ready received again after already being received."); + LogError("Session ready received again after already being received."); return; } if (size < sizeof(unsigned int)) { - Error("Session ready was too small."); + LogError("Session ready was too small."); return; } @@ -180,18 +180,18 @@ void Client::Handle_SessionReady(const char *data, unsigned int size) void Client::Handle_Login(const char *data, unsigned int size) { if (status != cs_waiting_for_login) { - Error("Login received after already having logged in"); + LogError("Login received after already having logged in"); return; } if ((size - 12) % 8 != 0) { - Error("Login received packet of size: {0}, this would cause a block corruption, discarding", size); + LogError("Login received packet of size: {0}, this would cause a block corruption, discarding", size); return; } if (size < sizeof(LoginLoginRequest_Struct)) { - Error("Login received packet of size: {0}, this would cause a buffer overflow, discarding", size); + LogError("Login received packet of size: {0}, this would cause a buffer overflow, discarding", size); return; } @@ -205,13 +205,13 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string outbuffer; outbuffer.resize(size - 12); if (outbuffer.length() == 0) { - Error("Corrupt buffer sent to server, no length."); + LogError("Corrupt buffer sent to server, no length."); return; } auto r = eqcrypt_block(data + 10, size - 12, &outbuffer[0], 0); if (r == nullptr) { - Error("Failed to decrypt eqcrypt block"); + LogError("Failed to decrypt eqcrypt block"); return; } @@ -219,7 +219,7 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string user(&outbuffer[0]); if (user.length() >= outbuffer.length()) { - Error("Corrupt buffer sent to server, preventing buffer overflow."); + LogError("Corrupt buffer sent to server, preventing buffer overflow."); return; } @@ -247,7 +247,7 @@ void Client::Handle_Login(const char *data, unsigned int size) user = components[1]; } - LogLoginserver( + LogInfo( "Attempting password based login [{0}] login [{1}] user [{2}]", user, db_loginserver, @@ -259,7 +259,7 @@ void Client::Handle_Login(const char *data, unsigned int size) if (server.db->GetLoginDataFromAccountInfo(user, db_loginserver, db_account_password_hash, db_account_id)) { result = VerifyLoginHash(user, db_loginserver, cred, db_account_password_hash); - LogLoginserverDetail("[VerifyLoginHash] Success [{0}]", (result ? "true" : "false")); + LogDebug("[VerifyLoginHash] Success [{0}]", (result ? "true" : "false")); } else { status = cs_creating_account; @@ -274,7 +274,7 @@ void Client::Handle_Login(const char *data, unsigned int size) * Login accepted */ if (result) { - LogLoginserverDetail( + LogDebug( "login [{0}] user [{1}] Login succeeded", db_loginserver, user @@ -283,7 +283,7 @@ void Client::Handle_Login(const char *data, unsigned int size) DoSuccessfulLogin(user, db_account_id, db_loginserver); } else { - LogLoginserverDetail( + LogDebug( "login [{0}] user [{1}] Login failed", db_loginserver, user @@ -301,7 +301,7 @@ void Client::Handle_Login(const char *data, unsigned int size) void Client::Handle_Play(const char *data) { if (status != cs_logged_in) { - Error("Client sent a play request when they were not logged in, discarding."); + LogError("Client sent a play request when they were not logged in, discarding."); return; } @@ -310,7 +310,7 @@ void Client::Handle_Play(const char *data) auto sequence_in = (unsigned int) play->Sequence; if (server.options.IsTraceOn()) { - LogLoginserver("Play received from client, server number {0} sequence {1}", server_id_in, sequence_in); + LogInfo("Play received from client, server number {0} sequence {1}", server_id_in, sequence_in); } this->play_server_id = (unsigned int) play->ServerNumber; @@ -375,10 +375,10 @@ void Client::AttemptLoginAccountCreation( { if (loginserver == "eqemu") { - LogLoginserver("Attempting login account creation via '{0}'", loginserver); + LogInfo("Attempting login account creation via '{0}'", loginserver); if (!server.options.CanAutoLinkAccounts()) { - LogLoginserver("CanAutoLinkAccounts disabled - sending failed login"); + LogInfo("CanAutoLinkAccounts disabled - sending failed login"); DoFailedLogin(); return; } @@ -500,7 +500,7 @@ bool Client::VerifyLoginHash( if (hash.length() == 32) { //md5 is insecure for (int i = EncryptionModeMD5; i <= EncryptionModeMD5Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogLoginserverDetail( + LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -514,7 +514,7 @@ bool Client::VerifyLoginHash( else if (hash.length() == 40) { //sha1 is insecure for (int i = EncryptionModeSHA; i <= EncryptionModeSHATriple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogLoginserverDetail( + LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -529,7 +529,7 @@ bool Client::VerifyLoginHash( else if (hash.length() == 128) { //sha2-512 is insecure for (int i = EncryptionModeSHA512; i <= EncryptionModeSHA512Triple; ++i) { if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { - LogLoginserverDetail( + LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", user, loginserver, @@ -605,7 +605,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const char encrypted_buffer[80] = {0}; auto rc = eqcrypt_block((const char *) login_failed_attempts, 75, encrypted_buffer, 1); if (rc == nullptr) { - LogLoginserverDetail("Failed to encrypt eqcrypt block"); + LogDebug("Failed to encrypt eqcrypt block"); } memcpy(login_accepted->encrypt, encrypted_buffer, 80); @@ -682,12 +682,12 @@ void Client::LoginOnStatusChange( ) { if (to == EQ::Net::StatusConnected) { - LogLoginserverDetail("EQ::Net::StatusConnected"); + LogDebug("EQ::Net::StatusConnected"); LoginSendSessionReady(); } if (to == EQ::Net::StatusDisconnecting || to == EQ::Net::StatusDisconnected) { - LogLoginserverDetail("EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected"); + LogDebug("EQ::Net::StatusDisconnecting || EQ::Net::StatusDisconnected"); DoFailedLogin(); } @@ -785,12 +785,12 @@ void Client::LoginProcessLoginResponse(const EQ::Net::Packet &p) ); if (response_error > 101) { - LogLoginserverDetail("response [{0}] failed login", response_error); + LogDebug("response [{0}] failed login", response_error); DoFailedLogin(); login_connection->Close(); } else { - LogLoginserverDetail( + LogDebug( "response [{0}] login succeeded user [{1}]", response_error, stored_user diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 1c610c562..0967f2a63 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -41,7 +41,7 @@ ClientManager::ClientManager() "login_opcodes.conf" ).c_str())) { - Error( + LogError( "ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]", server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf") ); @@ -51,7 +51,7 @@ ClientManager::ClientManager() titanium_stream->OnNewConnection( [this](std::shared_ptr stream) { - LogLoginserver( + LogInfo( "New Titanium client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort() @@ -69,7 +69,7 @@ ClientManager::ClientManager() sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) { - Error( + LogError( "ClientManager fatal error: couldn't load opcodes for SoD file {0}", server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str() ); @@ -79,7 +79,7 @@ ClientManager::ClientManager() sod_stream->OnNewConnection( [this](std::shared_ptr stream) { - LogLoginserver( + LogInfo( "New SoD client connection from {0}:{1}", stream->GetRemoteIP(), stream->GetRemotePort() @@ -134,7 +134,7 @@ void ClientManager::ProcessDisconnect() while (iter != clients.end()) { std::shared_ptr c = (*iter)->GetConnection(); if (c->CheckState(CLOSED)) { - LogLoginserver("Client disconnected from the server, removing client."); + LogInfo("Client disconnected from the server, removing client."); delete (*iter); iter = clients.erase(iter); } @@ -153,7 +153,7 @@ void ClientManager::RemoveExistingClient(unsigned int account_id, const std::str auto iter = clients.begin(); while (iter != clients.end()) { if ((*iter)->GetAccountID() == account_id && (*iter)->GetLoginServerName().compare(loginserver) == 0) { - LogLoginserver("Client attempting to log in existing client already logged in, removing existing client"); + LogInfo("Client attempting to log in existing client already logged in, removing existing client"); delete (*iter); iter = clients.erase(iter); } diff --git a/loginserver/config.cpp b/loginserver/config.cpp index 59b0f2ee5..88daab757 100644 --- a/loginserver/config.cpp +++ b/loginserver/config.cpp @@ -52,7 +52,7 @@ std::string Config::GetVariable(std::string title, std::string parameter) void Config::Parse(const char *file_name) { if (file_name == nullptr) { - Error("Config::Parse(), file_name passed was null"); + LogError("Config::Parse(), file_name passed was null"); return; } @@ -72,7 +72,7 @@ void Config::Parse(const char *file_name) bool first = true; ++iter; if (iter == tokens.end()) { - Error("Config::Parse(), EOF before title done parsing"); + LogError("Config::Parse(), EOF before title done parsing"); fclose(input); vars.clear(); return; @@ -99,7 +99,7 @@ void Config::Parse(const char *file_name) else if (mode == 1) { mode++; if ((*iter).compare("=") != 0) { - Error("Config::Parse(), invalid parse token where = should be"); + LogError("Config::Parse(), invalid parse token where = should be"); fclose(input); vars.clear(); return; @@ -124,7 +124,7 @@ void Config::Parse(const char *file_name) fclose(input); } else { - Error("Config::Parse(), file was unable to be opened for parsing"); + LogError("Config::Parse(), file was unable to be opened for parsing"); } } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 4336d7656..0a873be3f 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -103,7 +103,7 @@ bool Database::GetLoginDataFromAccountInfo( auto results = QueryDatabase(query); if (results.RowCount() != 1) { - LogLoginserverDetail( + LogDebug( "Could not find account for name [{0}] login [{1}]", name, loginserver @@ -121,7 +121,7 @@ bool Database::GetLoginDataFromAccountInfo( id = atoi(row[0]); password = row[1]; - LogLoginserverDetail( + LogDebug( "Found account for name [{0}] login [{1}]", name, loginserver @@ -301,7 +301,7 @@ void Database::UpdateLoginHash( const std::string &hash ) { - LogLoginserverDetail( + LogDebug( "name [{0}] loginserver [{1}] hash [{2}]", name, loginserver, diff --git a/loginserver/main.cpp b/loginserver/main.cpp index b95e51649..223df4197 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -47,10 +47,10 @@ int main() LogSys.LoadLogSettingsDefaults(); - LogLoginserver("Logging System Init"); + LogInfo("Logging System Init"); server.config = EQ::JsonConfigFile::Load("login.json"); - LogLoginserver("Config System Init"); + LogInfo("Config System Init"); server.options.Trace(server.config.GetVariableBool("general", "trace", false)); server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); @@ -119,7 +119,7 @@ int main() /** * mysql connect */ - LogLoginserver("MySQL Database Init"); + LogInfo("MySQL Database Init"); server.db = new Database( server.config.GetVariableString("database", "user", "root"), @@ -135,19 +135,19 @@ int main() * make sure our database got created okay, otherwise cleanup and exit */ if (!server.db) { - Error("Database Initialization Failure"); - LogLoginserver("Log System Shutdown"); + LogError("Database Initialization Failure"); + LogInfo("Log System Shutdown"); return 1; } /** * create server manager */ - LogLoginserver("Server Manager Init"); + LogInfo("Server Manager Init"); server.server_manager = new ServerManager(); if (!server.server_manager) { - Error("Server Manager Failed to Start"); - LogLoginserver("Database System Shutdown"); + LogError("Server Manager Failed to Start"); + LogInfo("Database System Shutdown"); delete server.db; return 1; } @@ -155,14 +155,14 @@ int main() /** * create client manager */ - LogLoginserver("Client Manager Init"); + LogInfo("Client Manager Init"); server.client_manager = new ClientManager(); if (!server.client_manager) { - Error("Client Manager Failed to Start"); - LogLoginserver("Server Manager Shutdown"); + LogError("Client Manager Failed to Start"); + LogInfo("Server Manager Shutdown"); delete server.server_manager; - LogLoginserver("Database System Shutdown"); + LogInfo("Database System Shutdown"); delete server.db; return 1; } @@ -175,10 +175,10 @@ int main() #endif #endif - LogLoginserver("Server Started"); + LogInfo("Server Started"); if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) { - LogLoginserver("Loginserver logging set to level [1] for more debugging, enable detail [3]"); + LogInfo("Loginserver logging set to level [1] for more debugging, enable detail [3]"); } while (run_server) { @@ -188,13 +188,13 @@ int main() Sleep(50); } - LogLoginserver("Server Shutdown"); - LogLoginserver("Client Manager Shutdown"); + LogInfo("Server Shutdown"); + LogInfo("Client Manager Shutdown"); delete server.client_manager; - LogLoginserver("Server Manager Shutdown"); + LogInfo("Server Manager Shutdown"); delete server.server_manager; - LogLoginserver("Database System Shutdown"); + LogInfo("Database System Shutdown"); delete server.db; return 0; } diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 44b323342..711104597 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -39,11 +39,11 @@ ServerManager::ServerManager() opts.ipv6 = false; server_connection->Listen(opts); - LogLoginserver("Loginserver now listening on port [{0}]", listen_port); + LogInfo("Loginserver now listening on port [{0}]", listen_port); server_connection->OnConnectionIdentified( "World", [this](std::shared_ptr world_connection) { - LogLoginserver( + LogInfo( "New world server connection from {0}:{1}", world_connection->Handle()->RemoteIP(), world_connection->Handle()->RemotePort() @@ -55,7 +55,7 @@ ServerManager::ServerManager() 0 && (*iter)->GetConnection()->Handle()->RemotePort() == world_connection->Handle()->RemotePort()) { - LogLoginserver( + LogInfo( "World server already existed for {0}:{1}, removing existing connection.", world_connection->Handle()->RemoteIP(), world_connection->Handle()->RemotePort() @@ -138,7 +138,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) { - LogLoginserver("Client is requesting server list from a local address [{0}]", client_ip); + LogInfo("Client is requesting server list from a local address [{0}]", client_ip); packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; } else { @@ -264,14 +264,14 @@ void ServerManager::SendUserToWorldRequest( found = true; if (server.options.IsDumpInPacketsOn()) { - LogLoginserver("{0}", outapp.ToString()); + LogInfo("{0}", outapp.ToString()); } } ++iter; } if (!found && server.options.IsTraceOn()) { - Error("Client requested a user to world but supplied an invalid id of {0}", server_id); + LogError("Client requested a user to world but supplied an invalid id of {0}", server_id); } } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index fe4fff693..74ae10a59 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -107,7 +107,7 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe } if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) { - Error( + LogError( "Received application packet from server that had opcode ServerOP_NewLSInfo, " "but was too small. Discarded to avoid buffer overrun" ); @@ -118,7 +118,7 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe auto *info = (ServerNewLSInfo_Struct *) packet.Data(); - LogLoginserver( + LogInfo( "Received New Login Server Info \n" " - name [{0}]\n" " - shortname [{1}]\n" @@ -162,7 +162,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet } if (packet.Length() < sizeof(ServerLSStatus_Struct)) { - Error( + LogError( "Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun" ); @@ -171,7 +171,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet auto *ls_status = (ServerLSStatus_Struct *) packet.Data(); - LogLoginserverDetail( + LogDebug( "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", this->GetLongName(), ls_status->status, @@ -201,7 +201,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack } if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) { - Error( + LogError( "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun" ); @@ -284,7 +284,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack delete outapp; } else { - Error( + LogError( "Received User-To-World Response for {0} but could not find the client referenced!", user_to_world_response->lsaccountid ); @@ -403,7 +403,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac delete outapp; } else { - Error("Received User-To-World Response for {0} but could not find the client referenced!.", + LogError("Received User-To-World Response for {0} but could not find the client referenced!.", user_to_world_response->lsaccountid); } } @@ -427,7 +427,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) { - Error( + LogError( "Received application packet from server that had opcode ServerLSAccountUpdate_Struct, " "but was too small. Discarded to avoid buffer overrun" ); @@ -464,7 +464,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info_packet) { if (is_server_logged_in) { - Error("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); + LogError("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); return; } @@ -472,7 +472,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info account_name = new_world_server_info_packet->account; } else { - Error("Handle_NewLSInfo error, account name was too long."); + LogError("Handle_NewLSInfo error, account name was too long."); return; } @@ -480,7 +480,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info account_password = new_world_server_info_packet->password; } else { - Error("Handle_NewLSInfo error, account password was too long."); + LogError("Handle_NewLSInfo error, account password was too long."); return; } @@ -488,7 +488,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info long_name = new_world_server_info_packet->name; } else { - Error("Handle_NewLSInfo error, long name was too long."); + LogError("Handle_NewLSInfo error, long name was too long."); return; } @@ -496,13 +496,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info short_name = new_world_server_info_packet->shortname; } else { - Error("Handle_NewLSInfo error, short name was too long."); + LogError("Handle_NewLSInfo error, short name was too long."); return; } if (strlen(new_world_server_info_packet->local_address) <= 125) { if (strlen(new_world_server_info_packet->local_address) == 0) { - Error("Handle_NewLSInfo error, local address was null, defaulting to localhost"); + LogError("Handle_NewLSInfo error, local address was null, defaulting to localhost"); local_ip = "127.0.0.1"; } else { @@ -510,7 +510,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info } } else { - Error("Handle_NewLSInfo error, local address was too long."); + LogError("Handle_NewLSInfo error, local address was too long."); return; } @@ -518,7 +518,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info if (strlen(new_world_server_info_packet->remote_address) <= 125) { if (strlen(new_world_server_info_packet->remote_address) == 0) { remote_ip = GetConnection()->Handle()->RemoteIP(); - Error( + LogError( "Remote address was null, defaulting to stream address %s.", remote_ip.c_str() ); @@ -542,7 +542,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info version = new_world_server_info_packet->serverversion; } else { - Error("Handle_NewLSInfo error, server version was too long."); + LogError("Handle_NewLSInfo error, server version was too long."); return; } @@ -550,7 +550,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info protocol = new_world_server_info_packet->protocolversion; } else { - Error("Handle_NewLSInfo error, protocol version was too long."); + LogError("Handle_NewLSInfo error, protocol version was too long."); return; } @@ -559,13 +559,13 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info if (server.options.IsRejectingDuplicateServers()) { if (server.server_manager->ServerExists(long_name, short_name, this)) { - Error("World tried to login but there already exists a server that has that name"); + LogError("World tried to login but there already exists a server that has that name"); return; } } else { if (server.server_manager->ServerExists(long_name, short_name, this)) { - Error("World tried to login but there already exists a server that has that name"); + LogError("World tried to login but there already exists a server that has that name"); server.server_manager->DestroyServerByName(long_name, short_name, this); } } @@ -700,14 +700,14 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info * this is the second of two cases where we should deny access even if unregistered is allowed */ if (server_account_name.size() > 0 || server_account_password.size() > 0) { - LogLoginserver( + LogInfo( "Server [{0}] [{1}] did not login but this server required a password to login", long_name, short_name ); } else { - LogLoginserver( + LogInfo( "Server [{0}] [{1}] did not login but unregistered servers are allowed", long_name, short_name @@ -720,7 +720,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info } } else { - LogLoginserver( + LogInfo( "Server [{0}] ({1}) is not registered but unregistered servers are allowed", long_name, short_name @@ -782,7 +782,7 @@ void WorldServer::SendClientAuth( client_auth.local = 1; } else if (IpUtil::IsIpInPrivateRfc1918(client_address)) { - LogLoginserver("Client is authenticating from a local address [{0}]", client_address); + LogInfo("Client is authenticating from a local address [{0}]", client_address); client_auth.local = 1; } else { @@ -792,13 +792,13 @@ void WorldServer::SendClientAuth( struct in_addr ip_addr{}; ip_addr.s_addr = client_auth.ip; - LogLoginserver( + LogInfo( "Client authentication response: world_address [{0}] client_address [{1}]", world_address, client_address ); - LogLoginserver( + LogInfo( "Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] " " world_admin [{5}] ip [{6}] local [{7}]", client_auth.lsaccount_id, From 9d3ece8133a1eefb19bdf87f0ed67ad31dceb62f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 18:34:08 -0500 Subject: [PATCH 049/491] More logging --- common/dbcore.cpp | 25 ++++++++++++++++++------- common/eqemu_logsys.h | 4 ---- loginserver/client.cpp | 4 ++-- loginserver/world_server.cpp | 4 +--- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/common/dbcore.cpp b/common/dbcore.cpp index e493042d0..47b70ca8d 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -21,6 +21,7 @@ #else #include "unix.h" +#include "timer.h" #include #endif @@ -129,29 +130,39 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo rowCount = (uint32) mysql_num_rows(res); } + BenchTimer timer; + timer.reset(); + MySQLRequestResult requestResult( res, (uint32) mysql_affected_rows(&mysql), rowCount, (uint32) mysql_field_count(&mysql), - (uint32) mysql_insert_id(&mysql)); + (uint32) mysql_insert_id(&mysql) + ); if (LogSys.log_settings[Logs::MySQLQuery].is_category_enabled == 1) { if ((strncasecmp(query, "select", 6) == 0)) { - Log(Logs::General, + LogF( + Logs::General, Logs::MySQLQuery, - "%s (%u row%s returned)", + "{0} ({1} row{2} returned) ({3}ms)", query, requestResult.RowCount(), - requestResult.RowCount() == 1 ? "" : "s"); + requestResult.RowCount() == 1 ? "" : "s", + std::to_string(timer.elapsed()) + ); } else { - Log(Logs::General, + LogF( + Logs::General, Logs::MySQLQuery, - "%s (%u row%s affected)", + "{0} ({1} row{2} affected) ({3}ms)", query, requestResult.RowsAffected(), - requestResult.RowsAffected() == 1 ? "" : "s"); + requestResult.RowsAffected() == 1 ? "" : "s", + std::to_string(timer.elapsed()) + ); } } diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 4626b0399..ecb779821 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -214,10 +214,6 @@ namespace Logs { OutF(LogSys, Logs::General, Logs::Debug, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) - - - - /** * Other */ diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 41e6c16dc..c9a762da4 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -274,7 +274,7 @@ void Client::Handle_Login(const char *data, unsigned int size) * Login accepted */ if (result) { - LogDebug( + LogInfo( "login [{0}] user [{1}] Login succeeded", db_loginserver, user @@ -283,7 +283,7 @@ void Client::Handle_Login(const char *data, unsigned int size) DoSuccessfulLogin(user, db_account_id, db_loginserver); } else { - LogDebug( + LogInfo( "login [{0}] user [{1}] Login failed", db_loginserver, user diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 74ae10a59..77be8513b 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -331,9 +331,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac user_to_world_response->login ); if (client) { - Log(Logs::General, - Logs::Debug, - "Found client with user id of %u and account name of %s.", + LogDebug("Found client with user id of {0} and account name of {1}", user_to_world_response->lsaccountid, client->GetAccountName().c_str() ); From 3eb102a006f68a18217d600289256305f263019c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 19:43:10 -0500 Subject: [PATCH 050/491] Fix issue with adding the real values of new logging categories --- common/database.cpp | 33 +++++++------ common/eqemu_logsys.cpp | 32 ++++++------ loginserver/database.cpp | 28 +++++------ queryserv/database.cpp | 104 ++++++++++++++++++++++++++++----------- ucs/database.cpp | 102 +++++++++++++++++++++++++++----------- 5 files changed, 194 insertions(+), 105 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 0e5ed3ae5..38c286620 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -2065,10 +2065,11 @@ uint32 Database::GetGuildIDByCharID(uint32 character_id) return atoi(row[0]); } +/** + * @param log_settings + */ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) { - // log_settings previously initialized to '0' by EQEmuLogSys::LoadLogSettingsDefaults() - std::string query = "SELECT " "log_category_id, " @@ -2080,11 +2081,10 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) "logsys_categories " "ORDER BY log_category_id"; - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); + int log_category_id = 0; - int log_category_id = 0; - - int categories_in_database[1000] = {}; + int *categories_in_database = new int[1000]; for (auto row = results.begin(); row != results.end(); ++row) { log_category_id = atoi(row[0]); @@ -2124,15 +2124,14 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) * Auto inject categories that don't exist in the database... */ for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { - if (!categories_in_database[log_index]) { + if (categories_in_database[log_index] != 1) { - Log(Logs::General, - Logs::Status, - "New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...", + LogInfo( + "New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...", Logs::LogCategoryName[log_index] ); - std::string inject_query = StringFormat( + auto inject_query = fmt::format( "INSERT INTO logsys_categories " "(log_category_id, " "log_category_description, " @@ -2140,17 +2139,19 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) "log_to_file, " "log_to_gmsay) " "VALUES " - "(%i, '%s', %i, %i, %i)", + "({0}, '{1}', {2}, {3}, {4})", log_index, - EscapeString(Logs::LogCategoryName[log_index]).c_str(), - log_settings[log_category_id].log_to_console, - log_settings[log_category_id].log_to_file, - log_settings[log_category_id].log_to_gmsay + EscapeString(Logs::LogCategoryName[log_index]), + std::to_string(log_settings[log_index].log_to_console), + std::to_string(log_settings[log_index].log_to_file), + std::to_string(log_settings[log_index].log_to_gmsay) ); QueryDatabase(inject_query); } } + + delete[] categories_in_database; } int Database::CountInvSnapshots() { diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 8c1f619f1..aed5365f5 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -123,26 +123,26 @@ void EQEmuLogSys::LoadLogSettingsDefaults() /** * Set Defaults */ - log_settings[Logs::World_Server].log_to_console = Logs::General; - log_settings[Logs::Zone_Server].log_to_console = Logs::General; - log_settings[Logs::QS_Server].log_to_console = Logs::General; - log_settings[Logs::UCS_Server].log_to_console = Logs::General; - log_settings[Logs::Crash].log_to_console = Logs::General; - log_settings[Logs::MySQLError].log_to_console = Logs::General; - log_settings[Logs::Login_Server].log_to_console = Logs::General; - log_settings[Logs::Headless_Client].log_to_console = Logs::General; - log_settings[Logs::NPCScaling].log_to_gmsay = Logs::General; + log_settings[Logs::World_Server].log_to_console = static_cast(Logs::General); + log_settings[Logs::Zone_Server].log_to_console = static_cast(Logs::General); + log_settings[Logs::QS_Server].log_to_console = static_cast(Logs::General); + log_settings[Logs::UCS_Server].log_to_console = static_cast(Logs::General); + log_settings[Logs::Crash].log_to_console = static_cast(Logs::General); + log_settings[Logs::MySQLError].log_to_console = static_cast(Logs::General); + log_settings[Logs::Login_Server].log_to_console = static_cast(Logs::General); + log_settings[Logs::Headless_Client].log_to_console = static_cast(Logs::General); + log_settings[Logs::NPCScaling].log_to_gmsay = static_cast(Logs::General); /** * RFC 5424 */ - log_settings[Logs::Emergency].log_to_console = Logs::General; - log_settings[Logs::Alert].log_to_console = Logs::General; - log_settings[Logs::Critical].log_to_console = Logs::General; - log_settings[Logs::Error].log_to_console = Logs::General; - log_settings[Logs::Warning].log_to_console = Logs::General; - log_settings[Logs::Notice].log_to_console = Logs::General; - log_settings[Logs::Info].log_to_console = Logs::General; + log_settings[Logs::Emergency].log_to_console = static_cast(Logs::General); + log_settings[Logs::Alert].log_to_console = static_cast(Logs::General); + log_settings[Logs::Critical].log_to_console = static_cast(Logs::General); + log_settings[Logs::Error].log_to_console = static_cast(Logs::General); + log_settings[Logs::Warning].log_to_console = static_cast(Logs::General); + log_settings[Logs::Notice].log_to_console = static_cast(Logs::General); + log_settings[Logs::Info].log_to_console = static_cast(Logs::General); /** * Set Category enabled status on defaults diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 0a873be3f..2bc6d9387 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -520,11 +520,10 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) "logsys_categories " "ORDER BY log_category_id"; - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); + int log_category_id = 0; - int log_category_id = 0; - - int categories_in_database[1000] = {}; + int *categories_in_database = new int[1000]; for (auto row = results.begin(); row != results.end(); ++row) { log_category_id = atoi(row[0]); @@ -564,15 +563,14 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) * Auto inject categories that don't exist in the database... */ for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { - if (!categories_in_database[log_index]) { + if (categories_in_database[log_index] != 1) { - Log(Logs::General, - Logs::Status, - "New Log Category '%s' doesn't exist... Automatically adding to `logsys_categories` table...", + LogInfo( + "New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...", Logs::LogCategoryName[log_index] ); - std::string inject_query = StringFormat( + auto inject_query = fmt::format( "INSERT INTO logsys_categories " "(log_category_id, " "log_category_description, " @@ -580,15 +578,17 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) "log_to_file, " "log_to_gmsay) " "VALUES " - "(%i, '%s', %i, %i, %i)", + "({0}, '{1}', {2}, {3}, {4})", log_index, - EscapeString(Logs::LogCategoryName[log_index]).c_str(), - log_settings[log_category_id].log_to_console, - log_settings[log_category_id].log_to_file, - log_settings[log_category_id].log_to_gmsay + EscapeString(Logs::LogCategoryName[log_index]), + std::to_string(log_settings[log_index].log_to_console), + std::to_string(log_settings[log_index].log_to_file), + std::to_string(log_settings[log_index].log_to_gmsay) ); QueryDatabase(inject_query); } } + + delete[] categories_in_database; } \ No newline at end of file diff --git a/queryserv/database.cpp b/queryserv/database.cpp index fcda884e4..02d985a8b 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -397,44 +397,88 @@ void Database::GeneralQueryReceive(ServerPacket *pack) { safe_delete_array(queryBuffer); } -void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings){ +void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) +{ std::string query = - "SELECT " - "log_category_id, " - "log_category_description, " - "log_to_console, " - "log_to_file, " - "log_to_gmsay " - "FROM " - "logsys_categories " - "ORDER BY log_category_id"; - auto results = QueryDatabase(query); + "SELECT " + "log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay " + "FROM " + "logsys_categories " + "ORDER BY log_category_id"; - int log_category = 0; - LogSys.file_logs_enabled = false; + auto results = QueryDatabase(query); + int log_category_id = 0; + + int *categories_in_database = new int[1000]; for (auto row = results.begin(); row != results.end(); ++row) { - log_category = atoi(row[0]); - log_settings[log_category].log_to_console = atoi(row[2]); - log_settings[log_category].log_to_file = atoi(row[3]); - log_settings[log_category].log_to_gmsay = atoi(row[4]); + log_category_id = atoi(row[0]); + if (log_category_id <= Logs::None || log_category_id >= Logs::MaxCategoryID) { + continue; + } - /* Determine if any output method is enabled for the category - and set it to 1 so it can used to check if category is enabled */ - const bool log_to_console = log_settings[log_category].log_to_console > 0; - const bool log_to_file = log_settings[log_category].log_to_file > 0; - const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; + log_settings[log_category_id].log_to_console = static_cast(atoi(row[2])); + log_settings[log_category_id].log_to_file = static_cast(atoi(row[3])); + log_settings[log_category_id].log_to_gmsay = static_cast(atoi(row[4])); + + /** + * Determine if any output method is enabled for the category + * and set it to 1 so it can used to check if category is enabled + */ + const bool log_to_console = log_settings[log_category_id].log_to_console > 0; + const bool log_to_file = log_settings[log_category_id].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0; const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay; - if (is_category_enabled) - log_settings[log_category].is_category_enabled = 1; + if (is_category_enabled) { + log_settings[log_category_id].is_category_enabled = 1; + } - /* - This determines whether or not the process needs to actually file log anything. - If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open - */ - if (log_settings[log_category].log_to_file > 0){ + /** + * This determines whether or not the process needs to actually file log anything. + * If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open + */ + if (log_settings[log_category_id].log_to_file > 0) { LogSys.file_logs_enabled = true; } + + categories_in_database[log_category_id] = 1; } -} + + /** + * Auto inject categories that don't exist in the database... + */ + for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { + if (categories_in_database[log_index] != 1) { + + LogInfo( + "New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...", + Logs::LogCategoryName[log_index] + ); + + auto inject_query = fmt::format( + "INSERT INTO logsys_categories " + "(log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay) " + "VALUES " + "({0}, '{1}', {2}, {3}, {4})", + log_index, + EscapeString(Logs::LogCategoryName[log_index]), + std::to_string(log_settings[log_index].log_to_console), + std::to_string(log_settings[log_index].log_to_file), + std::to_string(log_settings[log_index].log_to_gmsay) + ); + + QueryDatabase(inject_query); + } + } + + delete[] categories_in_database; +} \ No newline at end of file diff --git a/ucs/database.cpp b/ucs/database.cpp index 5104c851d..00cad774d 100644 --- a/ucs/database.cpp +++ b/ucs/database.cpp @@ -581,44 +581,88 @@ void Database::GetFriendsAndIgnore(int charID, std::vector &friends } -void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings){ +void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) +{ std::string query = - "SELECT " - "log_category_id, " - "log_category_description, " - "log_to_console, " - "log_to_file, " - "log_to_gmsay " - "FROM " - "logsys_categories " - "ORDER BY log_category_id"; - auto results = QueryDatabase(query); + "SELECT " + "log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay " + "FROM " + "logsys_categories " + "ORDER BY log_category_id"; - int log_category = 0; - LogSys.file_logs_enabled = false; + auto results = QueryDatabase(query); + int log_category_id = 0; + + int *categories_in_database = new int[1000]; for (auto row = results.begin(); row != results.end(); ++row) { - log_category = atoi(row[0]); - log_settings[log_category].log_to_console = atoi(row[2]); - log_settings[log_category].log_to_file = atoi(row[3]); - log_settings[log_category].log_to_gmsay = atoi(row[4]); + log_category_id = atoi(row[0]); + if (log_category_id <= Logs::None || log_category_id >= Logs::MaxCategoryID) { + continue; + } - /* Determine if any output method is enabled for the category - and set it to 1 so it can used to check if category is enabled */ - const bool log_to_console = log_settings[log_category].log_to_console > 0; - const bool log_to_file = log_settings[log_category].log_to_file > 0; - const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; + log_settings[log_category_id].log_to_console = static_cast(atoi(row[2])); + log_settings[log_category_id].log_to_file = static_cast(atoi(row[3])); + log_settings[log_category_id].log_to_gmsay = static_cast(atoi(row[4])); + + /** + * Determine if any output method is enabled for the category + * and set it to 1 so it can used to check if category is enabled + */ + const bool log_to_console = log_settings[log_category_id].log_to_console > 0; + const bool log_to_file = log_settings[log_category_id].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category_id].log_to_gmsay > 0; const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay; - if (is_category_enabled) - log_settings[log_category].is_category_enabled = 1; + if (is_category_enabled) { + log_settings[log_category_id].is_category_enabled = 1; + } - /* - This determines whether or not the process needs to actually file log anything. - If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open - */ - if (log_settings[log_category].log_to_file > 0){ + /** + * This determines whether or not the process needs to actually file log anything. + * If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open + */ + if (log_settings[log_category_id].log_to_file > 0) { LogSys.file_logs_enabled = true; } + + categories_in_database[log_category_id] = 1; } + + /** + * Auto inject categories that don't exist in the database... + */ + for (int log_index = Logs::AA; log_index != Logs::MaxCategoryID; log_index++) { + if (categories_in_database[log_index] != 1) { + + LogInfo( + "New Log Category [{0}] doesn't exist... Automatically adding to [logsys_categories] table...", + Logs::LogCategoryName[log_index] + ); + + auto inject_query = fmt::format( + "INSERT INTO logsys_categories " + "(log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay) " + "VALUES " + "({0}, '{1}', {2}, {3}, {4})", + log_index, + EscapeString(Logs::LogCategoryName[log_index]), + std::to_string(log_settings[log_index].log_to_console), + std::to_string(log_settings[log_index].log_to_file), + std::to_string(log_settings[log_index].log_to_gmsay) + ); + + QueryDatabase(inject_query); + } + } + + delete[] categories_in_database; } From a9969e500b088f27fd033383d8af71f2ec8275d0 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 5 Jul 2019 21:22:35 -0500 Subject: [PATCH 051/491] ls tweaks --- common/string_util.cpp | 1 - loginserver/client.cpp | 22 ++++++++++++++++------ loginserver/database.cpp | 4 ++-- loginserver/world_server.cpp | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/common/string_util.cpp b/common/string_util.cpp index 953fcada5..7a2a5b445 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -249,7 +249,6 @@ void ParseAccountString(const std::string &s, std::string &account, std::string account = split[1]; } else if(split.size() == 1) { - loginserver = "eqemu"; account = split[0]; } } diff --git a/loginserver/client.cpp b/loginserver/client.cpp index c9a762da4..df43a8693 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -198,9 +198,14 @@ void Client::Handle_Login(const char *data, unsigned int size) char *login_packet_buffer = nullptr; - unsigned int db_account_id = 0; - std::string db_loginserver = "eqemu"; - std::string db_account_password_hash; + unsigned int db_account_id = 0; + + std::string db_loginserver = "local"; + if (server.options.CanAutoLinkAccounts()) { + db_loginserver = "eqemu"; + } + + std::string db_account_password_hash; std::string outbuffer; outbuffer.resize(size - 12); @@ -310,7 +315,12 @@ void Client::Handle_Play(const char *data) auto sequence_in = (unsigned int) play->Sequence; if (server.options.IsTraceOn()) { - LogInfo("Play received from client, server number {0} sequence {1}", server_id_in, sequence_in); + LogInfo( + "Play received from client [{0}] server number {1} sequence {2}", + GetAccountName(), + server_id_in, + sequence_in + ); } this->play_server_id = (unsigned int) play->ServerNumber; @@ -373,9 +383,9 @@ void Client::AttemptLoginAccountCreation( const std::string &loginserver ) { - if (loginserver == "eqemu") { + LogInfo("Attempting login account creation via '{0}'", loginserver); - LogInfo("Attempting login account creation via '{0}'", loginserver); + if (loginserver == "eqemu") { if (!server.options.CanAutoLinkAccounts()) { LogInfo("CanAutoLinkAccounts disabled - sending failed login"); diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 2bc6d9387..19f69e5cb 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -192,7 +192,7 @@ bool Database::GetLoginTokenDataFromToken( unsigned int Database::GetFreeID(const std::string &loginserver) { auto query = fmt::format( - "SELECT MAX(LoginServerID) + 1 FROM {0} WHERE AccountLoginServer='{1}'", + "SELECT IFNULL(MAX(LoginServerID), 0) + 1 FROM {0} WHERE AccountLoginServer='{1}'", server.options.GetAccountTable(), EscapeString(loginserver) ); @@ -204,7 +204,7 @@ unsigned int Database::GetFreeID(const std::string &loginserver) auto row = results.begin(); - return atol(row[0]); + return std::stoi(row[0]); } /** diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 77be8513b..23308c93b 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -798,7 +798,7 @@ void WorldServer::SendClientAuth( LogInfo( "Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] " - " world_admin [{5}] ip [{6}] local [{7}]", + "world_admin [{5}] ip [{6}] local [{7}]", client_auth.lsaccount_id, client_auth.lsname, client_auth.name, From 0668f41de28c23bc466302000144410715f0a056 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 6 Jul 2019 03:19:50 -0500 Subject: [PATCH 052/491] Fix some edge case with account name not being passed to world --- common/database.cpp | 227 ++++++++++------- common/servertalk.h | 24 +- loginserver/client.cpp | 32 ++- loginserver/client.h | 4 +- loginserver/database.cpp | 12 +- loginserver/database.h | 4 +- loginserver/world_server.cpp | 39 +-- loginserver/world_server.h | 2 +- world/client.cpp | 5 +- world/cliententry.cpp | 252 +++++++++++-------- world/cliententry.h | 10 +- world/clientlist.cpp | 11 +- world/login_server.cpp | 476 ++++++++++++++++++++++++++--------- world/login_server.h | 2 +- 14 files changed, 718 insertions(+), 382 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 38c286620..92627f3bf 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -64,8 +64,8 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c uint32 errnum= 0; char errbuf[MYSQL_ERRMSG_SIZE]; if (!Open(host, user, passwd, database, port, &errnum, errbuf)) { - Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); - return false; + Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); + return false; } else { Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port); @@ -140,16 +140,16 @@ bool Database::CheckBannedIPs(const char* loginIP) } bool Database::AddBannedIP(char* bannedIP, const char* notes) { - std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes); - auto results = QueryDatabase(query); + std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes); + auto results = QueryDatabase(query); if (!results.Success()) { return false; - } + } return true; } bool Database::CheckGMIPs(const char* ip_address, uint32 account_id) { - std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id); + std::string query = StringFormat("SELECT * FROM `gm_ips` WHERE `ip_address` = '%s' AND `account_id` = %i", ip_address, account_id); auto results = QueryDatabase(query); if (!results.Success()) @@ -162,14 +162,14 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) { } bool Database::AddGMIP(char* ip_address, char* name) { - std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name); - auto results = QueryDatabase(query); + std::string query = StringFormat("INSERT into `gm_ips` SET `ip_address` = '%s', `name` = '%s'", ip_address, name); + auto results = QueryDatabase(query); return results.Success(); } void Database::LoginIP(uint32 AccountID, const char* LoginIP) { - std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP); - QueryDatabase(query); + std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP); + QueryDatabase(query); } int16 Database::CheckStatus(uint32 account_id) @@ -198,23 +198,52 @@ int16 Database::CheckStatus(uint32 account_id) return status; } -uint32 Database::CreateAccount(const char* name, const char* password, int16 status, const char* loginserver, uint32 lsaccount_id) { +/** + * @param name + * @param password + * @param status + * @param loginserver + * @param lsaccount_id + * @return + */ +uint32 Database::CreateAccount( + const char *name, + const char *password, + int16 status, + const char *loginserver, + uint32 lsaccount_id +) +{ std::string query; - if (password) - query = StringFormat("INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();", name, password, status, loginserver, lsaccount_id); - else - query = StringFormat("INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, loginserver, lsaccount_id); + if (password) { + query = StringFormat( + "INSERT INTO account SET name='%s', password='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();", + name, + password, + status, + loginserver, + lsaccount_id + ); + } + else { + query = StringFormat( + "INSERT INTO account SET name='%s', status=%i, ls_id='%s', lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();", + name, + status, + loginserver, + lsaccount_id + ); + } - Log(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s:%s' status: %i", loginserver, name, status); + LogInfo("Account Attempting to be created: [{0}:{1}] status: {2}", loginserver, name, status); auto results = QueryDatabase(query); if (!results.Success()) { return 0; } - if (results.LastInsertedID() == 0) - { + if (results.LastInsertedID() == 0) { return 0; } @@ -222,10 +251,10 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta } bool Database::DeleteAccount(const char* name, const char *loginserver) { - std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver); + std::string query = StringFormat("DELETE FROM account WHERE name='%s' AND ls_id='%s'", name, loginserver); Log(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s:%s'", loginserver, name); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); if (!results.Success()) { return false; } @@ -258,7 +287,7 @@ bool Database::SetAccountStatus(const char* name, int16 status) { if (results.RowsAffected() == 0) { std::cout << "Account: " << name << " does not exist, therefore it cannot be flagged\n"; - return false; + return false; } return true; @@ -275,9 +304,9 @@ bool Database::ReserveName(uint32 account_id, char* name) { } } - query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name); + query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name); results = QueryDatabase(query); - if (!results.Success() || results.ErrorMessage() != ""){ return false; } + if (!results.Success() || results.ErrorMessage() != ""){ return false; } return true; } @@ -297,9 +326,9 @@ bool Database::DeleteCharacter(char *name) { std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); } - if (charid <= 0){ + if (charid <= 0){ Log(Logs::General, Logs::Error, "Database::DeleteCharacter :: Character (%s) not found, stopping delete...", name); - return false; + return false; } query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query); @@ -342,7 +371,7 @@ bool Database::DeleteCharacter(char *name) { query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d'", charid); #endif QueryDatabase(query); - + return true; } @@ -657,7 +686,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } } } - results = QueryDatabase(query); + results = QueryDatabase(query); /* Save Language */ firstquery = 0; @@ -672,16 +701,16 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe } } } - results = QueryDatabase(query); + results = QueryDatabase(query); return true; } /* This only for new Character creation storing */ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv) { - uint32 charid = 0; - char zone[50]; - float x, y, z; + uint32 charid = 0; + char zone[50]; + float x, y, z; charid = GetCharacterID(pp->name); if(!charid) { @@ -702,7 +731,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu z = pp->z; /* Saves Player Profile Data */ - SaveCharacterCreate(charid, account_id, pp); + SaveCharacterCreate(charid, account_id, pp); /* Insert starting inventory... */ std::string invquery; @@ -710,23 +739,23 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu const EQEmu::ItemInstance* newinv = inv->GetItem(i); if (newinv) { invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)", - charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor()); - - auto results = QueryDatabase(invquery); + charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor()); + + auto results = QueryDatabase(invquery); } if (i == EQEmu::invslot::slotCursor) { - i = EQEmu::invbag::GENERAL_BAGS_BEGIN; + i = EQEmu::invbag::GENERAL_BAGS_BEGIN; continue; } - else if (i == EQEmu::invbag::CURSOR_BAG_END) { - i = EQEmu::invslot::BANK_BEGIN; - continue; + else if (i == EQEmu::invbag::CURSOR_BAG_END) { + i = EQEmu::invslot::BANK_BEGIN; + continue; + } + else if (i == EQEmu::invslot::BANK_END) { + i = EQEmu::invbag::BANK_BAGS_BEGIN; + continue; } - else if (i == EQEmu::invslot::BANK_END) { - i = EQEmu::invbag::BANK_BAGS_BEGIN; - continue; - } i++; } return true; @@ -740,7 +769,7 @@ uint32 Database::GetCharacterID(const char *name) { { return atoi(row[0]); } - return 0; + return 0; } /* @@ -759,7 +788,7 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { } if (results.RowCount() != 1) - return 0; + return 0; auto row = results.begin(); @@ -773,8 +802,8 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { // Retrieve account_id for a given char_id uint32 Database::GetAccountIDByChar(uint32 char_id) { - std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id); - auto results = QueryDatabase(query); + std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id); + auto results = QueryDatabase(query); if (!results.Success()) { return 0; } @@ -782,7 +811,7 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) { if (results.RowCount() != 1) return 0; - auto row = results.begin(); + auto row = results.begin(); return atoi(row[0]); } @@ -790,7 +819,7 @@ uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver if (!isAlphaNumeric(accname)) return 0; - std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1", + std::string query = StringFormat("SELECT `id`, `status`, `lsaccount_id` FROM `account` WHERE `name` = '%s' AND `ls_id`='%s' LIMIT 1", EscapeString(accname).c_str(), EscapeString(loginserver).c_str()); auto results = QueryDatabase(query); @@ -819,7 +848,7 @@ uint32 Database::GetAccountIDByName(const char* accname, const char *loginserver } void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID) { - std::string query = StringFormat("SELECT `name`, `lsaccount_id` FROM `account` WHERE `id` = '%i'", accountid); + std::string query = StringFormat("SELECT `name`, `lsaccount_id` FROM `account` WHERE `id` = '%i'", accountid); auto results = QueryDatabase(query); if (!results.Success()) { @@ -843,7 +872,7 @@ void Database::GetCharName(uint32 char_id, char* name) { auto results = QueryDatabase(query); if (!results.Success()) { - return; + return; } auto row = results.begin(); @@ -922,7 +951,7 @@ bool Database::SetVariable(const std::string varname, const std::string &varvalu // Get zone starting points from DB bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe_x, float* safe_y, float* safe_z, int16* minstatus, uint8* minlevel, char *flag_needed) { - + std::string query = StringFormat("SELECT safe_x, safe_y, safe_z, min_status, min_level, flag_needed FROM zone " " WHERE short_name='%s' AND (version=%i OR version=0) ORDER BY version DESC", short_name, version); auto results = QueryDatabase(query); @@ -952,7 +981,7 @@ bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe } bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) { - + std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name); auto results = QueryDatabase(query); @@ -1005,7 +1034,7 @@ uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) { } bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) { - + std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id); auto results = QueryDatabase(query); @@ -1077,7 +1106,7 @@ const char* Database::GetZoneName(uint32 zoneID, bool ErrorUnknown) { } uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){ - + std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version); auto results = QueryDatabase(query); @@ -1141,7 +1170,7 @@ bool Database::CheckNameFilter(const char* name, bool surname) } } - + std::string query("SELECT name FROM name_filter"); auto results = QueryDatabase(query); @@ -1166,7 +1195,7 @@ bool Database::CheckNameFilter(const char* name, bool surname) } bool Database::AddToNameFilter(const char* name) { - + std::string query = StringFormat("INSERT INTO name_filter (name) values ('%s')", name); auto results = QueryDatabase(query); @@ -1181,33 +1210,47 @@ bool Database::AddToNameFilter(const char* name) { return true; } -uint32 Database::GetAccountIDFromLSID(const std::string& iLoginServer, uint32 iLSID, char* oAccountName, int16* oStatus) { +uint32 Database::GetAccountIDFromLSID( + const std::string &iLoginServer, + uint32 iLSID, char *oAccountName, + int16 *oStatus +) +{ uint32 account_id = 0; //iLoginServer is set by config so don't need to worry about escaping it. - std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i AND ls_id='%s'", iLSID, iLoginServer.c_str()); + + auto query = fmt::format( + "SELECT id, name, status FROM account WHERE lsaccount_id = {0} AND ls_id = '{1}'", + iLSID, + iLoginServer + ); + auto results = QueryDatabase(query); if (!results.Success()) { return 0; } - if (results.RowCount() != 1) + if (results.RowCount() != 1) { return 0; + } for (auto row = results.begin(); row != results.end(); ++row) { account_id = atoi(row[0]); - if (oAccountName) + if (oAccountName) { strcpy(oAccountName, row[1]); - if (oStatus) + } + if (oStatus) { *oStatus = atoi(row[2]); + } } return account_id; } void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) { - + std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id); auto results = QueryDatabase(query); @@ -1230,8 +1273,8 @@ void Database::ClearMerchantTemp(){ QueryDatabase("DELETE FROM merchantlist_temp"); } -bool Database::UpdateName(const char* oldname, const char* newname) { - std::cout << "Renaming " << oldname << " to " << newname << "..." << std::endl; +bool Database::UpdateName(const char* oldname, const char* newname) { + std::cout << "Renaming " << oldname << " to " << newname << "..." << std::endl; std::string query = StringFormat("UPDATE `character_data` SET `name` = '%s' WHERE `name` = '%s';", newname, oldname); auto results = QueryDatabase(query); @@ -1247,7 +1290,7 @@ bool Database::UpdateName(const char* oldname, const char* newname) { // If the name is used or an error occurs, it returns false, otherwise it returns true bool Database::CheckUsedName(const char* name) { std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); if (!results.Success()) { return false; } @@ -1260,7 +1303,7 @@ bool Database::CheckUsedName(const char* name) { uint8 Database::GetServerType() { std::string query("SELECT `value` FROM `variables` WHERE `varname` = 'ServerType' LIMIT 1"); - auto results = QueryDatabase(query); + auto results = QueryDatabase(query); if (!results.Success()) { return 0; } @@ -1293,7 +1336,7 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename) { return MoveCharacterToZone(charname, zonename, GetZoneID(zonename)); } -bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) { +bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) { std::string query = StringFormat("UPDATE `character_data` SET `zone_id` = %i, `x` = -1, `y` = -1, `z` = -1 WHERE `id` = %i", GetZoneID(iZonename), iCharID); auto results = QueryDatabase(query); @@ -1304,7 +1347,7 @@ bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) { return results.RowsAffected() != 0; } -bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) { +bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) { std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked); auto results = QueryDatabase(query); @@ -1315,7 +1358,7 @@ bool Database::SetHackerFlag(const char* accountname, const char* charactername, return results.RowsAffected() != 0; } -bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) { +bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) { //Utilize the "hacker" table, but also give zone information. std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone); auto results = QueryDatabase(query); @@ -1331,7 +1374,7 @@ bool Database::SetMQDetectionFlag(const char* accountname, const char* character uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race) { uint16 race_cap = 0; - + //Check for a racial cap! std::string query = StringFormat("SELECT skillcap from race_skillcaps where skill = %i && race = %i", skillid, in_race); auto results = QueryDatabase(query); @@ -1350,7 +1393,7 @@ uint8 Database::GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 { uint8 skill_level = 0, skill_formula = 0; uint16 base_cap = 0, skill_cap = 0, skill_cap2 = 0, skill_cap3 = 0; - + //Fetch the data from DB. std::string query = StringFormat("SELECT level, formula, pre50cap, post50cap, post60cap from skillcaps where skill = %i && class = %i", skillid, in_class); @@ -1464,24 +1507,24 @@ bool Database::GetLiveChar(uint32 account_id, char* cname) { return true; } -void Database::SetLFP(uint32 CharID, bool LFP) { +void Database::SetLFP(uint32 CharID, bool LFP) { std::string query = StringFormat("UPDATE `character_data` SET `lfp` = %i WHERE `id` = %i",LFP, CharID); - QueryDatabase(query); + QueryDatabase(query); } -void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) { +void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) { std::string query = StringFormat("update `character_data` SET `lfp` = %i, `lfg` = %i, `firstlogon` = %i WHERE `id` = %i",LFP, LFG, firstlogon, CharID); - QueryDatabase(query); + QueryDatabase(query); } -void Database::SetLFG(uint32 CharID, bool LFG) { +void Database::SetLFG(uint32 CharID, bool LFG) { std::string query = StringFormat("update `character_data` SET `lfg` = %i WHERE `id` = %i",LFG, CharID); - QueryDatabase(query); + QueryDatabase(query); } -void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) { +void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) { std::string query = StringFormat( "UPDATE `character_data` SET `firstlogon` = %i WHERE `id` = %i",firstlogon, CharID); - QueryDatabase(query); + QueryDatabase(query); } void Database::AddReport(std::string who, std::string against, std::string lines) @@ -1521,7 +1564,7 @@ void Database::ClearAllGroups(void) void Database::ClearGroup(uint32 gid) { ClearGroupLeader(gid); - + if(gid == 0) { //clear all groups @@ -1534,7 +1577,7 @@ void Database::ClearGroup(uint32 gid) { QueryDatabase(query); } -uint32 Database::GetGroupID(const char* name){ +uint32 Database::GetGroupID(const char* name){ std::string query = StringFormat("SELECT groupid from group_id where name='%s'", name); auto results = QueryDatabase(query); @@ -1579,7 +1622,7 @@ char* Database::GetGroupLeaderForLogin(const char* name, char* leaderbuf) { return leaderbuf; } -void Database::SetGroupLeaderName(uint32 gid, const char* name) { +void Database::SetGroupLeaderName(uint32 gid, const char* name) { std::string query = StringFormat("UPDATE group_leaders SET leadername = '%s' WHERE gid = %u", EscapeString(name).c_str(), gid); auto result = QueryDatabase(query); @@ -1667,7 +1710,7 @@ void Database::ClearAllGroupLeaders(void) { } void Database::ClearGroupLeader(uint32 gid) { - + if(gid == 0) { ClearAllGroupLeaders(); @@ -1738,7 +1781,7 @@ void Database::ClearAllRaidDetails(void) } void Database::ClearRaidDetails(uint32 rid) { - + if(rid == 0) { //clear all raids @@ -1766,7 +1809,7 @@ void Database::PurgeAllDeletedDataBuckets() { // returns 0 on error or no raid for that character, or // the raid id that the character is a member of. uint32 Database::GetRaidID(const char* name) -{ +{ std::string query = StringFormat("SELECT `raidid` FROM `raid_members` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); @@ -1774,7 +1817,7 @@ uint32 Database::GetRaidID(const char* name) return 0; } - auto row = results.begin(); + auto row = results.begin(); if (row == results.end()) { return 0; } @@ -1793,7 +1836,7 @@ const char* Database::GetRaidLeaderName(uint32 raid_id) // variable). C++0x standard states this should be thread safe // but may not be fully supported in some compilers. static char name[128]; - + std::string query = StringFormat("SELECT `name` FROM `raid_members` WHERE `raidid` = %u AND `israidleader` = 1", raid_id); auto results = QueryDatabase(query); @@ -2021,7 +2064,7 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as) "FROM " "`adventure_stats` " "WHERE " - "player_id = %u ", + "player_id = %u ", char_id ); auto results = QueryDatabase(query); @@ -2050,7 +2093,7 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as) return true; } -uint32 Database::GetGuildIDByCharID(uint32 character_id) +uint32 Database::GetGuildIDByCharID(uint32 character_id) { std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", character_id); auto results = QueryDatabase(query); @@ -2222,12 +2265,12 @@ bool Database::SaveTime(int8 minute, int8 hour, int8 day, int8 month, int16 year int Database::GetIPExemption(std::string account_ip) { std::string query = StringFormat("SELECT `exemption_amount` FROM `ip_exemptions` WHERE `exemption_ip` = '%s'", account_ip.c_str()); auto results = QueryDatabase(query); - + if (results.Success() && results.RowCount() > 0) { auto row = results.begin(); return atoi(row[0]); } - + return RuleI(World, MaxClientsPerIP); } diff --git a/common/servertalk.h b/common/servertalk.h index 0a6bd25e6..242635b1d 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -519,35 +519,35 @@ struct ServerLSPlayerZoneChange_Struct { }; struct ClientAuth_Struct { - uint32 lsaccount_id; // ID# in login server's db - char lsname[64]; - char name[30]; // username in login server's db + uint32 loginserver_account_id; // ID# in login server's db + char loginserver_name[64]; + char account_name[30]; // username in login server's db char key[30]; // the Key the client will present uint8 lsadmin; // login server admin level - int16 worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it + int16 is_world_admin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it uint32 ip; - uint8 local; // 1 if the client is from the local network + uint8 is_client_from_local_network; // 1 if the client is from the local network template void serialize(Archive &ar) { - ar(lsaccount_id, lsname, name, key, lsadmin, worldadmin, ip, local); + ar(loginserver_account_id, loginserver_name, account_name, key, lsadmin, is_world_admin, ip, is_client_from_local_network); } }; struct ClientAuthLegacy_Struct { - uint32 lsaccount_id; // ID# in login server's db - char name[30]; // username in login server's db + uint32 loginserver_account_id; // ID# in login server's db + char loginserver_account_name[30]; // username in login server's db char key[30]; // the Key the client will present - uint8 lsadmin; // login server admin level - int16 worldadmin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it + uint8 loginserver_admin_level; // login server admin level + int16 is_world_admin; // login's suggested worldadmin level setting for this user, up to the world if they want to obey it uint32 ip; - uint8 local; // 1 if the client is from the local network + uint8 is_client_from_local_network; // 1 if the client is from the local network template void serialize(Archive &ar) { - ar(lsaccount_id, name, key, lsadmin, worldadmin, ip, local); + ar(loginserver_account_id, loginserver_account_name, key, loginserver_admin_level, is_world_admin, ip, is_client_from_local_network); } }; diff --git a/loginserver/client.cpp b/loginserver/client.cpp index df43a8693..a2cefd39b 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -560,11 +560,15 @@ bool Client::VerifyLoginHash( } /** - * @param user + * @param in_account_name * @param db_account_id * @param db_loginserver */ -void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver) +void Client::DoSuccessfulLogin( + const std::string in_account_name, + int db_account_id, + const std::string &db_loginserver +) { stored_user.clear(); stored_pass.clear(); @@ -578,7 +582,7 @@ void Client::DoSuccessfulLogin(const std::string &user, int db_account_id, const GenerateKey(); account_id = db_account_id; - account_name = user; + account_name = in_account_name; loginserver_name = db_loginserver; auto *outapp = new EQApplicationPacket(OP_LoginAccepted, 10 + 80); @@ -650,25 +654,29 @@ void Client::CreateLocalAccount(const std::string &user, const std::string &pass } /** - * @param user - * @param pass - * @param id + * @param in_account_name + * @param in_account_password + * @param loginserver_account_id */ -void Client::CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id) +void Client::CreateEQEmuAccount( + const std::string &in_account_name, + const std::string &in_account_password, + unsigned int loginserver_account_id +) { auto mode = server.options.GetEncryptionMode(); - auto hash = eqcrypt_hash(user, pass, mode); + auto hash = eqcrypt_hash(in_account_name, in_account_password, mode); - if (server.db->DoesLoginServerAccountExist(user, hash, "eqemu", id)) { - DoSuccessfulLogin(user, id, "eqemu"); + if (server.db->DoesLoginServerAccountExist(in_account_name, hash, "eqemu", loginserver_account_id)) { + DoSuccessfulLogin(in_account_name, loginserver_account_id, "eqemu"); return; } - if (!server.db->CreateLoginDataWithID(user, hash, "eqemu", id)) { + if (!server.db->CreateLoginDataWithID(in_account_name, hash, "eqemu", loginserver_account_id)) { DoFailedLogin(); } else { - DoSuccessfulLogin(user, id, "eqemu"); + DoSuccessfulLogin(in_account_name, loginserver_account_id, "eqemu"); } } diff --git a/loginserver/client.h b/loginserver/client.h index 57440be5a..d52c26f75 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -190,9 +190,9 @@ public: const std::string &hash ); - void DoSuccessfulLogin(const std::string &user, int db_account_id, const std::string &db_loginserver); + void DoSuccessfulLogin(const std::string in_account_name, int db_account_id, const std::string &db_loginserver); void CreateLocalAccount(const std::string &user, const std::string &pass); - void CreateEQEmuAccount(const std::string &user, const std::string &pass, unsigned int id); + void CreateEQEmuAccount(const std::string &in_account_name, const std::string &in_account_password, unsigned int loginserver_account_id); private: EQEmu::Random random; diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 19f69e5cb..176c7d4f2 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -225,15 +225,15 @@ bool Database::CreateLoginData( } /** - * @param name - * @param password + * @param in_account_name + * @param in_account_password * @param loginserver * @param id * @return */ bool Database::CreateLoginDataWithID( - const std::string &name, - const std::string &password, + const std::string &in_account_name, + const std::string &in_account_password, const std::string &loginserver, unsigned int id ) @@ -248,8 +248,8 @@ bool Database::CreateLoginDataWithID( server.options.GetAccountTable(), id, EscapeString(loginserver), - EscapeString(name), - EscapeString(password) + EscapeString(in_account_name), + EscapeString(in_account_password) ); auto results = QueryDatabase(query); diff --git a/loginserver/database.h b/loginserver/database.h index 97e80f073..55c3342af 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -80,8 +80,8 @@ public: unsigned int &id ); bool CreateLoginDataWithID( - const std::string &name, - const std::string &password, + const std::string &in_account_name, + const std::string &in_account_password, const std::string &loginserver, unsigned int id ); diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 23308c93b..518d919bd 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -56,7 +56,7 @@ WorldServer::WorldServer(std::shared_ptr wo worldserver_connection->OnMessage( ServerOP_UsertoWorldRespLeg, std::bind( - &WorldServer::ProcessUsertoWorldRespLeg, + &WorldServer::ProcessUserToWorldResponseLegacy, this, std::placeholders::_1, std::placeholders::_2 @@ -186,7 +186,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet * @param opcode * @param packet */ -void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet) +void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { Log(Logs::General, @@ -205,6 +205,7 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " "but was too small. Discarded to avoid buffer overrun" ); + return; } @@ -216,15 +217,15 @@ void WorldServer::ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Pack } auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); - Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); + + LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid); Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); if (c) { - Log(Logs::General, - Logs::Debug, - "Found client with user id of %u and account name of %s.", + LogDebug( + "Found client with user id of [{0}] and account name of [{1}]", user_to_world_response->lsaccountid, - c->GetAccountName().c_str() + c->GetAccountName() ); auto *outapp = new EQApplicationPacket( @@ -763,28 +764,28 @@ void WorldServer::SendClientAuth( EQ::Net::DynamicPacket outapp; ClientAuth_Struct client_auth{}; - client_auth.lsaccount_id = account_id; + client_auth.loginserver_account_id = account_id; - strncpy(client_auth.name, account.c_str(), 30); + strncpy(client_auth.account_name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); client_auth.lsadmin = 0; - client_auth.worldadmin = 0; + client_auth.is_world_admin = 0; client_auth.ip = inet_addr(ip.c_str()); - strncpy(client_auth.lsname, &loginserver_name[0], 64); + strncpy(client_auth.loginserver_name, &loginserver_name[0], 64); const std::string &client_address(ip); std::string world_address(connection->Handle()->RemoteIP()); if (client_address.compare(world_address) == 0) { - client_auth.local = 1; + client_auth.is_client_from_local_network = 1; } else if (IpUtil::IsIpInPrivateRfc1918(client_address)) { LogInfo("Client is authenticating from a local address [{0}]", client_address); - client_auth.local = 1; + client_auth.is_client_from_local_network = 1; } else { - client_auth.local = 0; + client_auth.is_client_from_local_network = 0; } struct in_addr ip_addr{}; @@ -799,14 +800,14 @@ void WorldServer::SendClientAuth( LogInfo( "Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] " "world_admin [{5}] ip [{6}] local [{7}]", - client_auth.lsaccount_id, - client_auth.lsname, - client_auth.name, + client_auth.loginserver_account_id, + client_auth.loginserver_name, + client_auth.account_name, client_auth.key, client_auth.lsadmin, - client_auth.worldadmin, + client_auth.is_world_admin, inet_ntoa(ip_addr), - client_auth.local + client_auth.is_client_from_local_network ); outapp.PutSerialize(0, client_auth); diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 26cc2762f..97cdb76d5 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -109,7 +109,7 @@ private: */ void ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet); void ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet); - void ProcessUsertoWorldRespLeg(uint16_t opcode, const EQ::Net::Packet &packet); + void ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Net::Packet &packet); void ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet); void ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet); diff --git a/world/client.cpp b/world/client.cpp index 4d677752a..ce97c98d9 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -414,10 +414,11 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { is_player_zoning = (li->zoning == 1); - uint32 id = atoi(name); + LogDebug("Receiving Login Info Packet from Client | name [{0}] password [{1}]", name, password); + uint32 id = atoi(name); if (id == 0) { - Log(Logs::General, Logs::World_Server, "Login ID is 0, disconnecting."); + LogWarning("Receiving Login Info Packet from Client | account_id is 0 - disconnecting"); return false; } diff --git a/world/cliententry.cpp b/world/cliententry.cpp index cb0234ad8..599dff322 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -26,44 +26,53 @@ #include "../common/guilds.h" #include "../common/string_util.h" -extern uint32 numplayers; +extern uint32 numplayers; extern LoginServerList loginserverlist; -extern ClientList client_list; -extern volatile bool RunLoops; +extern ClientList client_list; +extern volatile bool RunLoops; -ClientListEntry::ClientListEntry(uint32 in_id, uint32 iLSID, const char *iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin, uint32 ip, uint8 local) -: id(in_id) +ClientListEntry::ClientListEntry( + uint32 in_id, + uint32 iLSID, + const char *iLoginServerName, + const char *iLoginName, + const char *iLoginKey, + int16 iWorldAdmin, + uint32 ip, + uint8 local +) + : id(in_id) { ClearVars(true); - pIP = ip; + pIP = ip; pLSID = iLSID; if (iLSID > 0) { - + paccountid = database.GetAccountIDFromLSID(iLoginServerName, iLSID, paccountname, &padmin); } - strn0cpy(plsname, iLoginName, sizeof(plsname)); + strn0cpy(loginserver_account_name, iLoginName, sizeof(loginserver_account_name)); strn0cpy(plskey, iLoginKey, sizeof(plskey)); - strn0cpy(pLoginServer, iLoginServerName, sizeof(pLoginServer)); + strn0cpy(source_loginserver, iLoginServerName, sizeof(source_loginserver)); pworldadmin = iWorldAdmin; - plocal=(local==1); + plocal = (local == 1); - pinstance = 0; - pLFGFromLevel = 0; - pLFGToLevel = 0; + pinstance = 0; + pLFGFromLevel = 0; + pLFGToLevel = 0; pLFGMatchFilter = false; memset(pLFGComments, 0, 64); } -ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) -: id(in_id) +ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer *iZS, ServerClientList_Struct *scl, int8 iOnline) + : id(in_id) { ClearVars(true); - pIP = 0; + pIP = 0; pLSID = scl->LSAccountID; - strn0cpy(plsname, scl->name, sizeof(plsname)); + strn0cpy(loginserver_account_name, scl->name, sizeof(loginserver_account_name)); strn0cpy(plskey, scl->lskey, sizeof(plskey)); pworldadmin = 0; @@ -71,19 +80,22 @@ ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList strn0cpy(paccountname, scl->AccountName, sizeof(paccountname)); padmin = scl->Admin; - pinstance = 0; - pLFGFromLevel = 0; - pLFGToLevel = 0; + pinstance = 0; + pLFGFromLevel = 0; + pLFGToLevel = 0; pLFGMatchFilter = false; memset(pLFGComments, 0, 64); - if (iOnline >= CLE_Status_Zoning) + if (iOnline >= CLE_Status_Zoning) { Update(iZS, scl, iOnline); - else + } + else { SetOnline(iOnline); + } } -ClientListEntry::~ClientListEntry() { +ClientListEntry::~ClientListEntry() +{ if (RunLoops) { Camp(); // updates zoneserver's numplayers client_list.RemoveCLEReferances(this); @@ -93,97 +105,108 @@ ClientListEntry::~ClientListEntry() { tell_queue.clear(); } -void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) { +void ClientListEntry::SetChar(uint32 iCharID, const char *iCharName) +{ pcharid = iCharID; strn0cpy(pname, iCharName, sizeof(pname)); } -void ClientListEntry::SetOnline(ZoneServer* iZS, int8 iOnline) { - if (iZS == this->Server()) +void ClientListEntry::SetOnline(ZoneServer *iZS, int8 iOnline) +{ + if (iZS == this->Server()) { SetOnline(iOnline); + } } -void ClientListEntry::SetOnline(int8 iOnline) { - if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online) +void ClientListEntry::SetOnline(int8 iOnline) +{ + if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online) { numplayers++; + } else if (iOnline < CLE_Status_Online && pOnline >= CLE_Status_Online) { numplayers--; } - if (iOnline != CLE_Status_Online || pOnline < CLE_Status_Online) + if (iOnline != CLE_Status_Online || pOnline < CLE_Status_Online) { pOnline = iOnline; - if (iOnline < CLE_Status_Zoning) + } + if (iOnline < CLE_Status_Zoning) { Camp(); - if (pOnline >= CLE_Status_Online) + } + if (pOnline >= CLE_Status_Online) { stale = 0; + } } -void ClientListEntry::LSUpdate(ZoneServer* iZS){ - if(WorldConfig::get()->UpdateStats){ +void ClientListEntry::LSUpdate(ZoneServer *iZS) +{ + if (WorldConfig::get()->UpdateStats) { auto pack = new ServerPacket; - pack->opcode = ServerOP_LSZoneInfo; - pack->size = sizeof(ZoneInfo_Struct); + pack->opcode = ServerOP_LSZoneInfo; + pack->size = sizeof(ZoneInfo_Struct); pack->pBuffer = new uchar[pack->size]; - ZoneInfo_Struct* zone =(ZoneInfo_Struct*)pack->pBuffer; - zone->count=iZS->NumPlayers(); - zone->zone = iZS->GetZoneID(); + ZoneInfo_Struct *zone = (ZoneInfo_Struct *) pack->pBuffer; + zone->count = iZS->NumPlayers(); + zone->zone = iZS->GetZoneID(); zone->zone_wid = iZS->GetID(); loginserverlist.SendPacket(pack); safe_delete(pack); } } -void ClientListEntry::LSZoneChange(ZoneToZone_Struct* ztz){ - if(WorldConfig::get()->UpdateStats){ +void ClientListEntry::LSZoneChange(ZoneToZone_Struct *ztz) +{ + if (WorldConfig::get()->UpdateStats) { auto pack = new ServerPacket; - pack->opcode = ServerOP_LSPlayerZoneChange; - pack->size = sizeof(ServerLSPlayerZoneChange_Struct); + pack->opcode = ServerOP_LSPlayerZoneChange; + pack->size = sizeof(ServerLSPlayerZoneChange_Struct); pack->pBuffer = new uchar[pack->size]; - ServerLSPlayerZoneChange_Struct* zonechange =(ServerLSPlayerZoneChange_Struct*)pack->pBuffer; + ServerLSPlayerZoneChange_Struct *zonechange = (ServerLSPlayerZoneChange_Struct *) pack->pBuffer; zonechange->lsaccount_id = LSID(); - zonechange->from = ztz->current_zone_id; - zonechange->to = ztz->requested_zone_id; + zonechange->from = ztz->current_zone_id; + zonechange->to = ztz->requested_zone_id; loginserverlist.SendPacket(pack); safe_delete(pack); } } -void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) { +void ClientListEntry::Update(ZoneServer *iZS, ServerClientList_Struct *scl, int8 iOnline) +{ if (pzoneserver != iZS) { - if (pzoneserver){ + if (pzoneserver) { pzoneserver->RemovePlayer(); LSUpdate(pzoneserver); } - if (iZS){ + if (iZS) { iZS->AddPlayer(); LSUpdate(iZS); } } - pzoneserver = iZS; - pzone = scl->zone; - pinstance = scl->instance_id; - pcharid = scl->charid; + pzoneserver = iZS; + pzone = scl->zone; + pinstance = scl->instance_id; + pcharid = scl->charid; strcpy(pname, scl->name); if (paccountid == 0) { paccountid = scl->AccountID; strcpy(paccountname, scl->AccountName); - strcpy(plsname, scl->AccountName); - pIP = scl->IP; + strcpy(loginserver_account_name, scl->AccountName); + pIP = scl->IP; pLSID = scl->LSAccountID; strn0cpy(plskey, scl->lskey, sizeof(plskey)); } - padmin = scl->Admin; - plevel = scl->level; - pclass_ = scl->class_; - prace = scl->race; - panon = scl->anon; - ptellsoff = scl->tellsoff; - pguild_id = scl->guild_id; - pLFG = scl->LFG; - gm = scl->gm; + padmin = scl->Admin; + plevel = scl->level; + pclass_ = scl->class_; + prace = scl->race; + panon = scl->anon; + ptellsoff = scl->tellsoff; + pguild_id = scl->guild_id; + pLFG = scl->LFG; + gm = scl->gm; pClientVersion = scl->ClientVersion; // Fields from the LFG Window - if((scl->LFGFromLevel != 0) && (scl->LFGToLevel != 0)) { - pLFGFromLevel = scl->LFGFromLevel; - pLFGToLevel = scl->LFGToLevel; + if ((scl->LFGFromLevel != 0) && (scl->LFGToLevel != 0)) { + pLFGFromLevel = scl->LFGFromLevel; + pLFGToLevel = scl->LFGToLevel; pLFGMatchFilter = scl->LFGMatchFilter; memcpy(pLFGComments, scl->LFGComments, sizeof(pLFGComments)); } @@ -191,26 +214,29 @@ void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 SetOnline(iOnline); } -void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) { - if (iZS != 0 && iZS != pzoneserver) +void ClientListEntry::LeavingZone(ZoneServer *iZS, int8 iOnline) +{ + if (iZS != 0 && iZS != pzoneserver) { return; + } SetOnline(iOnline); - if (pzoneserver){ + if (pzoneserver) { pzoneserver->RemovePlayer(); LSUpdate(pzoneserver); } pzoneserver = 0; - pzone = 0; + pzone = 0; } -void ClientListEntry::ClearVars(bool iAll) { +void ClientListEntry::ClearVars(bool iAll) +{ if (iAll) { pOnline = CLE_Status_Never; - stale = 0; + stale = 0; pLSID = 0; - memset(plsname, 0, sizeof(plsname)); + memset(loginserver_account_name, 0, sizeof(loginserver_account_name)); memset(plskey, 0, sizeof(plskey)); pworldadmin = 0; @@ -219,27 +245,29 @@ void ClientListEntry::ClearVars(bool iAll) { padmin = 0; } pzoneserver = 0; - pzone = 0; - pcharid = 0; + pzone = 0; + pcharid = 0; memset(pname, 0, sizeof(pname)); - plevel = 0; - pclass_ = 0; - prace = 0; - panon = 0; - ptellsoff = 0; - pguild_id = GUILD_NONE; - pLFG = 0; - gm = 0; + plevel = 0; + pclass_ = 0; + prace = 0; + panon = 0; + ptellsoff = 0; + pguild_id = GUILD_NONE; + pLFG = 0; + gm = 0; pClientVersion = 0; for (auto &elem : tell_queue) safe_delete_array(elem); tell_queue.clear(); } -void ClientListEntry::Camp(ZoneServer* iZS) { - if (iZS != 0 && iZS != pzoneserver) +void ClientListEntry::Camp(ZoneServer *iZS) +{ + if (iZS != 0 && iZS != pzoneserver) { return; - if (pzoneserver){ + } + if (pzoneserver) { pzoneserver->RemovePlayer(); LSUpdate(pzoneserver); } @@ -249,33 +277,51 @@ void ClientListEntry::Camp(ZoneServer* iZS) { stale = 0; } -bool ClientListEntry::CheckStale() { +bool ClientListEntry::CheckStale() +{ stale++; if (stale > 20) { - if (pOnline > CLE_Status_Offline) + if (pOnline > CLE_Status_Offline) { SetOnline(CLE_Status_Offline); - else + } + else { return true; + } } return false; } -bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { - if (pLSID == iLSID && strncmp(plskey, iKey, 10) == 0) { +bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_password) +{ + if (pLSID == loginserver_account_id && strncmp(plskey, key_password, 10) == 0) { if (paccountid == 0 && LSID() > 0) { - int16 tmpStatus = WorldConfig::get()->DefaultStatus; - paccountid = database.CreateAccount(plsname, 0, tmpStatus, pLoginServer, LSID()); + int16 default_account_status = WorldConfig::get()->DefaultStatus; + + paccountid = database.CreateAccount( + loginserver_account_name, + 0, + default_account_status, + source_loginserver, + LSID() + ); + if (!paccountid) { - Log(Logs::Detail, Logs::World_Server,"Error adding local account for LS login: '%s:%s', duplicate name?", pLoginServer, plsname); + LogInfo( + "Error adding local account for LS login: [{0}:{1}], duplicate name", + source_loginserver, + loginserver_account_name + ); return false; } - strn0cpy(paccountname, plsname, sizeof(paccountname)); - padmin = tmpStatus; + strn0cpy(paccountname, loginserver_account_name, sizeof(paccountname)); + padmin = default_account_status; } std::string lsworldadmin; - if (database.GetVariable("honorlsworldadmin", lsworldadmin)) - if (atoi(lsworldadmin.c_str()) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == 0)) + if (database.GetVariable("honorlsworldadmin", lsworldadmin)) { + if (atoi(lsworldadmin.c_str()) == 1 && pworldadmin != 0 && (padmin < pworldadmin || padmin == 0)) { padmin = pworldadmin; + } + } return true; } return false; @@ -283,13 +329,17 @@ bool ClientListEntry::CheckAuth(uint32 iLSID, const char* iKey) { void ClientListEntry::ProcessTellQueue() { - if (!Server()) + if (!Server()) { return; + } ServerPacket *pack; - auto it = tell_queue.begin(); + auto it = tell_queue.begin(); while (it != tell_queue.end()) { - pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen((*it)->message) + 1); + pack = new ServerPacket( + ServerOP_ChannelMessage, + sizeof(ServerChannelMessage_Struct) + strlen((*it)->message) + 1 + ); memcpy(pack->pBuffer, *it, pack->size); Server()->SendPacket(pack); safe_delete(pack); diff --git a/world/cliententry.h b/world/cliententry.h index ca2f5e07d..0e03c647f 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -28,7 +28,7 @@ public: void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, int8 iOnline = CLE_Status_InZone); void LSUpdate(ZoneServer* zoneserver); void LSZoneChange(ZoneToZone_Struct* ztz); - bool CheckAuth(uint32 iLSID, const char* key); + bool CheckAuth(uint32 loginserver_account_id, const char* key_password); void SetOnline(ZoneServer* iZS, int8 iOnline); void SetOnline(int8 iOnline = CLE_Status_Online); void SetChar(uint32 iCharID, const char* iCharName); @@ -42,10 +42,10 @@ public: void Camp(ZoneServer* iZS = 0); // Login Server stuff - inline const char* LoginServer() const { return pLoginServer; } + inline const char* LoginServer() const { return source_loginserver; } inline uint32 LSID() const { return pLSID; } inline uint32 LSAccountID() const { return pLSID; } - inline const char* LSName() const { return plsname; } + inline const char* LSName() const { return loginserver_account_name; } inline int16 WorldAdmin() const { return pworldadmin; } inline const char* GetLSKey() const { return plskey; } inline const int8 GetOnline() const { return pOnline; } @@ -95,9 +95,9 @@ private: uint8 stale; // Login Server stuff - char pLoginServer[64]; //Loginserver we came from. + char source_loginserver[64]; //Loginserver we came from. uint32 pLSID; - char plsname[32]; + char loginserver_account_name[32]; char plskey[16]; int16 pworldadmin; // Login server's suggested admin status setting bool plocal; diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 237568ff6..c3404fb37 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -410,15 +410,18 @@ void ClientList::CLEKeepAlive(uint32 numupdates, uint32* wid) { } } -ClientListEntry* ClientList::CheckAuth(uint32 iLSID, const char* iKey) { - LinkedListIterator iterator(clientlist); +ClientListEntry *ClientList::CheckAuth(uint32 iLSID, const char *iKey) +{ + LinkedListIterator iterator(clientlist); iterator.Reset(); - while(iterator.MoreElements()) { - if (iterator.GetData()->CheckAuth(iLSID, iKey)) + while (iterator.MoreElements()) { + if (iterator.GetData()->CheckAuth(iLSID, iKey)) { return iterator.GetData(); + } iterator.Advance(); } + return 0; } diff --git a/world/login_server.cpp b/world/login_server.cpp index 4fdb9dc35..18904aaaf 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -36,180 +36,236 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "clientlist.h" #include "world_config.h" -extern ZSList zoneserver_list; -extern ClientList client_list; -extern uint32 numzones; -extern uint32 numplayers; -extern volatile bool RunLoops; +extern ZSList zoneserver_list; +extern ClientList client_list; +extern uint32 numzones; +extern uint32 numplayers; +extern volatile bool RunLoops; -LoginServer::LoginServer(const char* iAddress, uint16 iPort, const char* Account, const char* Password, bool legacy) +LoginServer::LoginServer(const char *iAddress, uint16 iPort, const char *Account, const char *Password, bool legacy) { strn0cpy(LoginServerAddress, iAddress, 256); - LoginServerPort = iPort; - LoginAccount = Account; - LoginPassword = Password; + LoginServerPort = iPort; + LoginAccount = Account; + LoginPassword = Password; CanAccountUpdate = false; - IsLegacy = legacy; + IsLegacy = legacy; Connect(); } -LoginServer::~LoginServer() { +LoginServer::~LoginServer() +{ } -void LoginServer::ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); - UsertoWorldRequestLegacy_Struct* utwr = (UsertoWorldRequestLegacy_Struct*)p.Data(); - uint32 id = database.GetAccountIDFromLSID("eqemu", utwr->lsaccountid); - int16 status = database.CheckStatus(id); + UsertoWorldRequestLegacy_Struct *utwr = (UsertoWorldRequestLegacy_Struct *) p.Data(); + uint32 id = database.GetAccountIDFromLSID("eqemu", utwr->lsaccountid); + int16 status = database.CheckStatus(id); auto outpack = new ServerPacket; - outpack->opcode = ServerOP_UsertoWorldRespLeg; - outpack->size = sizeof(UsertoWorldResponseLegacy_Struct); + outpack->opcode = ServerOP_UsertoWorldRespLeg; + outpack->size = sizeof(UsertoWorldResponseLegacy_Struct); outpack->pBuffer = new uchar[outpack->size]; memset(outpack->pBuffer, 0, outpack->size); - UsertoWorldResponseLegacy_Struct* utwrs = (UsertoWorldResponseLegacy_Struct*)outpack->pBuffer; + UsertoWorldResponseLegacy_Struct *utwrs = (UsertoWorldResponseLegacy_Struct *) outpack->pBuffer; utwrs->lsaccountid = utwr->lsaccountid; - utwrs->ToID = utwr->FromID; + utwrs->ToID = utwr->FromID; - if (Config->Locked == true) - { - if ((status == 0 || status < 100) && (status != -2 || status != -1)) + if (Config->Locked == true) { + if ((status == 0 || status < 100) && (status != -2 || status != -1)) { utwrs->response = 0; - if (status >= 100) + } + if (status >= 100) { utwrs->response = 1; + } } else { utwrs->response = 1; } int32 x = Config->MaxClients; - if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80) + if ((int32) numplayers >= x && x != -1 && x != 255 && status < 80) { utwrs->response = -3; + } - if (status == -1) + if (status == -1) { utwrs->response = -1; - if (status == -2) + } + if (status == -2) { utwrs->response = -2; + } utwrs->worldid = utwr->worldid; SendPacket(outpack); delete outpack; } -void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); - UsertoWorldRequest_Struct* utwr = (UsertoWorldRequest_Struct*)p.Data(); - uint32 id = database.GetAccountIDFromLSID(utwr->login, utwr->lsaccountid); - int16 status = database.CheckStatus(id); + UsertoWorldRequest_Struct *utwr = (UsertoWorldRequest_Struct *) p.Data(); + uint32 id = database.GetAccountIDFromLSID(utwr->login, utwr->lsaccountid); + int16 status = database.CheckStatus(id); auto outpack = new ServerPacket; - outpack->opcode = ServerOP_UsertoWorldResp; - outpack->size = sizeof(UsertoWorldResponse_Struct); + outpack->opcode = ServerOP_UsertoWorldResp; + outpack->size = sizeof(UsertoWorldResponse_Struct); outpack->pBuffer = new uchar[outpack->size]; memset(outpack->pBuffer, 0, outpack->size); - UsertoWorldResponse_Struct* utwrs = (UsertoWorldResponse_Struct*)outpack->pBuffer; + UsertoWorldResponse_Struct *utwrs = (UsertoWorldResponse_Struct *) outpack->pBuffer; utwrs->lsaccountid = utwr->lsaccountid; - utwrs->ToID = utwr->FromID; + utwrs->ToID = utwr->FromID; strn0cpy(utwrs->login, utwr->login, 64); - if (Config->Locked == true) - { - if ((status == 0 || status < 100) && (status != -2 || status != -1)) + if (Config->Locked == true) { + if ((status == 0 || status < 100) && (status != -2 || status != -1)) { utwrs->response = 0; - if (status >= 100) + } + if (status >= 100) { utwrs->response = 1; + } } else { utwrs->response = 1; } int32 x = Config->MaxClients; - if ((int32)numplayers >= x && x != -1 && x != 255 && status < 80) + if ((int32) numplayers >= x && x != -1 && x != 255 && status < 80) { utwrs->response = -3; + } - if (status == -1) + if (status == -1) { utwrs->response = -1; - if (status == -2) + } + if (status == -2) { utwrs->response = -2; + } utwrs->worldid = utwr->worldid; SendPacket(outpack); delete outpack; } -void LoginServer::ProcessLSClientAuthLeg(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessLSClientAuthLegacy(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); - Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + Log(Logs::Detail, Logs::World_Server, "Received ServerPacket from LS OpCode 0x04x", opcode); try { - auto slsca = p.GetSerialize(0); + auto client_authentication_request = p.GetSerialize(0); if (RuleI(World, AccountSessionLimit) >= 0) { // Enforce the limit on the number of characters on the same account that can be // online at the same time. - client_list.EnforceSessionLimit(slsca.lsaccount_id); + client_list.EnforceSessionLimit(client_authentication_request.loginserver_account_id); } - client_list.CLEAdd(slsca.lsaccount_id, "eqemu", slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); + LogDebug( + "Processing Loginserver Auth Legacy | account_id [{0}] account_name [{1}] key [{2}] admin [{3}] ip [{4}] " + "local_network [{5}]", + client_authentication_request.loginserver_account_id, + client_authentication_request.loginserver_account_name, + client_authentication_request.key, + client_authentication_request.is_world_admin, + client_authentication_request.ip, + client_authentication_request.is_client_from_local_network + ); + + client_list.CLEAdd( + client_authentication_request.loginserver_account_id, + "eqemu", + client_authentication_request.loginserver_account_name, + client_authentication_request.key, + client_authentication_request.is_world_admin, + client_authentication_request.ip, + client_authentication_request.is_client_from_local_network + ); } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); + LogError("Error parsing ClientAuthLegacy packet from world\nReason [{0}]", ex.what()); } } -void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); - Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); + Log(Logs::Detail, Logs::World_Server, "Received ServerPacket from LS OpCode 0x04x", opcode); try { - auto slsca = p.GetSerialize(0); + auto client_authentication_request = p.GetSerialize(0); if (RuleI(World, AccountSessionLimit) >= 0) { // Enforce the limit on the number of characters on the same account that can be // online at the same time. - client_list.EnforceSessionLimit(slsca.lsaccount_id); + client_list.EnforceSessionLimit(client_authentication_request.loginserver_account_id); } - client_list.CLEAdd(slsca.lsaccount_id, slsca.lsname, slsca.name, slsca.key, slsca.worldadmin, slsca.ip, slsca.local); + LogDebug( + "Processing Loginserver Auth | account_id [{0}] account_name [{1}] loginserver_name [{2}] key [{3}] " + "admin [{4}] ip [{5}] local_network [{6}]", + client_authentication_request.loginserver_account_id, + client_authentication_request.account_name, + client_authentication_request.loginserver_name, + client_authentication_request.key, + client_authentication_request.is_world_admin, + client_authentication_request.ip, + client_authentication_request.is_client_from_local_network + ); + + client_list.CLEAdd( + client_authentication_request.loginserver_account_id, + client_authentication_request.loginserver_name, + client_authentication_request.account_name, + client_authentication_request.key, + client_authentication_request.is_world_admin, + client_authentication_request.ip, + client_authentication_request.is_client_from_local_network + ); } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing LSClientAuth packet from world.\n{0}", ex.what()); + LogError("Error parsing ClientAuth packet from world\nReason [{0}]", ex.what()); } } -void LoginServer::ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); Log(Logs::Detail, Logs::World_Server, "Login server responded with FatalError."); if (p.Length() > 1) { - Log(Logs::Detail, Logs::World_Server, " %s", (const char*)p.Data()); + Log(Logs::Detail, Logs::World_Server, " %s", (const char *) p.Data()); } } -void LoginServer::ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); - ServerSystemwideMessage* swm = (ServerSystemwideMessage*)p.Data(); + ServerSystemwideMessage *swm = (ServerSystemwideMessage *) p.Data(); zoneserver_list.SendEmoteMessageRaw(0, 0, 0, swm->type, swm->message); } -void LoginServer::ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); if (!Config->WorldAddress.length()) { - WorldConfig::SetWorldAddress((char *)p.Data()); - Log(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char*)p.Data()); + WorldConfig::SetWorldAddress((char *) p.Data()); + Log(Logs::Detail, Logs::World_Server, "Loginserver provided %s as world address", (const char *) p.Data()); } } -void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) { +void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) +{ const WorldConfig *Config = WorldConfig::get(); Log(Logs::Detail, Logs::World_Server, "Recevied ServerPacket from LS OpCode 0x04x", opcode); @@ -217,7 +273,8 @@ void LoginServer::ProcessLSAccountUpdate(uint16_t opcode, EQ::Net::Packet &p) { CanAccountUpdate = true; } -bool LoginServer::Connect() { +bool LoginServer::Connect() +{ char errbuf[1024]; if ((LoginServerIP = ResolveIP(LoginServerAddress, errbuf)) == 0) { Log(Logs::Detail, Logs::World_Server, "Unable to resolve '%s' to an IP.", LoginServerAddress); @@ -225,88 +282,252 @@ bool LoginServer::Connect() { } if (LoginServerIP == 0 || LoginServerPort == 0) { - Log(Logs::Detail, Logs::World_Server, "Connect info incomplete, cannot connect: %s:%d", LoginServerAddress, LoginServerPort); + LogInfo( + "Connect info incomplete, cannot connect: [{0}:{1}]", + LoginServerAddress, + LoginServerPort + ); + return false; } if (IsLegacy) { legacy_client.reset(new EQ::Net::ServertalkLegacyClient(LoginServerAddress, LoginServerPort, false)); - legacy_client->OnConnect([this](EQ::Net::ServertalkLegacyClient *client) { - if (client) { - Log(Logs::Detail, Logs::World_Server, "Connected to Legacy Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - SendInfo(); - SendStatus(); - zoneserver_list.SendLSZones(); + legacy_client->OnConnect( + [this](EQ::Net::ServertalkLegacyClient *client) { + if (client) { + LogInfo( + "Connected to Legacy Loginserver: [{0}:{1}]", + LoginServerAddress, + LoginServerPort + ); - statusupdate_timer.reset(new EQ::Timer(LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) { + SendInfo(); SendStatus(); - })); - } - else { - Log(Logs::Detail, Logs::World_Server, "Could not connect to Legacy Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - } - }); + zoneserver_list.SendLSZones(); - legacy_client->OnMessage(ServerOP_UsertoWorldReqLeg, std::bind(&LoginServer::ProcessUsertoWorldReqLeg, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_LSClientAuthLeg, std::bind(&LoginServer::ProcessLSClientAuthLeg, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessLSRemoteAddr, this, std::placeholders::_1, std::placeholders::_2)); - legacy_client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); + statusupdate_timer.reset( + new EQ::Timer( + LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) { + SendStatus(); + } + ) + ); + } + else { + LogInfo( + "Could not connect to Legacy Loginserver: [{0}:{1}]", + LoginServerAddress, + LoginServerPort + ); + } + } + ); + + legacy_client->OnMessage( + ServerOP_UsertoWorldReqLeg, + std::bind( + &LoginServer::ProcessUsertoWorldReqLeg, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_UsertoWorldReq, + std::bind( + &LoginServer::ProcessUsertoWorldReq, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_LSClientAuthLeg, + std::bind( + &LoginServer::ProcessLSClientAuthLegacy, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_LSClientAuth, + std::bind( + &LoginServer::ProcessLSClientAuth, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_LSFatalError, + std::bind( + &LoginServer::ProcessLSFatalError, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_SystemwideMessage, + std::bind( + &LoginServer::ProcessSystemwideMessage, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_LSRemoteAddr, + std::bind( + &LoginServer::ProcessLSRemoteAddr, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + legacy_client->OnMessage( + ServerOP_LSAccountUpdate, + std::bind( + &LoginServer::ProcessLSAccountUpdate, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); } else { client.reset(new EQ::Net::ServertalkClient(LoginServerAddress, LoginServerPort, false, "World", "")); - client->OnConnect([this](EQ::Net::ServertalkClient *client) { - if (client) { - Log(Logs::Detail, Logs::World_Server, "Connected to Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - SendInfo(); - SendStatus(); - zoneserver_list.SendLSZones(); - - statusupdate_timer.reset(new EQ::Timer(LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) { + client->OnConnect( + [this](EQ::Net::ServertalkClient *client) { + if (client) { + LogInfo( + "Connected to Loginserver: {0}:{1}", + LoginServerAddress, + LoginServerPort + ); + SendInfo(); SendStatus(); - })); - } - else { - Log(Logs::Detail, Logs::World_Server, "Could not connect to Loginserver: %s:%d", LoginServerAddress, LoginServerPort); - } - }); + zoneserver_list.SendLSZones(); - client->OnMessage(ServerOP_UsertoWorldReqLeg, std::bind(&LoginServer::ProcessUsertoWorldReqLeg, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_UsertoWorldReq, std::bind(&LoginServer::ProcessUsertoWorldReq, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSClientAuthLeg, std::bind(&LoginServer::ProcessLSClientAuthLeg, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSClientAuth, std::bind(&LoginServer::ProcessLSClientAuth, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSFatalError, std::bind(&LoginServer::ProcessLSFatalError, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_SystemwideMessage, std::bind(&LoginServer::ProcessSystemwideMessage, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSRemoteAddr, std::bind(&LoginServer::ProcessLSRemoteAddr, this, std::placeholders::_1, std::placeholders::_2)); - client->OnMessage(ServerOP_LSAccountUpdate, std::bind(&LoginServer::ProcessLSAccountUpdate, this, std::placeholders::_1, std::placeholders::_2)); + statusupdate_timer.reset( + new EQ::Timer( + LoginServer_StatusUpdateInterval, true, [this](EQ::Timer *t) { + SendStatus(); + } + )); + } + else { + LogInfo( + "Could not connect to Loginserver: {0}:{1}", + LoginServerAddress, + LoginServerPort + ); + } + } + ); + + client->OnMessage( + ServerOP_UsertoWorldReqLeg, + std::bind( + &LoginServer::ProcessUsertoWorldReqLeg, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_UsertoWorldReq, + std::bind( + &LoginServer::ProcessUsertoWorldReq, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_LSClientAuthLeg, + std::bind( + &LoginServer::ProcessLSClientAuthLegacy, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_LSClientAuth, + std::bind( + &LoginServer::ProcessLSClientAuth, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_LSFatalError, + std::bind( + &LoginServer::ProcessLSFatalError, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_SystemwideMessage, + std::bind( + &LoginServer::ProcessSystemwideMessage, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_LSRemoteAddr, + std::bind( + &LoginServer::ProcessLSRemoteAddr, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + client->OnMessage( + ServerOP_LSAccountUpdate, + std::bind( + &LoginServer::ProcessLSAccountUpdate, + this, + std::placeholders::_1, + std::placeholders::_2 + ) + ); } return true; } -void LoginServer::SendInfo() { +void LoginServer::SendInfo() +{ const WorldConfig *Config = WorldConfig::get(); auto pack = new ServerPacket; - pack->opcode = ServerOP_NewLSInfo; - pack->size = sizeof(ServerNewLSInfo_Struct); + pack->opcode = ServerOP_NewLSInfo; + pack->size = sizeof(ServerNewLSInfo_Struct); pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); - ServerNewLSInfo_Struct* lsi = (ServerNewLSInfo_Struct*)pack->pBuffer; + ServerNewLSInfo_Struct *lsi = (ServerNewLSInfo_Struct *) pack->pBuffer; strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION); strcpy(lsi->serverversion, LOGIN_VERSION); strcpy(lsi->name, Config->LongName.c_str()); strcpy(lsi->shortname, Config->ShortName.c_str()); strn0cpy(lsi->account, LoginAccount.c_str(), 30); strn0cpy(lsi->password, LoginPassword.c_str(), 30); - if (Config->WorldAddress.length()) + if (Config->WorldAddress.length()) { strcpy(lsi->remote_address, Config->WorldAddress.c_str()); - if (Config->LocalAddress.length()) + } + if (Config->LocalAddress.length()) { strcpy(lsi->local_address, Config->LocalAddress.c_str()); + } else { auto local_addr = IsLegacy ? legacy_client->Handle()->LocalIP() : client->Handle()->LocalIP(); strcpy(lsi->local_address, local_addr.c_str()); @@ -316,22 +537,26 @@ void LoginServer::SendInfo() { delete pack; } -void LoginServer::SendStatus() { +void LoginServer::SendStatus() +{ auto pack = new ServerPacket; - pack->opcode = ServerOP_LSStatus; - pack->size = sizeof(ServerLSStatus_Struct); + pack->opcode = ServerOP_LSStatus; + pack->size = sizeof(ServerLSStatus_Struct); pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); - ServerLSStatus_Struct* lss = (ServerLSStatus_Struct*)pack->pBuffer; + ServerLSStatus_Struct *lss = (ServerLSStatus_Struct *) pack->pBuffer; - if (WorldConfig::get()->Locked) + if (WorldConfig::get()->Locked) { lss->status = -2; - else if (numzones <= 0) + } + else if (numzones <= 0) { lss->status = -2; - else + } + else { lss->status = numplayers; + } - lss->num_zones = numzones; + lss->num_zones = numzones; lss->num_players = numplayers; SendPacket(pack); delete pack; @@ -351,10 +576,15 @@ void LoginServer::SendPacket(ServerPacket *pack) } } -void LoginServer::SendAccountUpdate(ServerPacket* pack) { - ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *)pack->pBuffer; +void LoginServer::SendAccountUpdate(ServerPacket *pack) +{ + ServerLSAccountUpdate_Struct *s = (ServerLSAccountUpdate_Struct *) pack->pBuffer; if (CanUpdate()) { - Log(Logs::Detail, Logs::World_Server, "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d", LoginServerAddress, LoginServerPort); + Log(Logs::Detail, + Logs::World_Server, + "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d", + LoginServerAddress, + LoginServerPort); strn0cpy(s->worldaccount, LoginAccount.c_str(), 30); strn0cpy(s->worldpassword, LoginPassword.c_str(), 30); SendPacket(pack); diff --git a/world/login_server.h b/world/login_server.h index 9134f4654..3e5116247 100644 --- a/world/login_server.h +++ b/world/login_server.h @@ -47,7 +47,7 @@ private: void ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p); void ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSClientAuth(uint16_t opcode, EQ::Net::Packet &p); - void ProcessLSClientAuthLeg(uint16_t opcode, EQ::Net::Packet &p); + void ProcessLSClientAuthLegacy(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSFatalError(uint16_t opcode, EQ::Net::Packet &p); void ProcessSystemwideMessage(uint16_t opcode, EQ::Net::Packet &p); void ProcessLSRemoteAddr(uint16_t opcode, EQ::Net::Packet &p); From 7d71163fa08e9d2f792aa87de3e91d7c4e2a1f6b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 6 Jul 2019 03:33:41 -0500 Subject: [PATCH 053/491] Update dbcore.cpp --- common/dbcore.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 47b70ca8d..68cebc4f3 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -71,6 +71,9 @@ MySQLRequestResult DBcore::QueryDatabase(std::string query, bool retryOnFailureO MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, bool retryOnFailureOnce) { + BenchTimer timer; + timer.reset(); + LockMutex lock(&MDatabase); // Reconnect if we are not connected before hand. @@ -130,9 +133,6 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo rowCount = (uint32) mysql_num_rows(res); } - BenchTimer timer; - timer.reset(); - MySQLRequestResult requestResult( res, (uint32) mysql_affected_rows(&mysql), From 78d8b909be24dcea108b90c1bf64865428b4aa1e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 7 Jul 2019 03:13:04 -0500 Subject: [PATCH 054/491] Add standalone web api server, cli handler, authorization, commands --- common/CMakeLists.txt | 2 + common/cli/argh.h | 434 +++ common/eqemu_logsys.h | 1 - common/http/httplib.h | 2694 +++++++++++++++++++ common/json_config.cpp | 33 +- common/json_config.h | 3 +- loginserver/CMakeLists.txt | 4 + loginserver/database.cpp | 45 +- loginserver/database.h | 9 + loginserver/login_server.h | 18 +- loginserver/loginserver_command_handler.cpp | 142 + loginserver/loginserver_command_handler.h | 34 + loginserver/loginserver_webserver.cpp | 243 ++ loginserver/loginserver_webserver.h | 57 + loginserver/main.cpp | 32 +- loginserver/options.h | 2 - loginserver/server_manager.cpp | 8 + loginserver/server_manager.h | 6 + 18 files changed, 3749 insertions(+), 18 deletions(-) create mode 100644 common/cli/argh.h create mode 100644 common/http/httplib.h create mode 100644 loginserver/loginserver_command_handler.cpp create mode 100644 loginserver/loginserver_command_handler.h create mode 100644 loginserver/loginserver_webserver.cpp create mode 100644 loginserver/loginserver_webserver.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 276a1c95a..54c13d897 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -122,6 +122,7 @@ SET(common_headers crash.h crc16.h crc32.h + cli/argh.h data_verification.h database.h dbcore.h @@ -156,6 +157,7 @@ SET(common_headers global_define.h guild_base.h guilds.h + http/httplib.h inventory_profile.h inventory_slot.h ipc_mutex.h diff --git a/common/cli/argh.h b/common/cli/argh.h new file mode 100644 index 000000000..047fa190f --- /dev/null +++ b/common/cli/argh.h @@ -0,0 +1,434 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace argh +{ + // Terminology: + // A command line is composed of 2 types of args: + // 1. Positional args, i.e. free standing values + // 2. Options: args beginning with '-'. We identify two kinds: + // 2.1: Flags: boolean options => (exist ? true : false) + // 2.2: Parameters: a name followed by a non-option value + +#if !defined(__GNUC__) || (__GNUC__ >= 5) + using string_stream = std::istringstream; +#else + // Until GCC 5, istringstream did not have a move constructor. + // stringstream_proxy is used instead, as a workaround. + class stringstream_proxy + { + public: + stringstream_proxy() = default; + + // Construct with a value. + stringstream_proxy(std::string const& value) : + stream_(value) + {} + + // Copy constructor. + stringstream_proxy(const stringstream_proxy& other) : + stream_(other.stream_.str()) + { + stream_.setstate(other.stream_.rdstate()); + } + + void setstate(std::ios_base::iostate state) { stream_.setstate(state); } + + // Stream out the value of the parameter. + // If the conversion was not possible, the stream will enter the fail state, + // and operator bool will return false. + template + stringstream_proxy& operator >> (T& thing) + { + stream_ >> thing; + return *this; + } + + + // Get the string value. + std::string str() const { return stream_.str(); } + + std::stringbuf* rdbuf() const { return stream_.rdbuf(); } + + // Check the state of the stream. + // False when the most recent stream operation failed + operator bool() const { return !!stream_; } + + ~stringstream_proxy() = default; + private: + std::istringstream stream_; + }; + using string_stream = stringstream_proxy; +#endif + + class parser + { + public: + enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0, + PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1, + NO_SPLIT_ON_EQUALSIGN = 1 << 2, + SINGLE_DASH_IS_MULTIFLAG = 1 << 3, + }; + + parser() = default; + + parser(std::initializer_list pre_reg_names) + { add_params(pre_reg_names); } + + parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) + { parse(argv, mode); } + + parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) + { parse(argc, argv, mode); } + + void add_param(std::string const& name); + void add_params(std::initializer_list init_list); + + void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); + void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); + + std::multiset const& flags() const { return flags_; } + std::map const& params() const { return params_; } + std::vector const& pos_args() const { return pos_args_; } + + // begin() and end() for using range-for over positional args. + std::vector::const_iterator begin() const { return pos_args_.cbegin(); } + std::vector::const_iterator end() const { return pos_args_.cend(); } + size_t size() const { return pos_args_.size(); } + + ////////////////////////////////////////////////////////////////////////// + // Accessors + + // flag (boolean) accessors: return true if the flag appeared, otherwise false. + bool operator[](std::string const& name) const; + + // multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false. + bool operator[](std::initializer_list init_list) const; + + // returns positional arg string by order. Like argv[] but without the options + std::string const& operator[](size_t ind) const; + + // returns a std::istream that can be used to convert a positional arg to a typed value. + string_stream operator()(size_t ind) const; + + // same as above, but with a default value in case the arg is missing (index out of range). + template + string_stream operator()(size_t ind, T&& def_val) const; + + // parameter accessors, give a name get an std::istream that can be used to convert to a typed value. + // call .str() on result to get as string + string_stream operator()(std::string const& name) const; + + // accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value. + // call .str() on result to get as string + // returns the first value in the list to be found. + string_stream operator()(std::initializer_list init_list) const; + + // same as above, but with a default value in case the param was missing. + // Non-string def_val types must have an operator<<() (output stream operator) + // If T only has an input stream operator, pass the string version of the type as in "3" instead of 3. + template + string_stream operator()(std::string const& name, T&& def_val) const; + + // same as above but for a list of names. returns the first value to be found. + template + string_stream operator()(std::initializer_list init_list, T&& def_val) const; + + private: + string_stream bad_stream() const; + std::string trim_leading_dashes(std::string const& name) const; + bool is_number(std::string const& arg) const; + bool is_option(std::string const& arg) const; + bool got_flag(std::string const& name) const; + bool is_param(std::string const& name) const; + + private: + std::vector args_; + std::map params_; + std::vector pos_args_; + std::multiset flags_; + std::set registeredParams_; + std::string empty_; + }; + + + ////////////////////////////////////////////////////////////////////////// + + inline void parser::parse(const char * const argv[], int mode) + { + int argc = 0; + for (auto argvp = argv; *argvp; ++argc, ++argvp); + parse(argc, argv, mode); + } + + ////////////////////////////////////////////////////////////////////////// + + inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/) + { + // convert to strings + args_.resize(argc); + std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; }); + + // parse line + for (auto i = 0u; i < args_.size(); ++i) + { + if (!is_option(args_[i])) + { + pos_args_.emplace_back(args_[i]); + continue; + } + + auto name = trim_leading_dashes(args_[i]); + + if (!(mode & NO_SPLIT_ON_EQUALSIGN)) + { + auto equalPos = name.find('='); + if (equalPos != std::string::npos) + { + params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) }); + continue; + } + } + + // if the option is unregistered and should be a multi-flag + if (1 == (args_[i].size() - name.size()) && // single dash + argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode + !is_param(name)) // unregistered + { + std::string keep_param; + + if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param + { + keep_param += name.back(); + name.resize(name.size() - 1); + } + + for (auto const& c : name) + { + flags_.emplace(std::string{ c }); + } + + if (!keep_param.empty()) + { + name = keep_param; + } + else + { + continue; // do not consider other options for this arg + } + } + + // any potential option will get as its value the next arg, unless that arg is an option too + // in that case it will be determined a flag. + if (i == args_.size() - 1 || is_option(args_[i + 1])) + { + flags_.emplace(name); + continue; + } + + // if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped + // otherwise we have 2 modes: + // PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag. + // The following value (the next arg) will be a free parameter. + // + // PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg + // will be the value of that option. + + assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION) + || !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION)); + + bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION; + + if (is_param(name) || preferParam) + { + params_.insert({ name, args_[i + 1] }); + ++i; // skip next value, it is not a free parameter + continue; + } + else + { + flags_.emplace(name); + } + }; + } + + ////////////////////////////////////////////////////////////////////////// + + inline string_stream parser::bad_stream() const + { + string_stream bad; + bad.setstate(std::ios_base::failbit); + return bad; + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool parser::is_number(std::string const& arg) const + { + // inefficient but simple way to determine if a string is a number (which can start with a '-') + std::istringstream istr(arg); + double number; + istr >> number; + return !(istr.fail() || istr.bad()); + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool parser::is_option(std::string const& arg) const + { + assert(0 != arg.size()); + if (is_number(arg)) + return false; + return '-' == arg[0]; + } + + ////////////////////////////////////////////////////////////////////////// + + inline std::string parser::trim_leading_dashes(std::string const& name) const + { + auto pos = name.find_first_not_of('-'); + return std::string::npos != pos ? name.substr(pos) : name; + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool argh::parser::got_flag(std::string const& name) const + { + return flags_.end() != flags_.find(trim_leading_dashes(name)); + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool argh::parser::is_param(std::string const& name) const + { + return registeredParams_.count(name); + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool parser::operator[](std::string const& name) const + { + return got_flag(name); + } + + ////////////////////////////////////////////////////////////////////////// + + inline bool parser::operator[](std::initializer_list init_list) const + { + return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); }); + } + + ////////////////////////////////////////////////////////////////////////// + + inline std::string const& parser::operator[](size_t ind) const + { + if (ind < pos_args_.size()) + return pos_args_[ind]; + return empty_; + } + + ////////////////////////////////////////////////////////////////////////// + + inline string_stream parser::operator()(std::string const& name) const + { + auto optIt = params_.find(trim_leading_dashes(name)); + if (params_.end() != optIt) + return string_stream(optIt->second); + return bad_stream(); + } + + ////////////////////////////////////////////////////////////////////////// + + inline string_stream parser::operator()(std::initializer_list init_list) const + { + for (auto& name : init_list) + { + auto optIt = params_.find(trim_leading_dashes(name)); + if (params_.end() != optIt) + return string_stream(optIt->second); + } + return bad_stream(); + } + + ////////////////////////////////////////////////////////////////////////// + + template + string_stream parser::operator()(std::string const& name, T&& def_val) const + { + auto optIt = params_.find(trim_leading_dashes(name)); + if (params_.end() != optIt) + return string_stream(optIt->second); + + std::ostringstream ostr; + ostr.precision(std::numeric_limits::max_digits10); + ostr << def_val; + return string_stream(ostr.str()); // use default + } + + ////////////////////////////////////////////////////////////////////////// + + // same as above but for a list of names. returns the first value to be found. + template + string_stream parser::operator()(std::initializer_list init_list, T&& def_val) const + { + for (auto& name : init_list) + { + auto optIt = params_.find(trim_leading_dashes(name)); + if (params_.end() != optIt) + return string_stream(optIt->second); + } + std::ostringstream ostr; + ostr.precision(std::numeric_limits::max_digits10); + ostr << def_val; + return string_stream(ostr.str()); // use default + } + + ////////////////////////////////////////////////////////////////////////// + + inline string_stream parser::operator()(size_t ind) const + { + if (pos_args_.size() <= ind) + return bad_stream(); + + return string_stream(pos_args_[ind]); + } + + ////////////////////////////////////////////////////////////////////////// + + template + string_stream parser::operator()(size_t ind, T&& def_val) const + { + if (pos_args_.size() <= ind) + { + std::ostringstream ostr; + ostr.precision(std::numeric_limits::max_digits10); + ostr << def_val; + return string_stream(ostr.str()); + } + + return string_stream(pos_args_[ind]); + } + + ////////////////////////////////////////////////////////////////////////// + + inline void parser::add_param(std::string const& name) + { + registeredParams_.insert(trim_leading_dashes(name)); + } + + ////////////////////////////////////////////////////////////////////////// + + inline void parser::add_params(std::initializer_list init_list) + { + for (auto& name : init_list) + registeredParams_.insert(trim_leading_dashes(name)); + } +} \ No newline at end of file diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index ecb779821..c3856edbb 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -193,7 +193,6 @@ namespace Logs { OutF(LogSys, Logs::General, Logs::Error, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) - #define LogWarning(message, ...) do {\ if (LogSys.log_settings[Logs::Warning].is_category_enabled == 1)\ OutF(LogSys, Logs::General, Logs::Warning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ diff --git a/common/http/httplib.h b/common/http/httplib.h new file mode 100644 index 000000000..827d5f1e0 --- /dev/null +++ b/common/http/httplib.h @@ -0,0 +1,2694 @@ +// +// httplib.h +// +// Copyright (c) 2019 Yuji Hirose. All rights reserved. +// MIT License +// + +#ifndef CPPHTTPLIB_HTTPLIB_H +#define CPPHTTPLIB_HTTPLIB_H + +#ifdef _WIN32 +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS + +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE +#endif //_CRT_NONSTDC_NO_DEPRECATE + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf_s +#endif // _MSC_VER + +#ifndef S_ISREG +#define S_ISREG(m) (((m)&S_IFREG) == S_IFREG) +#endif // S_ISREG + +#ifndef S_ISDIR +#define S_ISDIR(m) (((m)&S_IFDIR) == S_IFDIR) +#endif // S_ISDIR + +#ifndef NOMINMAX +#define NOMINMAX +#endif // NOMINMAX + +#include +#include +#include + +#pragma comment(lib, "ws2_32.lib") + +#ifndef strcasecmp +#define strcasecmp _stricmp +#endif // strcasecmp + +typedef SOCKET socket_t; +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef int socket_t; +#define INVALID_SOCKET (-1) +#endif //_WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +#include +#include +#include + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) { + return M_ASN1_STRING_data(asn1); +} +#endif +#endif + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT +#include +#endif + +/* + * Configuration + */ +#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5 +#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND 0 +#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5 +#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5 +#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0 +#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192 +#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH (std::numeric_limits::max)() +#define CPPHTTPLIB_RECV_BUFSIZ 4096 + +namespace httplib { + + namespace detail { + + struct ci { + bool operator()(const std::string &s1, const std::string &s2) const { + return std::lexicographical_compare( + s1.begin(), s1.end(), s2.begin(), s2.end(), + [](char c1, char c2) { return ::tolower(c1) < ::tolower(c2); }); + } + }; + + } // namespace detail + + enum class HttpVersion { v1_0 = 0, v1_1 }; + + typedef std::multimap Headers; + + template + std::pair make_range_header(uint64_t value, + Args... args); + + typedef std::multimap Params; + typedef std::smatch Match; + typedef std::function Progress; + + struct MultipartFile { + std::string filename; + std::string content_type; + size_t offset = 0; + size_t length = 0; + }; + typedef std::multimap MultipartFiles; + + struct Request { + std::string version; + std::string method; + std::string target; + std::string path; + Headers headers; + std::string body; + Params params; + MultipartFiles files; + Match matches; + + Progress progress; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + const SSL *ssl; +#endif + + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + + bool has_param(const char *key) const; + std::string get_param_value(const char *key, size_t id = 0) const; + size_t get_param_value_count(const char *key) const; + + bool has_file(const char *key) const; + MultipartFile get_file_value(const char *key) const; + }; + + struct Response { + std::string version; + int status; + Headers headers; + std::string body; + std::function streamcb; + + bool has_header(const char *key) const; + std::string get_header_value(const char *key, size_t id = 0) const; + size_t get_header_value_count(const char *key) const; + void set_header(const char *key, const char *val); + + void set_redirect(const char *uri); + void set_content(const char *s, size_t n, const char *content_type); + void set_content(const std::string &s, const char *content_type); + + Response() : status(-1) {} + }; + + class Stream { + public: + virtual ~Stream() {} + virtual int read(char *ptr, size_t size) = 0; + virtual int write(const char *ptr, size_t size1) = 0; + virtual int write(const char *ptr) = 0; + virtual std::string get_remote_addr() const = 0; + + template + void write_format(const char *fmt, const Args &... args); + }; + + class SocketStream : public Stream { + public: + SocketStream(socket_t sock); + virtual ~SocketStream(); + + virtual int read(char *ptr, size_t size); + virtual int write(const char *ptr, size_t size); + virtual int write(const char *ptr); + virtual std::string get_remote_addr() const; + + private: + socket_t sock_; + }; + + class BufferStream : public Stream { + public: + BufferStream() {} + virtual ~BufferStream() {} + + virtual int read(char *ptr, size_t size); + virtual int write(const char *ptr, size_t size); + virtual int write(const char *ptr); + virtual std::string get_remote_addr() const; + + const std::string &get_buffer() const; + + private: + std::string buffer; + }; + + class Server { + public: + typedef std::function Handler; + typedef std::function Logger; + + Server(); + + virtual ~Server(); + + virtual bool is_valid() const; + + Server &Get(const char *pattern, Handler handler); + Server &Post(const char *pattern, Handler handler); + + Server &Put(const char *pattern, Handler handler); + Server &Patch(const char *pattern, Handler handler); + Server &Delete(const char *pattern, Handler handler); + Server &Options(const char *pattern, Handler handler); + + bool set_base_dir(const char *path); + + void set_error_handler(Handler handler); + void set_logger(Logger logger); + + void set_keep_alive_max_count(size_t count); + void set_payload_max_length(uint64_t length); + + int bind_to_any_port(const char *host, int socket_flags = 0); + + bool bind(const char *host, int port, int socket_flags = 0) + { + if (bind_internal(host, port, socket_flags) < 0) return false; + + return true; + } + + bool poll(); + + bool listen_after_bind(); + + bool listen(const char *host, int port, int socket_flags = 0); + + bool is_running() const; + void stop(); + + protected: + bool process_request(Stream &strm, bool last_connection, + bool &connection_close, + std::function setup_request = nullptr); + + size_t keep_alive_max_count_; + size_t payload_max_length_; + + private: + typedef std::vector> Handlers; + + socket_t create_server_socket(const char *host, int port, + int socket_flags) const; + int bind_internal(const char *host, int port, int socket_flags); + bool listen_internal(); + + bool routing(Request &req, Response &res); + bool handle_file_request(Request &req, Response &res); + bool dispatch_request(Request &req, Response &res, Handlers &handlers); + + bool parse_request_line(const char *s, Request &req); + void write_response(Stream &strm, bool last_connection, const Request &req, + Response &res); + + virtual bool read_and_close_socket(socket_t sock); + + std::atomic is_running_; + std::atomic svr_sock_; + std::string base_dir_; + Handlers get_handlers_; + Handlers post_handlers_; + Handlers put_handlers_; + Handlers patch_handlers_; + Handlers delete_handlers_; + Handlers options_handlers_; + Handler error_handler_; + Logger logger_; + + // TODO: Use thread pool... + std::mutex running_threads_mutex_; + int running_threads_; + }; + + class Client { + public: + Client(const char *host, int port = 80, time_t timeout_sec = 300); + + virtual ~Client(); + + virtual bool is_valid() const; + + std::shared_ptr Get(const char *path, Progress progress = nullptr); + std::shared_ptr Get(const char *path, const Headers &headers, + Progress progress = nullptr); + + std::shared_ptr Head(const char *path); + std::shared_ptr Head(const char *path, const Headers &headers); + + std::shared_ptr Post(const char *path, const std::string &body, + const char *content_type); + std::shared_ptr Post(const char *path, const Headers &headers, + const std::string &body, + const char *content_type); + + std::shared_ptr Post(const char *path, const Params ¶ms); + std::shared_ptr Post(const char *path, const Headers &headers, + const Params ¶ms); + + std::shared_ptr Put(const char *path, const std::string &body, + const char *content_type); + std::shared_ptr Put(const char *path, const Headers &headers, + const std::string &body, + const char *content_type); + + std::shared_ptr Patch(const char *path, const std::string &body, + const char *content_type); + std::shared_ptr Patch(const char *path, const Headers &headers, + const std::string &body, + const char *content_type); + + std::shared_ptr Delete(const char *path, + const std::string &body = std::string(), + const char *content_type = nullptr); + std::shared_ptr Delete(const char *path, const Headers &headers, + const std::string &body = std::string(), + const char *content_type = nullptr); + + std::shared_ptr Options(const char *path); + std::shared_ptr Options(const char *path, const Headers &headers); + + bool send(Request &req, Response &res); + + protected: + bool process_request(Stream &strm, Request &req, Response &res, + bool &connection_close); + + const std::string host_; + const int port_; + time_t timeout_sec_; + const std::string host_and_port_; + + private: + socket_t create_client_socket() const; + bool read_response_line(Stream &strm, Response &res); + void write_request(Stream &strm, Request &req); + + virtual bool read_and_close_socket(socket_t sock, Request &req, + Response &res); + virtual bool is_ssl() const; + }; + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + class SSLSocketStream : public Stream { +public: + SSLSocketStream(socket_t sock, SSL *ssl); + virtual ~SSLSocketStream(); + + virtual int read(char *ptr, size_t size); + virtual int write(const char *ptr, size_t size); + virtual int write(const char *ptr); + virtual std::string get_remote_addr() const; + +private: + socket_t sock_; + SSL *ssl_; +}; + +class SSLServer : public Server { +public: + SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path = nullptr, + const char *client_ca_cert_dir_path = nullptr); + + virtual ~SSLServer(); + + virtual bool is_valid() const; + +private: + virtual bool read_and_close_socket(socket_t sock); + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; +}; + +class SSLClient : public Client { +public: + SSLClient(const char *host, int port = 443, time_t timeout_sec = 300, + const char *client_cert_path = nullptr, + const char *client_key_path = nullptr); + + virtual ~SSLClient(); + + virtual bool is_valid() const; + + void set_ca_cert_path(const char *ca_ceert_file_path, + const char *ca_cert_dir_path = nullptr); + void enable_server_certificate_verification(bool enabled); + + long get_openssl_verify_result() const; + +private: + virtual bool read_and_close_socket(socket_t sock, Request &req, + Response &res); + virtual bool is_ssl() const; + + bool verify_host(X509 *server_cert) const; + bool verify_host_with_subject_alt_name(X509 *server_cert) const; + bool verify_host_with_common_name(X509 *server_cert) const; + bool check_host_name(const char *pattern, size_t pattern_len) const; + + SSL_CTX *ctx_; + std::mutex ctx_mutex_; + std::vector host_components_; + std::string ca_cert_file_path_; + std::string ca_cert_dir_path_; + bool server_certificate_verification_ = false; + long verify_result_ = 0; +}; +#endif + +/* + * Implementation + */ + namespace detail { + + template void split(const char *b, const char *e, char d, Fn fn) { + int i = 0; + int beg = 0; + + while (e ? (b + i != e) : (b[i] != '\0')) { + if (b[i] == d) { + fn(&b[beg], &b[i]); + beg = i + 1; + } + i++; + } + + if (i) { fn(&b[beg], &b[i]); } + } + +// NOTE: until the read size reaches `fixed_buffer_size`, use `fixed_buffer` +// to store data. The call can set memory on stack for performance. + class stream_line_reader { + public: + stream_line_reader(Stream &strm, char *fixed_buffer, size_t fixed_buffer_size) + : strm_(strm), fixed_buffer_(fixed_buffer), + fixed_buffer_size_(fixed_buffer_size) {} + + const char *ptr() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_; + } else { + return glowable_buffer_.data(); + } + } + + size_t size() const { + if (glowable_buffer_.empty()) { + return fixed_buffer_used_size_; + } else { + return glowable_buffer_.size(); + } + } + + bool getline() { + fixed_buffer_used_size_ = 0; + glowable_buffer_.clear(); + + for (size_t i = 0;; i++) { + char byte; + auto n = strm_.read(&byte, 1); + + if (n < 0) { + return false; + } else if (n == 0) { + if (i == 0) { + return false; + } else { + break; + } + } + + append(byte); + + if (byte == '\n') { break; } + } + + return true; + } + + private: + void append(char c) { + if (fixed_buffer_used_size_ < fixed_buffer_size_ - 1) { + fixed_buffer_[fixed_buffer_used_size_++] = c; + fixed_buffer_[fixed_buffer_used_size_] = '\0'; + } else { + if (glowable_buffer_.empty()) { + assert(fixed_buffer_[fixed_buffer_used_size_] == '\0'); + glowable_buffer_.assign(fixed_buffer_, fixed_buffer_used_size_); + } + glowable_buffer_ += c; + } + } + + Stream &strm_; + char *fixed_buffer_; + const size_t fixed_buffer_size_; + size_t fixed_buffer_used_size_; + std::string glowable_buffer_; + }; + + inline int close_socket(socket_t sock) { +#ifdef _WIN32 + return closesocket(sock); +#else + return close(sock); +#endif + } + + inline int select_read(socket_t sock, time_t sec, time_t usec) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(sock, &fds); + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + return select(static_cast(sock + 1), &fds, nullptr, nullptr, &tv); + } + + inline bool wait_until_socket_is_ready(socket_t sock, time_t sec, time_t usec) { + fd_set fdsr; + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + + auto fdsw = fdsr; + auto fdse = fdsr; + + timeval tv; + tv.tv_sec = static_cast(sec); + tv.tv_usec = static_cast(usec); + + if (select(static_cast(sock + 1), &fdsr, &fdsw, &fdse, &tv) < 0) { + return false; + } else if (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw)) { + int error = 0; + socklen_t len = sizeof(error); + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &len) < 0 || + error) { + return false; + } + } else { + return false; + } + + return true; + } + + template + inline bool read_and_close_socket(socket_t sock, size_t keep_alive_max_count, + T callback) { + bool ret = false; + + if (keep_alive_max_count > 0) { + auto count = keep_alive_max_count; + while (count > 0 && + detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND, + CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0) { + SocketStream strm(sock); + auto last_connection = count == 1; + auto connection_close = false; + + ret = callback(strm, last_connection, connection_close); + if (!ret || connection_close) { break; } + + count--; + } + } else { + SocketStream strm(sock); + auto dummy_connection_close = false; + ret = callback(strm, true, dummy_connection_close); + } + + close_socket(sock); + return ret; + } + + inline int shutdown_socket(socket_t sock) { +#ifdef _WIN32 + return shutdown(sock, SD_BOTH); +#else + return shutdown(sock, SHUT_RDWR); +#endif + } + + template + socket_t create_socket(const char *host, int port, Fn fn, + int socket_flags = 0) { +#ifdef _WIN32 + #define SO_SYNCHRONOUS_NONALERT 0x20 +#define SO_OPENTYPE 0x7008 + + int opt = SO_SYNCHRONOUS_NONALERT; + setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&opt, + sizeof(opt)); +#endif + + // Get address info + struct addrinfo hints; + struct addrinfo *result; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = socket_flags; + hints.ai_protocol = 0; + + auto service = std::to_string(port); + + if (getaddrinfo(host, service.c_str(), &hints, &result)) { + return INVALID_SOCKET; + } + + for (auto rp = result; rp; rp = rp->ai_next) { + // Create a socket +#ifdef _WIN32 + auto sock = WSASocketW(rp->ai_family, rp->ai_socktype, rp->ai_protocol, + nullptr, 0, WSA_FLAG_NO_HANDLE_INHERIT); +#else + auto sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); +#endif + if (sock == INVALID_SOCKET) { continue; } + +#ifndef _WIN32 + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { continue; } +#endif + + // Make 'reuse address' option available + int yes = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)); +#ifdef SO_REUSEPORT + setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&yes, sizeof(yes)); +#endif + + // bind or connect + if (fn(sock, *rp)) { + freeaddrinfo(result); + return sock; + } + + close_socket(sock); + } + + freeaddrinfo(result); + return INVALID_SOCKET; + } + + inline void set_nonblocking(socket_t sock, bool nonblocking) { +#ifdef _WIN32 + auto flags = nonblocking ? 1UL : 0UL; + ioctlsocket(sock, FIONBIO, &flags); +#else + auto flags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, + nonblocking ? (flags | O_NONBLOCK) : (flags & (~O_NONBLOCK))); +#endif + } + + inline bool is_connection_error() { +#ifdef _WIN32 + return WSAGetLastError() != WSAEWOULDBLOCK; +#else + return errno != EINPROGRESS; +#endif + } + + inline std::string get_remote_addr(socket_t sock) { + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + + if (!getpeername(sock, (struct sockaddr *)&addr, &len)) { + char ipstr[NI_MAXHOST]; + + if (!getnameinfo((struct sockaddr *)&addr, len, ipstr, sizeof(ipstr), + nullptr, 0, NI_NUMERICHOST)) { + return ipstr; + } + } + + return std::string(); + } + + inline bool is_file(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISREG(st.st_mode); + } + + inline bool is_dir(const std::string &path) { + struct stat st; + return stat(path.c_str(), &st) >= 0 && S_ISDIR(st.st_mode); + } + + inline bool is_valid_path(const std::string &path) { + size_t level = 0; + size_t i = 0; + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + + while (i < path.size()) { + // Read component + auto beg = i; + while (i < path.size() && path[i] != '/') { + i++; + } + + auto len = i - beg; + assert(len > 0); + + if (!path.compare(beg, len, ".")) { + ; + } else if (!path.compare(beg, len, "..")) { + if (level == 0) { return false; } + level--; + } else { + level++; + } + + // Skip slash + while (i < path.size() && path[i] == '/') { + i++; + } + } + + return true; + } + + inline void read_file(const std::string &path, std::string &out) { + std::ifstream fs(path, std::ios_base::binary); + fs.seekg(0, std::ios_base::end); + auto size = fs.tellg(); + fs.seekg(0); + out.resize(static_cast(size)); + fs.read(&out[0], size); + } + + inline std::string file_extension(const std::string &path) { + std::smatch m; + auto pat = std::regex("\\.([a-zA-Z0-9]+)$"); + if (std::regex_search(path, m, pat)) { return m[1].str(); } + return std::string(); + } + + inline const char *find_content_type(const std::string &path) { + auto ext = file_extension(path); + if (ext == "txt") { + return "text/plain"; + } else if (ext == "html") { + return "text/html"; + } else if (ext == "css") { + return "text/css"; + } else if (ext == "jpeg" || ext == "jpg") { + return "image/jpg"; + } else if (ext == "png") { + return "image/png"; + } else if (ext == "gif") { + return "image/gif"; + } else if (ext == "svg") { + return "image/svg+xml"; + } else if (ext == "ico") { + return "image/x-icon"; + } else if (ext == "json") { + return "application/json"; + } else if (ext == "pdf") { + return "application/pdf"; + } else if (ext == "js") { + return "application/javascript"; + } else if (ext == "xml") { + return "application/xml"; + } else if (ext == "xhtml") { + return "application/xhtml+xml"; + } + return nullptr; + } + + inline const char *status_message(int status) { + switch (status) { + case 200: return "OK"; + case 301: return "Moved Permanently"; + case 302: return "Found"; + case 303: return "See Other"; + case 304: return "Not Modified"; + case 400: return "Bad Request"; + case 403: return "Forbidden"; + case 404: return "Not Found"; + case 413: return "Payload Too Large"; + case 414: return "Request-URI Too Long"; + case 415: return "Unsupported Media Type"; + default: + case 500: return "Internal Server Error"; + } + } + + inline bool has_header(const Headers &headers, const char *key) { + return headers.find(key) != headers.end(); + } + + inline const char *get_header_value(const Headers &headers, const char *key, + size_t id = 0, const char *def = nullptr) { + auto it = headers.find(key); + std::advance(it, id); + if (it != headers.end()) { return it->second.c_str(); } + return def; + } + + inline uint64_t get_header_value_uint64(const Headers &headers, const char *key, + int def = 0) { + auto it = headers.find(key); + if (it != headers.end()) { + return std::strtoull(it->second.data(), nullptr, 10); + } + return def; + } + + inline bool read_headers(Stream &strm, Headers &headers) { + static std::regex re(R"((.+?):\s*(.+?)\s*\r\n)"); + + const auto bufsiz = 2048; + char buf[bufsiz]; + + stream_line_reader reader(strm, buf, bufsiz); + + for (;;) { + if (!reader.getline()) { return false; } + if (!strcmp(reader.ptr(), "\r\n")) { break; } + std::cmatch m; + if (std::regex_match(reader.ptr(), m, re)) { + auto key = std::string(m[1]); + auto val = std::string(m[2]); + headers.emplace(key, val); + } + } + + return true; + } + + inline bool read_content_with_length(Stream &strm, std::string &out, size_t len, + Progress progress) { + out.assign(len, 0); + size_t r = 0; + while (r < len) { + auto n = strm.read(&out[r], len - r); + if (n <= 0) { return false; } + + r += n; + + if (progress) { + if (!progress(r, len)) { return false; } + } + } + + return true; + } + + inline void skip_content_with_length(Stream &strm, size_t len) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + size_t r = 0; + while (r < len) { + auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ); + if (n <= 0) { return; } + r += n; + } + } + + inline bool read_content_without_length(Stream &strm, std::string &out) { + char buf[CPPHTTPLIB_RECV_BUFSIZ]; + for (;;) { + auto n = strm.read(buf, CPPHTTPLIB_RECV_BUFSIZ); + if (n < 0) { + return false; + } else if (n == 0) { + return true; + } + out.append(buf, n); + } + + return true; + } + + inline bool read_content_chunked(Stream &strm, std::string &out) { + const auto bufsiz = 16; + char buf[bufsiz]; + + stream_line_reader reader(strm, buf, bufsiz); + + if (!reader.getline()) { return false; } + + auto chunk_len = std::stoi(reader.ptr(), 0, 16); + + while (chunk_len > 0) { + std::string chunk; + if (!read_content_with_length(strm, chunk, chunk_len, nullptr)) { + return false; + } + + if (!reader.getline()) { return false; } + + if (strcmp(reader.ptr(), "\r\n")) { break; } + + out += chunk; + + if (!reader.getline()) { return false; } + + chunk_len = std::stoi(reader.ptr(), 0, 16); + } + + if (chunk_len == 0) { + // Reader terminator after chunks + if (!reader.getline() || strcmp(reader.ptr(), "\r\n")) return false; + } + + return true; + } + + template + bool read_content(Stream &strm, T &x, uint64_t payload_max_length, + bool &exceed_payload_max_length, + Progress progress = Progress()) { + if (has_header(x.headers, "Content-Length")) { + auto len = get_header_value_uint64(x.headers, "Content-Length", 0); + if (len == 0) { + const auto &encoding = + get_header_value(x.headers, "Transfer-Encoding", 0, ""); + if (!strcasecmp(encoding, "chunked")) { + return read_content_chunked(strm, x.body); + } + } + + if ((len > payload_max_length) || + // For 32-bit platform + (sizeof(size_t) < sizeof(uint64_t) && + len > std::numeric_limits::max())) { + exceed_payload_max_length = true; + skip_content_with_length(strm, len); + return false; + } + + return read_content_with_length(strm, x.body, len, progress); + } else { + const auto &encoding = + get_header_value(x.headers, "Transfer-Encoding", 0, ""); + if (!strcasecmp(encoding, "chunked")) { + return read_content_chunked(strm, x.body); + } + return read_content_without_length(strm, x.body); + } + return true; + } + + template inline void write_headers(Stream &strm, const T &info) { + for (const auto &x : info.headers) { + strm.write_format("%s: %s\r\n", x.first.c_str(), x.second.c_str()); + } + strm.write("\r\n"); + } + + inline std::string encode_url(const std::string &s) { + std::string result; + + for (auto i = 0; s[i]; i++) { + switch (s[i]) { + case ' ': result += "%20"; break; + case '+': result += "%2B"; break; + case '\r': result += "%0D"; break; + case '\n': result += "%0A"; break; + case '\'': result += "%27"; break; + case ',': result += "%2C"; break; + case ':': result += "%3A"; break; + case ';': result += "%3B"; break; + default: + auto c = static_cast(s[i]); + if (c >= 0x80) { + result += '%'; + char hex[4]; + size_t len = snprintf(hex, sizeof(hex) - 1, "%02X", c); + assert(len == 2); + result.append(hex, len); + } else { + result += s[i]; + } + break; + } + } + + return result; + } + + inline bool is_hex(char c, int &v) { + if (0x20 <= c && isdigit(c)) { + v = c - '0'; + return true; + } else if ('A' <= c && c <= 'F') { + v = c - 'A' + 10; + return true; + } else if ('a' <= c && c <= 'f') { + v = c - 'a' + 10; + return true; + } + return false; + } + + inline bool from_hex_to_i(const std::string &s, size_t i, size_t cnt, + int &val) { + if (i >= s.size()) { return false; } + + val = 0; + for (; cnt; i++, cnt--) { + if (!s[i]) { return false; } + int v = 0; + if (is_hex(s[i], v)) { + val = val * 16 + v; + } else { + return false; + } + } + return true; + } + + inline std::string from_i_to_hex(uint64_t n) { + const char *charset = "0123456789abcdef"; + std::string ret; + do { + ret = charset[n & 15] + ret; + n >>= 4; + } while (n > 0); + return ret; + } + + inline size_t to_utf8(int code, char *buff) { + if (code < 0x0080) { + buff[0] = (code & 0x7F); + return 1; + } else if (code < 0x0800) { + buff[0] = (0xC0 | ((code >> 6) & 0x1F)); + buff[1] = (0x80 | (code & 0x3F)); + return 2; + } else if (code < 0xD800) { + buff[0] = (0xE0 | ((code >> 12) & 0xF)); + buff[1] = (0x80 | ((code >> 6) & 0x3F)); + buff[2] = (0x80 | (code & 0x3F)); + return 3; + } else if (code < 0xE000) { // D800 - DFFF is invalid... + return 0; + } else if (code < 0x10000) { + buff[0] = (0xE0 | ((code >> 12) & 0xF)); + buff[1] = (0x80 | ((code >> 6) & 0x3F)); + buff[2] = (0x80 | (code & 0x3F)); + return 3; + } else if (code < 0x110000) { + buff[0] = (0xF0 | ((code >> 18) & 0x7)); + buff[1] = (0x80 | ((code >> 12) & 0x3F)); + buff[2] = (0x80 | ((code >> 6) & 0x3F)); + buff[3] = (0x80 | (code & 0x3F)); + return 4; + } + + // NOTREACHED + return 0; + } + + inline std::string decode_url(const std::string &s) { + std::string result; + + for (size_t i = 0; i < s.size(); i++) { + if (s[i] == '%' && i + 1 < s.size()) { + if (s[i + 1] == 'u') { + int val = 0; + if (from_hex_to_i(s, i + 2, 4, val)) { + // 4 digits Unicode codes + char buff[4]; + size_t len = to_utf8(val, buff); + if (len > 0) { result.append(buff, len); } + i += 5; // 'u0000' + } else { + result += s[i]; + } + } else { + int val = 0; + if (from_hex_to_i(s, i + 1, 2, val)) { + // 2 digits hex codes + result += val; + i += 2; // '00' + } else { + result += s[i]; + } + } + } else if (s[i] == '+') { + result += ' '; + } else { + result += s[i]; + } + } + + return result; + } + + inline void parse_query_text(const std::string &s, Params ¶ms) { + split(&s[0], &s[s.size()], '&', [&](const char *b, const char *e) { + std::string key; + std::string val; + split(b, e, '=', [&](const char *b, const char *e) { + if (key.empty()) { + key.assign(b, e); + } else { + val.assign(b, e); + } + }); + params.emplace(key, decode_url(val)); + }); + } + + inline bool parse_multipart_boundary(const std::string &content_type, + std::string &boundary) { + auto pos = content_type.find("boundary="); + if (pos == std::string::npos) { return false; } + + boundary = content_type.substr(pos + 9); + return true; + } + + inline bool parse_multipart_formdata(const std::string &boundary, + const std::string &body, + MultipartFiles &files) { + static std::string dash = "--"; + static std::string crlf = "\r\n"; + + static std::regex re_content_type("Content-Type: (.*?)", + std::regex_constants::icase); + + static std::regex re_content_disposition( + "Content-Disposition: form-data; name=\"(.*?)\"(?:; filename=\"(.*?)\")?", + std::regex_constants::icase); + + auto dash_boundary = dash + boundary; + + auto pos = body.find(dash_boundary); + if (pos != 0) { return false; } + + pos += dash_boundary.size(); + + auto next_pos = body.find(crlf, pos); + if (next_pos == std::string::npos) { return false; } + + pos = next_pos + crlf.size(); + + while (pos < body.size()) { + next_pos = body.find(crlf, pos); + if (next_pos == std::string::npos) { return false; } + + std::string name; + MultipartFile file; + + auto header = body.substr(pos, (next_pos - pos)); + + while (pos != next_pos) { + std::smatch m; + if (std::regex_match(header, m, re_content_type)) { + file.content_type = m[1]; + } else if (std::regex_match(header, m, re_content_disposition)) { + name = m[1]; + file.filename = m[2]; + } + + pos = next_pos + crlf.size(); + + next_pos = body.find(crlf, pos); + if (next_pos == std::string::npos) { return false; } + + header = body.substr(pos, (next_pos - pos)); + } + + pos = next_pos + crlf.size(); + + next_pos = body.find(crlf + dash_boundary, pos); + + if (next_pos == std::string::npos) { return false; } + + file.offset = pos; + file.length = next_pos - pos; + + pos = next_pos + crlf.size() + dash_boundary.size(); + + next_pos = body.find(crlf, pos); + if (next_pos == std::string::npos) { return false; } + + files.emplace(name, file); + + pos = next_pos + crlf.size(); + } + + return true; + } + + inline std::string to_lower(const char *beg, const char *end) { + std::string out; + auto it = beg; + while (it != end) { + out += ::tolower(*it); + it++; + } + return out; + } + + inline void make_range_header_core(std::string &) {} + + template + inline void make_range_header_core(std::string &field, uint64_t value) { + if (!field.empty()) { field += ", "; } + field += std::to_string(value) + "-"; + } + + template + inline void make_range_header_core(std::string &field, uint64_t value1, + uint64_t value2, Args... args) { + if (!field.empty()) { field += ", "; } + field += std::to_string(value1) + "-" + std::to_string(value2); + make_range_header_core(field, args...); + } + +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + inline bool can_compress(const std::string &content_type) { + return !content_type.find("text/") || content_type == "image/svg+xml" || + content_type == "application/javascript" || + content_type == "application/json" || + content_type == "application/xml" || + content_type == "application/xhtml+xml"; +} + +inline void compress(std::string &content) { + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + auto ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 31, 8, + Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { return; } + + strm.avail_in = content.size(); + strm.next_in = (Bytef *)content.data(); + + std::string compressed; + + const auto bufsiz = 16384; + char buff[bufsiz]; + do { + strm.avail_out = bufsiz; + strm.next_out = (Bytef *)buff; + deflate(&strm, Z_FINISH); + compressed.append(buff, bufsiz - strm.avail_out); + } while (strm.avail_out == 0); + + content.swap(compressed); + + deflateEnd(&strm); +} + +inline void decompress(std::string &content) { + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + // 15 is the value of wbits, which should be at the maximum possible value to + // ensure that any gzip stream can be decoded. The offset of 16 specifies that + // the stream to decompress will be formatted with a gzip wrapper. + auto ret = inflateInit2(&strm, 16 + 15); + if (ret != Z_OK) { return; } + + strm.avail_in = content.size(); + strm.next_in = (Bytef *)content.data(); + + std::string decompressed; + + const auto bufsiz = 16384; + char buff[bufsiz]; + do { + strm.avail_out = bufsiz; + strm.next_out = (Bytef *)buff; + inflate(&strm, Z_NO_FLUSH); + decompressed.append(buff, bufsiz - strm.avail_out); + } while (strm.avail_out == 0); + + content.swap(decompressed); + + inflateEnd(&strm); +} +#endif + +#ifdef _WIN32 + class WSInit { +public: + WSInit() { + WSADATA wsaData; + WSAStartup(0x0002, &wsaData); + } + + ~WSInit() { WSACleanup(); } +}; + +static WSInit wsinit_; +#endif + + } // namespace detail + +// Header utilities + template + inline std::pair make_range_header(uint64_t value, + Args... args) { + std::string field; + detail::make_range_header_core(field, value, args...); + field.insert(0, "bytes="); + return std::make_pair("Range", field); + } + +// Request implementation + inline bool Request::has_header(const char *key) const { + return detail::has_header(headers, key); + } + + inline std::string Request::get_header_value(const char *key, size_t id) const { + return detail::get_header_value(headers, key, id, ""); + } + + inline size_t Request::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return std::distance(r.first, r.second); + } + + inline void Request::set_header(const char *key, const char *val) { + headers.emplace(key, val); + } + + inline bool Request::has_param(const char *key) const { + return params.find(key) != params.end(); + } + + inline std::string Request::get_param_value(const char *key, size_t id) const { + auto it = params.find(key); + std::advance(it, id); + if (it != params.end()) { return it->second; } + return std::string(); + } + + inline size_t Request::get_param_value_count(const char *key) const { + auto r = params.equal_range(key); + return std::distance(r.first, r.second); + } + + inline bool Request::has_file(const char *key) const { + return files.find(key) != files.end(); + } + + inline MultipartFile Request::get_file_value(const char *key) const { + auto it = files.find(key); + if (it != files.end()) { return it->second; } + return MultipartFile(); + } + +// Response implementation + inline bool Response::has_header(const char *key) const { + return headers.find(key) != headers.end(); + } + + inline std::string Response::get_header_value(const char *key, + size_t id) const { + return detail::get_header_value(headers, key, id, ""); + } + + inline size_t Response::get_header_value_count(const char *key) const { + auto r = headers.equal_range(key); + return std::distance(r.first, r.second); + } + + inline void Response::set_header(const char *key, const char *val) { + headers.emplace(key, val); + } + + inline void Response::set_redirect(const char *url) { + set_header("Location", url); + status = 302; + } + + inline void Response::set_content(const char *s, size_t n, + const char *content_type) { + body.assign(s, n); + set_header("Content-Type", content_type); + } + + inline void Response::set_content(const std::string &s, + const char *content_type) { + body = s; + set_header("Content-Type", content_type); + } + +// Rstream implementation + template + inline void Stream::write_format(const char *fmt, const Args &... args) { + const auto bufsiz = 2048; + char buf[bufsiz]; + +#if defined(_MSC_VER) && _MSC_VER < 1900 + auto n = _snprintf_s(buf, bufsiz, bufsiz - 1, fmt, args...); +#else + auto n = snprintf(buf, bufsiz - 1, fmt, args...); +#endif + if (n > 0) { + if (n >= bufsiz - 1) { + std::vector glowable_buf(bufsiz); + + while (n >= static_cast(glowable_buf.size() - 1)) { + glowable_buf.resize(glowable_buf.size() * 2); +#if defined(_MSC_VER) && _MSC_VER < 1900 + n = _snprintf_s(&glowable_buf[0], glowable_buf.size(), + glowable_buf.size() - 1, fmt, args...); +#else + n = snprintf(&glowable_buf[0], glowable_buf.size() - 1, fmt, args...); +#endif + } + write(&glowable_buf[0], n); + } else { + write(buf, n); + } + } + } + +// Socket stream implementation + inline SocketStream::SocketStream(socket_t sock) : sock_(sock) {} + + inline SocketStream::~SocketStream() {} + + inline int SocketStream::read(char *ptr, size_t size) { + if (detail::select_read(sock_, CPPHTTPLIB_READ_TIMEOUT_SECOND, + CPPHTTPLIB_READ_TIMEOUT_USECOND) > 0) { + return recv(sock_, ptr, static_cast(size), 0); + } + return -1; + } + + inline int SocketStream::write(const char *ptr, size_t size) { + return send(sock_, ptr, static_cast(size), 0); + } + + inline int SocketStream::write(const char *ptr) { + return write(ptr, strlen(ptr)); + } + + inline std::string SocketStream::get_remote_addr() const { + return detail::get_remote_addr(sock_); + } + +// Buffer stream implementation + inline int BufferStream::read(char *ptr, size_t size) { +#if defined(_MSC_VER) && _MSC_VER < 1900 + return static_cast(buffer._Copy_s(ptr, size, size)); +#else + return static_cast(buffer.copy(ptr, size)); +#endif + } + + inline int BufferStream::write(const char *ptr, size_t size) { + buffer.append(ptr, size); + return static_cast(size); + } + + inline int BufferStream::write(const char *ptr) { + size_t size = strlen(ptr); + buffer.append(ptr, size); + return static_cast(size); + } + + inline std::string BufferStream::get_remote_addr() const { return ""; } + + inline const std::string &BufferStream::get_buffer() const { return buffer; } + +// HTTP server implementation + inline Server::Server() + : keep_alive_max_count_(CPPHTTPLIB_KEEPALIVE_MAX_COUNT), + payload_max_length_(CPPHTTPLIB_PAYLOAD_MAX_LENGTH), is_running_(false), + svr_sock_(INVALID_SOCKET), running_threads_(0) { +#ifndef _WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + } + + inline Server::~Server() {} + + inline Server &Server::Get(const char *pattern, Handler handler) { + get_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline Server &Server::Post(const char *pattern, Handler handler) { + post_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline Server &Server::Put(const char *pattern, Handler handler) { + put_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline Server &Server::Patch(const char *pattern, Handler handler) { + patch_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline Server &Server::Delete(const char *pattern, Handler handler) { + delete_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline Server &Server::Options(const char *pattern, Handler handler) { + options_handlers_.push_back(std::make_pair(std::regex(pattern), handler)); + return *this; + } + + inline bool Server::set_base_dir(const char *path) { + if (detail::is_dir(path)) { + base_dir_ = path; + return true; + } + return false; + } + + inline void Server::set_error_handler(Handler handler) { + error_handler_ = handler; + } + + inline void Server::set_logger(Logger logger) { logger_ = logger; } + + inline void Server::set_keep_alive_max_count(size_t count) { + keep_alive_max_count_ = count; + } + + inline void Server::set_payload_max_length(uint64_t length) { + payload_max_length_ = length; + } + + inline int Server::bind_to_any_port(const char *host, int socket_flags) { + return bind_internal(host, 0, socket_flags); + } + + inline bool Server::listen_after_bind() { return listen_internal(); } + + inline bool Server::listen(const char *host, int port, int socket_flags) { + if (bind_internal(host, port, socket_flags) < 0) return false; + return listen_internal(); + } + + inline bool Server::is_running() const { return is_running_; } + + inline void Server::stop() { + if (is_running_) { + assert(svr_sock_ != INVALID_SOCKET); + std::atomic sock (svr_sock_.exchange(INVALID_SOCKET)); + detail::shutdown_socket(sock); + detail::close_socket(sock); + } + } + + inline bool Server::parse_request_line(const char *s, Request &req) { + static std::regex re("(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS) " + "(([^?]+)(?:\\?(.+?))?) (HTTP/1\\.[01])\r\n"); + + std::cmatch m; + if (std::regex_match(s, m, re)) { + req.version = std::string(m[5]); + req.method = std::string(m[1]); + req.target = std::string(m[2]); + req.path = detail::decode_url(m[3]); + + // Parse query text + auto len = std::distance(m[4].first, m[4].second); + if (len > 0) { detail::parse_query_text(m[4], req.params); } + + return true; + } + + return false; + } + + inline void Server::write_response(Stream &strm, bool last_connection, + const Request &req, Response &res) { + assert(res.status != -1); + + if (400 <= res.status && error_handler_) { error_handler_(req, res); } + + // Response line + strm.write_format("HTTP/1.1 %d %s\r\n", res.status, + detail::status_message(res.status)); + + // Headers + if (last_connection || req.get_header_value("Connection") == "close") { + res.set_header("Connection", "close"); + } + + if (!last_connection && req.get_header_value("Connection") == "Keep-Alive") { + res.set_header("Connection", "Keep-Alive"); + } + + if (res.body.empty()) { + if (!res.has_header("Content-Length")) { + if (res.streamcb) { + // Streamed response + res.set_header("Transfer-Encoding", "chunked"); + } else { + res.set_header("Content-Length", "0"); + } + } + } else { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + // TODO: 'Accpet-Encoding' has gzip, not gzip;q=0 + const auto &encodings = req.get_header_value("Accept-Encoding"); + if (encodings.find("gzip") != std::string::npos && + detail::can_compress(res.get_header_value("Content-Type"))) { + detail::compress(res.body); + res.set_header("Content-Encoding", "gzip"); + } +#endif + + if (!res.has_header("Content-Type")) { + res.set_header("Content-Type", "text/plain"); + } + + auto length = std::to_string(res.body.size()); + res.set_header("Content-Length", length.c_str()); + } + + detail::write_headers(strm, res); + + // Body + if (req.method != "HEAD") { + if (!res.body.empty()) { + strm.write(res.body.c_str(), res.body.size()); + } else if (res.streamcb) { + bool chunked_response = !res.has_header("Content-Length"); + uint64_t offset = 0; + bool data_available = true; + while (data_available) { + std::string chunk = res.streamcb(offset); + offset += chunk.size(); + data_available = !chunk.empty(); + // Emit chunked response header and footer for each chunk + if (chunked_response) + chunk = detail::from_i_to_hex(chunk.size()) + "\r\n" + chunk + "\r\n"; + if (strm.write(chunk.c_str(), chunk.size()) < 0) break; // Stop on error + } + } + } + + // Log + if (logger_) { logger_(req, res); } + } + + inline bool Server::handle_file_request(Request &req, Response &res) { + if (!base_dir_.empty() && detail::is_valid_path(req.path)) { + std::string path = base_dir_ + req.path; + + if (!path.empty() && path.back() == '/') { path += "index.html"; } + + if (detail::is_file(path)) { + detail::read_file(path, res.body); + auto type = detail::find_content_type(path); + if (type) { res.set_header("Content-Type", type); } + res.status = 200; + return true; + } + } + + return false; + } + + inline socket_t Server::create_server_socket(const char *host, int port, + int socket_flags) const { + return detail::create_socket( + host, port, + [](socket_t sock, struct addrinfo &ai) -> bool { + if (::bind(sock, ai.ai_addr, static_cast(ai.ai_addrlen))) { + return false; + } + if (::listen(sock, 5)) { // Listen through 5 channels + return false; + } + return true; + }, + socket_flags); + } + + inline int Server::bind_internal(const char *host, int port, int socket_flags) { + if (!is_valid()) { return -1; } + + svr_sock_ = create_server_socket(host, port, socket_flags); + if (svr_sock_ == INVALID_SOCKET) { return -1; } + + if (port == 0) { + struct sockaddr_storage address; + socklen_t len = sizeof(address); + if (getsockname(svr_sock_, reinterpret_cast(&address), + &len) == -1) { + return -1; + } + if (address.ss_family == AF_INET) { + return ntohs(reinterpret_cast(&address)->sin_port); + } else if (address.ss_family == AF_INET6) { + return ntohs( + reinterpret_cast(&address)->sin6_port); + } else { + return -1; + } + } else { + return port; + } + } + + inline bool Server::poll() { + auto ret = true; + + is_running_ = true; + + if (svr_sock_ == INVALID_SOCKET) { + // The server socket was closed by 'stop' method. + return false; + } + + auto val = detail::select_read(svr_sock_, 0, 1000); + + if (val == 0) { // Timeout + return false; + } + + socket_t sock = accept(svr_sock_, nullptr, nullptr); + + if (sock == INVALID_SOCKET) { + if (svr_sock_ != INVALID_SOCKET) { + detail::close_socket(svr_sock_); + ret = false; + } else { + ; // The server socket was closed by user. + } + return false; + } + + read_and_close_socket(sock); + + is_running_ = false; + + return ret; + } + + inline bool Server::listen_internal() { + auto ret = true; + + is_running_ = true; + + for (;;) { + if (svr_sock_ == INVALID_SOCKET) { + // The server socket was closed by 'stop' method. + break; + } + + auto val = detail::select_read(svr_sock_, 0, 100000); + + if (val == 0) { // Timeout + continue; + } + + socket_t sock = accept(svr_sock_, nullptr, nullptr); + + if (sock == INVALID_SOCKET) { + if (svr_sock_ != INVALID_SOCKET) { + detail::close_socket(svr_sock_); + ret = false; + } else { + ; // The server socket was closed by user. + } + break; + } + + // TODO: Use thread pool... + std::thread([=]() { + { + std::lock_guard guard(running_threads_mutex_); + running_threads_++; + } + + read_and_close_socket(sock); + + { + std::lock_guard guard(running_threads_mutex_); + running_threads_--; + } + }).detach(); + } + + // TODO: Use thread pool... + for (;;) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + std::lock_guard guard(running_threads_mutex_); + if (!running_threads_) { break; } + } + + is_running_ = false; + + return ret; + } + + inline bool Server::routing(Request &req, Response &res) { + if (req.method == "GET" && handle_file_request(req, res)) { return true; } + + if (req.method == "GET" || req.method == "HEAD") { + return dispatch_request(req, res, get_handlers_); + } else if (req.method == "POST") { + return dispatch_request(req, res, post_handlers_); + } else if (req.method == "PUT") { + return dispatch_request(req, res, put_handlers_); + } else if (req.method == "PATCH") { + return dispatch_request(req, res, patch_handlers_); + } else if (req.method == "DELETE") { + return dispatch_request(req, res, delete_handlers_); + } else if (req.method == "OPTIONS") { + return dispatch_request(req, res, options_handlers_); + } + return false; + } + + inline bool Server::dispatch_request(Request &req, Response &res, + Handlers &handlers) { + for (const auto &x : handlers) { + const auto &pattern = x.first; + const auto &handler = x.second; + + if (std::regex_match(req.path, req.matches, pattern)) { + handler(req, res); + return true; + } + } + return false; + } + + inline bool + Server::process_request(Stream &strm, bool last_connection, + bool &connection_close, + std::function setup_request) { + const auto bufsiz = 2048; + char buf[bufsiz]; + + detail::stream_line_reader reader(strm, buf, bufsiz); + + // Connection has been closed on client + if (!reader.getline()) { return false; } + + Request req; + Response res; + + res.version = "HTTP/1.1"; + + // Check if the request URI doesn't exceed the limit + if (reader.size() > CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) { + res.status = 414; + write_response(strm, last_connection, req, res); + return true; + } + + // Request line and headers + if (!parse_request_line(reader.ptr(), req) || + !detail::read_headers(strm, req.headers)) { + res.status = 400; + write_response(strm, last_connection, req, res); + return true; + } + + if (req.get_header_value("Connection") == "close") { + connection_close = true; + } + + req.set_header("REMOTE_ADDR", strm.get_remote_addr().c_str()); + + // Body + if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH") { + bool exceed_payload_max_length = false; + if (!detail::read_content(strm, req, payload_max_length_, + exceed_payload_max_length)) { + res.status = exceed_payload_max_length ? 413 : 400; + write_response(strm, last_connection, req, res); + return !exceed_payload_max_length; + } + + const auto &content_type = req.get_header_value("Content-Type"); + + if (req.get_header_value("Content-Encoding") == "gzip") { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + detail::decompress(req.body); +#else + res.status = 415; + write_response(strm, last_connection, req, res); + return true; +#endif + } + + if (!content_type.find("application/x-www-form-urlencoded")) { + detail::parse_query_text(req.body, req.params); + } else if (!content_type.find("multipart/form-data")) { + std::string boundary; + if (!detail::parse_multipart_boundary(content_type, boundary) || + !detail::parse_multipart_formdata(boundary, req.body, req.files)) { + res.status = 400; + write_response(strm, last_connection, req, res); + return true; + } + } + } + + // TODO: Add additional request info + if (setup_request) { setup_request(req); } + + if (routing(req, res)) { + if (res.status == -1) { res.status = 200; } + } else { + res.status = 404; + } + + write_response(strm, last_connection, req, res); + return true; + } + + inline bool Server::is_valid() const { return true; } + + inline bool Server::read_and_close_socket(socket_t sock) { + return detail::read_and_close_socket( + sock, keep_alive_max_count_, + [this](Stream &strm, bool last_connection, bool &connection_close) { + return process_request(strm, last_connection, connection_close); + }); + } + +// HTTP client implementation + inline Client::Client(const char *host, int port, time_t timeout_sec) + : host_(host), port_(port), timeout_sec_(timeout_sec), + host_and_port_(host_ + ":" + std::to_string(port_)) {} + + inline Client::~Client() {} + + inline bool Client::is_valid() const { return true; } + + inline socket_t Client::create_client_socket() const { + return detail::create_socket( + host_.c_str(), port_, [=](socket_t sock, struct addrinfo &ai) -> bool { + detail::set_nonblocking(sock, true); + + auto ret = connect(sock, ai.ai_addr, static_cast(ai.ai_addrlen)); + if (ret < 0) { + if (detail::is_connection_error() || + !detail::wait_until_socket_is_ready(sock, timeout_sec_, 0)) { + detail::close_socket(sock); + return false; + } + } + + detail::set_nonblocking(sock, false); + return true; + }); + } + + inline bool Client::read_response_line(Stream &strm, Response &res) { + const auto bufsiz = 2048; + char buf[bufsiz]; + + detail::stream_line_reader reader(strm, buf, bufsiz); + + if (!reader.getline()) { return false; } + + const static std::regex re("(HTTP/1\\.[01]) (\\d+?) .*\r\n"); + + std::cmatch m; + if (std::regex_match(reader.ptr(), m, re)) { + res.version = std::string(m[1]); + res.status = std::stoi(std::string(m[2])); + } + + return true; + } + + inline bool Client::send(Request &req, Response &res) { + if (req.path.empty()) { return false; } + + auto sock = create_client_socket(); + if (sock == INVALID_SOCKET) { return false; } + + return read_and_close_socket(sock, req, res); + } + + inline void Client::write_request(Stream &strm, Request &req) { + BufferStream bstrm; + + // Request line + auto path = detail::encode_url(req.path); + + bstrm.write_format("%s %s HTTP/1.1\r\n", req.method.c_str(), path.c_str()); + + // Headers + if (!req.has_header("Host")) { + if (is_ssl()) { + if (port_ == 443) { + req.set_header("Host", host_.c_str()); + } else { + req.set_header("Host", host_and_port_.c_str()); + } + } else { + if (port_ == 80) { + req.set_header("Host", host_.c_str()); + } else { + req.set_header("Host", host_and_port_.c_str()); + } + } + } + + if (!req.has_header("Accept")) { req.set_header("Accept", "*/*"); } + + if (!req.has_header("User-Agent")) { + req.set_header("User-Agent", "cpp-httplib/0.2"); + } + + // TODO: Support KeepAlive connection + // if (!req.has_header("Connection")) { + req.set_header("Connection", "close"); + // } + + if (req.body.empty()) { + if (req.method == "POST" || req.method == "PUT" || req.method == "PATCH") { + req.set_header("Content-Length", "0"); + } + } else { + if (!req.has_header("Content-Type")) { + req.set_header("Content-Type", "text/plain"); + } + + if (!req.has_header("Content-Length")) { + auto length = std::to_string(req.body.size()); + req.set_header("Content-Length", length.c_str()); + } + } + + detail::write_headers(bstrm, req); + + // Body + if (!req.body.empty()) { bstrm.write(req.body.c_str(), req.body.size()); } + + // Flush buffer + auto &data = bstrm.get_buffer(); + strm.write(data.data(), data.size()); + } + + inline bool Client::process_request(Stream &strm, Request &req, Response &res, + bool &connection_close) { + // Send request + write_request(strm, req); + + // Receive response and headers + if (!read_response_line(strm, res) || + !detail::read_headers(strm, res.headers)) { + return false; + } + + if (res.get_header_value("Connection") == "close" || + res.version == "HTTP/1.0") { + connection_close = true; + } + + // Body + if (req.method != "HEAD") { + bool exceed_payload_max_length = false; + if (!detail::read_content(strm, res, std::numeric_limits::max(), + exceed_payload_max_length, req.progress)) { + return false; + } + + if (res.get_header_value("Content-Encoding") == "gzip") { +#ifdef CPPHTTPLIB_ZLIB_SUPPORT + detail::decompress(res.body); +#else + return false; +#endif + } + } + + return true; + } + + inline bool Client::read_and_close_socket(socket_t sock, Request &req, + Response &res) { + return detail::read_and_close_socket( + sock, 0, + [&](Stream &strm, bool /*last_connection*/, bool &connection_close) { + return process_request(strm, req, res, connection_close); + }); + } + + inline bool Client::is_ssl() const { return false; } + + inline std::shared_ptr Client::Get(const char *path, + Progress progress) { + return Get(path, Headers(), progress); + } + + inline std::shared_ptr + Client::Get(const char *path, const Headers &headers, Progress progress) { + Request req; + req.method = "GET"; + req.path = path; + req.headers = headers; + req.progress = progress; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Head(const char *path) { + return Head(path, Headers()); + } + + inline std::shared_ptr Client::Head(const char *path, + const Headers &headers) { + Request req; + req.method = "HEAD"; + req.headers = headers; + req.path = path; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Post(const char *path, + const std::string &body, + const char *content_type) { + return Post(path, Headers(), body, content_type); + } + + inline std::shared_ptr Client::Post(const char *path, + const Headers &headers, + const std::string &body, + const char *content_type) { + Request req; + req.method = "POST"; + req.headers = headers; + req.path = path; + + req.headers.emplace("Content-Type", content_type); + req.body = body; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Post(const char *path, + const Params ¶ms) { + return Post(path, Headers(), params); + } + + inline std::shared_ptr + Client::Post(const char *path, const Headers &headers, const Params ¶ms) { + std::string query; + for (auto it = params.begin(); it != params.end(); ++it) { + if (it != params.begin()) { query += "&"; } + query += it->first; + query += "="; + query += detail::encode_url(it->second); + } + + return Post(path, headers, query, "application/x-www-form-urlencoded"); + } + + inline std::shared_ptr Client::Put(const char *path, + const std::string &body, + const char *content_type) { + return Put(path, Headers(), body, content_type); + } + + inline std::shared_ptr Client::Put(const char *path, + const Headers &headers, + const std::string &body, + const char *content_type) { + Request req; + req.method = "PUT"; + req.headers = headers; + req.path = path; + + req.headers.emplace("Content-Type", content_type); + req.body = body; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Patch(const char *path, + const std::string &body, + const char *content_type) { + return Patch(path, Headers(), body, content_type); + } + + inline std::shared_ptr Client::Patch(const char *path, + const Headers &headers, + const std::string &body, + const char *content_type) { + Request req; + req.method = "PATCH"; + req.headers = headers; + req.path = path; + + req.headers.emplace("Content-Type", content_type); + req.body = body; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Delete(const char *path, + const std::string &body, + const char *content_type) { + return Delete(path, Headers(), body, content_type); + } + + inline std::shared_ptr Client::Delete(const char *path, + const Headers &headers, + const std::string &body, + const char *content_type) { + Request req; + req.method = "DELETE"; + req.headers = headers; + req.path = path; + + if (content_type) { req.headers.emplace("Content-Type", content_type); } + req.body = body; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + + inline std::shared_ptr Client::Options(const char *path) { + return Options(path, Headers()); + } + + inline std::shared_ptr Client::Options(const char *path, + const Headers &headers) { + Request req; + req.method = "OPTIONS"; + req.path = path; + req.headers = headers; + + auto res = std::make_shared(); + + return send(req, *res) ? res : nullptr; + } + +/* + * SSL Implementation + */ +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + namespace detail { + +template +inline bool +read_and_close_socket_ssl(socket_t sock, size_t keep_alive_max_count, + // TODO: OpenSSL 1.0.2 occasionally crashes... + // The upcoming 1.1.0 is going to be thread safe. + SSL_CTX *ctx, std::mutex &ctx_mutex, + U SSL_connect_or_accept, V setup, T callback) { + SSL *ssl = nullptr; + { + std::lock_guard guard(ctx_mutex); + ssl = SSL_new(ctx); + } + + if (!ssl) { + close_socket(sock); + return false; + } + + auto bio = BIO_new_socket(sock, BIO_NOCLOSE); + SSL_set_bio(ssl, bio, bio); + + if (!setup(ssl)) { + SSL_shutdown(ssl); + { + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); + } + + close_socket(sock); + return false; + } + + bool ret = false; + + if (SSL_connect_or_accept(ssl) == 1) { + if (keep_alive_max_count > 0) { + auto count = keep_alive_max_count; + while (count > 0 && + detail::select_read(sock, CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND, + CPPHTTPLIB_KEEPALIVE_TIMEOUT_USECOND) > 0) { + SSLSocketStream strm(sock, ssl); + auto last_connection = count == 1; + auto connection_close = false; + + ret = callback(ssl, strm, last_connection, connection_close); + if (!ret || connection_close) { break; } + + count--; + } + } else { + SSLSocketStream strm(sock, ssl); + auto dummy_connection_close = false; + ret = callback(ssl, strm, true, dummy_connection_close); + } + } + + SSL_shutdown(ssl); + { + std::lock_guard guard(ctx_mutex); + SSL_free(ssl); + } + + close_socket(sock); + + return ret; +} + +class SSLInit { +public: + SSLInit() { + SSL_load_error_strings(); + SSL_library_init(); + } + + ~SSLInit() { ERR_free_strings(); } +}; + +static SSLInit sslinit_; + +} // namespace detail + +// SSL socket stream implementation +inline SSLSocketStream::SSLSocketStream(socket_t sock, SSL *ssl) + : sock_(sock), ssl_(ssl) {} + +inline SSLSocketStream::~SSLSocketStream() {} + +inline int SSLSocketStream::read(char *ptr, size_t size) { + if (SSL_pending(ssl_) > 0 || + detail::select_read(sock_, CPPHTTPLIB_READ_TIMEOUT_SECOND, + CPPHTTPLIB_READ_TIMEOUT_USECOND) > 0) { + return SSL_read(ssl_, ptr, size); + } + return -1; +} + +inline int SSLSocketStream::write(const char *ptr, size_t size) { + return SSL_write(ssl_, ptr, size); +} + +inline int SSLSocketStream::write(const char *ptr) { + return write(ptr, strlen(ptr)); +} + +inline std::string SSLSocketStream::get_remote_addr() const { + return detail::get_remote_addr(sock_); +} + +// SSL HTTP server implementation +inline SSLServer::SSLServer(const char *cert_path, const char *private_key_path, + const char *client_ca_cert_file_path, + const char *client_ca_cert_dir_path) { + ctx_ = SSL_CTX_new(SSLv23_server_method()); + + if (ctx_) { + SSL_CTX_set_options(ctx_, + SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | + SSL_OP_NO_COMPRESSION | + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); + + // auto ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + // SSL_CTX_set_tmp_ecdh(ctx_, ecdh); + // EC_KEY_free(ecdh); + + if (SSL_CTX_use_certificate_chain_file(ctx_, cert_path) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, private_key_path, SSL_FILETYPE_PEM) != + 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } else if (client_ca_cert_file_path || client_ca_cert_dir_path) { + // if (client_ca_cert_file_path) { + // auto list = SSL_load_client_CA_file(client_ca_cert_file_path); + // SSL_CTX_set_client_CA_list(ctx_, list); + // } + + SSL_CTX_load_verify_locations(ctx_, client_ca_cert_file_path, + client_ca_cert_dir_path); + + SSL_CTX_set_verify( + ctx_, + SSL_VERIFY_PEER | + SSL_VERIFY_FAIL_IF_NO_PEER_CERT, // SSL_VERIFY_CLIENT_ONCE, + nullptr); + } + } +} + +inline SSLServer::~SSLServer() { + if (ctx_) { SSL_CTX_free(ctx_); } +} + +inline bool SSLServer::is_valid() const { return ctx_; } + +inline bool SSLServer::read_and_close_socket(socket_t sock) { + return detail::read_and_close_socket_ssl( + sock, keep_alive_max_count_, ctx_, ctx_mutex_, SSL_accept, + [](SSL * /*ssl*/) { return true; }, + [this](SSL *ssl, Stream &strm, bool last_connection, + bool &connection_close) { + return process_request(strm, last_connection, connection_close, + [&](Request &req) { req.ssl = ssl; }); + }); +} + +// SSL HTTP client implementation +inline SSLClient::SSLClient(const char *host, int port, time_t timeout_sec, + const char *client_cert_path, + const char *client_key_path) + : Client(host, port, timeout_sec) { + ctx_ = SSL_CTX_new(SSLv23_client_method()); + + detail::split(&host_[0], &host_[host_.size()], '.', + [&](const char *b, const char *e) { + host_components_.emplace_back(std::string(b, e)); + }); + if (client_cert_path && client_key_path) { + if (SSL_CTX_use_certificate_file(ctx_, client_cert_path, + SSL_FILETYPE_PEM) != 1 || + SSL_CTX_use_PrivateKey_file(ctx_, client_key_path, SSL_FILETYPE_PEM) != + 1) { + SSL_CTX_free(ctx_); + ctx_ = nullptr; + } + } +} + +inline SSLClient::~SSLClient() { + if (ctx_) { SSL_CTX_free(ctx_); } +} + +inline bool SSLClient::is_valid() const { return ctx_; } + +inline void SSLClient::set_ca_cert_path(const char *ca_cert_file_path, + const char *ca_cert_dir_path) { + if (ca_cert_file_path) { ca_cert_file_path_ = ca_cert_file_path; } + if (ca_cert_dir_path) { ca_cert_dir_path_ = ca_cert_dir_path; } +} + +inline void SSLClient::enable_server_certificate_verification(bool enabled) { + server_certificate_verification_ = enabled; +} + +inline long SSLClient::get_openssl_verify_result() const { + return verify_result_; +} + +inline bool SSLClient::read_and_close_socket(socket_t sock, Request &req, + Response &res) { + + return is_valid() && + detail::read_and_close_socket_ssl( + sock, 0, ctx_, ctx_mutex_, + [&](SSL *ssl) { + if (ca_cert_file_path_.empty()) { + SSL_CTX_set_verify(ctx_, SSL_VERIFY_NONE, nullptr); + } else { + if (!SSL_CTX_load_verify_locations( + ctx_, ca_cert_file_path_.c_str(), nullptr)) { + return false; + } + SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER, nullptr); + } + + if (SSL_connect(ssl) != 1) { return false; } + + if (server_certificate_verification_) { + verify_result_ = SSL_get_verify_result(ssl); + + if (verify_result_ != X509_V_OK) { return false; } + + auto server_cert = SSL_get_peer_certificate(ssl); + + if (server_cert == nullptr) { return false; } + + if (!verify_host(server_cert)) { + X509_free(server_cert); + return false; + } + X509_free(server_cert); + } + + return true; + }, + [&](SSL *ssl) { + SSL_set_tlsext_host_name(ssl, host_.c_str()); + return true; + }, + [&](SSL * /*ssl*/, Stream &strm, bool /*last_connection*/, + bool &connection_close) { + return process_request(strm, req, res, connection_close); + }); +} + +inline bool SSLClient::is_ssl() const { return true; } + +inline bool SSLClient::verify_host(X509 *server_cert) const { + /* Quote from RFC2818 section 3.1 "Server Identity" + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. + + Matching is performed using the matching rules specified by + [RFC2459]. If more than one identity of a given type is present in + the certificate (e.g., more than one dNSName name, a match in any one + of the set is considered acceptable.) Names may contain the wildcard + character * which is considered to match any single domain name + component or component fragment. E.g., *.a.com matches foo.a.com but + not bar.foo.a.com. f*.com matches foo.com but not bar.com. + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. + + */ + return verify_host_with_subject_alt_name(server_cert) || + verify_host_with_common_name(server_cert); +} + +inline bool +SSLClient::verify_host_with_subject_alt_name(X509 *server_cert) const { + auto ret = false; + + auto type = GEN_DNS; + + struct in6_addr addr6; + struct in_addr addr; + size_t addr_len = 0; + + if (inet_pton(AF_INET6, host_.c_str(), &addr6)) { + type = GEN_IPADD; + addr_len = sizeof(struct in6_addr); + } else if (inet_pton(AF_INET, host_.c_str(), &addr)) { + type = GEN_IPADD; + addr_len = sizeof(struct in_addr); + } + + auto alt_names = static_cast( + X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr)); + + if (alt_names) { + auto dsn_matched = false; + auto ip_mached = false; + + auto count = sk_GENERAL_NAME_num(alt_names); + + for (auto i = 0; i < count && !dsn_matched; i++) { + auto val = sk_GENERAL_NAME_value(alt_names, i); + if (val->type == type) { + auto name = (const char *)ASN1_STRING_get0_data(val->d.ia5); + auto name_len = (size_t)ASN1_STRING_length(val->d.ia5); + + if (strlen(name) == name_len) { + switch (type) { + case GEN_DNS: dsn_matched = check_host_name(name, name_len); break; + + case GEN_IPADD: + if (!memcmp(&addr6, name, addr_len) || + !memcmp(&addr, name, addr_len)) { + ip_mached = true; + } + break; + } + } + } + } + + if (dsn_matched || ip_mached) { ret = true; } + } + + GENERAL_NAMES_free((STACK_OF(GENERAL_NAME) *)alt_names); + + return ret; +} + +inline bool SSLClient::verify_host_with_common_name(X509 *server_cert) const { + const auto subject_name = X509_get_subject_name(server_cert); + + if (subject_name != nullptr) { + char name[BUFSIZ]; + auto name_len = X509_NAME_get_text_by_NID(subject_name, NID_commonName, + name, sizeof(name)); + + if (name_len != -1) { return check_host_name(name, name_len); } + } + + return false; +} + +inline bool SSLClient::check_host_name(const char *pattern, + size_t pattern_len) const { + if (host_.size() == pattern_len && host_ == pattern) { return true; } + + // Wildcard match + // https://bugs.launchpad.net/ubuntu/+source/firefox-3.0/+bug/376484 + std::vector pattern_components; + detail::split(&pattern[0], &pattern[pattern_len], '.', + [&](const char *b, const char *e) { + pattern_components.emplace_back(std::string(b, e)); + }); + + if (host_components_.size() != pattern_components.size()) { return false; } + + auto itr = pattern_components.begin(); + for (const auto &h : host_components_) { + auto &p = *itr; + if (p != h && p != "*") { + auto partial_match = (p.size() > 0 && p[p.size() - 1] == '*' && + !p.compare(0, p.size() - 1, h)); + if (!partial_match) { return false; } + } + ++itr; + } + + return true; +} +#endif + +} // namespace httplib + +#endif // CPPHTTPLIB_HTTPLIB_H \ No newline at end of file diff --git a/common/json_config.cpp b/common/json_config.cpp index 9f4688a71..d262038f6 100644 --- a/common/json_config.cpp +++ b/common/json_config.cpp @@ -12,16 +12,18 @@ EQ::JsonConfigFile::JsonConfigFile(const Json::Value &value) EQ::JsonConfigFile::~JsonConfigFile() = default; /** - * @param filename + * @param file_name * @return */ -EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename) +EQ::JsonConfigFile EQ::JsonConfigFile::Load( + const std::string &file_name +) { JsonConfigFile ret; ret.m_root = Json::Value(); std::ifstream ifs; - ifs.open(filename, std::ifstream::in); + ifs.open(file_name, std::ifstream::in); if (!ifs.good()) { return ret; @@ -37,6 +39,31 @@ EQ::JsonConfigFile EQ::JsonConfigFile::Load(const std::string &filename) return ret; } +/** + * @param file_name + * @return + */ +void EQ::JsonConfigFile::Save( + const std::string &file_name +) +{ + std::ofstream opened_config_file; + opened_config_file.open(file_name); + + /** + * Grab and build config contents + */ + Json::StreamWriterBuilder write_builder; + write_builder["indentation"] = " "; + std::string document = Json::writeString(write_builder, m_root); + + /** + * Write current contents and close + */ + opened_config_file << document; + opened_config_file.close(); +} + /** * @param title * @param parameter diff --git a/common/json_config.h b/common/json_config.h index ba1051970..aa4d2d8f6 100644 --- a/common/json_config.h +++ b/common/json_config.h @@ -11,7 +11,8 @@ namespace EQ JsonConfigFile(const Json::Value &value); ~JsonConfigFile(); - static JsonConfigFile Load(const std::string &filename); + static JsonConfigFile Load(const std::string &file_name); + void Save(const std::string &file_name); std::string GetVariableString(const std::string &title, const std::string ¶meter, const std::string &default_value); int GetVariableInt(const std::string &title, const std::string ¶meter, const int default_value); diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index cb3c36874..64bbc224f 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -5,6 +5,8 @@ SET(eqlogin_sources client_manager.cpp database.cpp encryption.cpp + loginserver_command_handler.cpp + loginserver_webserver.cpp main.cpp server_manager.cpp world_server.cpp @@ -15,6 +17,8 @@ SET(eqlogin_headers client_manager.h database.h encryption.h + loginserver_command_handler.h + loginserver_webserver.h login_server.h login_structures.h options.h diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 176c7d4f2..7db8ddad5 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -24,6 +24,7 @@ #include "login_server.h" #include "../common/eqemu_logsys.h" #include "../common/string_util.h" +#include "../common/util/uuid.h" extern LoginServer server; @@ -463,7 +464,11 @@ void Database::UpdateWorldRegistration(unsigned int id, std::string long_name, s * @param id * @return */ -bool Database::CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id) +bool Database::CreateWorldRegistration( + std::string long_name, + std::string short_name, + unsigned int &id +) { auto query = fmt::format( "SELECT ifnull(max(ServerID),0) + 1 FROM {0}", @@ -504,6 +509,44 @@ bool Database::CreateWorldRegistration(std::string long_name, std::string short_ return true; } +/** + * @param long_name + * @param short_name + * @param id + * @return + */ +std::string Database::CreateLoginserverApiToken( + bool write_mode, + bool read_mode +) +{ + std::string token = EQ::Util::UUID::Generate().ToString(); + auto query = fmt::format( + "INSERT INTO loginserver_api_tokens (token, can_write, can_read, created_at) VALUES ('{0}', {1}, {2}, NOW())", + token, + (write_mode ? "1" : "0"), + (read_mode ? "1" : "0") + ); + + auto results = QueryDatabase(query); + if (!results.Success()) { + return ""; + } + + return token; +} + +/** + * @param long_name + * @param short_name + * @param id + * @return + */ +MySQLRequestResult Database::GetLoginserverApiTokens() +{ + return QueryDatabase("SELECT token, can_write, can_read FROM loginserver_api_tokens"); +} + /** * @param log_settings */ diff --git a/loginserver/database.h b/loginserver/database.h index 55c3342af..69ca1c08b 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -128,6 +128,15 @@ public: void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); void LoadLogSettings(EQEmuLogSys::LogSettings *log_settings); + + /** + * @param write_mode + * @param read_mode + * @return + */ + std::string CreateLoginserverApiToken(bool write_mode, bool read_mode); + MySQLRequestResult GetLoginserverApiTokens(); + protected: std::string user, pass, host, port, name; MYSQL *database; diff --git a/loginserver/login_server.h b/loginserver/login_server.h index 1ab0fee76..e71cc7da0 100644 --- a/loginserver/login_server.h +++ b/loginserver/login_server.h @@ -1,3 +1,5 @@ +#include + /** * EQEmulator: Everquest Server Emulator * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) @@ -28,6 +30,7 @@ #include "options.h" #include "server_manager.h" #include "client_manager.h" +#include "loginserver_webserver.h" /** * Login server struct, contains every variable for the server that needs to exist outside the scope of main() @@ -35,13 +38,16 @@ struct LoginServer { public: - LoginServer() : db(nullptr), server_manager(nullptr) { } + LoginServer() : db(nullptr), server_manager(nullptr) { - EQ::JsonConfigFile config; - Database *db; - Options options; - ServerManager *server_manager; - ClientManager *client_manager{}; + } + + EQ::JsonConfigFile config; + Database *db; + LoginserverWebserver::TokenManager *token_manager{}; + Options options; + ServerManager *server_manager; + ClientManager *client_manager{}; }; #endif diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp new file mode 100644 index 000000000..e04bcff85 --- /dev/null +++ b/loginserver/loginserver_command_handler.cpp @@ -0,0 +1,142 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include "loginserver_command_handler.h" +#include "../common/util/uuid.h" +#include "login_server.h" +#include "loginserver_webserver.h" + +extern LoginServer server; + +namespace LoginserverCommandHandler { + + /** + * @param cmd + */ + void DisplayDebug(argh::parser &cmd) + { + if (cmd[{"-d", "--debug"}]) { + std::cout << "Positional args:\n"; + for (auto &pos_arg : cmd) + std::cout << '\t' << pos_arg << std::endl; + + std::cout << "Positional args:\n"; + for (auto &pos_arg : cmd.pos_args()) + std::cout << '\t' << pos_arg << std::endl; + + std::cout << "\nFlags:\n"; + for (auto &flag : cmd.flags()) + std::cout << '\t' << flag << std::endl; + + std::cout << "\nParameters:\n"; + for (auto ¶m : cmd.params()) + std::cout << '\t' << param.first << " : " << param.second << std::endl; + } + } + + /** + * @param argc + * @param argv + */ + void CommandHandler(int argc, char **argv) + { + if (argc == 1) { return; } + + argh::parser cmd; + cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); + + LoginserverCommandHandler::DisplayDebug(cmd); + + /** + * Declare command mapping + */ + std::map function_map; + function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + + std::map::const_iterator it = function_map.begin(); + std::map::const_iterator end = function_map.end(); + + bool ran_command = false; + while (it != end) { + if (it->first == argv[1]) { + (it->second)(argc, argv, cmd); + ran_command = true; + } + ++it; + } + + if (cmd[{"-h", "--help"}] || !ran_command) { + std::cout << std::endl; + std::cout << "###########################################################" << std::endl; + std::cout << "# Loginserver CLI Menu" << std::endl; + std::cout << "###########################################################" << std::endl; + std::cout << std::endl; + std::cout << "> create-loginserver-api-token --write --read" << std::endl; + std::cout << "> list-loginserver-api-tokens" << std::endl; + std::cout << std::endl; + std::cout << std::endl; + } + + exit(1); + } + + /** + * @param argc + * @param argv + * @param cmd + */ + void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd) + { + bool can_read = cmd[{"-r", "--read"}]; + bool can_write = cmd[{"-w", "--write"}]; + + if (!can_read || !can_write) { + LogInfo("[{0}] --read or --write must be set or both!", __func__); + exit(1); + } + + std::string token = server.db->CreateLoginserverApiToken(can_write, can_read); + if (!token.empty()) { + LogInfo("[{0}] Created Loginserver API token [{1}]", __func__, token); + } + } + + /** + * @param argc + * @param argv + * @param cmd + */ + void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd) + { + for (auto it = server.token_manager->loaded_api_tokens.begin(); + it != server.token_manager->loaded_api_tokens.end(); + ++it) { + LogInfo( + "token [{0}] can_write [{1}] can_read [{2}]", + it->second.token, + it->second.can_write, + it->second.can_read + ); + } + } +} diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h new file mode 100644 index 000000000..b32bd0ee9 --- /dev/null +++ b/loginserver/loginserver_command_handler.h @@ -0,0 +1,34 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "iostream" +#include "../common/cli/argh.h" + +#ifndef EQEMU_LOGINSERVER_COMMAND_HANDLER_H +#define EQEMU_LOGINSERVER_COMMAND_HANDLER_H + +namespace LoginserverCommandHandler { + void CommandHandler(int argc, char **argv); + void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd); + void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd); +}; + + +#endif //EQEMU_LOGINSERVER_COMMAND_HANDLER_H diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp new file mode 100644 index 000000000..c5b3eecf6 --- /dev/null +++ b/loginserver/loginserver_webserver.cpp @@ -0,0 +1,243 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "loginserver_webserver.h" +#include "server_manager.h" +#include "login_server.h" +#include "../common/json/json.h" +#include "../common/string_util.h" + +extern LoginServer server; + +namespace LoginserverWebserver { + + /** + * @param api + */ + void RegisterRoutes(httplib::Server &api) + { + server.token_manager = new LoginserverWebserver::TokenManager; + server.token_manager->LoadApiTokens(); + + api.Get( + "/servers/list", [](const httplib::Request &request, httplib::Response &res) { + + LoginserverWebserver::TokenManager::AuthCanRead(request, res); + + Json::Value response; + auto iter = server.server_manager->getWorldServers().begin(); + while (iter != server.server_manager->getWorldServers().end()) { + Json::Value row; + row["server_long_name"] = (*iter)->GetLongName(); + row["server_short_name"] = (*iter)->GetLongName(); + row["server_list_id"] = (*iter)->GetServerListID(); + row["server_status"] = (*iter)->GetStatus(); + row["zones_booted"] = (*iter)->GetZonesBooted(); + row["local_ip"] = (*iter)->GetLocalIP(); + row["remote_ip"] = (*iter)->GetRemoteIP(); + row["players_online"] = (*iter)->GetPlayersOnline(); + response.append(row); + ++iter; + } + + LoginserverWebserver::SendResponse(response, res); + } + ); + } + + /** + * @param payload + * @param res + */ + void SendResponse(const Json::Value &payload, httplib::Response &res) + { + if (res.get_header_value("response_set") == "true") { + res.set_header("response_set", ""); + return; + } + + std::stringstream response_payload; + + if (payload.empty()) { + Json::Value response; + response["message"] = "There were no results found"; + response_payload << response; + res.set_content(response_payload.str(), "application/json"); + return; + } + + response_payload << payload; + res.set_content(response_payload.str(), "application/json"); + } + + /** + * @param request + * @param res + */ + void LoginserverWebserver::TokenManager::AuthCanRead(const httplib::Request &request, httplib::Response &res) + { + LoginserverWebserver::TokenManager::token_data + user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); + + if (!user_token.can_read) { + Json::Value response; + std::stringstream response_payload; + response["message"] = "Authorization token is either invalid or cannot read!"; + response_payload << response; + res.set_content(response_payload.str(), "application/json"); + res.set_header("response_set", "true"); + + LogWarning( + "AuthCanRead access failure | token [{0}] remote_address [{1}] user_agent [{2}]", + user_token.token, + user_token.remote_address, + user_token.user_agent + ); + + return; + } + } + + /** + * @param request + * @param res + */ + void LoginserverWebserver::TokenManager::AuthCanWrite(const httplib::Request &request, httplib::Response &res) + { + LoginserverWebserver::TokenManager::token_data + user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); + + if (!user_token.can_write) { + Json::Value response; + std::stringstream response_payload; + response["message"] = "Authorization token is either invalid or cannot write!"; + response_payload << response; + res.set_content(response_payload.str(), "application/json"); + res.set_header("response_set", "true"); + + LogWarning( + "AuthCanWrite access failure | token [{0}] remote_address [{1}] user_agent [{2}]", + user_token.token, + user_token.remote_address, + user_token.user_agent + ); + + return; + } + } + + /** + * @param request + * @return + */ + LoginserverWebserver::TokenManager::token_data + LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders( + const httplib::Request &request + ) + { + std::string authorization_key; + + LoginserverWebserver::TokenManager::token_data user_token{}; + + for (const auto &header : request.headers) { + auto header_key = header.first; + auto header_value = header.second; + if (header_key == "Authorization") { + authorization_key = header.second; + find_replace(authorization_key, "Bearer: ", ""); + if (LoginserverWebserver::TokenManager::TokenExists(authorization_key)) { + user_token = server.token_manager->GetToken(authorization_key); + } + } + + if (header_key == "REMOTE_ADDR") { + user_token.remote_address = header.second; + } + + if (header_key == "User-Agent") { + user_token.user_agent = header.second; + } + } + + LogDebug( + "Authentication Request | remote_address [{0}] user_agent [{1}] authorization_key [{2}]", + user_token.remote_address, + user_token.user_agent, + authorization_key + ); + + return user_token; + } + + /** + * Loads API Tokens + */ + void TokenManager::LoadApiTokens() + { + auto results = server.db->GetLoginserverApiTokens(); + for (auto row = results.begin(); row != results.end(); ++row) { + LoginserverWebserver::TokenManager::token_data token_data; + token_data.token = row[0]; + token_data.can_write = std::stoi(row[1]) > 0; + token_data.can_read = std::stoi(row[2]) > 0; + + LogDebug( + "Inserting api token to internal list [{0}] write {1} read {2}", + token_data.token, + token_data.can_read, + token_data.can_write + ); + + server.token_manager->loaded_api_tokens.insert( + std::make_pair( + token_data.token, + token_data + ) + ); + } + } + + /** + * @param token + * @return + */ + bool TokenManager::TokenExists(const std::string &token) + { + auto it = server.token_manager->loaded_api_tokens.find(token); + + return !(it == server.token_manager->loaded_api_tokens.end()); + } + + /** + * @param token + * @return + */ + LoginserverWebserver::TokenManager::token_data TokenManager::GetToken( + const std::string &token + ) + { + auto iter = server.token_manager->loaded_api_tokens.find(token); + if (iter != server.token_manager->loaded_api_tokens.end()) { + return iter->second; + } + + return {}; + } +} \ No newline at end of file diff --git a/loginserver/loginserver_webserver.h b/loginserver/loginserver_webserver.h new file mode 100644 index 000000000..c7c589c91 --- /dev/null +++ b/loginserver/loginserver_webserver.h @@ -0,0 +1,57 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef EQEMU_LOGINSERVER_WEBSERVER_H +#define EQEMU_LOGINSERVER_WEBSERVER_H + +#include "../common/http/httplib.h" +#include "../common/json/json.h" +#include "../common/types.h" + +namespace LoginserverWebserver { + + class TokenManager { + + public: + TokenManager() = default; + + struct token_data { + std::string token; + bool can_read; + bool can_write; + std::string user_agent; + std::string remote_address; + }; + + std::map loaded_api_tokens{}; + + void LoadApiTokens(); + static bool TokenExists(const std::string &token); + token_data GetToken(const std::string &token); + static token_data CheckApiAuthorizationHeaders(const httplib::Request &request); + static void AuthCanRead(const httplib::Request &request, httplib::Response &res); + static void AuthCanWrite(const httplib::Request &request, httplib::Response &res); + }; + + void RegisterRoutes(httplib::Server &api); + void SendResponse(const Json::Value &payload, httplib::Response &res); +}; + +#endif //EQEMU_LOGINSERVER_WEBSERVER_H diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 223df4197..3c98fe3db 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -26,7 +26,10 @@ #include "../common/platform.h" #include "../common/crash.h" #include "../common/eqemu_logsys.h" +#include "../common/http/httplib.h" #include "login_server.h" +#include "loginserver_webserver.h" +#include "loginserver_command_handler.h" #include #include #include @@ -40,7 +43,7 @@ void CatchSignal(int sig_num) { } -int main() +int main(int argc, char** argv) { RegisterExecutablePlatform(ExePlatformLogin); set_exception_handler(); @@ -156,7 +159,7 @@ int main() * create client manager */ LogInfo("Client Manager Init"); - server.client_manager = new ClientManager(); + server.client_manager = new ClientManager(); if (!server.client_manager) { LogError("Client Manager Failed to Start"); LogInfo("Server Manager Shutdown"); @@ -176,25 +179,46 @@ int main() #endif LogInfo("Server Started"); - if (LogSys.log_settings[Logs::Login_Server].log_to_console == 1) { LogInfo("Loginserver logging set to level [1] for more debugging, enable detail [3]"); } + /** + * Web API + */ + httplib::Server api; + int web_api_port = server.config.GetVariableInt("web_api", "port", 6000); + bool web_api_enabled = server.config.GetVariableBool("web_api", "enabled", true); + if (web_api_enabled) { + api.bind("0.0.0.0", web_api_port); + LogInfo("Webserver API now listening on port [{0}]", web_api_port); + LoginserverWebserver::RegisterRoutes(api); + } + + LoginserverCommandHandler::CommandHandler(argc, argv); + while (run_server) { Timer::SetCurrentTime(); server.client_manager->Process(); EQ::EventLoop::Get().Process(); - Sleep(50); + + if (web_api_enabled) { + api.poll(); + } + + Sleep(5); } LogInfo("Server Shutdown"); + LogInfo("Client Manager Shutdown"); delete server.client_manager; + LogInfo("Server Manager Shutdown"); delete server.server_manager; LogInfo("Database System Shutdown"); delete server.db; + return 0; } diff --git a/loginserver/options.h b/loginserver/options.h index 00abd7abf..0de5cba60 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -37,7 +37,6 @@ public: dump_in_packets(false), dump_out_packets(false), encryption_mode(5), - local_network("127.0.0.1"), reject_duplicate_servers(false), allow_password_login(true), allow_token_login(false), @@ -187,7 +186,6 @@ private: bool auto_link_accounts; bool update_insecure_passwords; int encryption_mode; - std::string local_network; std::string account_table; std::string world_registration_table; std::string world_admin_registration_table; diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 711104597..cb164b727 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -332,3 +332,11 @@ void ServerManager::DestroyServerByName( ++iter; } } + +/** + * @return + */ +const std::list> &ServerManager::getWorldServers() const +{ + return world_servers; +} diff --git a/loginserver/server_manager.h b/loginserver/server_manager.h index a05590316..8babf8a56 100644 --- a/loginserver/server_manager.h +++ b/loginserver/server_manager.h @@ -86,6 +86,11 @@ public: */ void DestroyServerByName(std::string server_long_name, std::string server_short_name, WorldServer *ignore = nullptr); + /** + * @return + */ + const std::list> &getWorldServers() const; + private: /** @@ -100,6 +105,7 @@ private: std::unique_ptr server_connection; std::list> world_servers; + }; #endif From 4bc6493718b399ff431660ffeea8c4973e1537d7 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 7 Jul 2019 03:39:44 -0500 Subject: [PATCH 055/491] Add cli command create-loginserver-account --username=* --password=* --- loginserver/loginserver_command_handler.cpp | 37 +++++++++++++++++++++ loginserver/loginserver_command_handler.h | 1 + loginserver/main.cpp | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index e04bcff85..260201ca0 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -72,6 +72,7 @@ namespace LoginserverCommandHandler { std::map function_map; function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["create-loginserver-account"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; std::map::const_iterator it = function_map.begin(); std::map::const_iterator end = function_map.end(); @@ -79,6 +80,12 @@ namespace LoginserverCommandHandler { bool ran_command = false; while (it != end) { if (it->first == argv[1]) { + std::cout << std::endl; + std::cout << "###########################################################" << std::endl; + std::cout << "# Executing CLI Command" << std::endl; + std::cout << "###########################################################" << std::endl; + std::cout << std::endl; + (it->second)(argc, argv, cmd); ran_command = true; } @@ -91,9 +98,13 @@ namespace LoginserverCommandHandler { std::cout << "# Loginserver CLI Menu" << std::endl; std::cout << "###########################################################" << std::endl; std::cout << std::endl; + std::cout << "# API" << std::endl; std::cout << "> create-loginserver-api-token --write --read" << std::endl; std::cout << "> list-loginserver-api-tokens" << std::endl; std::cout << std::endl; + std::cout << "# Accounts" << std::endl; + std::cout << "> create-loginserver-account --username=* --password=*" << std::endl; + std::cout << std::endl; std::cout << std::endl; } @@ -139,4 +150,30 @@ namespace LoginserverCommandHandler { ); } } + + /** + * @param argc + * @param argv + * @param cmd + */ + void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd) + { + if (cmd("--username").str().empty() || cmd("--username").str().empty()) { + LogInfo("Command Example: create-loginserver-account --username=user --password=password"); + exit(1); + } + + std::string user = cmd("--username").str(); + std::string password = cmd("--password").str(); + + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(user, password, mode); + + unsigned int db_id = 0; + std::string db_login = server.options.GetDefaultLoginServerName(); + if (!server.db->CreateLoginData(user, hash, db_login, db_id)) { + + } + } + } diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index b32bd0ee9..25c9e050b 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -28,6 +28,7 @@ namespace LoginserverCommandHandler { void CommandHandler(int argc, char **argv); void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd); void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd); + void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd); }; diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 3c98fe3db..bfc70d1f5 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -75,7 +75,7 @@ int main(int argc, char** argv) server.config.GetVariableString( "general", "default_loginserver_name", - "peq" + "local" ) ); From 392b328a9573b5b63a03da22bf86f3b5581d820a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 7 Jul 2019 04:32:59 -0500 Subject: [PATCH 056/491] Centralize local account creation and create API endpoint for creation --- loginserver/CMakeLists.txt | 2 + loginserver/account_management.cpp | 72 +++++++++++++++++++++ loginserver/account_management.h | 31 +++++++++ loginserver/client.cpp | 2 +- loginserver/encryption.cpp | 35 ++++++++++ loginserver/encryption.h | 6 ++ loginserver/loginserver_command_handler.cpp | 13 +--- loginserver/loginserver_webserver.cpp | 23 ++++++- 8 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 loginserver/account_management.cpp create mode 100644 loginserver/account_management.h diff --git a/loginserver/CMakeLists.txt b/loginserver/CMakeLists.txt index 64bbc224f..43217a48d 100644 --- a/loginserver/CMakeLists.txt +++ b/loginserver/CMakeLists.txt @@ -1,6 +1,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(eqlogin_sources + account_management.cpp client.cpp client_manager.cpp database.cpp @@ -13,6 +14,7 @@ SET(eqlogin_sources ) SET(eqlogin_headers + account_management.h client.h client_manager.h database.h diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp new file mode 100644 index 000000000..d5a2fabdb --- /dev/null +++ b/loginserver/account_management.cpp @@ -0,0 +1,72 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "account_management.h" +#include "login_server.h" + +extern LoginServer server; + +/** + * @param username + * @param password + * @return + */ +bool AccountManagement::CreateLocalLoginServerAccount( + std::string username, + std::string password +) +{ + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(username, password, mode); + + LogInfo( + "Attempting to create local login account for user [{0}] encryption algorithm [{1}] ({2})", + username, + GetEncryptionByModeId(mode), + mode + ); + + unsigned int db_id = 0; + std::string db_loginserver = server.options.GetDefaultLoginServerName(); + if (server.db->DoesLoginServerAccountExist(username, hash, db_loginserver, 1)) { + LogInfo( + "Attempting to create local login account for user [{0}] login [{1}] db_id [{2}] but already exists!", + username, + db_loginserver, + db_id + ); + + return false; + } + + if (server.db->CreateLoginData(username, hash, db_loginserver, db_id)) { + LogInfo( + "Account creation success for user [{0}] encryption algorithm [{1}] ({2})", + username, + GetEncryptionByModeId(mode), + mode + ); + return true; + } + + LogError("Failed to create local login account for user [{0}]!", username); + + return false; +} diff --git a/loginserver/account_management.h b/loginserver/account_management.h new file mode 100644 index 000000000..907aaf509 --- /dev/null +++ b/loginserver/account_management.h @@ -0,0 +1,31 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef EQEMU_ACCOUNT_MANAGEMENT_H +#define EQEMU_ACCOUNT_MANAGEMENT_H + +#include "iostream" + +class AccountManagement { +public: + static bool CreateLocalLoginServerAccount(std::string username, std::string password); +}; + + +#endif //EQEMU_ACCOUNT_MANAGEMENT_H diff --git a/loginserver/client.cpp b/loginserver/client.cpp index a2cefd39b..0a48c8d3a 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -87,7 +87,7 @@ bool Client::Process() } if (server.options.IsTraceOn()) { - LogInfo("Server list request received from client."); + LogDebug("Server list request received from client."); } SendServerListPacket(*(uint32_t *) app->pBuffer); diff --git a/loginserver/encryption.cpp b/loginserver/encryption.cpp index bf15bd796..27d22cca8 100644 --- a/loginserver/encryption.cpp +++ b/loginserver/encryption.cpp @@ -230,4 +230,39 @@ bool eqcrypt_verify_hash(const std::string &username, const std::string &passwor } return false; +} + +std::string GetEncryptionByModeId(uint32 mode) { + switch (mode) { + case EncryptionModeMD5: + return "MD5"; + case EncryptionModeMD5PassUser: + return "MD5PassUser"; + case EncryptionModeMD5UserPass: + return "MD5UserPass"; + case EncryptionModeMD5Triple: + return "MD5Triple"; + case EncryptionModeSHA: + return "SHA"; + case EncryptionModeSHAPassUser: + return "SHAPassUser"; + case EncryptionModeSHAUserPass: + return "SHAUserPass"; + case EncryptionModeSHATriple: + return "SHATriple"; + case EncryptionModeSHA512: + return "SHA512"; + case EncryptionModeSHA512PassUser: + return "SHA512PassUser"; + case EncryptionModeSHA512UserPass: + return "SHA512UserPass"; + case EncryptionModeSHA512Triple: + return "SHA512Triple"; + case EncryptionModeArgon2: + return "Argon2"; + case EncryptionModeSCrypt: + return "SCrypt"; + default: + return ""; + } } \ No newline at end of file diff --git a/loginserver/encryption.h b/loginserver/encryption.h index a6e79292f..000a3d0b4 100644 --- a/loginserver/encryption.h +++ b/loginserver/encryption.h @@ -21,6 +21,7 @@ #pragma once #include +#include "../common/types.h" enum EncryptionMode { @@ -40,6 +41,11 @@ enum EncryptionMode EncryptionModeSCrypt = 14 }; +/** + * @param mode + * @return + */ +std::string GetEncryptionByModeId(uint32 mode); const char* eqcrypt_block(const char *buffer_in, size_t buffer_in_sz, char* buffer_out, bool enc); std::string eqcrypt_hash(const std::string &username, const std::string &password, int mode); bool eqcrypt_verify_hash(const std::string &username, const std::string &password, const std::string &pwhash, int mode); diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 260201ca0..cebf23746 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -24,6 +24,7 @@ #include "../common/util/uuid.h" #include "login_server.h" #include "loginserver_webserver.h" +#include "account_management.h" extern LoginServer server; @@ -163,17 +164,7 @@ namespace LoginserverCommandHandler { exit(1); } - std::string user = cmd("--username").str(); - std::string password = cmd("--password").str(); - - auto mode = server.options.GetEncryptionMode(); - auto hash = eqcrypt_hash(user, password, mode); - - unsigned int db_id = 0; - std::string db_login = server.options.GetDefaultLoginServerName(); - if (!server.db->CreateLoginData(user, hash, db_login, db_id)) { - - } + AccountManagement::CreateLocalLoginServerAccount(cmd("--username").str(), cmd("--password").str()); } } diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index c5b3eecf6..d11b081db 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -23,6 +23,7 @@ #include "login_server.h" #include "../common/json/json.h" #include "../common/string_util.h" +#include "account_management.h" extern LoginServer server; @@ -38,7 +39,6 @@ namespace LoginserverWebserver { api.Get( "/servers/list", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanRead(request, res); Json::Value response; @@ -60,6 +60,27 @@ namespace LoginserverWebserver { LoginserverWebserver::SendResponse(response, res); } ); + + api.Post( + "/account/create", [](const httplib::Request &request, httplib::Response &res) { + LoginserverWebserver::TokenManager::AuthCanWrite(request, res); + + Json::Value response; + bool account_created = AccountManagement::CreateLocalLoginServerAccount( + request.get_param_value("username"), + request.get_param_value("password") + ); + + if (account_created) { + response["message"] = "Account created successfully!"; + } + else { + response["message"] = "Account failed to create!"; + } + + LoginserverWebserver::SendResponse(response, res); + } + ); } /** From 5473457c0c08fee4b4e26edce0b89b4bca43cfba Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 7 Jul 2019 05:26:10 -0500 Subject: [PATCH 057/491] Migrate database schema --- loginserver/database.cpp | 64 ++++++++----------- .../login_util/EQEmuLoginServerDBInstall.sql | 57 ----------------- loginserver/login_util/login_schema.sql | 59 +++++++++++++++++ .../login_util/tblLoginServerAccounts.sql | 11 ---- .../login_util/tblServerAdminRegistration.sql | 12 ---- loginserver/login_util/tblServerListType.sql | 10 --- .../login_util/tblWorldServerRegistration.sql | 14 ---- 7 files changed, 86 insertions(+), 141 deletions(-) delete mode 100644 loginserver/login_util/EQEmuLoginServerDBInstall.sql create mode 100644 loginserver/login_util/login_schema.sql delete mode 100644 loginserver/login_util/tblLoginServerAccounts.sql delete mode 100644 loginserver/login_util/tblServerAdminRegistration.sql delete mode 100644 loginserver/login_util/tblServerListType.sql delete mode 100644 loginserver/login_util/tblWorldServerRegistration.sql diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 7db8ddad5..8c5eb5dce 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -95,8 +95,7 @@ bool Database::GetLoginDataFromAccountInfo( ) { auto query = fmt::format( - "SELECT LoginServerID, AccountPassword FROM {0} WHERE AccountName = '{1}' AND AccountLoginserver = '{2}' LIMIT 1", - server.options.GetAccountTable(), + "SELECT id, account_password FROM login_accounts WHERE account_name = '{0}' AND source_loginserver = '{1}' LIMIT 1", EscapeString(name), EscapeString(loginserver) ); @@ -193,8 +192,7 @@ bool Database::GetLoginTokenDataFromToken( unsigned int Database::GetFreeID(const std::string &loginserver) { auto query = fmt::format( - "SELECT IFNULL(MAX(LoginServerID), 0) + 1 FROM {0} WHERE AccountLoginServer='{1}'", - server.options.GetAccountTable(), + "SELECT IFNULL(MAX(id), 0) + 1 FROM login_accounts WHERE source_loginserver = '{0}'", EscapeString(loginserver) ); @@ -222,7 +220,10 @@ bool Database::CreateLoginData( unsigned int &id ) { - return CreateLoginDataWithID(name, password, loginserver, GetFreeID(loginserver)); + uint32 free_id = GetFreeID(loginserver); + id = free_id; + + return CreateLoginDataWithID(name, password, loginserver, free_id); } /** @@ -244,9 +245,8 @@ bool Database::CreateLoginDataWithID( } auto query = fmt::format( - "INSERT INTO {0} (LoginServerID, AccountLoginserver, AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) " - "VALUES ({1}, '{2}', '{3}', '{4}', 'local_creation', NOW(), '127.0.0.1')", - server.options.GetAccountTable(), + "INSERT INTO login_accounts (id, source_loginserver, account_name, account_password, account_email, last_login_date, last_ip_address, created_at) " + "VALUES ({0}, '{1}', '{2}', '{3}', 'local_creation', NOW(), '127.0.0.1', NOW())", id, EscapeString(loginserver), EscapeString(in_account_name), @@ -277,8 +277,7 @@ bool Database::DoesLoginServerAccountExist( } auto query = fmt::format( - "SELECT AccountName FROM {0} WHERE AccountName = '{1}' AND AccountLoginserver = '{2}'", - server.options.GetAccountTable(), + "SELECT AccountName FROM login_accounts WHERE account_name = '{0}' AND source_loginserver = '{1}'", EscapeString(name), EscapeString(loginserver) ); @@ -310,8 +309,7 @@ void Database::UpdateLoginHash( ); auto query = fmt::format( - "UPDATE {0} SET AccountPassword='{1}' WHERE AccountName='{2}' AND AccountLoginserver='{3}'", - server.options.GetAccountTable(), + "UPDATE login_accounts SET account_password = '{0}' WHERE account_name = '{1}' AND source_loginserver = '{2}'", hash, EscapeString(name), EscapeString(loginserver) @@ -346,19 +344,17 @@ bool Database::GetWorldRegistration( { auto query = fmt::format( "SELECT\n" - " ifnull(WSR.ServerID, 999999) AS ServerID,\n" - " WSR.ServerTagDescription,\n" - " ifnull(WSR.ServerTrusted, 0) AS ServerTrusted,\n" - " ifnull(SLT.ServerListTypeID, 3) AS ServerListTypeID,\n" - " SLT.ServerListTypeDescription,\n" - " ifnull(WSR.ServerAdminID, 0) AS ServerAdminID\n" + " ifnull(WSR.id, 999999) AS server_id,\n" + " WSR.tag_description,\n" + " ifnull(WSR.is_server_trusted, 0) AS is_server_trusted,\n" + " ifnull(SLT.id, 3) AS login_server_list_type_id,\n" + " SLT.description,\n" + " ifnull(WSR.login_server_admin_id, 0) AS login_server_admin_id\n" "FROM\n" - " {0} AS WSR\n" - " JOIN {1} AS SLT ON WSR.ServerListTypeID = SLT.ServerListTypeID\n" + " login_world_servers AS WSR\n" + " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.ServerShortName = '{2}' LIMIT 1", - server.options.GetWorldRegistrationTable(), - server.options.GetWorldServerTypeTable(), + " WSR.short_name = '{0}' LIMIT 1", EscapeString(short_name) ); @@ -379,8 +375,7 @@ bool Database::GetWorldRegistration( if (db_account_id > 0) { auto world_registration_query = fmt::format( - "SELECT AccountName, AccountPassword FROM {0} WHERE ServerAdminID = {1} LIMIT 1", - server.options.GetWorldAdminRegistrationTable(), + "SELECT account_name, account_password FROM login_server_admins WHERE id = {0} LIMIT 1", db_account_id ); @@ -405,8 +400,7 @@ bool Database::GetWorldRegistration( void Database::UpdateLSAccountData(unsigned int id, std::string ip_address) { auto query = fmt::format( - "UPDATE {0} SET LastIPAddress = '{1}', LastLoginDate = NOW() where LoginServerId = {2}", - server.options.GetAccountTable(), + "UPDATE login_accounts SET last_ip_address = '{0}', last_login_date = NOW() where id = {1}", ip_address, id ); @@ -428,9 +422,8 @@ void Database::UpdateLSAccountInfo( ) { auto query = fmt::format( - "REPLACE {0} SET LoginServerID = {1}, AccountName = '{2}', AccountPassword = sha('{3}'), AccountCreateDate = now(), " - "AccountEmail = '{4}', LastIPAddress = '0.0.0.0', LastLoginDate = now()", - server.options.GetAccountTable(), + "REPLACE login_accounts SET id = {0}, account_name = '{1}', account_password = sha('{2}'), " + "account_email = '{3}', last_ip_address = '0.0.0.0', last_login_date = now()", id, EscapeString(name), EscapeString(password), @@ -448,8 +441,7 @@ void Database::UpdateLSAccountInfo( void Database::UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address) { auto query = fmt::format( - "UPDATE {0} SET ServerLastLoginDate = NOW(), ServerLastIPAddr = '{1}', ServerLongName = '{2}' WHERE ServerID = {3}", - server.options.GetWorldRegistrationTable(), + "UPDATE login_world_servers SET last_login_date = NOW(), last_ip_address = '{0}', long_name = '{1}' WHERE id = {2}", ip_address, EscapeString(long_name), id @@ -471,8 +463,7 @@ bool Database::CreateWorldRegistration( ) { auto query = fmt::format( - "SELECT ifnull(max(ServerID),0) + 1 FROM {0}", - server.options.GetWorldRegistrationTable() + "SELECT ifnull(max(id),0) + 1 FROM login_world_servers" ); auto results = QueryDatabase(query); @@ -485,9 +476,8 @@ bool Database::CreateWorldRegistration( id = atoi(row[0]); auto insert_query = fmt::format( - "INSERT INTO {0} SET ServerID = {1}, ServerLongName = '{2}', ServerShortName = '{3}', \n" - "ServerListTypeID = 3, ServerAdminID = 0, ServerTrusted = 0, ServerTagDescription = ''", - server.options.GetWorldRegistrationTable(), + "INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', \n" + "login_server_list_type_id = 3, login_server_admin_id = 0, is_server_trusted = 0, tag_description = ''", id, long_name, short_name diff --git a/loginserver/login_util/EQEmuLoginServerDBInstall.sql b/loginserver/login_util/EQEmuLoginServerDBInstall.sql deleted file mode 100644 index ae8f6e5e8..000000000 --- a/loginserver/login_util/EQEmuLoginServerDBInstall.sql +++ /dev/null @@ -1,57 +0,0 @@ -DROP TABLE IF EXISTS tblLoginServerAccounts; -CREATE TABLE IF NOT EXISTS tblLoginServerAccounts ( - LoginServerID integer unsigned NOT NULL auto_increment, - AccountName varchar(30) NOT NULL, - AccountPassword varchar(50) NOT NULL, - AccountCreateDate timestamp default CURRENT_TIMESTAMP NOT NULL, - AccountEmail varchar(100) NOT NULL, - LastLoginDate datetime NOT NULL, - LastIPAddress varchar(15) NOT NULL, - PRIMARY KEY (LoginServerID, AccountName) -) ENGINE=InnoDB; - -insert into tblLoginServerAccounts (AccountName, AccountPassword, AccountEmail, LastLoginDate, LastIPAddress) values('Admin', sha('password'), 'admin@somewhere.com', now(), '127.0.0.1'); - -DROP TABLE IF EXISTS tblServerListType; -CREATE TABLE IF NOT EXISTS tblServerListType ( - ServerListTypeID integer unsigned NOT NULL, - ServerListTypeDescription varchar(20) NOT NULL, - PRIMARY KEY (ServerListTypeID) -) ENGINE=MyISAM; - -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (1, 'Legends'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (2, 'Preferred'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (3, 'Standard'); - -DROP TABLE IF EXISTS tblServerAdminRegistration; -CREATE TABLE IF NOT EXISTS tblServerAdminRegistration ( - ServerAdminID integer unsigned NOT NULL auto_increment, - AccountName varchar(30) NOT NULL, - AccountPassword varchar(30) NOT NULL, - FirstName varchar(40) NOT NULL, - LastName varchar(50) NOT NULL, - Email varchar(100) NULL, - RegistrationDate datetime NOT NULL, - RegistrationIPAddr varchar(15) NOT NULL, - PRIMARY KEY (ServerAdminID, Email) -) ENGINE=MyISAM; - -INSERT INTO tblServerAdminRegistration (AccountName, AccountPassword, FirstName, LastName, Email, RegistrationDate, RegistrationIPAddr) VALUES ('Admin', 'Password', 'Tom', 'Wilson', 'Tom.Wilson@gmail.com', now(), '0.0.0.0'); - -DROP TABLE IF EXISTS tblWorldServerRegistration; -CREATE TABLE IF NOT EXISTS tblWorldServerRegistration ( - ServerID integer unsigned NOT NULL auto_increment, - ServerLongName varchar(100) NOT NULL, - ServerTagDescription varchar(50) NOT NULL DEFAULT '', - ServerShortName varchar(25) NOT NULL, - ServerListTypeID integer NOT NULL, - ServerLastLoginDate datetime NULL, - ServerLastIPAddr varchar(15) NULL, - ServerAdminID integer NOT NULL, - ServerTrusted integer NOT NULL, - Note varchar(300) NULL, - PRIMARY KEY (ServerID, ServerLongName) -) ENGINE=InnoDB; - - -INSERT INTO tblWorldServerRegistration (ServerLongName, ServerTagDescription, ServerShortName, ServerListTypeID, ServerLastLoginDate, ServerLastIPAddr, ServerAdminID, ServerTrusted, Note) VALUES ('My Test Server', 'A test server', 'MTST', 1, now(), '0.0.0.0', 1, 0, 'This is a note for the test server'); diff --git a/loginserver/login_util/login_schema.sql b/loginserver/login_util/login_schema.sql new file mode 100644 index 000000000..b96f08e0e --- /dev/null +++ b/loginserver/login_util/login_schema.sql @@ -0,0 +1,59 @@ +CREATE TABLE `login_accounts` ( + `id` int(11) unsigned NOT NULL, + `account_name` varchar(50) NOT NULL, + `account_password` text NOT NULL, + `account_email` varchar(100) NOT NULL, + `source_loginserver` varchar(64) DEFAULT NULL, + `last_ip_address` varchar(15) NOT NULL, + `last_login_date` datetime NOT NULL, + `created_at` datetime DEFAULT NULL, + `updated_at` datetime DEFAULT current_timestamp(), + PRIMARY KEY (`id`,`account_name`), + UNIQUE KEY `source_loginserver_account_name` (`source_loginserver`,`account_name`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `login_server_admins` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `account_name` varchar(30) NOT NULL, + `account_password` varchar(100) NOT NULL, + `first_name` varchar(50) NOT NULL, + `last_name` varchar(50) NOT NULL, + `email` varchar(100) NOT NULL, + `registration_date` datetime NOT NULL, + `registration_ip_address` varchar(15) NOT NULL, + PRIMARY KEY (`id`,`account_name`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; + +CREATE TABLE `login_server_list_types` ( + `id` int(10) unsigned NOT NULL, + `description` varchar(60) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +INSERT INTO `login_server_list_types` (`id`, `description`) VALUES ('1', 'Legends'), +('2', 'Preferred'), +('3', 'Standard'); + +CREATE TABLE `login_world_servers` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `long_name` varchar(100) NOT NULL, + `short_name` varchar(100) NOT NULL, + `tag_description` varchar(50) NOT NULL DEFAULT '', + `login_server_list_type_id` int(11) NOT NULL, + `last_login_date` datetime DEFAULT NULL, + `last_ip_address` varchar(15) DEFAULT NULL, + `login_server_admin_id` int(11) NOT NULL, + `is_server_trusted` int(11) NOT NULL, + `note` varchar(300) DEFAULT NULL, + PRIMARY KEY (`id`,`long_name`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; + +CREATE TABLE `login_api_tokens` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `token` varchar(200) DEFAULT NULL, + `can_write` int(11) DEFAULT 0, + `can_read` int(11) DEFAULT 0, + `created_at` datetime DEFAULT NULL, + `updated_at` datetime DEFAULT current_timestamp(), + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; \ No newline at end of file diff --git a/loginserver/login_util/tblLoginServerAccounts.sql b/loginserver/login_util/tblLoginServerAccounts.sql deleted file mode 100644 index 65143b38b..000000000 --- a/loginserver/login_util/tblLoginServerAccounts.sql +++ /dev/null @@ -1,11 +0,0 @@ -DROP TABLE IF EXISTS tblLoginServerAccounts; -CREATE TABLE IF NOT EXISTS tblLoginServerAccounts ( - LoginServerID integer unsigned NOT NULL auto_increment, - AccountName varchar(30) NOT NULL, - AccountPassword varchar(50) NOT NULL, - AccountCreateDate timestamp default CURRENT_TIMESTAMP NOT NULL, - AccountEmail varchar(100) NOT NULL, - LastLoginDate datetime NOT NULL, - LastIPAddress varchar(15) NOT NULL, - PRIMARY KEY (LoginServerID, AccountName) -) ENGINE=InnoDB; diff --git a/loginserver/login_util/tblServerAdminRegistration.sql b/loginserver/login_util/tblServerAdminRegistration.sql deleted file mode 100644 index 8e91a5a77..000000000 --- a/loginserver/login_util/tblServerAdminRegistration.sql +++ /dev/null @@ -1,12 +0,0 @@ -DROP TABLE IF EXISTS tblServerAdminRegistration; -CREATE TABLE IF NOT EXISTS tblServerAdminRegistration ( - ServerAdminID integer unsigned NOT NULL auto_increment, - AccountName varchar(30) NOT NULL, - AccountPassword varchar(30) NOT NULL, - FirstName varchar(40) NOT NULL, - LastName varchar(50) NOT NULL, - Email varchar(100) NULL, - RegistrationDate datetime NOT NULL, - RegistrationIPAddr varchar(15) NOT NULL, - PRIMARY KEY (ServerAdminID, Email) -) ENGINE=MyISAM; \ No newline at end of file diff --git a/loginserver/login_util/tblServerListType.sql b/loginserver/login_util/tblServerListType.sql deleted file mode 100644 index fafaffe45..000000000 --- a/loginserver/login_util/tblServerListType.sql +++ /dev/null @@ -1,10 +0,0 @@ -DROP TABLE IF EXISTS tblServerListType; -CREATE TABLE IF NOT EXISTS tblServerListType ( - ServerListTypeID integer unsigned NOT NULL, - ServerListTypeDescription varchar(20) NOT NULL, - PRIMARY KEY (ServerListTypeID) -) ENGINE=MyISAM; - -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (1, 'Legends'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (2, 'Preferred'); -INSERT INTO tblServerListType (ServerListTypeID, ServerListTypeDescription) VALUES (3, 'Standard'); \ No newline at end of file diff --git a/loginserver/login_util/tblWorldServerRegistration.sql b/loginserver/login_util/tblWorldServerRegistration.sql deleted file mode 100644 index e0ee4dc9f..000000000 --- a/loginserver/login_util/tblWorldServerRegistration.sql +++ /dev/null @@ -1,14 +0,0 @@ -DROP TABLE IF EXISTS tblWorldServerRegistration; -CREATE TABLE IF NOT EXISTS tblWorldServerRegistration ( - ServerID integer unsigned NOT NULL auto_increment, - ServerLongName varchar(100) NOT NULL, - ServerTagDescription varchar(50) NOT NULL DEFAULT '', - ServerShortName varchar(25) NOT NULL, - ServerListTypeID integer NOT NULL, - ServerLastLoginDate datetime NULL, - ServerLastIPAddr varchar(15) NULL, - ServerAdminID integer NOT NULL, - Note varchar(300) NULL, - ServerTrusted int(11), - PRIMARY KEY (ServerID, ServerLongName) -) ENGINE=InnoDB; From c2917a90047e4e4c13331039ba448f39d802675b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 7 Jul 2019 19:57:05 -0500 Subject: [PATCH 058/491] Take in API requests via json payload instead of params --- CMakeLists.txt | 90 ++------------------------- loginserver/client.cpp | 16 ++--- loginserver/database.cpp | 2 +- loginserver/loginserver_webserver.cpp | 27 ++++++-- loginserver/loginserver_webserver.h | 1 + loginserver/main.cpp | 22 ------- loginserver/options.h | 44 ------------- zone/CMakeLists.txt | 4 -- 8 files changed, 40 insertions(+), 166 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c1538b03..87966f3ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,16 +6,8 @@ #EQEMU_DISABLE_SAFESEH #EQEMU_BUILD_MSVC_MP #EQEMU_DEBUG_LEVEL -#EQEMU_LOG_LEVEL_STATUS -#EQEMU_LOG_LEVEL_NORMAL -#EQEMU_LOG_LEVEL_ERROR #EQEMU_LOG_LEVEL_DEBUG -#EQEMU_LOG_LEVEL_QUEST -#EQEMU_LOG_LEVEL_COMMANDS -#EQEMU_LOG_LEVEL_CRASH -#EQEMU_DEPOP_INVALIDATES_CACHE #EQEMU_ENABLE_BOTS -#EQEMU_DISABLE_LOGSYS #EQEMU_COMMANDS_LOGGING #EQEMU_BUILD_SERVER #EQEMU_BUILD_LOGIN @@ -144,36 +136,6 @@ SET(EQEMU_DEBUG_LEVEL 5 CACHE STRING "EQEmu debug level: 10 - More errors than you ever wanted to see" ) -SET(EQEMU_LOG_LEVEL_STATUS 2 CACHE STRING "EQEmu logging level for [Status]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) - -SET(EQEMU_LOG_LEVEL_NORMAL 3 CACHE STRING "EQEmu logging level for [Normal]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) - -SET(EQEMU_LOG_LEVEL_ERROR 2 CACHE STRING "EQEmu logging level for [Error]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) - SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]: 0 - Disabled 1 - Ouput to File Enabled @@ -184,47 +146,17 @@ SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]: 11 - Output to File, stdout and stderr Enabled" ) -SET(EQEMU_LOG_LEVEL_QUEST 2 CACHE STRING "EQEmu logging level for [Quest]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) +OPTION(EQEMU_LSPX "" OFF) +IF(EQEMU_LSPX) + ADD_DEFINITIONS(-DLSPX=ON) +ENDIF(EQEMU_LSPX) +MARK_AS_ADVANCED(EQEMU_LSPX) -SET(EQEMU_LOG_LEVEL_COMMANDS 1 CACHE STRING "EQEmu logging level for [Commands]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) - -SET(EQEMU_LOG_LEVEL_CRASH 3 CACHE STRING "EQEmu logging level for [Crash]: - 0 - Disabled - 1 - Ouput to File Enabled - 2 - Output to stdout Enabled - 3 - Output to File and stdout Enabled - 8 - Output to stderr Enabled - 9 - Output to File and stderr Enabled - 11 - Output to File, stdout and stderr Enabled" -) - -MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_STATUS EQEMU_LOG_LEVEL_NORMAL EQEMU_LOG_LEVEL_ERROR EQEMU_LOG_LEVEL_DEBUG EQEMU_LOG_LEVEL_QUEST EQEMU_LOG_LEVEL_COMMANDS EQEMU_LOG_LEVEL_CRASH) - -#NPC Types Cache Behavior -OPTION(EQEMU_DEPOP_INVALIDATES_CACHE "#repop invalidates the npc_types cache (will cause a larger database hit on #repop but is more convienent)." ON) +MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_DEBUG) #Bots are a compile time option so on/off OPTION(EQEMU_ENABLE_BOTS "Enable Bots" OFF) -#Disable entire _mlog system (excludes trade/command logs) -OPTION(EQEMU_DISABLE_LOGSYS "Disable Logging INI System" ON) - #Enable GM Command log system OPTION(EQEMU_COMMANDS_LOGGING "Enable GM Command logs" ON) @@ -232,10 +164,6 @@ IF(EQEMU_COMMANDS_LOGGING) ADD_DEFINITIONS(-DCOMMANDS_LOGGING) ENDIF(EQEMU_COMMANDS_LOGGING) -IF(EQEMU_DISABLE_LOGSYS) - ADD_DEFINITIONS(-DDISABLE_LOGSYS) -ENDIF(EQEMU_DISABLE_LOGSYS) - IF(EQEMU_ENABLE_BOTS) ADD_DEFINITIONS(-DBOTS) ENDIF(EQEMU_ENABLE_BOTS) @@ -278,13 +206,7 @@ ADD_DEFINITIONS(-DEQDEBUG=${EQEMU_DEBUG_LEVEL}) ADD_DEFINITIONS(-DINVERSEXY) ADD_DEFINITIONS(-DFIELD_ITEMS) ADD_DEFINITIONS(-DMAP_DIR="${EQEMU_MAP_DIR}") -ADD_DEFINITIONS(-DLOG_LEVEL_STATUS=${EQEMU_LOG_LEVEL_STATUS}) -ADD_DEFINITIONS(-DLOG_LEVEL_NORMAL=${EQEMU_LOG_LEVEL_NORMAL}) -ADD_DEFINITIONS(-DLOG_LEVEL_ERROR=${EQEMU_LOG_LEVEL_ERROR}) ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG}) -ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST}) -ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS}) -ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH}) ADD_DEFINITIONS(-DGLM_FORCE_RADIANS) ADD_DEFINITIONS(-DGLM_FORCE_CTOR_INIT) ADD_DEFINITIONS(-DGLM_ENABLE_EXPERIMENTAL) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 0a48c8d3a..4d4e9c37f 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -385,8 +385,9 @@ void Client::AttemptLoginAccountCreation( { LogInfo("Attempting login account creation via '{0}'", loginserver); - if (loginserver == "eqemu") { +#ifdef LSPX + if (loginserver == "eqemu") { if (!server.options.CanAutoLinkAccounts()) { LogInfo("CanAutoLinkAccounts disabled - sending failed login"); DoFailedLogin(); @@ -445,16 +446,17 @@ void Client::AttemptLoginAccountCreation( login_connection_manager->Connect(addr, port); } ); + + return; } - else { - - if (!server.options.CanAutoCreateAccounts()) { - DoFailedLogin(); - return; - } +#endif + if (server.options.CanAutoCreateAccounts() && loginserver == "local") { CreateLocalAccount(user, pass); + return; } + + DoFailedLogin(); } void Client::DoFailedLogin() diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 8c5eb5dce..e4a10d19e 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -277,7 +277,7 @@ bool Database::DoesLoginServerAccountExist( } auto query = fmt::format( - "SELECT AccountName FROM login_accounts WHERE account_name = '{0}' AND source_loginserver = '{1}'", + "SELECT account_name FROM login_accounts WHERE account_name = '{0}' AND source_loginserver = '{1}'", EscapeString(name), EscapeString(loginserver) ); diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index d11b081db..6a090f828 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -64,13 +64,18 @@ namespace LoginserverWebserver { api.Post( "/account/create", [](const httplib::Request &request, httplib::Response &res) { LoginserverWebserver::TokenManager::AuthCanWrite(request, res); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); Json::Value response; - bool account_created = AccountManagement::CreateLocalLoginServerAccount( - request.get_param_value("username"), - request.get_param_value("password") - ); + if (username.empty() || password.empty()) { + response["message"] = "Username or password not set"; + LoginserverWebserver::SendResponse(response, res); + return; + } + bool account_created = AccountManagement::CreateLocalLoginServerAccount(username, password); if (account_created) { response["message"] = "Account created successfully!"; } @@ -108,6 +113,20 @@ namespace LoginserverWebserver { res.set_content(response_payload.str(), "application/json"); } + /** + * @param payload + * @param res + */ + Json::Value ParseRequestBody(const httplib::Request &request) + { + std::stringstream ss; + ss.str(request.body); + Json::Value request_body; + ss >> request_body; + + return request_body; + } + /** * @param request * @param res diff --git a/loginserver/loginserver_webserver.h b/loginserver/loginserver_webserver.h index c7c589c91..2c5d07866 100644 --- a/loginserver/loginserver_webserver.h +++ b/loginserver/loginserver_webserver.h @@ -52,6 +52,7 @@ namespace LoginserverWebserver { void RegisterRoutes(httplib::Server &api); void SendResponse(const Json::Value &payload, httplib::Response &res); + static Json::Value ParseRequestBody(const httplib::Request &request); }; #endif //EQEMU_LOGINSERVER_WEBSERVER_H diff --git a/loginserver/main.cpp b/loginserver/main.cpp index bfc70d1f5..31cd3429d 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -96,28 +96,6 @@ int main(int argc, char** argv) true ) ); - server.options.AccountTable(server.config.GetVariableString("schema", "account_table", "tblLoginServerAccounts")); - server.options.WorldRegistrationTable( - server.config.GetVariableString( - "schema", - "world_registration_table", - "tblWorldServerRegistration" - ) - ); - server.options.WorldAdminRegistrationTable( - server.config.GetVariableString( - "schema", - "world_admin_registration_table", - "tblServerAdminRegistration" - ) - ); - server.options.WorldServerTypeTable( - server.config.GetVariableString( - "schema", - "world_server_type_table", - "tblServerListType" - ) - ); /** * mysql connect diff --git a/loginserver/options.h b/loginserver/options.h index 0de5cba60..b774a88a0 100644 --- a/loginserver/options.h +++ b/loginserver/options.h @@ -102,46 +102,6 @@ public: */ inline int GetEncryptionMode() const { return encryption_mode; } - /** - * Sets account table. - */ - inline void AccountTable(std::string t) { account_table = t; } - - /** - * Return the value of world account table. - */ - inline std::string GetAccountTable() const { return account_table; } - - /** - * Sets world registration table. - */ - inline void WorldRegistrationTable(std::string t) { world_registration_table = t; } - - /** - * Return the value of world registration table. - */ - inline std::string GetWorldRegistrationTable() const { return world_registration_table; } - - /** - * Sets world admin account table. - */ - inline void WorldAdminRegistrationTable(std::string t) { world_admin_registration_table = t; } - - /** - * Return the value of world admin account table. - */ - inline std::string GetWorldAdminRegistrationTable() const { return world_admin_registration_table; } - - /** - * Sets world server type table. - */ - inline void WorldServerTypeTable(std::string t) { world_server_type_table = t; } - - /** - * Return the value of world server type table. - */ - inline std::string GetWorldServerTypeTable() const { return world_server_type_table; } - /** * Sets whether we are rejecting duplicate servers or not. */ @@ -186,10 +146,6 @@ private: bool auto_link_accounts; bool update_insecure_passwords; int encryption_mode; - std::string account_table; - std::string world_registration_table; - std::string world_admin_registration_table; - std::string world_server_type_table; std::string eqemu_loginserver_address; std::string default_loginserver_name; }; diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 3a897fda9..2de1ac1f6 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -250,10 +250,6 @@ SET(zone_headers zonedb.h zonedump.h) -IF(EQEMU_DEPOP_INVALIDATES_CACHE) - ADD_DEFINITIONS(-DDEPOP_INVALIDATES_NPC_TYPES_CACHE) -ENDIF(EQEMU_DEPOP_INVALIDATES_CACHE) - ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers}) INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) From d8f34651de6756374a2220036ffdd6e3b9c18399 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 8 Jul 2019 20:25:37 -0500 Subject: [PATCH 059/491] Streamline worldserver authorization handlers, cleanup and refactoring --- common/servertalk.h | 18 +- loginserver/database.cpp | 79 +-- loginserver/database.h | 37 +- loginserver/login_util/login_schema.sql | 13 +- loginserver/loginserver_webserver.cpp | 4 +- loginserver/server_manager.cpp | 36 +- loginserver/world_server.cpp | 881 ++++++++++++++++-------- loginserver/world_server.h | 70 +- world/login_server.cpp | 20 +- 9 files changed, 766 insertions(+), 392 deletions(-) diff --git a/common/servertalk.h b/common/servertalk.h index 242635b1d..7584d4942 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -455,15 +455,15 @@ struct ServerLSInfo_Struct { }; struct ServerNewLSInfo_Struct { - char name[201]; // name the worldserver wants - char shortname[50]; // shortname the worldserver wants - char remote_address[125]; // DNS address of the server - char local_address[125]; // DNS address of the server - char account[31]; // account name for the worldserver - char password[31]; // password for the name - char protocolversion[25]; // Major protocol version number - char serverversion[64]; // minor server software version number - uint8 servertype; // 0=world, 1=chat, 2=login, 3=MeshLogin + char server_long_name[201]; // name the worldserver wants + char server_short_name[50]; // shortname the worldserver wants + char remote_ip_address[125]; // DNS address of the server + char local_ip_address[125]; // DNS address of the server + char account_name[31]; // account name for the worldserver + char account_password[31]; // password for the name + char protocol_version[25]; // Major protocol version number + char server_version[64]; // minor server software version number + uint8 server_process_type; // 0=world, 1=chat, 2=login, 3=MeshLogin }; struct ServerLSAccountUpdate_Struct { // for updating info on login server diff --git a/loginserver/database.cpp b/loginserver/database.cpp index e4a10d19e..82d8d2d72 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -319,27 +319,15 @@ void Database::UpdateLoginHash( } /** - * @param long_name * @param short_name - * @param id - * @param desc - * @param list_id - * @param trusted - * @param list_desc - * @param account - * @param password + * @param remote_ip + * @param local_ip * @return */ -bool Database::GetWorldRegistration( - std::string long_name, - std::string short_name, - unsigned int &id, - std::string &desc, - unsigned int &list_id, - unsigned int &trusted, - std::string &list_desc, - std::string &account, - std::string &password +Database::DbWorldRegistration Database::GetWorldRegistration( + const std::string &short_name, + const std::string &remote_ip, + const std::string &local_ip ) { auto query = fmt::format( @@ -354,43 +342,46 @@ bool Database::GetWorldRegistration( " login_world_servers AS WSR\n" " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.short_name = '{0}' LIMIT 1", - EscapeString(short_name) + " WSR.short_name = '{0}' AND (WSR.last_ip_address = '{1}' OR WSR.last_ip_address = '{2}') LIMIT 1", + EscapeString(short_name), + EscapeString(remote_ip), + EscapeString(local_ip) ); + Database::DbWorldRegistration world_registration{}; + auto results = QueryDatabase(query); if (!results.Success() || results.RowCount() != 1) { - return false; + return world_registration; } auto row = results.begin(); - id = atoi(row[0]); - desc = row[1]; - trusted = atoi(row[2]); - list_id = atoi(row[3]); - list_desc = row[4]; + world_registration.loaded = true; + world_registration.server_id = std::stoi(row[0]); + world_registration.server_description = row[1]; + world_registration.server_list_type = std::stoi(row[3]); + world_registration.is_server_trusted = std::stoi(row[2]) > 0; + world_registration.server_list_description = row[4]; - int db_account_id = atoi(row[5]); - if (db_account_id > 0) { - - auto world_registration_query = fmt::format( - "SELECT account_name, account_password FROM login_server_admins WHERE id = {0} LIMIT 1", - db_account_id - ); - - auto world_registration_results = QueryDatabase(world_registration_query); - if (!world_registration_results.Success() || world_registration_results.RowCount() != 1) { - return false; - } - - auto world_registration_row = world_registration_results.begin(); - - account = world_registration_row[0]; - password = world_registration_row[1]; + int db_account_id = std::stoi(row[5]); + if (db_account_id <= 0) { + return world_registration; } - return true; + auto world_registration_query = fmt::format( + "SELECT account_name, account_password FROM login_server_admins WHERE id = {0} LIMIT 1", + db_account_id + ); + + auto world_registration_results = QueryDatabase(world_registration_query); + if (world_registration_results.Success() && world_registration_results.RowCount() == 1) { + auto world_registration_row = world_registration_results.begin(); + world_registration.server_admin_account_name = world_registration_row[0]; + world_registration.server_admin_account_password = world_registration_row[1]; + } + + return world_registration; } /** diff --git a/loginserver/database.h b/loginserver/database.h index 69ca1c08b..44b1f95c1 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -95,32 +95,31 @@ public: unsigned int id ); + struct DbWorldRegistration { + bool loaded = false; + int32 server_id = 0; + int8 server_list_type = 3; + bool is_server_trusted = false; + std::string server_description; + std::string server_list_description; + std::string server_admin_account_name; + std::string server_admin_account_password; + }; + /** * Retrieves the world registration from the long and short names provided * Needed for world login procedure - * Returns true if the record was found, false otherwise. + * Returns true if the record was found, false otherwise * - * @param long_name * @param short_name - * @param id - * @param desc - * @param list_id - * @param trusted - * @param list_desc - * @param account - * @param password + * @param remote_ip + * @param local_ip * @return */ - bool GetWorldRegistration( - std::string long_name, - std::string short_name, - unsigned int &id, - std::string &desc, - unsigned int &list_id, - unsigned int &trusted, - std::string &list_desc, - std::string &account, - std::string &password + Database::DbWorldRegistration GetWorldRegistration( + const std::string& short_name, + const std::string& remote_ip, + const std::string& local_ip ); void UpdateLSAccountData(unsigned int id, std::string ip_address); diff --git a/loginserver/login_util/login_schema.sql b/loginserver/login_util/login_schema.sql index b96f08e0e..d38b5358c 100644 --- a/loginserver/login_util/login_schema.sql +++ b/loginserver/login_util/login_schema.sql @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS `login_accounts`; CREATE TABLE `login_accounts` ( `id` int(11) unsigned NOT NULL, `account_name` varchar(50) NOT NULL, @@ -8,10 +9,11 @@ CREATE TABLE `login_accounts` ( `last_login_date` datetime NOT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT current_timestamp(), - PRIMARY KEY (`id`,`account_name`), + PRIMARY KEY (`id`), UNIQUE KEY `source_loginserver_account_name` (`source_loginserver`,`account_name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `login_server_admins`; CREATE TABLE `login_server_admins` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `account_name` varchar(30) NOT NULL, @@ -21,9 +23,10 @@ CREATE TABLE `login_server_admins` ( `email` varchar(100) NOT NULL, `registration_date` datetime NOT NULL, `registration_ip_address` varchar(15) NOT NULL, - PRIMARY KEY (`id`,`account_name`) + PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `login_server_list_types`; CREATE TABLE `login_server_list_types` ( `id` int(10) unsigned NOT NULL, `description` varchar(60) NOT NULL, @@ -34,6 +37,7 @@ INSERT INTO `login_server_list_types` (`id`, `description`) VALUES ('1', 'Legend ('2', 'Preferred'), ('3', 'Standard'); +DROP TABLE IF EXISTS `login_world_servers`; CREATE TABLE `login_world_servers` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `long_name` varchar(100) NOT NULL, @@ -44,10 +48,11 @@ CREATE TABLE `login_world_servers` ( `last_ip_address` varchar(15) DEFAULT NULL, `login_server_admin_id` int(11) NOT NULL, `is_server_trusted` int(11) NOT NULL, - `note` varchar(300) DEFAULT NULL, - PRIMARY KEY (`id`,`long_name`) + `note` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `login_api_tokens`; CREATE TABLE `login_api_tokens` ( `id` int(11) NOT NULL AUTO_INCREMENT, `token` varchar(200) DEFAULT NULL, diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 6a090f828..732ce4ff7 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -45,8 +45,8 @@ namespace LoginserverWebserver { auto iter = server.server_manager->getWorldServers().begin(); while (iter != server.server_manager->getWorldServers().end()) { Json::Value row; - row["server_long_name"] = (*iter)->GetLongName(); - row["server_short_name"] = (*iter)->GetLongName(); + row["server_long_name"] = (*iter)->GetServerLongName(); + row["server_short_name"] = (*iter)->GetServerLongName(); row["server_list_id"] = (*iter)->GetServerListID(); row["server_status"] = (*iter)->GetStatus(); row["zones_booted"] = (*iter)->GetZonesBooted(); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index cb164b727..e91e26ac2 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -80,7 +80,7 @@ ServerManager::ServerManager() LogF(Logs::General, Logs::World_Server, "World server {0} has been disconnected, removing.", - (*iter)->GetLongName().c_str()); + (*iter)->GetServerLongName().c_str()); world_servers.erase(iter); return; } @@ -125,24 +125,30 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 in.s_addr = client->GetConnection()->GetRemoteIP(); std::string client_ip = inet_ntoa(in); + LogDebug("ServerManager::CreateServerListPacket via client address [{0}]", client_ip); + auto iter = world_servers.begin(); while (iter != world_servers.end()) { - if ((*iter)->IsAuthorized() == false) { + if (!(*iter)->IsAuthorized()) { + LogDebug( + "ServerManager::CreateServerListPacket | Server [{0}] via IP [{1}] is not authorized to be listed", + (*iter)->GetServerLongName(), + (*iter)->GetConnection()->Handle()->RemoteIP() + ); ++iter; continue; } std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP(); - - if (world_ip.compare(client_ip) == 0) { - packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; + if (world_ip == client_ip) { + packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24; } else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) { LogInfo("Client is requesting server list from a local address [{0}]", client_ip); - packet_size += (*iter)->GetLongName().size() + (*iter)->GetLocalIP().size() + 24; + packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24; } else { - packet_size += (*iter)->GetLongName().size() + (*iter)->GetRemoteIP().size() + 24; + packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetRemoteIP().size() + 24; } server_count++; @@ -203,11 +209,11 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 data_pointer += 4; - *(unsigned int *) data_pointer = (*iter)->GetRuntimeID(); + *(unsigned int *) data_pointer = (*iter)->GetServerId(); data_pointer += 4; - memcpy(data_pointer, (*iter)->GetLongName().c_str(), (*iter)->GetLongName().size()); - data_pointer += ((*iter)->GetLongName().size() + 1); + memcpy(data_pointer, (*iter)->GetServerLongName().c_str(), (*iter)->GetServerLongName().size()); + data_pointer += ((*iter)->GetServerLongName().size() + 1); memcpy(data_pointer, "EN", 2); data_pointer += 3; @@ -252,7 +258,7 @@ void ServerManager::SendUserToWorldRequest( auto iter = world_servers.begin(); bool found = false; while (iter != world_servers.end()) { - if ((*iter)->GetRuntimeID() == server_id) { + if ((*iter)->GetServerId() == server_id) { EQ::Net::DynamicPacket outapp; outapp.Resize(sizeof(UsertoWorldRequest_Struct)); @@ -294,8 +300,8 @@ bool ServerManager::ServerExists( continue; } - if ((*iter)->GetLongName().compare(server_long_name) == 0 && - (*iter)->GetShortName().compare(server_short_name) == 0) { + if ((*iter)->GetServerLongName().compare(server_long_name) == 0 && + (*iter)->GetServerShortName().compare(server_short_name) == 0) { return true; } @@ -322,8 +328,8 @@ void ServerManager::DestroyServerByName( continue; } - if ((*iter)->GetLongName().compare(server_long_name) == 0 && - (*iter)->GetShortName().compare(server_short_name) == 0) { + if ((*iter)->GetServerLongName().compare(server_long_name) == 0 && + (*iter)->GetServerShortName().compare(server_short_name) == 0) { (*iter)->GetConnection()->Handle()->Disconnect(); iter = world_servers.erase(iter); continue; diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 518d919bd..c85b92d8e 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -32,16 +32,16 @@ extern LoginServer server; */ WorldServer::WorldServer(std::shared_ptr worldserver_connection) { - connection = worldserver_connection; - zones_booted = 0; - players_online = 0; - server_status = 0; - runtime_id = 0; - server_list_id = 0; - server_type = 0; + connection = worldserver_connection; + zones_booted = 0; + players_online = 0; + server_status = 0; + server_id = 0; + server_list_type_id = 0; + server_process_type = 0; is_server_authorized = false; - is_server_trusted = false; - is_server_logged_in = false; + is_server_trusted = false; + is_server_logged_in = false; worldserver_connection->OnMessage( ServerOP_NewLSInfo, @@ -78,14 +78,14 @@ WorldServer::~WorldServer() = default; void WorldServer::Reset() { - runtime_id; - zones_booted = 0; - players_online = 0; - server_status = 0; - server_list_id = 0; - server_type = 0; + server_id; + zones_booted = 0; + players_online = 0; + server_status = 0; + server_list_type_id = 0; + server_process_type = 0; is_server_authorized = false; - is_server_logged_in = false; + is_server_logged_in = false; } /** @@ -129,15 +129,15 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe " - protocolversion [{6}]\n" " - server_version [{7}]\n" " - server_type [{8}]", - info->name, - info->shortname, - info->remote_address, - info->local_address, - info->account, - info->password, - info->protocolversion, - info->serverversion, - info->servertype + info->server_long_name, + info->server_short_name, + info->remote_ip_address, + info->local_ip_address, + info->account_name, + info->account_password, + info->protocol_version, + info->server_version, + info->server_process_type ); Handle_NewLSInfo(info); @@ -173,7 +173,7 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet LogDebug( "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", - this->GetLongName(), + this->GetServerLongName(), ls_status->status, ls_status->num_players, ls_status->num_zones @@ -213,7 +213,7 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "User-To-World Response received."); + Log(Logs::General, Logs::Netcode, "User-To-World Response received"); } auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); @@ -314,7 +314,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac Log(Logs::General, Logs::Error, "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " - "but was too small. Discarded to avoid buffer overrun."); + "but was too small. Discarded to avoid buffer overrun"); return; } @@ -322,7 +322,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "User-To-World Response received."); + Log(Logs::General, Logs::Netcode, "User-To-World Response received"); } auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data(); @@ -333,8 +333,8 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac ); if (client) { LogDebug("Found client with user id of {0} and account name of {1}", - user_to_world_response->lsaccountid, - client->GetAccountName().c_str() + user_to_world_response->lsaccountid, + client->GetAccountName().c_str() ); auto *outapp = new EQApplicationPacket( @@ -403,7 +403,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac } else { LogError("Received User-To-World Response for {0} but could not find the client referenced!.", - user_to_world_response->lsaccountid); + user_to_world_response->lsaccountid); } } @@ -457,104 +457,33 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet } /** + * When a worldserver first messages the loginserver telling them who they are * * @param new_world_server_info_packet */ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info_packet) { if (is_server_logged_in) { - LogError("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting."); + LogError("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting"); return; } - if (strlen(new_world_server_info_packet->account) <= 30) { - account_name = new_world_server_info_packet->account; - } - else { - LogError("Handle_NewLSInfo error, account name was too long."); + if (!this->HandleNewLoginserverInfoValidation(new_world_server_info_packet)) { + LogError("WorldServer::Handle_NewLSInfo failed validation rules"); return; } - if (strlen(new_world_server_info_packet->password) <= 30) { - account_password = new_world_server_info_packet->password; - } - else { - LogError("Handle_NewLSInfo error, account password was too long."); - return; - } - - if (strlen(new_world_server_info_packet->name) <= 200) { - long_name = new_world_server_info_packet->name; - } - else { - LogError("Handle_NewLSInfo error, long name was too long."); - return; - } - - if (strlen(new_world_server_info_packet->shortname) <= 50) { - short_name = new_world_server_info_packet->shortname; - } - else { - LogError("Handle_NewLSInfo error, short name was too long."); - return; - } - - if (strlen(new_world_server_info_packet->local_address) <= 125) { - if (strlen(new_world_server_info_packet->local_address) == 0) { - LogError("Handle_NewLSInfo error, local address was null, defaulting to localhost"); - local_ip = "127.0.0.1"; - } - else { - local_ip = new_world_server_info_packet->local_address; - } - } - else { - LogError("Handle_NewLSInfo error, local address was too long."); - - return; - } - - if (strlen(new_world_server_info_packet->remote_address) <= 125) { - if (strlen(new_world_server_info_packet->remote_address) == 0) { - remote_ip = GetConnection()->Handle()->RemoteIP(); - LogError( - "Remote address was null, defaulting to stream address %s.", - remote_ip.c_str() - ); - } - else { - remote_ip = new_world_server_info_packet->remote_address; - } - } - else { - remote_ip = GetConnection()->Handle()->RemoteIP(); - - Log( - Logs::General, - Logs::Error, - "Handle_NewLSInfo error, remote address was too long, defaulting to stream address %s.", - remote_ip.c_str() - ); - } - - if (strlen(new_world_server_info_packet->serverversion) <= 64) { - version = new_world_server_info_packet->serverversion; - } - else { - LogError("Handle_NewLSInfo error, server version was too long."); - return; - } - - if (strlen(new_world_server_info_packet->protocolversion) <= 25) { - protocol = new_world_server_info_packet->protocolversion; - } - else { - LogError("Handle_NewLSInfo error, protocol version was too long."); - return; - } - - server_type = new_world_server_info_packet->servertype; - is_server_logged_in = true; + this + ->SetAccountPassword(new_world_server_info_packet->account_password) + ->SetLongName(new_world_server_info_packet->server_long_name) + ->SetShortName(new_world_server_info_packet->server_short_name) + ->SetLocalIp(new_world_server_info_packet->local_ip_address) + ->SetRemoteIp(new_world_server_info_packet->remote_ip_address) + ->SetVersion(new_world_server_info_packet->server_version) + ->SetProtocol(new_world_server_info_packet->protocol_version) + ->SetServerProcessType(new_world_server_info_packet->server_process_type) + ->SetIsServerLoggedIn(true) + ->SetAccountName(new_world_server_info_packet->account_name); if (server.options.IsRejectingDuplicateServers()) { if (server.server_manager->ServerExists(long_name, short_name, this)) { @@ -569,171 +498,27 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info } } - if (!server.options.IsUnregisteredAllowed()) { - if (account_name.size() > 0 && account_password.size() > 0) { - unsigned int s_id = 0; - unsigned int s_list_type = 0; - unsigned int s_trusted = 0; - std::string s_desc; - std::string s_list_desc; - std::string s_acct_name; - std::string s_acct_pass; - if (server.db->GetWorldRegistration( - long_name, - short_name, - s_id, - s_desc, - s_list_type, - s_trusted, - s_list_desc, - s_acct_name, - s_acct_pass - )) { - if (s_acct_name.size() == 0 || s_acct_pass.size() == 0) { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) successfully logged into account that had no user/password requirement.", - long_name.c_str(), - short_name.c_str()); - is_server_authorized = true; - SetRuntimeID(s_id); - server_list_id = s_list_type; - desc = s_desc; - } - else if (s_acct_name.compare(account_name) == 0 && s_acct_pass.compare(account_password) == 0) { - Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.", - long_name.c_str(), short_name.c_str()); - is_server_authorized = true; - SetRuntimeID(s_id); - server_list_id = s_list_type; - desc = s_desc; - if (s_trusted) { - Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); - is_server_trusted = true; + Database::DbWorldRegistration + world_registration = server.db->GetWorldRegistration(short_name, remote_ip_address, local_ip); - EQ::Net::DynamicPacket outapp; - connection->Send(ServerOP_LSAccountUpdate, outapp); - } - } - else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) attempted to log in but account and password did not match the entry in the database, and only" - " registered servers are allowed.", - long_name.c_str(), - short_name.c_str()); - return; - } - } - else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) attempted to log in but database couldn't find an entry and only registered servers are allowed.", - long_name.c_str(), - short_name.c_str()); - return; - } - } - else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) did not attempt to log in but only registered servers are allowed.", - long_name.c_str(), - short_name.c_str()); + if (!server.options.IsUnregisteredAllowed()) { + if (!this->HandleNewLoginserverRegisteredOnly(world_registration)){ + LogError("WorldServer::HandleNewLoginserverRegisteredOnly checks failed"); return; } } else { - unsigned int server_id = 0; - unsigned int server_list_type = 0; - unsigned int is_server_trusted = 0; - std::string server_description; - std::string server_list_description; - std::string server_account_name; - std::string server_account_password; - - if (server.db->GetWorldRegistration( - long_name, - short_name, - server_id, - server_description, - server_list_type, - is_server_trusted, - server_list_description, - server_account_name, - server_account_password - )) { - - if (account_name.size() > 0 && account_password.size() > 0) { - if (server_account_name.compare(account_name) == 0 && - server_account_password.compare(account_password) == 0) { - Log(Logs::General, Logs::World_Server, "Server %s(%s) successfully logged in.", - long_name.c_str(), short_name.c_str()); - is_server_authorized = true; - SetRuntimeID(server_id); - server_list_id = server_list_type; - desc = server_description; - - if (is_server_trusted) { - Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate sent to world"); - is_server_trusted = true; - EQ::Net::DynamicPacket outapp; - connection->Send(ServerOP_LSAccountUpdate, outapp); - } - } - - /** - * this is the first of two cases where we should deny access even if unregistered is allowed - */ - else { - Log(Logs::General, - Logs::World_Server, - "Server %s(%s) attempted to log in but account and password did not match the entry in the database.", - long_name.c_str(), - short_name.c_str()); - } - } - else { - - /** - * this is the second of two cases where we should deny access even if unregistered is allowed - */ - if (server_account_name.size() > 0 || server_account_password.size() > 0) { - LogInfo( - "Server [{0}] [{1}] did not login but this server required a password to login", - long_name, - short_name - ); - } - else { - LogInfo( - "Server [{0}] [{1}] did not login but unregistered servers are allowed", - long_name, - short_name - ); - - is_server_authorized = true; - SetRuntimeID(server_id); - server_list_id = 3; - } - } - } - else { - LogInfo( - "Server [{0}] ({1}) is not registered but unregistered servers are allowed", - long_name, - short_name - ); - - if (server.db->CreateWorldRegistration(long_name, short_name, server_id)) { - is_server_authorized = true; - SetRuntimeID(server_id); - server_list_id = 3; - } + if (!this->HandleNewLoginserverInfoUnregisteredAllowed(world_registration)){ + LogError("WorldServer::HandleNewLoginserverInfoUnregisteredAllowed checks failed"); + return; } } - server.db->UpdateWorldRegistration(GetRuntimeID(), long_name, GetConnection()->Handle()->RemoteIP()); + server.db->UpdateWorldRegistration( + GetServerId(), + GetServerLongName(), + GetConnection()->Handle()->RemoteIP() + ); } /** @@ -769,15 +554,15 @@ void WorldServer::SendClientAuth( strncpy(client_auth.account_name, account.c_str(), 30); strncpy(client_auth.key, key.c_str(), 30); - client_auth.lsadmin = 0; + client_auth.lsadmin = 0; client_auth.is_world_admin = 0; - client_auth.ip = inet_addr(ip.c_str()); + client_auth.ip = inet_addr(ip.c_str()); strncpy(client_auth.loginserver_name, &loginserver_name[0], 64); const std::string &client_address(ip); std::string world_address(connection->Handle()->RemoteIP()); - if (client_address.compare(world_address) == 0) { + if (client_address == world_address) { client_auth.is_client_from_local_network = 1; } else if (IpUtil::IsIpInPrivateRfc1918(client_address)) { @@ -817,3 +602,543 @@ void WorldServer::SendClientAuth( DumpPacket(ServerOP_LSClientAuth, outapp); } } + +/** + * @param new_world_server_info_packet + * @return + */ +bool WorldServer::HandleNewLoginserverInfoValidation( + ServerNewLSInfo_Struct *new_world_server_info_packet +) +{ + const int max_account_name_length = 30; + const int max_account_password_length = 30; + const int max_server_long_name_length = 200; + const int max_server_short_name_length = 50; + const int max_server_local_address_length = 125; + const int max_server_remote_address_length = 125; + const int max_server_version_length = 64; + const int max_server_protocol_version = 25; + + if (strlen(new_world_server_info_packet->account_name) >= max_account_name_length) { + LogError("Handle_NewLSInfo error [account_name] was too long | max [{0}]", max_account_name_length); + return false; + } + else if (strlen(new_world_server_info_packet->account_password) >= max_account_password_length) { + LogError("Handle_NewLSInfo error [account_password] was too long | max [{0}]", max_account_password_length); + return false; + } + else if (strlen(new_world_server_info_packet->server_long_name) >= max_server_long_name_length) { + LogError("Handle_NewLSInfo error [server_long_name] was too long | max [{0}]", max_server_long_name_length); + return false; + } + else if (strlen(new_world_server_info_packet->server_short_name) >= max_server_short_name_length) { + LogError("Handle_NewLSInfo error [server_short_name] was too long | max [{0}]", max_server_short_name_length); + return false; + } + else if (strlen(new_world_server_info_packet->server_version) >= max_server_short_name_length) { + LogError("Handle_NewLSInfo error [server_version] was too long | max [{0}]", max_server_version_length); + return false; + } + else if (strlen(new_world_server_info_packet->protocol_version) >= max_server_protocol_version) { + LogError("Handle_NewLSInfo error [protocol_version] was too long | max [{0}]", max_server_protocol_version); + return false; + } + + if (strlen(new_world_server_info_packet->local_ip_address) <= max_server_local_address_length) { + if (strlen(new_world_server_info_packet->local_ip_address) == 0) { + LogError("Handle_NewLSInfo error, local address was null, defaulting to localhost"); + this->SetLocalIp("127.0.0.1"); + } + else { + this->SetLocalIp(new_world_server_info_packet->local_ip_address); + } + } + else { + LogError("Handle_NewLSInfo error, local address was too long | max [{0}]", max_server_local_address_length); + return false; + } + + if (strlen(new_world_server_info_packet->remote_ip_address) <= max_server_remote_address_length) { + if (strlen(new_world_server_info_packet->remote_ip_address) == 0) { + this->SetRemoteIp(GetConnection()->Handle()->RemoteIP()); + + LogError( + "Remote address was null, defaulting to stream address {0}", + remote_ip_address + ); + } + else { + this->SetRemoteIp(new_world_server_info_packet->remote_ip_address); + } + } + else { + this->SetRemoteIp(GetConnection()->Handle()->RemoteIP()); + + LogError( + "Handle_NewLSInfo error, remote address was too long, defaulting to stream address [{0}]", + remote_ip_address + ); + } + + return true; +} + +/** + * @param world_registration + * @return + */ +bool WorldServer::HandleNewLoginserverRegisteredOnly( + Database::DbWorldRegistration &world_registration +) { + if (!this->GetAccountName().empty() && !this->GetAccountPassword().empty()) { + if (world_registration.loaded) { + bool does_world_server_not_require_authentication = ( + world_registration.server_admin_account_name.empty() || + world_registration.server_admin_account_password.empty() + ); + + bool does_world_server_pass_authentication_check = ( + world_registration.server_admin_account_name == this->GetAccountName() && + world_registration.server_admin_account_password == this->GetAccountPassword() + ); + + this + ->SetServerDescription(world_registration.server_description) + ->SetServerId(world_registration.server_id) + ->SetIsServerTrusted(world_registration.is_server_trusted) + ->SetServerListTypeId(world_registration.server_list_type); + + if (does_world_server_not_require_authentication) { + + this->SetIsServerAuthorized(true); + + LogInfo( + "Server long_name {0} short_name [{1}] successfully logged into account that had no user/password requirement", + this->GetServerLongName(), + this->GetServerShortName() + ); + } + else if (does_world_server_pass_authentication_check) { + + this->SetIsServerAuthorized(true); + + LogInfo( + "Server long_name {0} short_name [{1}] successfully logged in", + this->GetServerLongName(), + this->GetServerShortName() + ); + + if (IsServerTrusted()) { + LogDebug("WorldServer::HandleNewLoginserverRegisteredOnly | ServerOP_LSAccountUpdate sent to world"); + EQ::Net::DynamicPacket outapp; + connection->Send(ServerOP_LSAccountUpdate, outapp); + } + } + else { + LogInfo( + "Server long_name {0} short_name [{1}] attempted to log in but account and password did not " + "match the entry in the database, and only registered servers are allowed", + this->GetServerLongName(), + this->GetServerShortName() + ); + + return false; + } + } + else { + LogInfo( + "Server long_name {0} short_name [{1}] attempted to log in but database couldn't find an entry and only registered servers are allowed", + this->GetServerLongName(), + this->GetServerShortName() + ); + + return false; + } + } + else { + LogInfo( + "Server long_name {0} short_name [{1}] did not attempt to log in but only registered servers are allowed", + this->GetServerLongName(), + this->GetServerShortName() + ); + + return false; + } + + return true; +} + +/** + * @param world_registration + * @return + */ +bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( + Database::DbWorldRegistration &world_registration +) { + if (world_registration.loaded) { + + this + ->SetServerDescription(world_registration.server_description) + ->SetServerId(world_registration.server_id) + ->SetIsServerTrusted(world_registration.is_server_trusted) + ->SetServerListTypeId(world_registration.server_list_type); + + bool does_world_server_pass_authentication_check = ( + world_registration.server_admin_account_name == this->GetAccountName() && + world_registration.server_admin_account_password == this->GetAccountPassword() + ); + + bool does_world_server_have_non_empty_credentials = ( + !this->GetAccountName().empty() && + !this->GetAccountPassword().empty() + ); + + if (does_world_server_have_non_empty_credentials) { + if (does_world_server_pass_authentication_check) { + + this->SetIsServerAuthorized(true); + + LogInfo( + "Server long_name {0} short_name [{1}] successfully logged in", + this->GetServerLongName(), + this->GetServerShortName() + ); + + if (IsServerTrusted()) { + LogDebug("WorldServer::HandleNewLoginserverRegisteredOnly | ServerOP_LSAccountUpdate sent to world"); + EQ::Net::DynamicPacket outapp; + connection->Send(ServerOP_LSAccountUpdate, outapp); + } + } + else { + + /** + * this is the first of two cases where we should deny access even if unregistered is allowed + */ + LogInfo( + "Server long_name {0} short_name [{1}] attempted to log in but account and password did not match the entry in the database.", + this->GetServerLongName(), + this->GetServerShortName() + ); + } + } + else { + + /** + * this is the second of two cases where we should deny access even if unregistered is allowed + */ + if (!this->GetAccountName().empty() || !this->GetAccountPassword().empty()) { + LogInfo( + "Server [{0}] [{1}] did not login but this server required a password to login", + this->GetServerLongName(), + this->GetServerShortName() + ); + } + else { + this->SetIsServerAuthorized(true); + LogInfo( + "Server [{0}] [{1}] did not login but unregistered servers are allowed", + this->GetServerLongName(), + this->GetServerShortName() + ); + } + } + } + else { + LogInfo( + "Server [{0}] ({1}) is not registered but unregistered servers are allowed", + this->GetServerLongName(), + this->GetServerShortName() + ); + + if (world_registration.loaded) { + this->SetIsServerAuthorized(true); + return true; + } + + /** + * Auto create a registration + */ + if (!server.db->CreateWorldRegistration(long_name, short_name, server_id)) { + return false; + } + } + + return true; +} + +/** + * @param in_server_list_id + * @return + */ +WorldServer * WorldServer::SetServerListTypeId(unsigned int in_server_list_id) +{ + server_list_type_id = in_server_list_id; + + return this; +} + +/** + * @return + */ +const std::string &WorldServer::GetServerDescription() const +{ + return server_description; +} + +/** + * @param in_server_description + */ +WorldServer * WorldServer::SetServerDescription(const std::string &in_server_description) +{ + WorldServer::server_description = in_server_description; + + return this; +} + +/** + * @return + */ +bool WorldServer::IsServerAuthorized() const +{ + return is_server_authorized; +} + +/** + * @param in_is_server_authorized + */ +WorldServer * WorldServer::SetIsServerAuthorized(bool in_is_server_authorized) +{ + WorldServer::is_server_authorized = in_is_server_authorized; + + return this; +} + +/** + * @return + */ +bool WorldServer::IsServerLoggedIn() const +{ + return is_server_logged_in; +} + +/** + * @param in_is_server_logged_in + */ +WorldServer * WorldServer::SetIsServerLoggedIn(bool in_is_server_logged_in) +{ + WorldServer::is_server_logged_in = in_is_server_logged_in; + + return this; +} + +/** + * @return + */ +bool WorldServer::IsServerTrusted() const +{ + return is_server_trusted; +} + +/** + * @param in_is_server_trusted + */ +WorldServer * WorldServer::SetIsServerTrusted(bool in_is_server_trusted) +{ + WorldServer::is_server_trusted = in_is_server_trusted; + + return this; +} + +/** + * @param in_zones_booted + */ +WorldServer * WorldServer::SetZonesBooted(unsigned int in_zones_booted) +{ + WorldServer::zones_booted = in_zones_booted; + + return this; +} + +/** + * @param in_players_online + */ +WorldServer * WorldServer::SetPlayersOnline(unsigned int in_players_online) +{ + WorldServer::players_online = in_players_online; + + return this; +} + +/** + * @param in_server_status + */ +WorldServer * WorldServer::SetServerStatus(int in_server_status) +{ + WorldServer::server_status = in_server_status; + + return this; +} + +/** + * @param in_server_process_type + */ +WorldServer * WorldServer::SetServerProcessType(unsigned int in_server_process_type) +{ + WorldServer::server_process_type = in_server_process_type; + + return this; +} + +/** + * @param in_long_name + */ +WorldServer * WorldServer::SetLongName(const std::string &in_long_name) +{ + WorldServer::long_name = in_long_name; + + return this; +} + +/** + * @param in_short_name + */ +WorldServer * WorldServer::SetShortName(const std::string &in_short_name) +{ + WorldServer::short_name = in_short_name; + + return this; +} + +/** + * @param in_account_name + */ +WorldServer * WorldServer::SetAccountName(const std::string &in_account_name) +{ + WorldServer::account_name = in_account_name; + + return this; +} + +/** + * @param in_account_password + */ +WorldServer * WorldServer::SetAccountPassword(const std::string &in_account_password) +{ + WorldServer::account_password = in_account_password; + + return this; +} + +/** + * @param in_remote_ip + */ +WorldServer * WorldServer::SetRemoteIp(const std::string &in_remote_ip) +{ + WorldServer::remote_ip_address = in_remote_ip; + + return this; +} + +/** + * @param in_local_ip + */ +WorldServer * WorldServer::SetLocalIp(const std::string &in_local_ip) +{ + WorldServer::local_ip = in_local_ip; + + return this; +} + +/** + * @param in_protocol + */ +WorldServer * WorldServer::SetProtocol(const std::string &in_protocol) +{ + WorldServer::protocol = in_protocol; + + return this; +} + +/** + * @param in_version + */ +WorldServer * WorldServer::SetVersion(const std::string &in_version) +{ + WorldServer::version = in_version; + + return this; +} + +/** + * @return + */ +int WorldServer::GetServerStatus() const +{ + return server_status; +} + +/** + * @return + */ +unsigned int WorldServer::GetServerListTypeId() const +{ + return server_list_type_id; +} + +/** + * @return + */ +unsigned int WorldServer::GetServerProcessType() const +{ + return server_process_type; +} + +/** + * @return + */ +const std::string &WorldServer::GetAccountName() const +{ + return account_name; +} + +/** + * @return + */ +const std::string &WorldServer::GetAccountPassword() const +{ + return account_password; +} + +/** + * @return + */ +const std::string &WorldServer::GetRemoteIp() const +{ + return remote_ip_address; +} + +/** + * @return + */ +const std::string &WorldServer::GetLocalIp() const +{ + return local_ip; +} + +/** + * @return + */ +const std::string &WorldServer::GetProtocol() const +{ + return protocol; +} + +/** + * @return + */ +const std::string &WorldServer::GetVersion() const +{ + return version; +} \ No newline at end of file diff --git a/loginserver/world_server.h b/loginserver/world_server.h index 97cdb76d5..ffd2153cb 100644 --- a/loginserver/world_server.h +++ b/loginserver/world_server.h @@ -25,6 +25,7 @@ #include "../common/net/servertalk_server_connection.h" #include "../common/servertalk.h" #include "../common/packet_dump.h" +#include "database.h" #include #include @@ -51,10 +52,18 @@ public: */ std::shared_ptr GetConnection() { return connection; } void SetConnection(std::shared_ptr c) { connection = c; } - unsigned int GetRuntimeID() const { return runtime_id; } - void SetRuntimeID(unsigned int id) { runtime_id = id; } - std::string GetLongName() const { return long_name; } - std::string GetShortName() const { return short_name; } + + /** + * @return + */ + unsigned int GetServerId() const { return server_id; } + WorldServer * SetServerId(unsigned int id) { server_id = id; return this; } + + /** + * @return + */ + std::string GetServerLongName() const { return long_name; } + std::string GetServerShortName() const { return short_name; } /** * Gets whether the server is authorized to show up on the server list or not @@ -62,14 +71,16 @@ public: */ bool IsAuthorized() const { return is_server_authorized; } std::string GetLocalIP() const { return local_ip; } - std::string GetRemoteIP() const { return remote_ip; } + std::string GetRemoteIP() const { return remote_ip_address; } /** * Gets what kind of server this server is (legends, preferred, normal) * * @return */ - unsigned int GetServerListID() const { return server_list_id; } + unsigned int GetServerListID() const { return server_list_type_id; } + WorldServer * SetServerListTypeId(unsigned int in_server_list_id); + int GetStatus() const { return server_status; } unsigned int GetZonesBooted() const { return zones_booted; } unsigned int GetPlayersOnline() const { return players_online; } @@ -88,6 +99,8 @@ public: */ void Handle_LSStatus(ServerLSStatus_Struct *server_login_status); + bool HandleNewLoginserverInfoValidation(ServerNewLSInfo_Struct *new_world_server_info_packet); + /** * Informs world that there is a client incoming with the following data. * @@ -99,6 +112,40 @@ public: */ void SendClientAuth(std::string ip, std::string account, std::string key, unsigned int account_id, const std::string &loginserver_name); + WorldServer * SetZonesBooted(unsigned int in_zones_booted); + WorldServer * SetPlayersOnline(unsigned int in_players_online); + WorldServer * SetServerStatus(int in_server_status); + WorldServer * SetServerProcessType(unsigned int in_server_process_type); + WorldServer * SetLongName(const std::string &in_long_name); + WorldServer * SetShortName(const std::string &in_short_name); + WorldServer * SetAccountName(const std::string &in_account_name); + WorldServer * SetAccountPassword(const std::string &in_account_password); + WorldServer * SetRemoteIp(const std::string &in_remote_ip); + WorldServer * SetLocalIp(const std::string &in_local_ip); + WorldServer * SetProtocol(const std::string &in_protocol); + WorldServer * SetVersion(const std::string &in_version); + WorldServer * SetServerDescription(const std::string &in_server_description); + WorldServer * SetIsServerAuthorized(bool in_is_server_authorized); + WorldServer * SetIsServerLoggedIn(bool in_is_server_logged_in); + WorldServer * SetIsServerTrusted(bool in_is_server_trusted); + + bool IsServerAuthorized() const; + bool IsServerLoggedIn() const; + bool IsServerTrusted() const; + const std::string &GetAccountName() const; + const std::string &GetAccountPassword() const; + const std::string &GetLocalIp() const; + const std::string &GetProtocol() const; + const std::string &GetRemoteIp() const; + const std::string &GetServerDescription() const; + const std::string &GetVersion() const; + int GetServerStatus() const; + unsigned int GetServerListTypeId() const; + unsigned int GetServerProcessType() const; + + bool HandleNewLoginserverRegisteredOnly(Database::DbWorldRegistration &world_registration); + bool HandleNewLoginserverInfoUnregisteredAllowed(Database::DbWorldRegistration &world_registration); + private: /** @@ -117,21 +164,22 @@ private: unsigned int zones_booted; unsigned int players_online; int server_status; - unsigned int runtime_id; - unsigned int server_list_id; - unsigned int server_type; - std::string desc; + unsigned int server_id; + unsigned int server_list_type_id; + unsigned int server_process_type; + std::string server_description; std::string long_name; std::string short_name; std::string account_name; std::string account_password; - std::string remote_ip; + std::string remote_ip_address; std::string local_ip; std::string protocol; std::string version; bool is_server_authorized; bool is_server_logged_in; bool is_server_trusted; + }; #endif diff --git a/world/login_server.cpp b/world/login_server.cpp index 18904aaaf..e1cc8a3f1 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -516,22 +516,22 @@ void LoginServer::SendInfo() pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); ServerNewLSInfo_Struct *lsi = (ServerNewLSInfo_Struct *) pack->pBuffer; - strcpy(lsi->protocolversion, EQEMU_PROTOCOL_VERSION); - strcpy(lsi->serverversion, LOGIN_VERSION); - strcpy(lsi->name, Config->LongName.c_str()); - strcpy(lsi->shortname, Config->ShortName.c_str()); - strn0cpy(lsi->account, LoginAccount.c_str(), 30); - strn0cpy(lsi->password, LoginPassword.c_str(), 30); + strcpy(lsi->protocol_version, EQEMU_PROTOCOL_VERSION); + strcpy(lsi->server_version, LOGIN_VERSION); + strcpy(lsi->server_long_name, Config->LongName.c_str()); + strcpy(lsi->server_short_name, Config->ShortName.c_str()); + strn0cpy(lsi->account_name, LoginAccount.c_str(), 30); + strn0cpy(lsi->account_password, LoginPassword.c_str(), 30); if (Config->WorldAddress.length()) { - strcpy(lsi->remote_address, Config->WorldAddress.c_str()); + strcpy(lsi->remote_ip_address, Config->WorldAddress.c_str()); } if (Config->LocalAddress.length()) { - strcpy(lsi->local_address, Config->LocalAddress.c_str()); + strcpy(lsi->local_ip_address, Config->LocalAddress.c_str()); } else { auto local_addr = IsLegacy ? legacy_client->Handle()->LocalIP() : client->Handle()->LocalIP(); - strcpy(lsi->local_address, local_addr.c_str()); - WorldConfig::SetLocalAddress(lsi->local_address); + strcpy(lsi->local_ip_address, local_addr.c_str()); + WorldConfig::SetLocalAddress(lsi->local_ip_address); } SendPacket(pack); delete pack; From 8c75cf1ff5cbf9bd27f577d92070df698b04a66e Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 8 Jul 2019 19:26:21 -0700 Subject: [PATCH 060/491] Fix for compile issues on windows (bad perl bad) --- common/dbcore.cpp | 6 +++--- common/eqemu_logsys.cpp | 7 ++++--- common/eqemu_logsys.h | 9 ++++++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 68cebc4f3..1189a8a62 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -2,8 +2,9 @@ #include #endif -#include "../common/misc_functions.h" -#include "../common/eqemu_logsys.h" +#include "misc_functions.h" +#include "eqemu_logsys.h" +#include "timer.h" #include "dbcore.h" @@ -21,7 +22,6 @@ #else #include "unix.h" -#include "timer.h" #include #endif diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index aed5365f5..3389342b9 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -468,9 +468,10 @@ void EQEmuLogSys::Out( prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line); } + auto msg_cstr = message.c_str(); va_list args; - va_start(args, message); - std::string output_message = vStringFormat(message.c_str(), args); + va_start(args, msg_cstr); + std::string output_message = vStringFormat(msg_cstr, args); va_end(args); std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message); @@ -597,4 +598,4 @@ void EQEmuLogSys::StartFileLogs(const std::string &log_name) std::ios_base::app | std::ios_base::out ); } -} \ No newline at end of file +} diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index c3856edbb..f3c48ae88 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -21,11 +21,18 @@ #ifndef EQEMU_LOGSYS_H #define EQEMU_LOGSYS_H -#include #include #include #include #include + +#ifdef _WIN32 +#ifdef utf16_to_utf8 +#undef utf16_to_utf8 +#endif +#endif + +#include #include "types.h" namespace Logs { From 8eaeda5ec558676c4ea1cd2ae4fc78f8650d48fa Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 02:10:10 -0500 Subject: [PATCH 061/491] Tweaks --- CMakeLists.txt | 7 +- common/servertalk.h | 2 +- loginserver/client.cpp | 6 +- loginserver/database.cpp | 2 +- loginserver/database.h | 70 +++++++++++++ loginserver/main.cpp | 17 +++- loginserver/server_manager.cpp | 6 +- loginserver/world_server.cpp | 181 ++++++++++++++++++--------------- world/login_server.cpp | 32 +++--- zone/command.cpp | 2 +- 10 files changed, 217 insertions(+), 108 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87966f3ea..8a20677ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,9 +147,6 @@ SET(EQEMU_LOG_LEVEL_DEBUG 3 CACHE STRING "EQEmu logging level for [Debug]: ) OPTION(EQEMU_LSPX "" OFF) -IF(EQEMU_LSPX) - ADD_DEFINITIONS(-DLSPX=ON) -ENDIF(EQEMU_LSPX) MARK_AS_ADVANCED(EQEMU_LSPX) MARK_AS_ADVANCED(EQEMU_LOG_LEVEL_DEBUG) @@ -164,6 +161,10 @@ IF(EQEMU_COMMANDS_LOGGING) ADD_DEFINITIONS(-DCOMMANDS_LOGGING) ENDIF(EQEMU_COMMANDS_LOGGING) +IF(EQEMU_LSPX) + ADD_DEFINITIONS(-DLSPX=ON) +ENDIF(EQEMU_LSPX) + IF(EQEMU_ENABLE_BOTS) ADD_DEFINITIONS(-DBOTS) ENDIF(EQEMU_ENABLE_BOTS) diff --git a/common/servertalk.h b/common/servertalk.h index 7584d4942..4befd253d 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -472,7 +472,7 @@ struct ServerLSAccountUpdate_Struct { // for updating info on login server uint32 useraccountid; // player account ID char useraccount[31]; // player account name char userpassword[51]; // player account password - char useremail[101]; // player account email address + char user_email[101]; // player account email address }; struct ServerLSStatus_Struct { diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 4d4e9c37f..c8b675361 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -383,11 +383,10 @@ void Client::AttemptLoginAccountCreation( const std::string &loginserver ) { - LogInfo("Attempting login account creation via '{0}'", loginserver); - #ifdef LSPX - if (loginserver == "eqemu") { + LogInfo("Attempting login account creation via '{0}'", loginserver); + if (!server.options.CanAutoLinkAccounts()) { LogInfo("CanAutoLinkAccounts disabled - sending failed login"); DoFailedLogin(); @@ -452,6 +451,7 @@ void Client::AttemptLoginAccountCreation( #endif if (server.options.CanAutoCreateAccounts() && loginserver == "local") { + LogInfo("CanAutoCreateAccounts enabled, attempting to creating account [{0}]", user); CreateLocalAccount(user, pass); return; } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 82d8d2d72..1784e0377 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -503,7 +503,7 @@ std::string Database::CreateLoginserverApiToken( { std::string token = EQ::Util::UUID::Generate().ToString(); auto query = fmt::format( - "INSERT INTO loginserver_api_tokens (token, can_write, can_read, created_at) VALUES ('{0}', {1}, {2}, NOW())", + "INSERT INTO login_api_tokens (token, can_write, can_read, created_at) VALUES ('{0}', {1}, {2}, NOW())", token, (write_mode ? "1" : "0"), (read_mode ? "1" : "0") diff --git a/loginserver/database.h b/loginserver/database.h index 44b1f95c1..2fc312a6a 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -65,6 +65,15 @@ public: std::string &password, unsigned int &id ); + + /** + * @param token + * @param ip + * @param db_account_id + * @param db_loginserver + * @param user + * @return + */ bool GetLoginTokenDataFromToken( const std::string &token, const std::string &ip, @@ -72,13 +81,34 @@ public: std::string &db_loginserver, std::string &user ); + + /** + * @param loginserver + * @return + */ unsigned int GetFreeID(const std::string &loginserver); + + /** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ bool CreateLoginData( const std::string &name, const std::string &password, const std::string &loginserver, unsigned int &id ); + + /** + * @param in_account_name + * @param in_account_password + * @param loginserver + * @param id + * @return + */ bool CreateLoginDataWithID( const std::string &in_account_name, const std::string &in_account_password, @@ -86,8 +116,20 @@ public: unsigned int id ); + /** + * @param name + * @param loginserver + * @param hash + */ void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + /** + * @param name + * @param password + * @param loginserver + * @param id + * @return + */ bool DoesLoginServerAccountExist( const std::string &name, const std::string &password, @@ -122,10 +164,38 @@ public: const std::string& local_ip ); + /** + * @param id + * @param ip_address + */ void UpdateLSAccountData(unsigned int id, std::string ip_address); + + /** + * @param id + * @param name + * @param password + * @param email + */ void UpdateLSAccountInfo(unsigned int id, std::string name, std::string password, std::string email); + + /** + * @param id + * @param long_name + * @param ip_address + */ void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); + + /** + * @param long_name + * @param short_name + * @param id + * @return + */ bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); + + /** + * @param log_settings + */ void LoadLogSettings(EQEmuLogSys::LogSettings *log_settings); /** diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 31cd3429d..ab5ad699e 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -63,6 +63,7 @@ int main(int argc, char** argv) server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", true)); +#ifdef LSPX server.options.EQEmuLoginServerAddress( server.config.GetVariableString( "general", @@ -78,6 +79,7 @@ int main(int argc, char** argv) "local" ) ); +#endif #ifdef ENABLE_SECURITY @@ -137,7 +139,7 @@ int main(int argc, char** argv) * create client manager */ LogInfo("Client Manager Init"); - server.client_manager = new ClientManager(); + server.client_manager = new ClientManager(); if (!server.client_manager) { LogError("Client Manager Failed to Start"); LogInfo("Server Manager Shutdown"); @@ -175,6 +177,19 @@ int main(int argc, char** argv) LoginserverCommandHandler::CommandHandler(argc, argv); + LogInfo("[Config] IsTraceOn [{0}]", server.options.IsTraceOn()); + LogInfo("[Config] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn()); + LogInfo("[Config] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn()); + LogInfo("[Config] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn()); + LogInfo("[Config] IsRejectingDuplicateServers [{0}]", server.options.IsRejectingDuplicateServers()); + LogInfo("[Config] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts()); + LogInfo("[Config] CanAutoLinkAccounts [{0}]", server.options.CanAutoLinkAccounts()); + LogInfo("[Config] GetEncryptionMode [{0}]", server.options.GetEncryptionMode()); + LogInfo("[Config] IsUnregisteredAllowed [{0}]", server.options.IsUnregisteredAllowed()); + LogInfo("[Config] IsTokenLoginAllowed [{0}]", server.options.IsTokenLoginAllowed()); + LogInfo("[Config] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed()); + LogInfo("[Config] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords()); + while (run_server) { Timer::SetCurrentTime(); server.client_manager->Process(); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index e91e26ac2..41b86bc4f 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -121,7 +121,7 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 { unsigned int packet_size = sizeof(ServerListHeader_Struct); unsigned int server_count = 0; - in_addr in; + in_addr in{}; in.s_addr = client->GetConnection()->GetRemoteIP(); std::string client_ip = inet_ntoa(in); @@ -174,13 +174,13 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 iter = world_servers.begin(); while (iter != world_servers.end()) { - if ((*iter)->IsAuthorized() == false) { + if (!(*iter)->IsAuthorized()) { ++iter; continue; } std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP(); - if (world_ip.compare(client_ip) == 0) { + if (world_ip == client_ip) { memcpy(data_pointer, (*iter)->GetLocalIP().c_str(), (*iter)->GetLocalIP().size()); data_pointer += ((*iter)->GetLocalIP().size() + 1); } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index c85b92d8e..800bbff4b 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -32,16 +32,16 @@ extern LoginServer server; */ WorldServer::WorldServer(std::shared_ptr worldserver_connection) { - connection = worldserver_connection; - zones_booted = 0; - players_online = 0; - server_status = 0; - server_id = 0; - server_list_type_id = 0; - server_process_type = 0; + connection = worldserver_connection; + zones_booted = 0; + players_online = 0; + server_status = 0; + server_id = 0; + server_list_type_id = 0; + server_process_type = 0; is_server_authorized = false; - is_server_trusted = false; - is_server_logged_in = false; + is_server_trusted = false; + is_server_logged_in = false; worldserver_connection->OnMessage( ServerOP_NewLSInfo, @@ -79,13 +79,13 @@ WorldServer::~WorldServer() = default; void WorldServer::Reset() { server_id; - zones_booted = 0; - players_online = 0; - server_status = 0; - server_list_type_id = 0; - server_process_type = 0; + zones_booted = 0; + players_online = 0; + server_status = 0; + server_list_type_id = 0; + server_process_type = 0; is_server_authorized = false; - is_server_logged_in = false; + is_server_logged_in = false; } /** @@ -219,13 +219,13 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid); - Client *c = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); - if (c) { + Client *client = server.client_manager->GetClient(user_to_world_response->lsaccountid, "eqemu"); + if (client) { LogDebug( "Found client with user id of [{0}] and account name of [{1}]", user_to_world_response->lsaccountid, - c->GetAccountName() + client->GetAccountName() ); auto *outapp = new EQApplicationPacket( @@ -234,17 +234,17 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne ); auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; - per->Sequence = c->GetPlaySequence(); - per->ServerNumber = c->GetPlayServerID(); + per->Sequence = client->GetPlaySequence(); + per->ServerNumber = client->GetPlayServerID(); if (user_to_world_response->response > 0) { per->Allowed = 1; SendClientAuth( - c->GetConnection()->GetRemoteAddr(), - c->GetAccountName(), - c->GetKey(), - c->GetAccountID(), - c->GetLoginServerName() + client->GetConnection()->GetRemoteAddr(), + client->GetAccountName(), + client->GetKey(), + client->GetAccountID(), + client->GetLoginServerName() ); } @@ -281,7 +281,7 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne DumpPacket(outapp); } - c->SendPlayResponse(outapp); + client->SendPlayResponse(outapp); delete outapp; } else { @@ -311,10 +311,11 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac } if (packet.Length() < sizeof(UsertoWorldResponse_Struct)) { - Log(Logs::General, - Logs::Error, + LogError( "Received application packet from server that had opcode ServerOP_UsertoWorldResp, " - "but was too small. Discarded to avoid buffer overrun"); + "but was too small. Discarded to avoid buffer overrun" + ); + return; } @@ -326,11 +327,13 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac } auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data(); - Log(Logs::General, Logs::Debug, "Trying to find client with user id of %u.", user_to_world_response->lsaccountid); + LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid); + Client *client = server.client_manager->GetClient( user_to_world_response->lsaccountid, user_to_world_response->login ); + if (client) { LogDebug("Found client with user id of {0} and account name of {1}", user_to_world_response->lsaccountid, @@ -345,9 +348,9 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer; per->Sequence = client->GetPlaySequence(); per->ServerNumber = client->GetPlayServerID(); - Log(Logs::General, - Logs::Debug, - "Found sequence and play of %u %u", + + LogDebug( + "Found sequence and play of [{0}] [{1}]", client->GetPlaySequence(), client->GetPlayServerID() ); @@ -402,8 +405,10 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac delete outapp; } else { - LogError("Received User-To-World Response for {0} but could not find the client referenced!.", - user_to_world_response->lsaccountid); + LogError( + "Received User-To-World Response for {0} but could not find the client referenced!.", + user_to_world_response->lsaccountid + ); } } @@ -437,22 +442,25 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data(); - if (is_server_trusted) { - Log(Logs::General, - Logs::Netcode, - "ServerOP_LSAccountUpdate update processed for: %s", - loginserver_update->useraccount); - std::string name = ""; - std::string password = ""; - std::string email = ""; + if (IsServerTrusted()) { + LogDebug("ServerOP_LSAccountUpdate update processed for: [{0}]", loginserver_update->useraccount); + std::string name; + std::string password; + std::string email; + name.assign(loginserver_update->useraccount); password.assign(loginserver_update->userpassword); - if (loginserver_update->useremail) { - email.assign(loginserver_update->useremail); + if (loginserver_update->user_email) { + email.assign(loginserver_update->user_email); } - server.db->UpdateLSAccountInfo(loginserver_update->useraccountid, name, password, email); + server.db->UpdateLSAccountInfo( + loginserver_update->useraccountid, + name, + password, + email + ); } } @@ -473,8 +481,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info return; } - this - ->SetAccountPassword(new_world_server_info_packet->account_password) + this->SetAccountPassword(new_world_server_info_packet->account_password) ->SetLongName(new_world_server_info_packet->server_long_name) ->SetShortName(new_world_server_info_packet->server_short_name) ->SetLocalIp(new_world_server_info_packet->local_ip_address) @@ -486,30 +493,40 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info ->SetAccountName(new_world_server_info_packet->account_name); if (server.options.IsRejectingDuplicateServers()) { - if (server.server_manager->ServerExists(long_name, short_name, this)) { + if (server.server_manager->ServerExists(GetServerLongName(), GetServerShortName(), this)) { LogError("World tried to login but there already exists a server that has that name"); return; } } else { - if (server.server_manager->ServerExists(long_name, short_name, this)) { - LogError("World tried to login but there already exists a server that has that name"); + if (server.server_manager->ServerExists(GetServerLongName(), GetServerShortName(), this)) { + LogInfo("World tried to login but there already exists a server that has that name"); server.server_manager->DestroyServerByName(long_name, short_name, this); } } Database::DbWorldRegistration - world_registration = server.db->GetWorldRegistration(short_name, remote_ip_address, local_ip); + world_registration = server.db->GetWorldRegistration( + GetServerShortName(), + GetRemoteIp(), + GetLocalIp() + ); if (!server.options.IsUnregisteredAllowed()) { - if (!this->HandleNewLoginserverRegisteredOnly(world_registration)){ - LogError("WorldServer::HandleNewLoginserverRegisteredOnly checks failed"); + if (!this->HandleNewLoginserverRegisteredOnly(world_registration)) { + LogError( + "WorldServer::HandleNewLoginserverRegisteredOnly checks failed with server [{0}]", + this->GetServerLongName() + ); return; } } else { - if (!this->HandleNewLoginserverInfoUnregisteredAllowed(world_registration)){ - LogError("WorldServer::HandleNewLoginserverInfoUnregisteredAllowed checks failed"); + if (!this->HandleNewLoginserverInfoUnregisteredAllowed(world_registration)) { + LogError( + "WorldServer::HandleNewLoginserverInfoUnregisteredAllowed checks failed with server [{0}]", + this->GetServerLongName() + ); return; } } @@ -526,9 +543,9 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info */ void WorldServer::Handle_LSStatus(ServerLSStatus_Struct *server_login_status) { - players_online = server_login_status->num_players; - zones_booted = server_login_status->num_zones; - server_status = server_login_status->status; + SetPlayersOnline(server_login_status->num_players); + SetZonesBooted(server_login_status->num_zones); + SetServerStatus(server_login_status->status); } /** @@ -663,7 +680,7 @@ bool WorldServer::HandleNewLoginserverInfoValidation( if (strlen(new_world_server_info_packet->remote_ip_address) == 0) { this->SetRemoteIp(GetConnection()->Handle()->RemoteIP()); - LogError( + LogWarning( "Remote address was null, defaulting to stream address {0}", remote_ip_address ); @@ -675,8 +692,8 @@ bool WorldServer::HandleNewLoginserverInfoValidation( else { this->SetRemoteIp(GetConnection()->Handle()->RemoteIP()); - LogError( - "Handle_NewLSInfo error, remote address was too long, defaulting to stream address [{0}]", + LogWarning( + "Handle_NewLSInfo remote address was too long, defaulting to stream address [{0}]", remote_ip_address ); } @@ -690,7 +707,8 @@ bool WorldServer::HandleNewLoginserverInfoValidation( */ bool WorldServer::HandleNewLoginserverRegisteredOnly( Database::DbWorldRegistration &world_registration -) { +) +{ if (!this->GetAccountName().empty() && !this->GetAccountPassword().empty()) { if (world_registration.loaded) { bool does_world_server_not_require_authentication = ( @@ -775,7 +793,8 @@ bool WorldServer::HandleNewLoginserverRegisteredOnly( */ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( Database::DbWorldRegistration &world_registration -) { +) +{ if (world_registration.loaded) { this @@ -872,7 +891,7 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( * @param in_server_list_id * @return */ -WorldServer * WorldServer::SetServerListTypeId(unsigned int in_server_list_id) +WorldServer *WorldServer::SetServerListTypeId(unsigned int in_server_list_id) { server_list_type_id = in_server_list_id; @@ -890,7 +909,7 @@ const std::string &WorldServer::GetServerDescription() const /** * @param in_server_description */ -WorldServer * WorldServer::SetServerDescription(const std::string &in_server_description) +WorldServer *WorldServer::SetServerDescription(const std::string &in_server_description) { WorldServer::server_description = in_server_description; @@ -908,7 +927,7 @@ bool WorldServer::IsServerAuthorized() const /** * @param in_is_server_authorized */ -WorldServer * WorldServer::SetIsServerAuthorized(bool in_is_server_authorized) +WorldServer *WorldServer::SetIsServerAuthorized(bool in_is_server_authorized) { WorldServer::is_server_authorized = in_is_server_authorized; @@ -926,7 +945,7 @@ bool WorldServer::IsServerLoggedIn() const /** * @param in_is_server_logged_in */ -WorldServer * WorldServer::SetIsServerLoggedIn(bool in_is_server_logged_in) +WorldServer *WorldServer::SetIsServerLoggedIn(bool in_is_server_logged_in) { WorldServer::is_server_logged_in = in_is_server_logged_in; @@ -944,7 +963,7 @@ bool WorldServer::IsServerTrusted() const /** * @param in_is_server_trusted */ -WorldServer * WorldServer::SetIsServerTrusted(bool in_is_server_trusted) +WorldServer *WorldServer::SetIsServerTrusted(bool in_is_server_trusted) { WorldServer::is_server_trusted = in_is_server_trusted; @@ -954,7 +973,7 @@ WorldServer * WorldServer::SetIsServerTrusted(bool in_is_server_trusted) /** * @param in_zones_booted */ -WorldServer * WorldServer::SetZonesBooted(unsigned int in_zones_booted) +WorldServer *WorldServer::SetZonesBooted(unsigned int in_zones_booted) { WorldServer::zones_booted = in_zones_booted; @@ -964,7 +983,7 @@ WorldServer * WorldServer::SetZonesBooted(unsigned int in_zones_booted) /** * @param in_players_online */ -WorldServer * WorldServer::SetPlayersOnline(unsigned int in_players_online) +WorldServer *WorldServer::SetPlayersOnline(unsigned int in_players_online) { WorldServer::players_online = in_players_online; @@ -974,7 +993,7 @@ WorldServer * WorldServer::SetPlayersOnline(unsigned int in_players_online) /** * @param in_server_status */ -WorldServer * WorldServer::SetServerStatus(int in_server_status) +WorldServer *WorldServer::SetServerStatus(int in_server_status) { WorldServer::server_status = in_server_status; @@ -984,7 +1003,7 @@ WorldServer * WorldServer::SetServerStatus(int in_server_status) /** * @param in_server_process_type */ -WorldServer * WorldServer::SetServerProcessType(unsigned int in_server_process_type) +WorldServer *WorldServer::SetServerProcessType(unsigned int in_server_process_type) { WorldServer::server_process_type = in_server_process_type; @@ -994,7 +1013,7 @@ WorldServer * WorldServer::SetServerProcessType(unsigned int in_server_process_t /** * @param in_long_name */ -WorldServer * WorldServer::SetLongName(const std::string &in_long_name) +WorldServer *WorldServer::SetLongName(const std::string &in_long_name) { WorldServer::long_name = in_long_name; @@ -1004,7 +1023,7 @@ WorldServer * WorldServer::SetLongName(const std::string &in_long_name) /** * @param in_short_name */ -WorldServer * WorldServer::SetShortName(const std::string &in_short_name) +WorldServer *WorldServer::SetShortName(const std::string &in_short_name) { WorldServer::short_name = in_short_name; @@ -1014,7 +1033,7 @@ WorldServer * WorldServer::SetShortName(const std::string &in_short_name) /** * @param in_account_name */ -WorldServer * WorldServer::SetAccountName(const std::string &in_account_name) +WorldServer *WorldServer::SetAccountName(const std::string &in_account_name) { WorldServer::account_name = in_account_name; @@ -1024,7 +1043,7 @@ WorldServer * WorldServer::SetAccountName(const std::string &in_account_name) /** * @param in_account_password */ -WorldServer * WorldServer::SetAccountPassword(const std::string &in_account_password) +WorldServer *WorldServer::SetAccountPassword(const std::string &in_account_password) { WorldServer::account_password = in_account_password; @@ -1034,7 +1053,7 @@ WorldServer * WorldServer::SetAccountPassword(const std::string &in_account_pass /** * @param in_remote_ip */ -WorldServer * WorldServer::SetRemoteIp(const std::string &in_remote_ip) +WorldServer *WorldServer::SetRemoteIp(const std::string &in_remote_ip) { WorldServer::remote_ip_address = in_remote_ip; @@ -1044,7 +1063,7 @@ WorldServer * WorldServer::SetRemoteIp(const std::string &in_remote_ip) /** * @param in_local_ip */ -WorldServer * WorldServer::SetLocalIp(const std::string &in_local_ip) +WorldServer *WorldServer::SetLocalIp(const std::string &in_local_ip) { WorldServer::local_ip = in_local_ip; @@ -1054,7 +1073,7 @@ WorldServer * WorldServer::SetLocalIp(const std::string &in_local_ip) /** * @param in_protocol */ -WorldServer * WorldServer::SetProtocol(const std::string &in_protocol) +WorldServer *WorldServer::SetProtocol(const std::string &in_protocol) { WorldServer::protocol = in_protocol; @@ -1064,7 +1083,7 @@ WorldServer * WorldServer::SetProtocol(const std::string &in_protocol) /** * @param in_version */ -WorldServer * WorldServer::SetVersion(const std::string &in_version) +WorldServer *WorldServer::SetVersion(const std::string &in_version) { WorldServer::version = in_version; diff --git a/world/login_server.cpp b/world/login_server.cpp index e1cc8a3f1..41fa92efa 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "clientlist.h" #include "world_config.h" + extern ZSList zoneserver_list; extern ClientList client_list; extern uint32 numzones; @@ -544,24 +545,27 @@ void LoginServer::SendStatus() pack->size = sizeof(ServerLSStatus_Struct); pack->pBuffer = new uchar[pack->size]; memset(pack->pBuffer, 0, pack->size); - ServerLSStatus_Struct *lss = (ServerLSStatus_Struct *) pack->pBuffer; + auto loginserver_status = (ServerLSStatus_Struct *) pack->pBuffer; if (WorldConfig::get()->Locked) { - lss->status = -2; + loginserver_status->status = -2; } else if (numzones <= 0) { - lss->status = -2; + loginserver_status->status = -2; } else { - lss->status = numplayers; + loginserver_status->status = numplayers; } - lss->num_zones = numzones; - lss->num_players = numplayers; + loginserver_status->num_zones = numzones; + loginserver_status->num_players = numplayers; SendPacket(pack); delete pack; } +/** + * @param pack + */ void LoginServer::SendPacket(ServerPacket *pack) { if (IsLegacy) { @@ -578,15 +582,15 @@ void LoginServer::SendPacket(ServerPacket *pack) void LoginServer::SendAccountUpdate(ServerPacket *pack) { - ServerLSAccountUpdate_Struct *s = (ServerLSAccountUpdate_Struct *) pack->pBuffer; + auto *ls_account_update = (ServerLSAccountUpdate_Struct *) pack->pBuffer; if (CanUpdate()) { - Log(Logs::Detail, - Logs::World_Server, - "Sending ServerOP_LSAccountUpdate packet to loginserver: %s:%d", + LogInfo( + "Sending ServerOP_LSAccountUpdate packet to loginserver: [{0}]:[{1}]", LoginServerAddress, - LoginServerPort); - strn0cpy(s->worldaccount, LoginAccount.c_str(), 30); - strn0cpy(s->worldpassword, LoginPassword.c_str(), 30); + LoginServerPort + ); + strn0cpy(ls_account_update->worldaccount, LoginAccount.c_str(), 30); + strn0cpy(ls_account_update->worldpassword, LoginPassword.c_str(), 30); SendPacket(pack); } -} \ No newline at end of file +} diff --git a/zone/command.cpp b/zone/command.cpp index 37af976ba..e47b9be01 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -2361,7 +2361,7 @@ void command_setlsinfo(Client *c, const Seperator *sep) ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *) pack->pBuffer; s->useraccountid = c->LSAccountID(); strn0cpy(s->useraccount, c->AccountName(), 30); - strn0cpy(s->useremail, sep->arg[1], 100); + strn0cpy(s->user_email, sep->arg[1], 100); strn0cpy(s->userpassword, sep->arg[2], 50); worldserver.SendPacket(pack); c->Message(0, "Login Server update packet sent."); From 0c2d26579a941fbc65f7e45bff77056603e7961f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 02:14:41 -0500 Subject: [PATCH 062/491] Update database.cpp --- loginserver/database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 1784e0377..97a5e7349 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -525,7 +525,7 @@ std::string Database::CreateLoginserverApiToken( */ MySQLRequestResult Database::GetLoginserverApiTokens() { - return QueryDatabase("SELECT token, can_write, can_read FROM loginserver_api_tokens"); + return QueryDatabase("SELECT token, can_write, can_read FROM login_api_tokens"); } /** From 0111e9a5d0d6c5e347ed73c3b71c679b1ea9df98 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 02:32:20 -0500 Subject: [PATCH 063/491] Update client [skip ci] --- loginserver/client.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index c8b675361..92cd693b1 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -637,21 +637,20 @@ void Client::DoSuccessfulLogin( } /** - * @param user - * @param pass + * @param username + * @param password */ -void Client::CreateLocalAccount(const std::string &user, const std::string &pass) +void Client::CreateLocalAccount(const std::string &username, const std::string &password) { auto mode = server.options.GetEncryptionMode(); - auto hash = eqcrypt_hash(user, pass, mode); + auto hash = eqcrypt_hash(username, password, mode); unsigned int db_id = 0; - std::string db_login = server.options.GetDefaultLoginServerName(); - if (!server.db->CreateLoginData(user, hash, db_login, db_id)) { + if (!server.db->CreateLoginData(username, hash, "local", db_id)) { DoFailedLogin(); } else { - DoSuccessfulLogin(user, db_id, db_login); + DoSuccessfulLogin(username, db_id, "local"); } } From 54ea7d7c4ba35d755a41bd249d3db894d9508846 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 02:41:09 -0500 Subject: [PATCH 064/491] Update remote ip [skip ci] --- loginserver/client.h | 2 +- loginserver/world_server.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/loginserver/client.h b/loginserver/client.h index d52c26f75..d95b3c286 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -191,7 +191,7 @@ public: ); void DoSuccessfulLogin(const std::string in_account_name, int db_account_id, const std::string &db_loginserver); - void CreateLocalAccount(const std::string &user, const std::string &pass); + void CreateLocalAccount(const std::string &username, const std::string &password); void CreateEQEmuAccount(const std::string &in_account_name, const std::string &in_account_password, unsigned int loginserver_account_id); private: diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 800bbff4b..3022de53c 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -534,7 +534,7 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info server.db->UpdateWorldRegistration( GetServerId(), GetServerLongName(), - GetConnection()->Handle()->RemoteIP() + GetRemoteIp() ); } From 1a577014d945e8eb32766160365224891d88a74b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 03:46:59 -0500 Subject: [PATCH 065/491] Few more updates [skip ci] --- loginserver/client.cpp | 7 +++-- loginserver/database.cpp | 47 +++++++++++++++------------------- loginserver/database.h | 11 +++++--- loginserver/server_manager.cpp | 3 +-- loginserver/world_server.cpp | 12 ++++++--- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 92cd693b1..64c429a96 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -642,10 +642,9 @@ void Client::DoSuccessfulLogin( */ void Client::CreateLocalAccount(const std::string &username, const std::string &password) { - auto mode = server.options.GetEncryptionMode(); - auto hash = eqcrypt_hash(username, password, mode); - - unsigned int db_id = 0; + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(username, password, mode); + unsigned int db_id = 0; if (!server.db->CreateLoginData(username, hash, "local", db_id)) { DoFailedLogin(); } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 97a5e7349..e050befae 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -332,20 +332,18 @@ Database::DbWorldRegistration Database::GetWorldRegistration( { auto query = fmt::format( "SELECT\n" - " ifnull(WSR.id, 999999) AS server_id,\n" + " WSR.id,\n" " WSR.tag_description,\n" - " ifnull(WSR.is_server_trusted, 0) AS is_server_trusted,\n" - " ifnull(SLT.id, 3) AS login_server_list_type_id,\n" + " WSR.is_server_trusted,\n" + " SLT.id,\n" " SLT.description,\n" " ifnull(WSR.login_server_admin_id, 0) AS login_server_admin_id\n" "FROM\n" " login_world_servers AS WSR\n" " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.short_name = '{0}' AND (WSR.last_ip_address = '{1}' OR WSR.last_ip_address = '{2}') LIMIT 1", - EscapeString(short_name), - EscapeString(remote_ip), - EscapeString(local_ip) + " WSR.short_name = '{0}' LIMIT 1", + EscapeString(short_name) ); Database::DbWorldRegistration world_registration{}; @@ -442,46 +440,41 @@ void Database::UpdateWorldRegistration(unsigned int id, std::string long_name, s } /** - * @param long_name - * @param short_name + * @param server_long_name + * @param server_short_name * @param id * @return */ bool Database::CreateWorldRegistration( - std::string long_name, - std::string short_name, + std::string server_long_name, + std::string server_short_name, + std::string server_remote_ip, unsigned int &id ) { - auto query = fmt::format( - "SELECT ifnull(max(id),0) + 1 FROM login_world_servers" - ); - - auto results = QueryDatabase(query); + auto results = QueryDatabase("SELECT max(id) + 1 FROM login_world_servers"); if (!results.Success() || results.RowCount() != 1) { return false; } auto row = results.begin(); - id = atoi(row[0]); - + id = std::stoi(row[0]); auto insert_query = fmt::format( - "INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', \n" + "INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n" "login_server_list_type_id = 3, login_server_admin_id = 0, is_server_trusted = 0, tag_description = ''", id, - long_name, - short_name + server_long_name, + server_short_name, + server_remote_ip ); auto insert_results = QueryDatabase(insert_query); if (!insert_results.Success()) { - LogF( - Logs::General, - Logs::Error, - "World registration did not exist in the database for {0} - {1}", - long_name, - short_name + LogError( + "Failed to register world server {0} - {1}", + server_long_name, + server_short_name ); return false; diff --git a/loginserver/database.h b/loginserver/database.h index 2fc312a6a..cda677bb0 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -186,12 +186,17 @@ public: void UpdateWorldRegistration(unsigned int id, std::string long_name, std::string ip_address); /** - * @param long_name - * @param short_name + * @param server_long_name + * @param server_short_name * @param id * @return */ - bool CreateWorldRegistration(std::string long_name, std::string short_name, unsigned int &id); + bool CreateWorldRegistration( + std::string server_long_name, + std::string server_short_name, + std::string server_remote_ip, + unsigned int &id + ); /** * @param log_settings diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 41b86bc4f..797b1138f 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -300,8 +300,7 @@ bool ServerManager::ServerExists( continue; } - if ((*iter)->GetServerLongName().compare(server_long_name) == 0 && - (*iter)->GetServerShortName().compare(server_short_name) == 0) { + if ((*iter)->GetServerLongName() == server_long_name && (*iter)->GetServerShortName() == server_short_name) { return true; } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 3022de53c..3b267cd7c 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -471,7 +471,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet */ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info_packet) { - if (is_server_logged_in) { + if (IsServerLoggedIn()) { LogError("WorldServer::Handle_NewLSInfo called but the login server was already marked as logged in, aborting"); return; } @@ -796,7 +796,6 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( ) { if (world_registration.loaded) { - this ->SetServerDescription(world_registration.server_description) ->SetServerId(world_registration.server_id) @@ -824,7 +823,7 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( this->GetServerShortName() ); - if (IsServerTrusted()) { + if (this->IsServerTrusted()) { LogDebug("WorldServer::HandleNewLoginserverRegisteredOnly | ServerOP_LSAccountUpdate sent to world"); EQ::Net::DynamicPacket outapp; connection->Send(ServerOP_LSAccountUpdate, outapp); @@ -879,7 +878,12 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( /** * Auto create a registration */ - if (!server.db->CreateWorldRegistration(long_name, short_name, server_id)) { + if (!server.db->CreateWorldRegistration( + GetServerLongName(), + GetServerShortName(), + GetRemoteIp(), + server_id + )) { return false; } } From b165760f182e7824f09ae7a92798739d32e92d74 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 04:02:13 -0500 Subject: [PATCH 066/491] Update database [skip ci] --- loginserver/database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index e050befae..06cfbeb31 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -452,7 +452,7 @@ bool Database::CreateWorldRegistration( unsigned int &id ) { - auto results = QueryDatabase("SELECT max(id) + 1 FROM login_world_servers"); + auto results = QueryDatabase("SELECT IFNULL(max(id), 0) + 1 FROM login_world_servers"); if (!results.Success() || results.RowCount() != 1) { return false; } From 739f54bbfb7f5d350ab5228d65c8badf026ce9f7 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 05:23:21 -0500 Subject: [PATCH 067/491] Add CreateLoginserverWorldAdminAccount command [skip ci] --- loginserver/account_management.cpp | 56 +++++++++++++++++++ loginserver/account_management.h | 21 ++++++++ loginserver/database.cpp | 60 +++++++++++++++++++-- loginserver/database.h | 32 +++++++++-- loginserver/login_util/login_schema.sql | 2 +- loginserver/loginserver_command_handler.cpp | 52 +++++++++++++++--- loginserver/loginserver_command_handler.h | 1 + 7 files changed, 208 insertions(+), 16 deletions(-) diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index d5a2fabdb..8100ff467 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -70,3 +70,59 @@ bool AccountManagement::CreateLocalLoginServerAccount( return false; } + +/** + * @param username + * @param password + * @param email + * @return + */ +bool AccountManagement::CreateLoginserverWorldAdminAccount( + const std::string &username, + const std::string &password, + const std::string &email, + const std::string &first_name, + const std::string &last_name, + const std::string &ip_address +) +{ + auto mode = server.options.GetEncryptionMode(); + auto hash = eqcrypt_hash(username, password, mode); + + LogInfo( + "Attempting to create world admin account | username [{0}] encryption algorithm [{1}] ({2})", + username, + GetEncryptionByModeId(mode), + mode + ); + + if (server.db->DoesLoginserverWorldAdminAccountExist(username)) { + LogInfo( + "Attempting to create world admin account for user [{0}] but already exists!", + username + ); + + return false; + } + + if (server.db->CreateLoginserverWorldAdminAccount( + username, + hash, + first_name, + last_name, + email, + ip_address + )) { + LogInfo( + "Account creation success for user [{0}] encryption algorithm [{1}] ({2})", + username, + GetEncryptionByModeId(mode), + mode + ); + return true; + } + + LogError("Failed to create world admin account account for user [{0}]!", username); + + return false; +} diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 907aaf509..360ecb4b0 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -24,7 +24,28 @@ class AccountManagement { public: + + /** + * @param username + * @param password + * @return + */ static bool CreateLocalLoginServerAccount(std::string username, std::string password); + + /** + * @param username + * @param password + * @param email + * @return + */ + static bool CreateLoginserverWorldAdminAccount( + const std::string &username, + const std::string &password, + const std::string &email, + const std::string &first_name = "", + const std::string &last_name = "", + const std::string &ip_address = "" + ); }; diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 06cfbeb31..debbe37df 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -57,7 +57,7 @@ Database::Database( user.c_str(), pass.c_str(), name.c_str(), - atoi(port.c_str()), + std::stoi(port), &errnum, errbuf ) @@ -66,7 +66,7 @@ Database::Database( exit(1); } else { - Log(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host, port); + LogStatus("Using database [{0}] at [{1}:{2}]", name, host, port); } } @@ -477,6 +477,7 @@ bool Database::CreateWorldRegistration( server_short_name ); + return false; } @@ -608,4 +609,57 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) } delete[] categories_in_database; -} \ No newline at end of file +} + +/** + * @param account_name + * @param account_password + * @param first_name + * @param last_name + * @param email + * @param ip_address + * @return + */ +bool Database::CreateLoginserverWorldAdminAccount( + const std::string &account_name, + const std::string &account_password, + const std::string &first_name, + const std::string &last_name, + const std::string &email, + const std::string &ip_address +) +{ + auto query = fmt::format( + "INSERT INTO login_server_admins (account_name, account_password, first_name, last_name, email, registration_date, " + "registration_ip_address) " + "VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', NOW(), '{5}')", + EscapeString(account_name), + EscapeString(account_password), + EscapeString(first_name), + EscapeString(last_name), + EscapeString(email), + ip_address + ); + + auto results = QueryDatabase(query); + + return results.Success(); +} + +/** + * @param account_name + * @return + */ +bool Database::DoesLoginserverWorldAdminAccountExist( + const std::string &account_name +) +{ + auto query = fmt::format( + "SELECT account_name FROM login_server_admins WHERE account_name = '{0}'", + EscapeString(account_name) + ); + + auto results = QueryDatabase(query); + + return (results.RowCount() == 1); +} diff --git a/loginserver/database.h b/loginserver/database.h index cda677bb0..fb48c91a2 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -159,9 +159,9 @@ public: * @return */ Database::DbWorldRegistration GetWorldRegistration( - const std::string& short_name, - const std::string& remote_ip, - const std::string& local_ip + const std::string &short_name, + const std::string &remote_ip, + const std::string &local_ip ); /** @@ -211,9 +211,33 @@ public: std::string CreateLoginserverApiToken(bool write_mode, bool read_mode); MySQLRequestResult GetLoginserverApiTokens(); + /** + * @param account_name + * @param account_password + * @param first_name + * @param last_name + * @param email + * @param ip_address + * @return + */ + bool CreateLoginserverWorldAdminAccount( + const std::string &account_name, + const std::string &account_password, + const std::string &first_name, + const std::string &last_name, + const std::string &email, + const std::string &ip_address + ); + + /** + * @param account_name + * @return + */ + bool DoesLoginserverWorldAdminAccountExist(const std::string &account_name); + protected: std::string user, pass, host, port, name; - MYSQL *database; + MYSQL *database{}; }; #endif diff --git a/loginserver/login_util/login_schema.sql b/loginserver/login_util/login_schema.sql index d38b5358c..b07362830 100644 --- a/loginserver/login_util/login_schema.sql +++ b/loginserver/login_util/login_schema.sql @@ -17,7 +17,7 @@ DROP TABLE IF EXISTS `login_server_admins`; CREATE TABLE `login_server_admins` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `account_name` varchar(30) NOT NULL, - `account_password` varchar(100) NOT NULL, + `account_password` varchar(255) NOT NULL, `first_name` varchar(50) NOT NULL, `last_name` varchar(50) NOT NULL, `email` varchar(100) NOT NULL, diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index cebf23746..1c77eeec5 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -64,19 +64,29 @@ namespace LoginserverCommandHandler { argh::parser cmd; cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); - LoginserverCommandHandler::DisplayDebug(cmd); /** * Declare command mapping */ std::map function_map; - function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; - function_map["create-loginserver-account"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; - std::map::const_iterator it = function_map.begin(); - std::map::const_iterator end = function_map.end(); + function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["create-loginserver-account"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["create-loginserver-world-admin-account"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; + + std::map::const_iterator it = function_map.begin(); + + std::map::const_iterator end = function_map.end(); bool ran_command = false; while (it != end) { @@ -103,9 +113,12 @@ namespace LoginserverCommandHandler { std::cout << "> create-loginserver-api-token --write --read" << std::endl; std::cout << "> list-loginserver-api-tokens" << std::endl; std::cout << std::endl; - std::cout << "# Accounts" << std::endl; + std::cout << "# User Accounts" << std::endl; std::cout << "> create-loginserver-account --username=* --password=*" << std::endl; std::cout << std::endl; + std::cout << "# World Accounts" << std::endl; + std::cout << "> create-loginserver-world-admin-account --username=* --password=* --email=*" << std::endl; + std::cout << std::endl; std::cout << std::endl; } @@ -159,7 +172,7 @@ namespace LoginserverCommandHandler { */ void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd) { - if (cmd("--username").str().empty() || cmd("--username").str().empty()) { + if (cmd("--username").str().empty() || cmd("--password").str().empty()) { LogInfo("Command Example: create-loginserver-account --username=user --password=password"); exit(1); } @@ -167,4 +180,27 @@ namespace LoginserverCommandHandler { AccountManagement::CreateLocalLoginServerAccount(cmd("--username").str(), cmd("--password").str()); } + /** + * @param argc + * @param argv + * @param cmd + */ + void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd) + { + if ( + cmd("--username").str().empty() || + cmd("--password").str().empty() || + cmd("--email").str().empty()) { + + LogInfo("Command Example: create-loginserver-account --username=user --password=password"); + exit(1); + } + + AccountManagement::CreateLoginserverWorldAdminAccount( + cmd("--username").str(), + cmd("--password").str(), + cmd("--email").str() + ); + } + } diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index 25c9e050b..e37432807 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -29,6 +29,7 @@ namespace LoginserverCommandHandler { void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd); void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd); void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd); + void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd); }; From 86943ce6be7c7ec8196c864c2a71ec64530c1067 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 16:57:14 -0500 Subject: [PATCH 068/491] Add Database::DbLoginServerAdmin GetLoginServerAdmin [skip ci] --- loginserver/database.cpp | 41 +++++++++++++++++++-- loginserver/database.h | 17 ++++++++- loginserver/loginserver_command_handler.cpp | 2 +- loginserver/world_server.cpp | 20 +++++++++- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index debbe37df..09d0431f3 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -449,7 +449,8 @@ bool Database::CreateWorldRegistration( std::string server_long_name, std::string server_short_name, std::string server_remote_ip, - unsigned int &id + unsigned int &id, + unsigned int &server_admin_id ) { auto results = QueryDatabase("SELECT IFNULL(max(id), 0) + 1 FROM login_world_servers"); @@ -462,11 +463,12 @@ bool Database::CreateWorldRegistration( id = std::stoi(row[0]); auto insert_query = fmt::format( "INSERT INTO login_world_servers SET id = {0}, long_name = '{1}', short_name = '{2}', last_ip_address = '{3}', \n" - "login_server_list_type_id = 3, login_server_admin_id = 0, is_server_trusted = 0, tag_description = ''", + "login_server_list_type_id = 3, login_server_admin_id = {4}, is_server_trusted = 0, tag_description = ''", id, server_long_name, server_short_name, - server_remote_ip + server_remote_ip, + server_admin_id ); auto insert_results = QueryDatabase(insert_query); @@ -655,7 +657,7 @@ bool Database::DoesLoginserverWorldAdminAccountExist( ) { auto query = fmt::format( - "SELECT account_name FROM login_server_admins WHERE account_name = '{0}'", + "SELECT account_name FROM login_server_admins WHERE account_name = '{0}' LIMIT 1", EscapeString(account_name) ); @@ -663,3 +665,34 @@ bool Database::DoesLoginserverWorldAdminAccountExist( return (results.RowCount() == 1); } + +/** + * @param account_name + * @return + */ +Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &account_name) +{ + auto query = fmt::format( + "SELECT id, account_name, account_password, first_name, last_name, email, registration_date, registration_ip_address" + " FROM login_server_admins WHERE account_name = '{0}' LIMIT 1", + EscapeString(account_name) + ); + + auto results = QueryDatabase(query); + + Database::DbLoginServerAdmin login_server_admin{}; + if (results.RowCount() == 1) { + auto row = results.begin(); + login_server_admin.loaded = true; + login_server_admin.id = std::stoi(row[0]); + login_server_admin.account_name = row[1]; + login_server_admin.account_password = row[2]; + login_server_admin.first_name = row[3]; + login_server_admin.last_name = row[4]; + login_server_admin.email = row[5]; + login_server_admin.registration_date = row[7]; + login_server_admin.registration_ip_address = row[8]; + } + + return login_server_admin; +} diff --git a/loginserver/database.h b/loginserver/database.h index fb48c91a2..d9cafca4a 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -195,7 +195,8 @@ public: std::string server_long_name, std::string server_short_name, std::string server_remote_ip, - unsigned int &id + unsigned int &id, + unsigned int &server_admin_id ); /** @@ -235,6 +236,20 @@ public: */ bool DoesLoginserverWorldAdminAccountExist(const std::string &account_name); + struct DbLoginServerAdmin { + bool loaded = false; + uint32 id; + std::string account_name; + std::string account_password; + std::string first_name; + std::string last_name; + std::string email; + std::string registration_date; + std::string registration_ip_address; + }; + + Database::DbLoginServerAdmin GetLoginServerAdmin(const std::string &account_name); + protected: std::string user, pass, host, port, name; MYSQL *database{}; diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 1c77eeec5..52b1928fc 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -192,7 +192,7 @@ namespace LoginserverCommandHandler { cmd("--password").str().empty() || cmd("--email").str().empty()) { - LogInfo("Command Example: create-loginserver-account --username=user --password=password"); + LogInfo("Command Example: create-loginserver-world-admin-account --username=* --password=* --email=*"); exit(1); } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 3b267cd7c..de5477a02 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -875,6 +875,23 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( return true; } + Database::DbLoginServerAdmin login_server_admin = + server.db->GetLoginServerAdmin(GetAccountName()); + + uint32 server_admin_id = 0; + + if (login_server_admin.loaded) { + auto mode = server.options.GetEncryptionMode(); + if (eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + login_server_admin.account_password, + mode + )) { + server_admin_id = login_server_admin.id; + } + } + /** * Auto create a registration */ @@ -882,7 +899,8 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( GetServerLongName(), GetServerShortName(), GetRemoteIp(), - server_id + server_id, + server_admin_id )) { return false; } From 193dbe5938e4fff43f3606257c4e577635c4cbe5 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:22:11 -0500 Subject: [PATCH 069/491] Few tweaks [skip ci] --- loginserver/account_management.cpp | 11 +++++++---- loginserver/database.cpp | 4 ++-- loginserver/database.h | 2 +- loginserver/loginserver_command_handler.cpp | 19 ++++++++++--------- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 8100ff467..2ac3c07b5 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -105,19 +105,22 @@ bool AccountManagement::CreateLoginserverWorldAdminAccount( return false; } - if (server.db->CreateLoginserverWorldAdminAccount( + uint32 created_world_admin_id = server.db->CreateLoginserverWorldAdminAccount( username, hash, first_name, last_name, email, ip_address - )) { + ); + + if (created_world_admin_id > 0) { LogInfo( - "Account creation success for user [{0}] encryption algorithm [{1}] ({2})", + "Account creation success for user [{0}] encryption algorithm [{1}] ({2}) new admin id [{3}]", username, GetEncryptionByModeId(mode), - mode + mode, + created_world_admin_id ); return true; } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 09d0431f3..6437cc1ec 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -622,7 +622,7 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings *log_settings) * @param ip_address * @return */ -bool Database::CreateLoginserverWorldAdminAccount( +uint32 Database::CreateLoginserverWorldAdminAccount( const std::string &account_name, const std::string &account_password, const std::string &first_name, @@ -645,7 +645,7 @@ bool Database::CreateLoginserverWorldAdminAccount( auto results = QueryDatabase(query); - return results.Success(); + return (results.Success() ? results.LastInsertedID() : 0); } /** diff --git a/loginserver/database.h b/loginserver/database.h index d9cafca4a..816a008d3 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -221,7 +221,7 @@ public: * @param ip_address * @return */ - bool CreateLoginserverWorldAdminAccount( + uint32 CreateLoginserverWorldAdminAccount( const std::string &account_name, const std::string &account_password, const std::string &first_name, diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 52b1928fc..3337a52e9 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -71,10 +71,10 @@ namespace LoginserverCommandHandler { */ std::map function_map; - function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; function_map["create-loginserver-account"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; function_map["create-loginserver-world-admin-account"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; + function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; std::maploaded_api_tokens.begin(); - it != server.token_manager->loaded_api_tokens.end(); - ++it) { + for (auto &it : server.token_manager->loaded_api_tokens) { LogInfo( "token [{0}] can_write [{1}] can_read [{2}]", - it->second.token, - it->second.can_write, - it->second.can_read + it.second.token, + it.second.can_write, + it.second.can_read ); } } @@ -177,7 +175,10 @@ namespace LoginserverCommandHandler { exit(1); } - AccountManagement::CreateLocalLoginServerAccount(cmd("--username").str(), cmd("--password").str()); + AccountManagement::CreateLocalLoginServerAccount( + cmd("--username").str(), + cmd("--password").str() + ); } /** From 32e8a0fa45e5b73985a47018fb80efb2fd0a4457 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:39:06 -0500 Subject: [PATCH 070/491] Authenticate world admin prior to checking against a world short name [skip ci] --- loginserver/database.cpp | 11 ++++----- loginserver/database.h | 6 ++--- loginserver/world_server.cpp | 45 ++++++++++++++++++++++++++++++++---- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 6437cc1ec..523994148 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -320,14 +320,12 @@ void Database::UpdateLoginHash( /** * @param short_name - * @param remote_ip - * @param local_ip + * @param login_world_server_admin_id * @return */ Database::DbWorldRegistration Database::GetWorldRegistration( const std::string &short_name, - const std::string &remote_ip, - const std::string &local_ip + uint32 login_world_server_admin_id ) { auto query = fmt::format( @@ -342,8 +340,9 @@ Database::DbWorldRegistration Database::GetWorldRegistration( " login_world_servers AS WSR\n" " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.short_name = '{0}' LIMIT 1", - EscapeString(short_name) + " WSR.short_name = '{0}' WSR.login_server_admin_id = {1} AND LIMIT 1", + EscapeString(short_name), + login_world_server_admin_id ); Database::DbWorldRegistration world_registration{}; diff --git a/loginserver/database.h b/loginserver/database.h index 816a008d3..fec7ad797 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -154,14 +154,12 @@ public: * Returns true if the record was found, false otherwise * * @param short_name - * @param remote_ip - * @param local_ip + * @param login_world_server_admin_id * @return */ Database::DbWorldRegistration GetWorldRegistration( const std::string &short_name, - const std::string &remote_ip, - const std::string &local_ip + uint32 login_world_server_admin_id ); /** diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index de5477a02..b13bb17ef 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -505,11 +505,49 @@ void WorldServer::Handle_NewLSInfo(ServerNewLSInfo_Struct *new_world_server_info } } + uint32 world_server_admin_id = 0; + + /** + * If our world is trying to authenticate, let's try and pull the owner first to try associating + * with a world short_name + */ + if (!GetAccountName().empty() && !GetAccountPassword().empty()) { + Database::DbLoginServerAdmin + login_server_admin = server.db->GetLoginServerAdmin(GetAccountName()); + + if (login_server_admin.loaded) { + LogDebug( + "WorldServer::Handle_NewLSInfo | Attempting to authenticate world admin... [{0}] ({1}) against worldserver [{2}]", + GetAccountName(), + login_server_admin.id, + GetServerShortName() + ); + + /** + * Validate password hash + */ + auto mode = server.options.GetEncryptionMode(); + if (eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + login_server_admin.account_password, + mode + )) { + LogDebug( + "WorldServer::Handle_NewLSInfo | Authenticating world admin... [{0}] ({1}) success! World ({2})", + GetAccountName(), + login_server_admin.id, + GetServerShortName() + ); + world_server_admin_id = login_server_admin.id; + } + } + } + Database::DbWorldRegistration world_registration = server.db->GetWorldRegistration( GetServerShortName(), - GetRemoteIp(), - GetLocalIp() + world_server_admin_id ); if (!server.options.IsUnregisteredAllowed()) { @@ -876,10 +914,9 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( } Database::DbLoginServerAdmin login_server_admin = - server.db->GetLoginServerAdmin(GetAccountName()); + server.db->GetLoginServerAdmin(GetAccountName()); uint32 server_admin_id = 0; - if (login_server_admin.loaded) { auto mode = server.options.GetEncryptionMode(); if (eqcrypt_verify_hash( From 9730917d73d418487498c60bc7695cf2c70a1697 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:40:04 -0500 Subject: [PATCH 071/491] Format [skip ci] --- loginserver/world_server.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index b13bb17ef..d8782451a 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -913,8 +913,7 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( return true; } - Database::DbLoginServerAdmin login_server_admin = - server.db->GetLoginServerAdmin(GetAccountName()); + Database::DbLoginServerAdmin login_server_admin = server.db->GetLoginServerAdmin(GetAccountName()); uint32 server_admin_id = 0; if (login_server_admin.loaded) { From 910dfaf08256212cae3deeea52a35ade3ac6cd64 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:41:08 -0500 Subject: [PATCH 072/491] Typo fail [skip ci] --- loginserver/database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 523994148..dc7367049 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -340,7 +340,7 @@ Database::DbWorldRegistration Database::GetWorldRegistration( " login_world_servers AS WSR\n" " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.short_name = '{0}' WSR.login_server_admin_id = {1} AND LIMIT 1", + " WSR.short_name = '{0}' AND WSR.login_server_admin_id = {1} AND LIMIT 1", EscapeString(short_name), login_world_server_admin_id ); From 553d9aca6fe4d11e7dd1af22689ed2fdfbf103e3 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:42:29 -0500 Subject: [PATCH 073/491] Need more coffee apparently [skip ci] --- loginserver/database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginserver/database.cpp b/loginserver/database.cpp index dc7367049..11e884ee1 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -340,7 +340,7 @@ Database::DbWorldRegistration Database::GetWorldRegistration( " login_world_servers AS WSR\n" " JOIN login_server_list_types AS SLT ON WSR.login_server_list_type_id = SLT.id\n" "WHERE\n" - " WSR.short_name = '{0}' AND WSR.login_server_admin_id = {1} AND LIMIT 1", + " WSR.short_name = '{0}' AND WSR.login_server_admin_id = {1} LIMIT 1", EscapeString(short_name), login_world_server_admin_id ); From 5c2ac5ab24b52c36e0e7cdb7940b5415e029231d Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 17:52:04 -0500 Subject: [PATCH 074/491] Validate password hash in WS auth [skip ci] --- loginserver/world_server.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index d8782451a..48bf57d13 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -756,7 +756,12 @@ bool WorldServer::HandleNewLoginserverRegisteredOnly( bool does_world_server_pass_authentication_check = ( world_registration.server_admin_account_name == this->GetAccountName() && - world_registration.server_admin_account_password == this->GetAccountPassword() + eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + world_registration.server_admin_account_password, + server.options.GetEncryptionMode() + ) ); this @@ -842,7 +847,12 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( bool does_world_server_pass_authentication_check = ( world_registration.server_admin_account_name == this->GetAccountName() && - world_registration.server_admin_account_password == this->GetAccountPassword() + eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + world_registration.server_admin_account_password, + server.options.GetEncryptionMode() + ) ); bool does_world_server_have_non_empty_credentials = ( @@ -852,7 +862,6 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( if (does_world_server_have_non_empty_credentials) { if (does_world_server_pass_authentication_check) { - this->SetIsServerAuthorized(true); LogInfo( From 839baba553af986f8ae47f39f7e175b3b8529eee Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 19:27:23 -0500 Subject: [PATCH 075/491] Logging [skip ci] --- world/cliententry.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 599dff322..f8ca1454a 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -293,7 +293,23 @@ bool ClientListEntry::CheckStale() bool ClientListEntry::CheckAuth(uint32 loginserver_account_id, const char *key_password) { + LogDebug( + "ClientListEntry::CheckAuth ls_account_id [{0}] key_password [{1}] plskey [{2}]", + loginserver_account_id, + key_password, + plskey + ); if (pLSID == loginserver_account_id && strncmp(plskey, key_password, 10) == 0) { + + LogDebug( + "ClientListEntry::CheckAuth ls_account_id [{0}] key_password [{1}] plskey [{2}] lsid [{3}] paccountid [{4}]", + loginserver_account_id, + key_password, + plskey, + LSID(), + paccountid + ); + if (paccountid == 0 && LSID() > 0) { int16 default_account_status = WorldConfig::get()->DefaultStatus; From 6e550ecc755e786d7fd9686951c615a1095199ad Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 9 Jul 2019 23:58:47 -0500 Subject: [PATCH 076/491] CLE changes [skip ci] --- world/cliententry.cpp | 48 ++++++++++++++++++++-------- world/cliententry.h | 73 +++++++++++++++++++++++++++++-------------- 2 files changed, 85 insertions(+), 36 deletions(-) diff --git a/world/cliententry.cpp b/world/cliententry.cpp index f8ca1454a..45e281409 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -31,13 +31,23 @@ extern LoginServerList loginserverlist; extern ClientList client_list; extern volatile bool RunLoops; +/** + * @param in_id + * @param in_loginserver_id + * @param in_loginserver_name + * @param in_login_name + * @param in_login_key + * @param in_is_world_admin + * @param ip + * @param local + */ ClientListEntry::ClientListEntry( uint32 in_id, - uint32 iLSID, - const char *iLoginServerName, - const char *iLoginName, - const char *iLoginKey, - int16 iWorldAdmin, + uint32 in_loginserver_id, + const char *in_loginserver_name, + const char *in_login_name, + const char *in_login_key, + int16 in_is_world_admin, uint32 ip, uint8 local ) @@ -45,17 +55,29 @@ ClientListEntry::ClientListEntry( { ClearVars(true); - pIP = ip; - pLSID = iLSID; - if (iLSID > 0) { + LogDebug( + "ClientListEntry in_id [{0}] in_loginserver_id [{1}] in_loginserver_name [{2}] in_login_name [{3}] in_login_key [{4}] " + " in_is_world_admin [{5}] ip [{6}] local [{7}]", + in_id, + in_loginserver_id, + in_loginserver_name, + in_login_name, + in_login_key, + in_is_world_admin, + ip, + local + ); - paccountid = database.GetAccountIDFromLSID(iLoginServerName, iLSID, paccountname, &padmin); + pIP = ip; + pLSID = in_loginserver_id; + if (in_loginserver_id > 0) { + paccountid = database.GetAccountIDFromLSID(in_loginserver_name, in_loginserver_id, paccountname, &padmin); } - strn0cpy(loginserver_account_name, iLoginName, sizeof(loginserver_account_name)); - strn0cpy(plskey, iLoginKey, sizeof(plskey)); - strn0cpy(source_loginserver, iLoginServerName, sizeof(source_loginserver)); - pworldadmin = iWorldAdmin; + strn0cpy(loginserver_account_name, in_login_name, sizeof(loginserver_account_name)); + strn0cpy(plskey, in_login_key, sizeof(plskey)); + strn0cpy(source_loginserver, in_loginserver_name, sizeof(source_loginserver)); + pworldadmin = in_is_world_admin; plocal = (local == 1); pinstance = 0; diff --git a/world/cliententry.h b/world/cliententry.h index 0e03c647f..5c3619e07 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -21,8 +21,35 @@ struct ServerClientList_Struct; class ClientListEntry { public: - ClientListEntry(uint32 id, uint32 iLSID, const char *iLoginServerName, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); - ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline); + + /** + * @param id + * @param in_loginserver_id + * @param in_loginserver_name + * @param in_login_name + * @param in_login_key + * @param in_is_world_admin + * @param ip + * @param local + */ + ClientListEntry( + uint32 id, + uint32 in_loginserver_id, + const char *in_loginserver_name, + const char *in_login_name, + const char *in_login_key, + int16 in_is_world_admin = 0, + uint32 ip = 0, + uint8 local = 0 + ); + + /** + * @param id + * @param iZS + * @param scl + * @param iOnline + */ + ClientListEntry(uint32 id, ZoneServer *iZS, ServerClientList_Struct *scl, int8 iOnline); ~ClientListEntry(); bool CheckStale(); void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, int8 iOnline = CLE_Status_InZone); @@ -91,42 +118,42 @@ private: const uint32 id; uint32 pIP; - int8 pOnline; - uint8 stale; + int8 pOnline{}; + uint8 stale{}; // Login Server stuff - char source_loginserver[64]; //Loginserver we came from. + char source_loginserver[64]{}; //Loginserver we came from. uint32 pLSID; - char loginserver_account_name[32]; - char plskey[16]; + char loginserver_account_name[32]{}; + char plskey[16]{}; int16 pworldadmin; // Login server's suggested admin status setting bool plocal; // Account stuff uint32 paccountid; - char paccountname[32]; + char paccountname[32]{}; MD5 pMD5Pass; - int16 padmin; + int16 padmin{}; // Character info - ZoneServer* pzoneserver; - uint32 pzone; + ZoneServer* pzoneserver{}; + uint32 pzone{}; uint16 pinstance; - uint32 pcharid; - char pname[64]; - uint8 plevel; - uint8 pclass_; - uint16 prace; - uint8 panon; - uint8 ptellsoff; - uint32 pguild_id; - bool pLFG; - uint8 gm; - uint8 pClientVersion; + uint32 pcharid{}; + char pname[64]{}; + uint8 plevel{}; + uint8 pclass_{}; + uint16 prace{}; + uint8 panon{}; + uint8 ptellsoff{}; + uint32 pguild_id{}; + bool pLFG{}; + uint8 gm{}; + uint8 pClientVersion{}; uint8 pLFGFromLevel; uint8 pLFGToLevel; bool pLFGMatchFilter; - char pLFGComments[64]; + char pLFGComments[64]{}; // Tell Queue -- really a vector :D std::vector tell_queue; From 2a927c5c802b248de6e0ee9c3e9699b590f0c6eb Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 10 Jul 2019 00:11:17 -0500 Subject: [PATCH 077/491] Logging / initializers [skip ci] --- common/database.cpp | 30 ++++++++++++++++++------------ common/database.h | 2 +- world/client.cpp | 25 +++++++++++++------------ world/cliententry.cpp | 4 ---- world/cliententry.h | 8 ++++---- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/common/database.cpp b/common/database.cpp index 92627f3bf..bf156d5a9 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -1210,19 +1210,25 @@ bool Database::AddToNameFilter(const char* name) { return true; } +/** + * @param in_loginserver_id + * @param in_loginserver_account_id + * @param in_account_name + * @param in_status + * @return + */ uint32 Database::GetAccountIDFromLSID( - const std::string &iLoginServer, - uint32 iLSID, char *oAccountName, - int16 *oStatus + const std::string &in_loginserver_id, + uint32 in_loginserver_account_id, + char *in_account_name, + int16 *in_status ) { uint32 account_id = 0; - //iLoginServer is set by config so don't need to worry about escaping it. - auto query = fmt::format( "SELECT id, name, status FROM account WHERE lsaccount_id = {0} AND ls_id = '{1}'", - iLSID, - iLoginServer + in_loginserver_account_id, + in_loginserver_id ); auto results = QueryDatabase(query); @@ -1236,13 +1242,13 @@ uint32 Database::GetAccountIDFromLSID( } for (auto row = results.begin(); row != results.end(); ++row) { - account_id = atoi(row[0]); + account_id = std::stoi(row[0]); - if (oAccountName) { - strcpy(oAccountName, row[1]); + if (in_account_name) { + strcpy(in_account_name, row[1]); } - if (oStatus) { - *oStatus = atoi(row[2]); + if (in_status) { + *in_status = std::stoi(row[2]); } } diff --git a/common/database.h b/common/database.h index 510812177..2c1c1205a 100644 --- a/common/database.h +++ b/common/database.h @@ -184,7 +184,7 @@ public: 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& iLoginServer, uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); + 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 acctid); void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); diff --git a/world/client.cpp b/world/client.cpp index ce97c98d9..18e6d3810 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -394,35 +394,36 @@ void Client::SendPostEnterWorld() { safe_delete(outapp); } -bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { +bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) +{ if (app->size != sizeof(LoginInfo_Struct)) { return false; } - - LoginInfo_Struct *li=(LoginInfo_Struct *)app->pBuffer; + + auto *login_info = (LoginInfo_Struct *) app->pBuffer; // Quagmire - max len for name is 18, pass 15 - char name[19] = {0}; + char name[19] = {0}; char password[16] = {0}; - strn0cpy(name, (char*)li->login_info,18); - strn0cpy(password, (char*)&(li->login_info[strlen(name)+1]), 15); + strn0cpy(name, (char *) login_info->login_info, 18); + strn0cpy(password, (char *) &(login_info->login_info[strlen(name) + 1]), 15); + + LogDebug("Receiving Login Info Packet from Client | name [{0}] password [{1}]", name, password); if (strlen(password) <= 1) { Log(Logs::Detail, Logs::World_Server, "Login without a password"); return false; } - is_player_zoning = (li->zoning == 1); - - LogDebug("Receiving Login Info Packet from Client | name [{0}] password [{1}]", name, password); - - uint32 id = atoi(name); + is_player_zoning = (login_info->zoning == 1); + + uint32 id = std::stoi(name); if (id == 0) { LogWarning("Receiving Login Info Packet from Client | account_id is 0 - disconnecting"); return false; } - if (cle = client_list.CheckAuth(id, password)) { + if ((cle = client_list.CheckAuth(id, password))) { if (!is_player_zoning) { // Track who is in and who is out of the game char *inout= (char *) ""; diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 45e281409..2ce17c53e 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -80,10 +80,6 @@ ClientListEntry::ClientListEntry( pworldadmin = in_is_world_admin; plocal = (local == 1); - pinstance = 0; - pLFGFromLevel = 0; - pLFGToLevel = 0; - pLFGMatchFilter = false; memset(pLFGComments, 0, 64); } diff --git a/world/cliententry.h b/world/cliententry.h index 5c3619e07..30ba002d5 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -138,7 +138,7 @@ private: // Character info ZoneServer* pzoneserver{}; uint32 pzone{}; - uint16 pinstance; + uint16 pinstance{}; uint32 pcharid{}; char pname[64]{}; uint8 plevel{}; @@ -150,9 +150,9 @@ private: bool pLFG{}; uint8 gm{}; uint8 pClientVersion{}; - uint8 pLFGFromLevel; - uint8 pLFGToLevel; - bool pLFGMatchFilter; + uint8 pLFGFromLevel{}; + uint8 pLFGToLevel{}; + bool pLFGMatchFilter{}; char pLFGComments[64]{}; // Tell Queue -- really a vector :D From 7b808ee6e0d60f762659489cc3592c6e780e23b4 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 10 Jul 2019 00:45:40 -0500 Subject: [PATCH 078/491] Add more debug logging for ServerListPacket [skip ci] --- loginserver/server_manager.cpp | 25 ++++++++++++++++++++++++- world/client.cpp | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index 797b1138f..e2d7ff089 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -142,13 +142,36 @@ EQApplicationPacket *ServerManager::CreateServerListPacket(Client *client, uint3 std::string world_ip = (*iter)->GetConnection()->Handle()->RemoteIP(); if (world_ip == client_ip) { packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24; + + LogDebug( + "CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Local)", + client->GetAccountName(), + client_ip, + (*iter)->GetServerLongName(), + (*iter)->GetLocalIP() + ); } else if (IpUtil::IsIpInPrivateRfc1918(client_ip)) { - LogInfo("Client is requesting server list from a local address [{0}]", client_ip); packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetLocalIP().size() + 24; + + LogDebug( + "CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Local)", + client->GetAccountName(), + client_ip, + (*iter)->GetServerLongName(), + (*iter)->GetLocalIP() + ); } else { packet_size += (*iter)->GetServerLongName().size() + (*iter)->GetRemoteIP().size() + 24; + + LogDebug( + "CreateServerListPacket | Building list entry | Client [{0}] IP [{1}] Server Long Name [{2}] Server IP [{3}] (Remote)", + client->GetAccountName(), + client_ip, + (*iter)->GetServerLongName(), + (*iter)->GetRemoteIP() + ); } server_count++; diff --git a/world/client.cpp b/world/client.cpp index 18e6d3810..53ea40036 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -416,7 +416,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) } is_player_zoning = (login_info->zoning == 1); - + uint32 id = std::stoi(name); if (id == 0) { LogWarning("Receiving Login Info Packet from Client | account_id is 0 - disconnecting"); From 949e7adff8893c7fd4945c2d6f8ff820d6b87dc6 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 11 Jul 2019 01:23:55 -0500 Subject: [PATCH 079/491] init vars [skip ci] --- loginserver/main.cpp | 2 +- zone/mob.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/loginserver/main.cpp b/loginserver/main.cpp index ab5ad699e..76a4390cf 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -61,7 +61,7 @@ int main(int argc, char** argv) server.options.DumpOutPackets(server.config.GetVariableBool("general", "dump_packets_out", false)); server.options.RejectDuplicateServers(server.config.GetVariableBool("general", "reject_duplicate_servers", false)); server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); - server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", true)); + server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", false)); #ifdef LSPX server.options.EQEmuLoginServerAddress( diff --git a/zone/mob.h b/zone/mob.h index ea71017c7..71c58ec6e 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1467,8 +1467,8 @@ protected: eStandingPetOrder pStandingPetOrder; uint32 minLastFightingDelayMoving; uint32 maxLastFightingDelayMoving; - float pAggroRange; - float pAssistRange; + float pAggroRange = 0; + float pAssistRange = 0; std::unique_ptr AI_think_timer; std::unique_ptr AI_movement_timer; std::unique_ptr AI_target_check_timer; From ce09aad28a9838d867d8a5e0b29c0332ede8c3dc Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 14 Jul 2019 22:16:26 -0500 Subject: [PATCH 080/491] Move rest of logging to FMT and move config options into more finite categories --- common/eqemu_logsys.cpp | 2 + loginserver/client.cpp | 26 +++++----- loginserver/client_manager.cpp | 25 +++++---- loginserver/database.cpp | 2 +- loginserver/main.cpp | 51 +++++++++++-------- loginserver/server_manager.cpp | 8 +-- loginserver/world_server.cpp | 93 ++++++++++++++++++---------------- 7 files changed, 115 insertions(+), 92 deletions(-) diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 3389342b9..36246ae32 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -317,6 +317,8 @@ std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) case Logs::Normal: return LC_YELLOW; case Logs::MySQLError: + case Logs::Warning: + case Logs::Critical: case Logs::Error: return LC_RED; case Logs::MySQLQuery: diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 64c429a96..5e82dea74 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -46,7 +46,7 @@ bool Client::Process() EQApplicationPacket *app = connection->PopPacket(); while (app) { if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "Application packet received from client (size %u)", app->Size()); + LogDebug("Application packet received from client (size {0})", app->Size()); } if (server.options.IsDumpInPacketsOn()) { @@ -62,19 +62,19 @@ bool Client::Process() switch (app->GetOpcode()) { case OP_SessionReady: { if (server.options.IsTraceOn()) { - LogInfo("Session ready received from client."); + LogInfo("Session ready received from client"); } Handle_SessionReady((const char *) app->pBuffer, app->Size()); break; } case OP_Login: { if (app->Size() < 20) { - LogError("Login received but it is too small, discarding."); + LogError("Login received but it is too small, discarding"); break; } if (server.options.IsTraceOn()) { - LogInfo("Login received from client."); + LogInfo("Login received from client"); } Handle_Login((const char *) app->pBuffer, app->Size()); @@ -82,12 +82,12 @@ bool Client::Process() } case OP_ServerListRequest: { if (app->Size() < 4) { - LogError("Server List Request received but it is too small, discarding."); + LogError("Server List Request received but it is too small, discarding"); break; } if (server.options.IsTraceOn()) { - LogDebug("Server list request received from client."); + LogDebug("Server list request received from client"); } SendServerListPacket(*(uint32_t *) app->pBuffer); @@ -95,7 +95,7 @@ bool Client::Process() } case OP_PlayEverquestRequest: { if (app->Size() < sizeof(PlayEverquestRequest_Struct)) { - LogError("Play received but it is too small, discarding."); + LogError("Play received but it is too small, discarding"); break; } @@ -127,12 +127,12 @@ bool Client::Process() void Client::Handle_SessionReady(const char *data, unsigned int size) { if (status != cs_not_sent_session_ready) { - LogError("Session ready received again after already being received."); + LogError("Session ready received again after already being received"); return; } if (size < sizeof(unsigned int)) { - LogError("Session ready was too small."); + LogError("Session ready was too small"); return; } @@ -210,7 +210,7 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string outbuffer; outbuffer.resize(size - 12); if (outbuffer.length() == 0) { - LogError("Corrupt buffer sent to server, no length."); + LogError("Corrupt buffer sent to server, no length"); return; } @@ -224,7 +224,7 @@ void Client::Handle_Login(const char *data, unsigned int size) std::string user(&outbuffer[0]); if (user.length() >= outbuffer.length()) { - LogError("Corrupt buffer sent to server, preventing buffer overflow."); + LogError("Corrupt buffer sent to server, preventing buffer overflow"); return; } @@ -306,7 +306,7 @@ void Client::Handle_Login(const char *data, unsigned int size) void Client::Handle_Play(const char *data) { if (status != cs_logged_in) { - LogError("Client sent a play request when they were not logged in, discarding."); + LogError("Client sent a play request when they were not logged in, discarding"); return; } @@ -347,7 +347,7 @@ void Client::SendServerListPacket(uint32 seq) void Client::SendPlayResponse(EQApplicationPacket *outapp) { if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "Sending play response for %s.", GetAccountName().c_str()); + LogDebug("Sending play response for {0}", GetAccountName()); // server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size); } connection->QueuePacket(outapp); diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 0967f2a63..d37ec545f 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -28,7 +28,7 @@ extern bool run_server; ClientManager::ClientManager() { - int titanium_port = server.config.GetVariableInt("Titanium", "port", 5998); + int titanium_port = server.config.GetVariableInt("client_configuration", "titanium_port", 5998); EQStreamManagerInterfaceOptions titanium_opts(titanium_port, false, false); @@ -36,14 +36,14 @@ ClientManager::ClientManager() titanium_ops = new RegularOpcodeManager; if (!titanium_ops->LoadOpcodes( server.config.GetVariableString( - "Titanium", - "opcodes", + "client_configuration", + "titanium_opcodes", "login_opcodes.conf" ).c_str())) { LogError( "ClientManager fatal error: couldn't load opcodes for Titanium file [{0}]", - server.config.GetVariableString("Titanium", "opcodes", "login_opcodes.conf") + server.config.GetVariableString("client_configuration", "titanium_opcodes", "login_opcodes.conf") ); run_server = false; @@ -63,15 +63,22 @@ ClientManager::ClientManager() } ); - int sod_port = server.config.GetVariableInt("SoD", "port", 5999); + int sod_port = server.config.GetVariableInt("client_configuration", "sod_port", 5999); EQStreamManagerInterfaceOptions sod_opts(sod_port, false, false); sod_stream = new EQ::Net::EQStreamManager(sod_opts); sod_ops = new RegularOpcodeManager; - if (!sod_ops->LoadOpcodes(server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str())) { + if ( + !sod_ops->LoadOpcodes( + server.config.GetVariableString( + "client_configuration", + "sod_opcodes", + "login_opcodes.conf" + ).c_str() + )) { LogError( "ClientManager fatal error: couldn't load opcodes for SoD file {0}", - server.config.GetVariableString("SoD", "opcodes", "login_opcodes.conf").c_str() + server.config.GetVariableString("client_configuration", "sod_opcodes", "login_opcodes.conf").c_str() ); run_server = false; @@ -118,7 +125,7 @@ void ClientManager::Process() auto iter = clients.begin(); while (iter != clients.end()) { if ((*iter)->Process() == false) { - Log(Logs::General, Logs::Debug, "Client had a fatal error and had to be removed from the login."); + LogWarning("Client had a fatal error and had to be removed from the login"); delete (*iter); iter = clients.erase(iter); } @@ -134,7 +141,7 @@ void ClientManager::ProcessDisconnect() while (iter != clients.end()) { std::shared_ptr c = (*iter)->GetConnection(); if (c->CheckState(CLOSED)) { - LogInfo("Client disconnected from the server, removing client."); + LogInfo("Client disconnected from the server, removing client"); delete (*iter); iter = clients.erase(iter); } diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 11e884ee1..ce1de51ce 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -62,7 +62,7 @@ Database::Database( errbuf ) ) { - Log(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); + LogError("Failed to connect to database: Error: [{0}]", errbuf); exit(1); } else { diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 76a4390cf..2a3db762c 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -55,13 +55,25 @@ int main(int argc, char** argv) server.config = EQ::JsonConfigFile::Load("login.json"); LogInfo("Config System Init"); - server.options.Trace(server.config.GetVariableBool("general", "trace", false)); - server.options.WorldTrace(server.config.GetVariableBool("general", "world_trace", false)); - server.options.DumpInPackets(server.config.GetVariableBool("general", "dump_packets_in", false)); - server.options.DumpOutPackets(server.config.GetVariableBool("general", "dump_packets_out", false)); - server.options.RejectDuplicateServers(server.config.GetVariableBool("general", "reject_duplicate_servers", false)); - server.options.AutoCreateAccounts(server.config.GetVariableBool("general", "auto_create_accounts", true)); - server.options.AutoLinkAccounts(server.config.GetVariableBool("general", "auto_link_accounts", false)); + /** + * options: logging + */ + server.options.Trace(server.config.GetVariableBool("logging", "trace", false)); + server.options.WorldTrace(server.config.GetVariableBool("logging", "world_trace", false)); + server.options.DumpInPackets(server.config.GetVariableBool("logging", "dump_packets_in", false)); + server.options.DumpOutPackets(server.config.GetVariableBool("logging", "dump_packets_out", false)); + + /** + * options: worldservers + */ + server.options.RejectDuplicateServers(server.config.GetVariableBool("worldservers", "reject_duplicate_servers", false)); + server.options.AllowUnregistered(server.config.GetVariableBool("worldservers", "unregistered_allowed", true)); + + /** + * options: account + */ + server.options.AutoCreateAccounts(server.config.GetVariableBool("account", "auto_create_accounts", true)); + server.options.AutoLinkAccounts(server.config.GetVariableBool("account", "auto_link_accounts", false)); #ifdef LSPX server.options.EQEmuLoginServerAddress( @@ -88,7 +100,6 @@ int main(int argc, char** argv) server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 6)); #endif - server.options.AllowUnregistered(server.config.GetVariableBool("security", "unregistered_allowed", true)); server.options.AllowTokenLogin(server.config.GetVariableBool("security", "allow_token_login", false)); server.options.AllowPasswordLogin(server.config.GetVariableBool("security", "allow_password_login", true)); server.options.UpdateInsecurePasswords( @@ -177,18 +188,18 @@ int main(int argc, char** argv) LoginserverCommandHandler::CommandHandler(argc, argv); - LogInfo("[Config] IsTraceOn [{0}]", server.options.IsTraceOn()); - LogInfo("[Config] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn()); - LogInfo("[Config] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn()); - LogInfo("[Config] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn()); - LogInfo("[Config] IsRejectingDuplicateServers [{0}]", server.options.IsRejectingDuplicateServers()); - LogInfo("[Config] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts()); - LogInfo("[Config] CanAutoLinkAccounts [{0}]", server.options.CanAutoLinkAccounts()); - LogInfo("[Config] GetEncryptionMode [{0}]", server.options.GetEncryptionMode()); - LogInfo("[Config] IsUnregisteredAllowed [{0}]", server.options.IsUnregisteredAllowed()); - LogInfo("[Config] IsTokenLoginAllowed [{0}]", server.options.IsTokenLoginAllowed()); - LogInfo("[Config] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed()); - LogInfo("[Config] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords()); + LogInfo("[Config] [Logging] IsTraceOn [{0}]", server.options.IsTraceOn()); + LogInfo("[Config] [Logging] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn()); + LogInfo("[Config] [Logging] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn()); + LogInfo("[Config] [Logging] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn()); + LogInfo("[Config] [Account] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts()); + LogInfo("[Config] [Account] CanAutoLinkAccounts [{0}]", server.options.CanAutoLinkAccounts()); + LogInfo("[Config] [WorldServer] IsRejectingDuplicateServers [{0}]", server.options.IsRejectingDuplicateServers()); + LogInfo("[Config] [WorldServer] IsUnregisteredAllowed [{0}]", server.options.IsUnregisteredAllowed()); + LogInfo("[Config] [Security] GetEncryptionMode [{0}]", server.options.GetEncryptionMode()); + LogInfo("[Config] [Security] IsTokenLoginAllowed [{0}]", server.options.IsTokenLoginAllowed()); + LogInfo("[Config] [Security] IsPasswordLoginAllowed [{0}]", server.options.IsPasswordLoginAllowed()); + LogInfo("[Config] [Security] IsUpdatingInsecurePasswords [{0}]", server.options.IsUpdatingInsecurePasswords()); while (run_server) { Timer::SetCurrentTime(); diff --git a/loginserver/server_manager.cpp b/loginserver/server_manager.cpp index e2d7ff089..3bc001a69 100644 --- a/loginserver/server_manager.cpp +++ b/loginserver/server_manager.cpp @@ -77,10 +77,10 @@ ServerManager::ServerManager() auto iter = world_servers.begin(); while (iter != world_servers.end()) { if ((*iter)->GetConnection()->GetUUID() == c->GetUUID()) { - LogF(Logs::General, - Logs::World_Server, - "World server {0} has been disconnected, removing.", - (*iter)->GetServerLongName().c_str()); + LogInfo( + "World server {0} has been disconnected, removing.", + (*iter)->GetServerLongName() + ); world_servers.erase(iter); return; } diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 48bf57d13..049804943 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -95,11 +95,11 @@ void WorldServer::Reset() void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Application packet received from server: 0x%.4X, (size %u)", + LogDebug( + "Application packet received from server: {0}, (size {1})", opcode, - packet.Length()); + packet.Length() + ); } if (server.options.IsDumpInPacketsOn()) { @@ -189,11 +189,11 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Application packet received from server: 0x%.4X, (size %u)", + LogDebug( + "Application packet received from server: {0}, (size {1})", opcode, - packet.Length()); + packet.Length() + ); } if (server.options.IsDumpInPacketsOn()) { @@ -213,7 +213,7 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "User-To-World Response received"); + LogDebug("User-To-World Response received"); } auto *user_to_world_response = (UsertoWorldResponseLegacy_Struct *) packet.Data(); @@ -266,16 +266,17 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne break; } - LogF(Logs::General, - Logs::Netcode, - "Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]", - per->Allowed, - per->Sequence, - per->ServerNumber, - per->Message - ); + if (server.options.IsWorldTraceOn()) { + LogDebug( + "Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]", + per->Allowed, + per->Sequence, + per->ServerNumber, + per->Message + ); - Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + LogDebug("[Size: {0}] {1}", outapp->size, DumpPacketToString(outapp)); + } if (server.options.IsDumpOutPacketsOn()) { DumpPacket(outapp); @@ -299,11 +300,11 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { - Log(Logs::General, - Logs::Netcode, + LogDebug( "Application packet received from server: 0x%.4X, (size %u)", opcode, - packet.Length()); + packet.Length() + ); } if (server.options.IsDumpInPacketsOn()) { @@ -323,7 +324,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac //Because this is a part of the client login procedure it makes tracking client errors //While keeping world server spam with multiple servers connected almost impossible. if (server.options.IsTraceOn()) { - Log(Logs::General, Logs::Netcode, "User-To-World Response received"); + LogDebug("User-To-World Response received"); } auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data(); @@ -355,7 +356,7 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac client->GetPlayServerID() ); - Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + LogDebug("[Size: {0}] {1}", outapp->size, DumpPacketToString(outapp)); if (user_to_world_response->response > 0) { per->Allowed = 1; @@ -387,14 +388,14 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac } if (server.options.IsTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Sending play response with following data, allowed %u, sequence %u, server number %u, message %u", + LogDebug( + "Sending play response with following data, allowed {0}, sequence {1}, server number {2}, message {3}", per->Allowed, per->Sequence, per->ServerNumber, - per->Message); - Log(Logs::General, Logs::Netcode, "[Size: %u] %s", outapp->size, DumpPacketToString(outapp).c_str()); + per->Message + ); + LogDebug("[Size: {0}] {1}", outapp->size, DumpPacketToString(outapp)); } if (server.options.IsDumpOutPacketsOn()) { @@ -419,11 +420,11 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet) { if (server.options.IsWorldTraceOn()) { - Log(Logs::General, - Logs::Netcode, - "Application packet received from server: 0x%.4X, (size %u)", + LogDebug( + "Application packet received from server: {0}, (size {1})", opcode, - packet.Length()); + packet.Length() + ); } if (server.options.IsDumpInPacketsOn()) { @@ -439,7 +440,9 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet return; } - Log(Logs::General, Logs::Netcode, "ServerOP_LSAccountUpdate packet received from: %s", short_name.c_str()); + if (server.options.IsWorldTraceOn()) { + LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", short_name); + } auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data(); if (IsServerTrusted()) { @@ -756,12 +759,12 @@ bool WorldServer::HandleNewLoginserverRegisteredOnly( bool does_world_server_pass_authentication_check = ( world_registration.server_admin_account_name == this->GetAccountName() && - eqcrypt_verify_hash( - GetAccountName(), - GetAccountPassword(), - world_registration.server_admin_account_password, - server.options.GetEncryptionMode() - ) + eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + world_registration.server_admin_account_password, + server.options.GetEncryptionMode() + ) ); this @@ -847,12 +850,12 @@ bool WorldServer::HandleNewLoginserverInfoUnregisteredAllowed( bool does_world_server_pass_authentication_check = ( world_registration.server_admin_account_name == this->GetAccountName() && - eqcrypt_verify_hash( - GetAccountName(), - GetAccountPassword(), - world_registration.server_admin_account_password, - server.options.GetEncryptionMode() - ) + eqcrypt_verify_hash( + GetAccountName(), + GetAccountPassword(), + world_registration.server_admin_account_password, + server.options.GetEncryptionMode() + ) ); bool does_world_server_have_non_empty_credentials = ( From 6d9bcfe39fb7195f62353a3d9f06a953dbd0deac Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 14 Jul 2019 22:16:50 -0500 Subject: [PATCH 081/491] Remove old login.ini --- loginserver/login_util/login.ini | 35 -------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 loginserver/login_util/login.ini diff --git a/loginserver/login_util/login.ini b/loginserver/login_util/login.ini deleted file mode 100644 index bde7616f1..000000000 --- a/loginserver/login_util/login.ini +++ /dev/null @@ -1,35 +0,0 @@ -[database] -host = localhost -port = 3306 -db = eqemu -user = user -password = password -subsystem = MySQL - -[options] -unregistered_allowed = TRUE -reject_duplicate_servers = FALSE -trace = TRUE -world_trace = FALSE -dump_packets_in = FALSE -dump_packets_out = FALSE -listen_port = 5998 -local_network = 192.168.1. - -[security] -plugin = EQEmuAuthCrypto -mode = 5 - -[Titanium] -port = 5998 -opcodes = login_opcodes.conf - -[SoD] -port = 5999 -opcodes = login_opcodes_sod.conf - -[schema] -account_table = tblLoginServerAccounts -world_registration_table = tblWorldServerRegistration -world_admin_registration_table = tblServerAdminRegistration -world_server_type_table = tblServerListType \ No newline at end of file From 25c119b8439418fd616c8c2eda38e86affa6305a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 14 Jul 2019 22:23:51 -0500 Subject: [PATCH 082/491] Add new default login.json --- loginserver/login_util/login.json | 39 +++++++++++++++++++++++++++++++ loginserver/main.cpp | 2 ++ loginserver/world_server.cpp | 16 +++++++------ 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 loginserver/login_util/login.json diff --git a/loginserver/login_util/login.json b/loginserver/login_util/login.json new file mode 100644 index 000000000..f6c81ffcc --- /dev/null +++ b/loginserver/login_util/login.json @@ -0,0 +1,39 @@ +{ + "database": { + "host": "mariadb", // database host + "port": "3306", // database port + "db": "peq", // database name + "user": "eqemu", // database user + "password": "eqemu" // database password + }, + "account": { + // ideal for local LAN setups, if you want a login attempt to automatically create an account + // this will automatically create the account using the username and password if it doesn't exist + "auto_create_accounts": true + }, + "worldservers": { + "unregistered_allowed": true, // allows worldservers to connect to your loginserver without server admin authentication + "reject_duplicate_servers": false // if enabled, rejects duplicate worldservers + }, + "web_api": { + "enabled": true, // enable/disable embedded webserver api + "port": 6000 // the port you want the web api to serve on (recommended not to change) + }, + "security": { + "mode": 14, // encryption mode (dont touch) (14=scrypt) + "allow_password_login": true, // allows users to login via password, most cases, leave this on + "allow_token_login": true // allows token based login directly from launching game + }, + "logging": { + "trace": false, // For debugging general packet messaging + "world_trace": false, // For debugging world to loginserver messaging + "dump_packets_in": false, // for debugging inbound packets + "dump_packets_out": false // for debugging outbound packets + }, + "client_configuration": { + "titanium_port": 5998, // don't change + "titanium_opcodes": "login_opcodes.conf", // opcodes for the titanium era clients + "sod_port": 5999, // don't change + "sod_opcodes": "login_opcodes_sod.conf" // opcodes for sod and higher era clients + } +} \ No newline at end of file diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 2a3db762c..f94bdd0c7 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -193,7 +193,9 @@ int main(int argc, char** argv) LogInfo("[Config] [Logging] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn()); LogInfo("[Config] [Logging] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn()); LogInfo("[Config] [Account] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts()); +#ifdef LSPX LogInfo("[Config] [Account] CanAutoLinkAccounts [{0}]", server.options.CanAutoLinkAccounts()); +#endif LogInfo("[Config] [WorldServer] IsRejectingDuplicateServers [{0}]", server.options.IsRejectingDuplicateServers()); LogInfo("[Config] [WorldServer] IsUnregisteredAllowed [{0}]", server.options.IsUnregisteredAllowed()); LogInfo("[Config] [Security] GetEncryptionMode [{0}]", server.options.GetEncryptionMode()); diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 049804943..4f880d506 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -171,13 +171,15 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet auto *ls_status = (ServerLSStatus_Struct *) packet.Data(); - LogDebug( - "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", - this->GetServerLongName(), - ls_status->status, - ls_status->num_players, - ls_status->num_zones - ); + if (server.options.IsWorldTraceOn()) { + LogDebug( + "World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]", + this->GetServerLongName(), + ls_status->status, + ls_status->num_players, + ls_status->num_zones + ); + } Handle_LSStatus(ls_status); } From f6259af22b10a661c81c86f20907dc21c48f4692 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 14 Jul 2019 22:26:12 -0500 Subject: [PATCH 083/491] Add login schema conversion script --- .../login_old_to_new_schema_convert.sql | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 loginserver/login_util/login_old_to_new_schema_convert.sql diff --git a/loginserver/login_util/login_old_to_new_schema_convert.sql b/loginserver/login_util/login_old_to_new_schema_convert.sql new file mode 100644 index 000000000..c3daa627e --- /dev/null +++ b/loginserver/login_util/login_old_to_new_schema_convert.sql @@ -0,0 +1,82 @@ +-- Because the old / legacy schema was mostly inconsistent with naming and overall data structure, we have +-- migrated to a schema that follows our modern conventions and meanwhile fixes quite a few bugs that +-- were present as well + +-- Login Accounts + +INSERT INTO + login_accounts ( + id, + account_name, + account_password, + account_email, + source_loginserver, + last_ip_address, + last_login_date, + created_at + ) +SELECT + LoginServerID, + AccountName, + AccountPassword, + AccountEmail, + 'local', + LastIPAddress, + LastLoginDate, + AccountCreateDate +FROM + tblLoginServerAccounts; + +-- Server Admins + +INSERT INTO + login_server_admins ( + id, + account_name, + account_password, + first_name, + last_name, + email, + registration_date, + registration_ip_address + ) +SELECT + ServerAdminID, + AccountName, + AccountPassword, + FirstName, + LastName, + Email, + RegistrationDate, + RegistrationIPAddr +FROM + tblServerAdminRegistration; + +-- World Servers + +INSERT INTO + login_world_servers ( + id, + long_name, + short_name, + tag_description, + login_server_list_type_id, + last_login_date, + last_ip_address, + login_server_admin_id, + is_server_trusted, + note + ) +SELECT + `ServerID`, + `ServerLongName`, + `ServerShortName`, + `ServerTagDescription`, + `ServerListTypeID`, + `ServerLastLoginDate`, + `ServerLastIPAddr`, + `ServerAdminID`, + `ServerTrusted`, + `Note` +FROM + tblWorldServerRegistration; \ No newline at end of file From e92d1305381fdfd3800b5b3625d85833ed0c9a42 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 15 Jul 2019 02:21:19 -0500 Subject: [PATCH 084/491] Adust ProcessUsertoWorldReq reponse codes --- loginserver/loginserver_webserver.cpp | 10 ++--- world/login_server.cpp | 63 ++++++++++++++++----------- zone/client_process.cpp | 5 +-- 3 files changed, 45 insertions(+), 33 deletions(-) diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 732ce4ff7..ca8d00404 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -64,9 +64,9 @@ namespace LoginserverWebserver { api.Post( "/account/create", [](const httplib::Request &request, httplib::Response &res) { LoginserverWebserver::TokenManager::AuthCanWrite(request, res); - Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); - std::string username = request_body.get("username", "").asString(); - std::string password = request_body.get("password", "").asString(); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); Json::Value response; if (username.empty() || password.empty()) { @@ -137,7 +137,7 @@ namespace LoginserverWebserver { user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); if (!user_token.can_read) { - Json::Value response; + Json::Value response; std::stringstream response_payload; response["message"] = "Authorization token is either invalid or cannot read!"; response_payload << response; @@ -165,7 +165,7 @@ namespace LoginserverWebserver { user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); if (!user_token.can_write) { - Json::Value response; + Json::Value response; std::stringstream response_payload; response["message"] = "Authorization token is either invalid or cannot write!"; response_payload << response; diff --git a/world/login_server.cpp b/world/login_server.cpp index dc7d3d5d9..235fbc746 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -70,7 +70,7 @@ void LoginServer::ProcessUsertoWorldReqLeg(uint16_t opcode, EQ::Net::Packet &p) ServerPacket outpack; outpack.opcode = ServerOP_UsertoWorldResp; - outpack.size = sizeof(UsertoWorldResponse_Struct); + outpack.size = sizeof(UsertoWorldResponseLegacy_Struct); outpack.pBuffer = new uchar[outpack.size]; memset(outpack.pBuffer, 0, outpack.size); @@ -132,46 +132,59 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) uint32 id = database.GetAccountIDFromLSID(utwr->login, utwr->lsaccountid); int16 status = database.CheckStatus(id); - auto outpack = new ServerPacket; - outpack->opcode = ServerOP_UsertoWorldResp; - outpack->size = sizeof(UsertoWorldResponse_Struct); - outpack->pBuffer = new uchar[outpack->size]; - memset(outpack->pBuffer, 0, outpack->size); + ServerPacket outpack; + outpack.opcode = ServerOP_UsertoWorldResp; + outpack.size = sizeof(UsertoWorldResponse_Struct); + outpack.pBuffer = new uchar[outpack.size]; + memset(outpack.pBuffer, 0, outpack.size); - UsertoWorldResponse_Struct *utwrs = (UsertoWorldResponse_Struct *) outpack->pBuffer; + UsertoWorldResponse_Struct *utwrs = (UsertoWorldResponse_Struct *) outpack.pBuffer; utwrs->lsaccountid = utwr->lsaccountid; utwrs->ToID = utwr->FromID; strn0cpy(utwrs->login, utwr->login, 64); - utwrs->worldid = utwr->worldid; - utwrs->response = UserToWorldStatusSuccess; + utwrs->worldid = utwr->worldid; + utwrs->response = UserToWorldStatusSuccess; if (Config->Locked == true) { - if ((status == 0 || status < 100) && (status != -2 || status != -1)) { - utwrs->response = 0; + if (status < 100) { + utwrs->response = UserToWorldStatusWorldUnavail; + SendPacket(&outpack); + return; } - if (status >= 100) { - utwrs->response = 1; - } - } - else { - utwrs->response = 1; } int32 x = Config->MaxClients; if ((int32) numplayers >= x && x != -1 && x != 255 && status < 80) { - utwrs->response = -3; + utwrs->response = UserToWorldStatusWorldAtCapacity; + SendPacket(&outpack); + return; } if (status == -1) { - utwrs->response = -1; - } - if (status == -2) { - utwrs->response = -2; + utwrs->response = UserToWorldStatusSuspended; + SendPacket(&outpack); + return; } - utwrs->worldid = utwr->worldid; - SendPacket(outpack); - delete outpack; + if (status == -2) { + utwrs->response = UserToWorldStatusBanned; + SendPacket(&outpack); + return; + } + + if (RuleB(World, DisallowDuplicateAccountLogins)) { + auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); + if (cle != nullptr) { + auto status = cle->GetOnline(); + if (CLE_Status_Never != status && CLE_Status_Offline != status) { + utwrs->response = UserToWorldStatusAlreadyOnline; + SendPacket(&outpack); + return; + } + } + } + + SendPacket(&outpack); } void LoginServer::ProcessLSClientAuthLegacy(uint16_t opcode, EQ::Net::Packet &p) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 5c750f03a..493864fea 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -560,9 +560,8 @@ bool Client::Process() { OnDisconnect(true); Log(Logs::General, Logs::Zone_Server, "Client linkdead: %s", name); - if (GetGM()) { - if (GetMerc()) - { + if (Admin() > 100) { + if (GetMerc()) { GetMerc()->Save(); GetMerc()->Depop(); } From 9fe17f4d464d6c2cd49e57e1fc90eb65bbcafd8d Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Thu, 18 Jul 2019 00:56:46 -0400 Subject: [PATCH 085/491] Fix issues with OP_SpecialMesg handling This should prevent any optimizations being done on the "1 char string" This also fully documents the packet and expands the uses of quest::say/QuestSay --- common/base_packet.h | 1 + common/eq_constants.h | 1 + common/eq_packet_structs.h | 14 ++++++ common/patches/rof.cpp | 50 +++++++++----------- common/patches/rof2.cpp | 50 +++++++++----------- common/patches/sod.cpp | 50 +++++++++----------- common/patches/sof.cpp | 50 +++++++++----------- common/patches/titanium.cpp | 50 +++++++++----------- common/patches/uf.cpp | 50 +++++++++----------- zone/client.cpp | 92 ++++++++++--------------------------- zone/client.h | 1 - zone/common.h | 25 ++++++++++ zone/embparser_api.cpp | 31 ++++++++++--- zone/entity.cpp | 34 +++++++------- zone/entity.h | 3 +- zone/lua_general.cpp | 26 +++++++++++ zone/lua_general.h | 2 + zone/lua_mob.cpp | 63 ++++++++++++++++++++++++- zone/lua_mob.h | 1 + zone/lua_parser.cpp | 4 +- zone/mob.cpp | 8 +++- zone/mob.h | 2 +- zone/questmgr.cpp | 23 +++------- zone/questmgr.h | 3 +- 24 files changed, 343 insertions(+), 291 deletions(-) diff --git a/common/base_packet.h b/common/base_packet.h index 4f47c919a..3b92e3e90 100644 --- a/common/base_packet.h +++ b/common/base_packet.h @@ -75,6 +75,7 @@ public: uint32 ReadUInt32() { uint32 value = *(uint32 *)(pBuffer + _rpos); _rpos += sizeof(uint32); return value; } uint32 ReadUInt32(uint32 Offset) const { uint32 value = *(uint32 *)(pBuffer + Offset); return value; } void ReadString(char *str) { uint32 len = static_cast(strlen((char *)(pBuffer + _rpos))) + 1; memcpy(str, pBuffer + _rpos, len); _rpos += len; } + void ReadString(std::string &str) { str = reinterpret_cast(pBuffer + _rpos); _rpos += str.length() + 1; } void ReadString(char *str, uint32 Offset, uint32 MaxLength) const; uint32 GetWritePosition() { return _wpos; } diff --git a/common/eq_constants.h b/common/eq_constants.h index faa0ab247..657db450e 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -87,6 +87,7 @@ typedef enum { _eaMaxAppearance } EmuAppearance; +#define MT_NPCQuestSay 10 // msg_type's for custom usercolors #define MT_Say 256 #define MT_Tell 257 diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index c80fdcc02..fb9260857 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -1188,6 +1188,20 @@ struct SpecialMesg_Struct /*24*/ char message[1]; // What is being said? }; +struct SpecialMesgHeader_Struct +{ +/*00*/ char SpeakMode; // 2 shouts, 4 %1 %2, 3 %2, 5 tells group, 0 copy, default says +/*01*/ char JournalMode; // 1 and 2 go to journal +/*02*/ char language; +/*03*/ uint32 msg_type; // Color of text (see MT_*** below) +/*07*/ uint32 target_spawn_id; // Who is it being said to? +/*11*/ // speaker's name +/*xx*/ // unknown, location, client doesn't care +/*xx*/ // unknown +/*xx*/ // unknown +/*xx*/ // message +}; + /* ** When somebody changes what they're wearing or give a pet a weapon (model changes) ** Length: 19 Bytes diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index d7fa21c41..322e187e4 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -3199,43 +3199,35 @@ namespace RoF EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); // NPC names max out at 63 chars - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToRoFSayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_Stun) diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 66e699e2a..a6cf7a134 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -3266,43 +3266,35 @@ namespace RoF2 EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); // NPC names max out at 63 chars - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToRoF2SayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_Stun) diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 2c9d70edf..11aae5cc9 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -2069,43 +2069,35 @@ namespace SoD EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); // NPC names max out at 63 chars - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToSoDSayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_Stun) diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 0b3043c70..7569b4c5d 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -1720,43 +1720,35 @@ namespace SoF EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToSoFSayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_Stun) diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index c4bef5bea..d8a115a98 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -1420,43 +1420,35 @@ namespace Titanium EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); // NPC names max out at 63 chars - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToTitaniumSayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_TaskDescription) diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 7db0cfb92..b644c9554 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -2369,43 +2369,35 @@ namespace UF EQApplicationPacket *in = *p; *p = nullptr; - SpecialMesg_Struct *emu = (SpecialMesg_Struct *)in->pBuffer; + SerializeBuffer buf(in->size); + buf.WriteInt8(in->ReadUInt8()); // speak mode + buf.WriteInt8(in->ReadUInt8()); // journal mode + buf.WriteInt8(in->ReadUInt8()); // language + buf.WriteInt32(in->ReadUInt32()); // message type + buf.WriteInt32(in->ReadUInt32()); // target spawn id - unsigned char *__emu_buffer = in->pBuffer; - // break strlen optimizations! - char *message = emu->sayer; - auto sayer_length = std::char_traits::length(message); - message += sayer_length + 1 + 12; // skip over sayer name, null term, and 3 floats + std::string name; + in->ReadString(name); // NPC names max out at 63 chars - std::string old_message = message; + buf.WriteString(name); + + buf.WriteInt32(in->ReadUInt32()); // loc + buf.WriteInt32(in->ReadUInt32()); + buf.WriteInt32(in->ReadUInt32()); + + std::string old_message; std::string new_message; + in->ReadString(old_message); + ServerToUFSayLink(new_message, old_message); - //in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1; - in->size = sayer_length + new_message.length() + 25; - in->pBuffer = new unsigned char[in->size]; + buf.WriteString(new_message); - char *OutBuffer = (char *)in->pBuffer; + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[0]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[1]); - VARSTRUCT_ENCODE_TYPE(uint8, OutBuffer, emu->header[2]); - - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->msg_type); - VARSTRUCT_ENCODE_TYPE(uint32, OutBuffer, emu->target_spawn_id); - - VARSTRUCT_ENCODE_STRING(OutBuffer, emu->sayer); - - // TODO: figure this shit out - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - VARSTRUCT_ENCODE_TYPE(float, OutBuffer, 0.0f); - - VARSTRUCT_ENCODE_STRING(OutBuffer, new_message.c_str()); - - delete[] __emu_buffer; - dest->FastQueuePacket(&in, ack_req); + dest->FastQueuePacket(&outapp, ack_req); + delete in; } ENCODE(OP_Stun) diff --git a/zone/client.cpp b/zone/client.cpp index fd2df48bc..e90dafa8a 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1277,21 +1277,19 @@ void Client::Message(uint32 type, const char* message, ...) { vsnprintf(buffer, 4096, message, argptr); va_end(argptr); - size_t len = strlen(buffer); + SerializeBuffer buf(sizeof(SpecialMesgHeader_Struct) + 12 + 64 + 64); + buf.WriteInt8(static_cast(Journal::SpeakMode::Raw)); + buf.WriteInt8(static_cast(Journal::Mode::None)); + buf.WriteInt8(0); // language + buf.WriteUInt32(type); + buf.WriteUInt32(0); // target spawn ID used for journal filtering, ignored here + buf.WriteString(""); // send name, not applicable here + buf.WriteInt32(0); // location, client seems to ignore + buf.WriteInt32(0); + buf.WriteInt32(0); + buf.WriteString(buffer); - //client dosent like our packet all the time unless - //we make it really big, then it seems to not care that - //our header is malformed. - //len = 4096 - sizeof(SpecialMesg_Struct); - - uint32 len_packet = sizeof(SpecialMesg_Struct)+len; - auto app = new EQApplicationPacket(OP_SpecialMesg, len_packet); - SpecialMesg_Struct* sm=(SpecialMesg_Struct*)app->pBuffer; - sm->header[0] = 0x00; // Header used for #emote style messages.. - sm->header[1] = 0x00; // Play around with these to see other types - sm->header[2] = 0x00; - sm->msg_type = type; - memcpy(sm->message, buffer, len+1); + auto app = new EQApplicationPacket(OP_SpecialMesg, buf); FastQueuePacket(&app); @@ -1308,67 +1306,25 @@ void Client::FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, cons vsnprintf(buffer, 4096, message, argptr); va_end(argptr); - size_t len = strlen(buffer); + SerializeBuffer buf(sizeof(SpecialMesgHeader_Struct) + 12 + 64 + 64); + buf.WriteInt8(static_cast(Journal::SpeakMode::Raw)); + buf.WriteInt8(static_cast(Journal::Mode::None)); + buf.WriteInt8(0); // language + buf.WriteUInt32(type); + buf.WriteUInt32(0); // target spawn ID used for journal filtering, ignored here + buf.WriteString(""); // send name, not applicable here + buf.WriteInt32(0); // location, client seems to ignore + buf.WriteInt32(0); + buf.WriteInt32(0); + buf.WriteString(buffer); - //client dosent like our packet all the time unless - //we make it really big, then it seems to not care that - //our header is malformed. - //len = 4096 - sizeof(SpecialMesg_Struct); - - uint32 len_packet = sizeof(SpecialMesg_Struct) + len; - auto app = new EQApplicationPacket(OP_SpecialMesg, len_packet); - SpecialMesg_Struct* sm = (SpecialMesg_Struct*)app->pBuffer; - sm->header[0] = 0x00; // Header used for #emote style messages.. - sm->header[1] = 0x00; // Play around with these to see other types - sm->header[2] = 0x00; - sm->msg_type = type; - memcpy(sm->message, buffer, len + 1); + auto app = new EQApplicationPacket(OP_SpecialMesg, buf); FastQueuePacket(&app); safe_delete_array(buffer); } -void Client::QuestJournalledMessage(const char *npcname, const char* message) { - - // npcnames longer than 60 characters crash the client when they log back in - const int MaxNPCNameLength = 60; - // I assume there is an upper safe limit on the message length. Don't know what it is, but 4000 doesn't crash - // the client. - const int MaxMessageLength = 4000; - - char OutNPCName[MaxNPCNameLength+1]; - char OutMessage[MaxMessageLength+1]; - - // Apparently Visual C++ snprintf is not C99 compliant and doesn't put the null terminator - // in if the formatted string >= the maximum length, so we put it in. - // - snprintf(OutNPCName, MaxNPCNameLength, "%s", npcname); OutNPCName[MaxNPCNameLength]='\0'; - snprintf(OutMessage, MaxMessageLength, "%s", message); OutMessage[MaxMessageLength]='\0'; - - uint32 len_packet = sizeof(SpecialMesg_Struct) + strlen(OutNPCName) + strlen(OutMessage); - auto app = new EQApplicationPacket(OP_SpecialMesg, len_packet); - SpecialMesg_Struct* sm=(SpecialMesg_Struct*)app->pBuffer; - - sm->header[0] = 0; - sm->header[1] = 2; - sm->header[2] = 0; - sm->msg_type = 0x0a; - sm->target_spawn_id = GetID(); - - char *dest = &sm->sayer[0]; - - memcpy(dest, OutNPCName, strlen(OutNPCName) + 1); - - dest = dest + strlen(OutNPCName) + 13; - - memcpy(dest, OutMessage, strlen(OutMessage) + 1); - - QueuePacket(app); - - safe_delete(app); -} - void Client::SetMaxHP() { if(dead) return; diff --git a/zone/client.h b/zone/client.h index a44e83087..0272fb21b 100644 --- a/zone/client.h +++ b/zone/client.h @@ -341,7 +341,6 @@ public: void ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...); void Message(uint32 type, const char* message, ...); void FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...); - void QuestJournalledMessage(const char *npcname, const char* message); void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber); void SendSound(); void LearnRecipe(uint32 recipeID); diff --git a/zone/common.h b/zone/common.h index 62f1d9771..0ffa67468 100644 --- a/zone/common.h +++ b/zone/common.h @@ -272,6 +272,31 @@ enum class LootRequestType : uint8 { AllowedPVPDefined, }; +namespace Journal { + enum class SpeakMode : uint8 { + Raw = 0, // this just uses the raw message + Say = 1, // prints with "%1 says,%2 '%3'" if in another language else "%1 says '%2'" + Shout = 2, // prints with "%1 shouts,%2 '%3'" if in another language else "%1 shouts '%2'" + EmoteAlt = 3, // prints "%2", this should just be the same as raw ... + Emote = 4, // prints "%1 %2" if message doesn't start with "\" or "@", else "%1%2" + Group = 5 // prints "%1 tells the group,%2 '%3'" + }; + + enum class Mode : uint8 { + None = 0, + Log1 = 1, // 1 and 2 log to journal + Log2 = 2, // our current code uses 2 + }; + + struct Options { + SpeakMode speak_mode; + Mode journal_mode; + int8 language; + uint32 message_type; + uint32 target_spawn_id; // who the message is talking to (limits journaling) + }; +}; + //this is our internal representation of the BUFF struct, can put whatever we want in it struct Buffs_Struct { uint16 spellid; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 154e28566..bdb190e9c 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -155,12 +155,31 @@ XS(XS__say); // prototype to pass -Wmissing-prototypes XS(XS__say) { dXSARGS; - if (items == 1) - quest_manager.say(SvPV_nolen(ST(0))); - else if (items == 2) - quest_manager.say(SvPV_nolen(ST(0)), (int) SvIV(ST(1))); - else - Perl_croak(aTHX_ "Usage: quest::say(string message, int language_id])"); + Journal::Options opts; + // we currently default to these + opts.speak_mode = Journal::SpeakMode::Say; + opts.journal_mode = Journal::Mode::Log2; + opts.language = 0; + opts.message_type = MT_NPCQuestSay; + if (items == 0 || items > 5) { + Perl_croak(aTHX_ "Usage: quest::say(string message, [int language_id], [int message_type], [int speak_mode], [int journal_mode])"); + } else if (items == 2) { + opts.language = (int)SvIV(ST(1)); + } else if (items == 3) { + opts.language = (int)SvIV(ST(1)); + opts.message_type = (int)SvIV(ST(2)); + } else if (items == 4) { + opts.language = (int)SvIV(ST(1)); + opts.message_type = (int)SvIV(ST(2)); + opts.speak_mode = (Journal::SpeakMode)SvIV(ST(3)); + } else if (items == 5) { + opts.language = (int)SvIV(ST(1)); + opts.message_type = (int)SvIV(ST(2)); + opts.speak_mode = (Journal::SpeakMode)SvIV(ST(3)); + opts.journal_mode = (Journal::Mode)SvIV(ST(4)); + } + + quest_manager.say(SvPV_nolen(ST(0)), opts); XSRETURN_EMPTY; } diff --git a/zone/entity.cpp b/zone/entity.cpp index 0ed696327..f7fea532b 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3733,24 +3733,26 @@ bool Entity::CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z, } void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator, - float dist, const char* mobname, const char* message) + float dist, const char* mobname, const char* message, Journal::Options &opts) { - Client *c = nullptr; - float dist2 = dist * dist; + SerializeBuffer buf(sizeof(SpecialMesgHeader_Struct) + 12 + 64 + 64); - // Send the message to the quest initiator such that the client will enter it into the NPC Quest Journal - if (QuestInitiator) { - auto buf = new char[strlen(mobname) + strlen(message) + 10]; - sprintf(buf, "%s says, '%s'", mobname, message); - QuestInitiator->QuestJournalledMessage(mobname, buf); - safe_delete_array(buf); - } - // Use the old method for all other nearby clients - for (auto it = client_list.begin(); it != client_list.end(); ++it) { - c = it->second; - if(c && (c != QuestInitiator) && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2) - c->Message_StringID(10, GENERIC_SAY, mobname, message); - } + buf.WriteInt8(static_cast(opts.speak_mode)); + buf.WriteInt8(static_cast(opts.journal_mode)); + buf.WriteInt8(opts.language); + buf.WriteInt32(opts.message_type); + buf.WriteInt32(opts.target_spawn_id); + buf.WriteString(mobname); + buf.WriteInt32(0); // location, client doesn't seem to do anything with this + buf.WriteInt32(0); + buf.WriteInt32(0); + buf.WriteString(message); + + auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); + + // client only bothers logging if target spawn ID matches, safe to send to everyone + QueueCloseClients(sender, outapp, false, dist); + delete outapp; } Corpse *EntityList::GetClosestCorpse(Mob *sender, const char *Name) diff --git a/zone/entity.h b/zone/entity.h index 084cf6f01..c50575b5b 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -29,6 +29,7 @@ #include "position.h" #include "zonedump.h" +#include "common.h" class Encounter; class Beacon; @@ -337,7 +338,7 @@ public: void SendNimbusEffects(Client *c); void SendUntargetable(Client *c); void DuelMessage(Mob* winner, Mob* loser, bool flee); - void QuestJournalledSayClose(Mob *sender, Client *QuestIntiator, float dist, const char* mobname, const char* message); + void QuestJournalledSayClose(Mob *sender, Client *QuestIntiator, float dist, const char* mobname, const char* message, Journal::Options &opts); void GroupMessage(uint32 gid, const char *from, const char *message); void ExpeditionWarning(uint32 minutes_left); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 9dd1d8c9b..2a9ec5f8a 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -36,6 +36,8 @@ struct BodyTypes { }; struct Filters { }; struct MessageTypes { }; struct Rule { }; +struct Journal_SpeakMode { }; +struct Journal_Mode { }; struct lua_registered_event { std::string encounter_name; @@ -2232,6 +2234,7 @@ luabind::scope lua_register_message_types() { return luabind::class_("MT") .enum_("constants") [ + luabind::value("NPCQuestSay", MT_NPCQuestSay), luabind::value("Say", MT_Say), luabind::value("Tell", MT_Tell), luabind::value("Group", MT_Group), @@ -2362,4 +2365,27 @@ luabind::scope lua_register_ruleb() { ]; } +luabind::scope lua_register_journal_speakmode() { + return luabind::class_("Journal_SpeakMode") + .enum_("constants") + [ + luabind::value("Raw", static_cast(Journal::SpeakMode::Raw)), + luabind::value("Say", static_cast(Journal::SpeakMode::Say)), + luabind::value("Shout", static_cast(Journal::SpeakMode::Shout)), + luabind::value("EmoteAlt", static_cast(Journal::SpeakMode::EmoteAlt)), + luabind::value("Emote", static_cast(Journal::SpeakMode::Emote)), + luabind::value("Group", static_cast(Journal::SpeakMode::Group)) + ]; +} + +luabind::scope lua_register_journal_mode() { + return luabind::class_("Journal_Mode") + .enum_("constants") + [ + luabind::value("None", static_cast(Journal::Mode::None)), + luabind::value("Log1", static_cast(Journal::Mode::Log1)), + luabind::value("Log2", static_cast(Journal::Mode::Log2)) + ]; +} + #endif diff --git a/zone/lua_general.h b/zone/lua_general.h index 4c8b7f8d2..d5b741a76 100644 --- a/zone/lua_general.h +++ b/zone/lua_general.h @@ -19,6 +19,8 @@ luabind::scope lua_register_rules_const(); luabind::scope lua_register_rulei(); luabind::scope lua_register_ruler(); luabind::scope lua_register_ruleb(); +luabind::scope lua_register_journal_speakmode(); +luabind::scope lua_register_journal_mode(); #endif #endif diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index e801f07dc..8dfc37176 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -755,7 +755,65 @@ void Lua_Mob::Say(const char *message) { void Lua_Mob::QuestSay(Lua_Client client, const char *message) { Lua_Safe_Call_Void(); - self->QuestJournalledSay(client, message); + Journal::Options journal_opts; + journal_opts.speak_mode = Journal::SpeakMode::Say; + journal_opts.journal_mode = RuleB(NPC, EnableNPCQuestJournal) ? Journal::Mode::Log2 : Journal::Mode::None; + journal_opts.language = 0; + journal_opts.message_type = MT_NPCQuestSay; + journal_opts.target_spawn_id = 0; + self->QuestJournalledSay(client, message, journal_opts); +} + +void Lua_Mob::QuestSay(Lua_Client client, const char *message, luabind::adl::object opts) { + Lua_Safe_Call_Void(); + + Journal::Options journal_opts; + // defaults + journal_opts.speak_mode = Journal::SpeakMode::Say; + journal_opts.journal_mode = Journal::Mode::Log2; + journal_opts.language = 0; + journal_opts.message_type = MT_NPCQuestSay; + journal_opts.target_spawn_id = 0; + + if (luabind::type(opts) == LUA_TTABLE) { + auto cur = opts["speak_mode"]; + if (luabind::type(cur) != LUA_TNIL) { + try { + journal_opts.speak_mode = static_cast(luabind::object_cast(cur)); + } catch (luabind::cast_failed) { + } + } + + cur = opts["journal_mode"]; + if (luabind::type(cur) != LUA_TNIL) { + try { + journal_opts.journal_mode = static_cast(luabind::object_cast(cur)); + } catch (luabind::cast_failed) { + } + } + + cur = opts["language"]; + if (luabind::type(cur) != LUA_TNIL) { + try { + journal_opts.language = luabind::object_cast(cur); + } catch (luabind::cast_failed) { + } + } + + cur = opts["message_type"]; + if (luabind::type(cur) != LUA_TNIL) { + try { + journal_opts.message_type = luabind::object_cast(cur); + } catch (luabind::cast_failed) { + } + } + } + + // if rule disables it, we override provided + if (!RuleB(NPC, EnableNPCQuestJournal)) + journal_opts.journal_mode = Journal::Mode::None; + + self->QuestJournalledSay(client, message, journal_opts); } void Lua_Mob::Shout(const char *message) { @@ -2320,7 +2378,8 @@ luabind::scope lua_register_mob() { .def("Message", &Lua_Mob::Message) .def("Message_StringID", &Lua_Mob::Message_StringID) .def("Say", &Lua_Mob::Say) - .def("QuestSay", &Lua_Mob::QuestSay) + .def("QuestSay", (void(Lua_Mob::*)(Lua_Client,const char *))&Lua_Mob::QuestSay) + .def("QuestSay", (void(Lua_Mob::*)(Lua_Client,const char *,luabind::adl::object))&Lua_Mob::QuestSay) .def("Shout", &Lua_Mob::Shout) .def("Emote", &Lua_Mob::Emote) .def("InterruptSpell", (void(Lua_Mob::*)(void))&Lua_Mob::InterruptSpell) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index e7dcc1ee3..3ea4f14f5 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -169,6 +169,7 @@ public: void Message_StringID(int type, int string_id, uint32 distance); void Say(const char *message); void QuestSay(Lua_Client client, const char *message); + void QuestSay(Lua_Client client, const char *message, luabind::adl::object opts); void Shout(const char *message); void Emote(const char *message); void InterruptSpell(); diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index dda4b2d23..2c7cfe53e 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -1102,7 +1102,9 @@ void LuaParser::MapFunctions(lua_State *L) { lua_register_rules_const(), lua_register_rulei(), lua_register_ruler(), - lua_register_ruleb() + lua_register_ruleb(), + lua_register_journal_speakmode(), + lua_register_journal_mode() ]; } catch(std::exception &ex) { diff --git a/zone/mob.cpp b/zone/mob.cpp index b068905a9..ca844d459 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2911,9 +2911,13 @@ void Mob::Emote(const char *format, ...) GENERIC_EMOTE, GetCleanName(), buf); } -void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str) +void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::Options &opts) { - entity_list.QuestJournalledSayClose(this, QuestInitiator, 200, GetCleanName(), str); + // just in case + if (opts.target_spawn_id == 0 && QuestInitiator) + opts.target_spawn_id = QuestInitiator->GetID(); + + entity_list.QuestJournalledSayClose(this, QuestInitiator, 200, GetCleanName(), str, opts); } const char *Mob::GetCleanName() diff --git a/zone/mob.h b/zone/mob.h index ea71017c7..d2ebe3934 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -744,7 +744,7 @@ public: const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0); void Shout(const char *format, ...); void Emote(const char *format, ...); - void QuestJournalledSay(Client *QuestInitiator, const char *str); + void QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::Options &opts); int32 GetItemStat(uint32 itemid, const char *identifier); int16 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 42cb39503..79f5af8a5 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -154,30 +154,19 @@ void QuestManager::echo(int colour, const char *str) { entity_list.MessageClose(initiator, false, 200, colour, str); } -void QuestManager::say(const char *str) { +void QuestManager::say(const char *str, Journal::Options &opts) { QuestManagerCurrentQuestVars(); if (!owner) { Log(Logs::General, Logs::Quests, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); return; } else { - if(RuleB(NPC, EnableNPCQuestJournal) && initiator) { - owner->QuestJournalledSay(initiator, str); + if (!RuleB(NPC, EnableNPCQuestJournal)) + opts.journal_mode = Journal::Mode::None; + if (initiator) { + opts.target_spawn_id = initiator->GetID(); + owner->QuestJournalledSay(initiator, str, opts); } - else { - owner->Say(str); - } - } -} - -void QuestManager::say(const char *str, uint8 language) { - QuestManagerCurrentQuestVars(); - if (!owner) { - Log(Logs::General, Logs::Quests, "QuestManager::say called with nullptr owner. Probably syntax error in quest file."); - return; - } - else { - entity_list.ChannelMessage(owner, 8, language, str); } } diff --git a/zone/questmgr.h b/zone/questmgr.h index 6517872d8..1b9ea9c4d 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -62,8 +62,7 @@ public: //quest functions void echo(int colour, const char *str); - void say(const char *str); - void say(const char *str, uint8 language); + void say(const char *str, Journal::Options &opts); void me(const char *str); void summonitem(uint32 itemid, int16 charges = -1); void write(const char *file, const char *str); From 222fd060a37a335644c5d920c4384a4e54052152 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Fri, 19 Jul 2019 13:04:27 -0400 Subject: [PATCH 086/491] Change lua constants to be less ugly --- zone/lua_general.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 2a9ec5f8a..ef9180b68 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -2366,7 +2366,7 @@ luabind::scope lua_register_ruleb() { } luabind::scope lua_register_journal_speakmode() { - return luabind::class_("Journal_SpeakMode") + return luabind::class_("SpeakMode") .enum_("constants") [ luabind::value("Raw", static_cast(Journal::SpeakMode::Raw)), @@ -2379,7 +2379,7 @@ luabind::scope lua_register_journal_speakmode() { } luabind::scope lua_register_journal_mode() { - return luabind::class_("Journal_Mode") + return luabind::class_("JournalMode") .enum_("constants") [ luabind::value("None", static_cast(Journal::Mode::None)), From 780f8f85155a1efddb62008eb3db0eaabc2cdb66 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 20 Jul 2019 22:12:48 -0700 Subject: [PATCH 087/491] Mark old cle entries as stale when you login --- world/clientlist.cpp | 12 ++++++++++++ world/clientlist.h | 1 + world/login_server.cpp | 6 +++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 1264957a7..2c3a958d2 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -1277,7 +1277,19 @@ void ClientList::UpdateClientGuild(uint32 char_id, uint32 guild_id) { } } +void ClientList::RemoveCLEByLSID(uint32 iLSID) +{ + LinkedListIterator iterator(clientlist); + iterator.Reset(); + while (iterator.MoreElements()) { + if (iterator.GetData()->LSAccountID() == iLSID) { + iterator.RemoveCurrent(); + } + else + iterator.Advance(); + } +} int ClientList::GetClientCount() { return(numplayers); diff --git a/world/clientlist.h b/world/clientlist.h index 5b3bad297..19b8adc05 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -66,6 +66,7 @@ public: void CLEKeepAlive(uint32 numupdates, uint32* wid); void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); void UpdateClientGuild(uint32 char_id, uint32 guild_id); + void RemoveCLEByLSID(uint32 iLSID); int GetClientCount(); void GetClients(const char *zone_name, std::vector &into); diff --git a/world/login_server.cpp b/world/login_server.cpp index 61cc53bc2..73cb8a3eb 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -109,11 +109,15 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); if (cle != nullptr) { auto status = cle->GetOnline(); - if (CLE_Status_Never != status && CLE_Status_Offline != status) { + if (CLE_Status_Zoning == status || CLE_Status_InZone == status) { utwrs->response = UserToWorldStatusAlreadyOnline; SendPacket(&outpack); return; } + else { + //our existing cle is in a state we can login to, mark the old as stale and remove it. + client_list.RemoveCLEByLSID(utwr->lsaccountid); + } } } From 4aca39ad9bd5f032a0158dbc5cadf93218fa042b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 21 Jul 2019 17:47:34 -0500 Subject: [PATCH 088/491] Send correct response --- loginserver/world_server.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index b188f68e6..9fd5d4763 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -377,21 +377,26 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac } switch (user_to_world_response->response) { - case 1: + case UserToWorldStatusSuccess: per->Message = 101; break; - case 0: + case UserToWorldStatusWorldUnavail: per->Message = 326; break; - case -1: + case UserToWorldStatusSuspended: per->Message = 337; break; - case -2: + case UserToWorldStatusBanned: per->Message = 338; break; - case -3: - per->Message = 303; + case UserToWorldStatusWorldAtCapacity: + per->Message = 339; break; + case UserToWorldStatusAlreadyOnline: + per->Message = 111; + break; + default: + per->Message = 102; } if (server.options.IsTraceOn()) { From 581cbccad5b3febf2b23713e90ab0ef7246dee2f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 21 Jul 2019 18:11:09 -0500 Subject: [PATCH 089/491] CLE checks in non legacy user to world --- world/clientlist.cpp | 5 +++-- world/login_server.cpp | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/world/clientlist.cpp b/world/clientlist.cpp index c0e6a5116..2614d1d71 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -1245,15 +1245,16 @@ void ClientList::UpdateClientGuild(uint32 char_id, uint32 guild_id) { void ClientList::RemoveCLEByLSID(uint32 iLSID) { - LinkedListIterator iterator(clientlist); + LinkedListIterator iterator(clientlist); iterator.Reset(); while (iterator.MoreElements()) { if (iterator.GetData()->LSAccountID() == iLSID) { iterator.RemoveCurrent(); } - else + else { iterator.Advance(); + } } } diff --git a/world/login_server.cpp b/world/login_server.cpp index 074a270ca..78c736a0c 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -180,11 +180,15 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); if (cle != nullptr) { auto status = cle->GetOnline(); - if (CLE_Status_Never != status && CLE_Status_Offline != status) { + if (CLE_Status_Zoning == status || CLE_Status_InZone == status) { utwrs->response = UserToWorldStatusAlreadyOnline; SendPacket(&outpack); return; } + else { + //our existing cle is in a state we can login to, mark the old as stale and remove it. + client_list.RemoveCLEByLSID(utwr->lsaccountid); + } } } From 72ae1b0e0bbd7cca3d6fc6e896589054dab84bae Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 22 Jul 2019 23:05:33 -0400 Subject: [PATCH 090/491] Added 'vcxproj_dependencies.py' --- changelog.txt | 3 + utils/scripts/.gitignore | 3 +- utils/scripts/vcxproj_dependencies.py | 735 ++++++++++++++++++++++++++ 3 files changed, 740 insertions(+), 1 deletion(-) create mode 100644 utils/scripts/vcxproj_dependencies.py diff --git a/changelog.txt b/changelog.txt index dc9d0f16c..6b9d00a80 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 7/22/2019 == +Uleat: Added script 'vcxproj_dependencies.py' - a script to help determine conflicting project dependencies (alpha-stage) + == 7/10/2019 == Akkadius: Add #npcedit flymode [0 = ground, 1 = flying, 2 = levitate, 3 = water, 4 = floating] diff --git a/utils/scripts/.gitignore b/utils/scripts/.gitignore index eba9f59cb..76f70485c 100644 --- a/utils/scripts/.gitignore +++ b/utils/scripts/.gitignore @@ -1 +1,2 @@ -opcode_handlers_output \ No newline at end of file +opcode_handlers_output +vcxproj_dependencies_output diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py new file mode 100644 index 000000000..581103506 --- /dev/null +++ b/utils/scripts/vcxproj_dependencies.py @@ -0,0 +1,735 @@ +#! /usr/bin/env python +# + +""" +'VCXProj-Dependencies' for EQEmulator + +This script locates external dependency paths and generates lists for each +project. In addition, it will cross-check these lists to determine if any +discrepancies exist for any dependencies globally and across all projects. + +""" + + +import sys +import os +import fnmatch + +try: + import xml.etree.cElementTree as ElementTree +except ImportError: + import xml.etree.ElementTree as ElementTree + +from time import time, ctime + + +QUIET_REPORT = True + +include_projects = [] +exclude_projects = ['VCTargetsPath', 'CompilerIdC', 'CompilerIdCXX'] # these three should be left in by default + +base_path = os.getcwd()[:-14] # '/utils/scripts' +base_path = base_path.replace('\\', '/') + +file_extensions = ['vcxproj'] +project_paths = [] +master_dependencies = [] +# {[project]:{[build]:{[resource]:{[reference]:[paths]}}}} +project_dependencies = {} + +out_files = {} + +col1 = '{0}'.format(' ' * 0) +col2 = '{0}'.format(' ' * 2) +col3 = '{0}'.format(' ' * 4) +col4 = '{0}'.format(' ' * 6) +col5 = '{0}'.format(' ' * 8) + + +def main(): + """ main """ + + if not create_output_directory(): + exit() + + if not open_output_files(): + exit() + + print 'Locating project paths...' + locate_project_paths() + print '..project count: {0}'.format(len(project_paths)) + print 'Parsing project files...' + parse_project_files() + print 'Building master dependencies...' + build_master_dependencies() + print '..dependency count: {0}'.format(len(master_dependencies)) + print 'Checking for version discrepancies...' + check_for_version_discrepancies() + close_output_files() + print '\n..fin' + + return + + +def create_output_directory(): + """ Check for output directory - create if does not exist """ + + try: + output_path = '{0}/utils/scripts/vcxproj_dependencies_output'.format(base_path) + if not os.path.exists(output_path): + os.mkdir(output_path) + + return True + + except IOError: + print('(Exception Error: {0}) create_output_directory()'.format(sys.exc_info()[0])) + + return False + + +def open_output_files(): + """ Open all output files """ + + try: + file_name = '{0}/utils/scripts/vcxproj_dependencies_output/ProjectPaths.txt'.format(base_path) + out_files['ProjectPaths'] = open(file_name, 'w') + file_name = '{0}/utils/scripts/vcxproj_dependencies_output/MasterDependencies.txt'.format(base_path) + out_files['MasterDependencies'] = open(file_name, 'w') + file_name = '{0}/utils/scripts/vcxproj_dependencies_output/ProjectDependencies.txt'.format(base_path) + out_files['ProjectDependencies'] = open(file_name, 'w') + file_name = '{0}/utils/scripts/vcxproj_dependencies_output/ContextTree.txt'.format(base_path) + out_files['ContextTree'] = open(file_name, 'w') + file_name = '{0}/utils/scripts/vcxproj_dependencies_output/DiscrepancyReport.txt'.format(base_path) + out_files['DiscrepancyReport'] = open(file_name, 'w') + for file in out_files: + out_files[file].write('>> \'VCXProj-Dependencies\' {0} file\n'.format(file)) + out_files[file].write('>> file generated @ {0}\n\n'.format(ctime(time()))) + + return True + + except IOError: + print('(Exception Error: {0}) open_output_files()'.format(sys.exc_info()[0])) + close_output_files() + + return False + + +def locate_project_paths(): + """ Locate vcxproj files in the build folder """ + + for root, dirs, files in os.walk('{0}/build'.format(base_path)): + for name in files: + project = name.split('.')[0] + if not len(include_projects) == 0 and project not in include_projects: + continue + if not len(exclude_projects) == 0 and project in exclude_projects: + continue + for extension in file_extensions: + if fnmatch.fnmatch(name, '*.{0}'.format(extension)): + project_paths.append(os.path.join(root, name).replace('\\', '/').lower()) + for path in project_paths: + out_files['ProjectPaths'].write('{0};\n'.format(path)) + + return + + +def fixup_path(project_path, dependency_path): + """ Fix-up malformed dependency paths """ + + trailing = dependency_path.replace('\\', '/') + if '../' in trailing: + if trailing[:3] == '../': # windows + leading = project_path[:project_path.rfind('/')] + while trailing[:3] == '../': + leading = leading[:leading.rfind('/')] + trailing = trailing[3:] + trailing = trailing.lower() + trailing = '{0}/{1};'.format(leading, trailing) + else: # unix + print '..processing unix-style path fix-up' + while '../' in trailing: + backout = trailing.find('../') + backdir = trailing.rfind('/', 0, backout - 1) + trailing = trailing.replace(trailing[backdir:backout + 2], '', 1) + trailing = trailing.lower() + else: + trailing = trailing.lower() + + return trailing + + +def parse_project_files(): + """ Parse each vcxproj file's xml data """ + + for key1 in project_paths: + with open(key1, 'r') as vcxproj_file: + project_dependencies[key1] = {} + xml_tree = ElementTree.ElementTree(file=vcxproj_file) + for element1 in xml_tree.getroot(): + if not element1.tag[-19:] == 'ItemDefinitionGroup': + continue + # add '.split('|')[0]' to remove the '|Win##' attribute + key2 = element1.attrib['Condition'].split('==')[1][1:-1] + project_dependencies[key1][key2] = {} + for element2 in element1.getiterator(): + if element2.tag[-9:] == 'ClCompile': + key3 = element2.tag[-9:] + project_dependencies[key1][key2][key3] = {} + for element3 in element2.getiterator(): + if element3.tag[-28:] == 'AdditionalIncludeDirectories': + key4 = element3.tag[-28:] + project_dependencies[key1][key2][key3][key4] = [] + paths = element3.text.split(';') + for path in paths: + project_dependencies[key1][key2][key3][key4].append(fixup_path(key1, path)) + elif element2.tag[-15:] == 'ResourceCompile': + key3 = element2.tag[-15:] + project_dependencies[key1][key2][key3] = {} + for element3 in element2.getiterator(): + if element3.tag[-28:] == 'AdditionalIncludeDirectories': + key4 = element3.tag[-28:] + project_dependencies[key1][key2][key3][key4] = [] + paths = element3.text.split(';') + for path in paths: + project_dependencies[key1][key2][key3][key4].append(fixup_path(key1, path)) + elif element2.tag[-4:] == 'Midl': + key3 = element2.tag[-4:] + project_dependencies[key1][key2][key3] = {} + for element3 in element2.getiterator(): + if element3.tag[-28:] == 'AdditionalIncludeDirectories': + key4 = element3.tag[-28:] + project_dependencies[key1][key2][key3][key4] = [] + paths = element3.text.split(';') + for path in paths: + project_dependencies[key1][key2][key3][key4].append(fixup_path(key1, path)) + elif element2.tag[-4:] == 'Link': + key3 = element2.tag[-4:] + project_dependencies[key1][key2][key3] = {} + for element3 in element2.getiterator(): + if element3.tag[-22:] == 'AdditionalDependencies': + key4 = element3.tag[-22:] + project_dependencies[key1][key2][key3][key4] = [] + paths = element3.text.split(';') + for path in paths: + project_dependencies[key1][key2][key3][key4].append(fixup_path(key1, path)) + if element3.tag[-28:] == 'AdditionalLibraryDirectories': + key4 = element3.tag[-28:] + project_dependencies[key1][key2][key3][key4] = [] + paths = element3.text.split(';') + for path in paths: + project_dependencies[key1][key2][key3][key4].append(fixup_path(key1, path)) + vcxproj_file.close() + + return + + +def build_master_dependencies(): + """ Build master dependencies list """ + + def write(message): + """ internal 'ProjectDependencies' write method - performed here so processing takes place after fix-up """ + + out_files['ProjectDependencies'].write('{0}\n'.format(message)) + + return + + for key1 in project_dependencies: + write('{0}'.format(col1, key1)) + for key2 in project_dependencies[key1]: + write('{0}'.format(col2, key2)) + for key3 in project_dependencies[key1][key2]: + write('{0}'.format(col3, key3)) + for key4 in project_dependencies[key1][key2][key3]: + write('{0}'.format(col4, key4)) + for path in project_dependencies[key1][key2][key3][key4]: + write('{0}{1}'.format(col4, path)) + if path not in master_dependencies: + master_dependencies.append(path) + write('{0}'.format(col4)) + write('{0}'.format(col3)) + write('{0}'.format(col2)) + write('{0}'.format(col1)) + master_dependencies.sort() + for path in master_dependencies: + out_files['MasterDependencies'].write('{0}\n'.format(path)) + + return + + +def check_for_version_discrepancies(): + """ Check for dependency version discrepancies """ + + def twrite(message): + """ internal 'ContextTree' write method """ + + out_files['ContextTree'].write('{0}\n'.format(message)) + + return + + def rwrite(message): + """ internal 'DiscrepancyReport' write method """ + + out_files['DiscrepancyReport'].write('{0}\n'.format(message)) + + return + + libraries = [ + 'mysql', + 'zlib', + 'perl', + 'lua', + 'boost', + 'sodium', + 'openssl' + ] + references = [ + 'include', + 'source', + 'library' + ] + priorities = { + 0: 'NOT FOUND', + 1: 'install', + 2: 'dependencies', + 3: 'libs', + 4: 'vcpkg', + 5: 'static', + 6: 'submodule' + } + # use all lowercase for path description + # use forward slash ('/') for directory name breaks + # use '|' token for multiple hints ('my_file_path_1|my_file_path_2') + # use '##' token for joined hints ('my_file_##_1') + # use '&&' and '^' tokens for multiple argument hints ('my_file_&&path_1^path_2') + # joined hints may be nested until the multiple argument token is used.. + # ..then, only argument separators ('^') may be used + # (i.e., 'my_file_path_1|my_file_##_2|my_##_##&&_3^_4') + # {[library]:{[reference]:[[priority]:hint]}} + hints = { + # Notes: + 'mysql': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/mysql_##/include', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + 'dependencies/mysql_##/lib', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + }, + 'zlib': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/zlib_x##/include', # 'dependencies' + # not sure if this should be '/libs/zlibng' or '/build/libs/zlibng' based on cmake behavior + '/build/libs/zlibng', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/build/libs/zlibng', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '/libs/zlibng', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + 'dependencies/zlib_x##/lib/zdll.lib', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib^debug/lib/zlibd.lib', # 'vcpkg' + '/build/libs/zlibng/##&&zlibstatic.lib^zlibstaticd.lib', # 'static' + '' # 'submodule' + ] + }, + 'perl': { + 'include': [ + '', # 'NOT FOUND' + '/perl/lib/core', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '/perl/lib/core/perl51##.lib', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + }, + 'lua': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/luaj_x##/src', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/luaj_x##/src', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/luaj_x##/bin/lua51.lib', # 'dependencies' + '', # 'libs' + # debug lua package likely incorrect..should be 'lua51d.lib' - or whatever debug version is + '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/lua51.lib^debug/lib/lua51.lib', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + }, + 'boost': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/boost', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/boost', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + }, + 'sodium': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/libsodium/include', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + 'dependencies/libsodium/##/dynamic/libsodium.lib', # 'dependencies' + '', # 'libs' + # debug libsodium package likely incorrect..should be 'libsodiumd.lib' - or whatever debug version is + '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libsodium.lib^debug/lib/libsodium.lib', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + }, + 'openssl': { + 'include': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/openssl_x##/include', # 'dependencies' + '', # 'libs' + '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'source': [ + '', # 'NOT FOUND' + '', # 'install' + '', # 'dependencies' + '', # 'libs' + '', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ], + 'library': [ + '', # 'NOT FOUND' + '', # 'install' + '/dependencies/openssl_x##/lib/VC/&&libeay32MD.lib^libeay32MDd.lib^' + 'ssleay32MD.lib^ssleay32MDd.lib', # 'dependencies' + '', # 'libs' + # debug openssl package likely incorrect..should be + # 'libeay32d.lib' and 'ssleay32d.lib' - or whatever debug versions are + '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libeay32.lib^' + 'lib/ssleay32.lib^debug/lib/libeay32.lib^debug/lib/ssleay32.lib', # 'vcpkg' + '', # 'static' + '' # 'submodule' + ] + } + } + # {[project]:{[build]:{[resource]:{[library]:{[reference]:priority}}}}} + context_tree = {} + # {[library]:priority} + global_priorities = { + 'mysql': 0, + 'zlib': 0, + 'perl': 0, + 'lua': 0, + 'boost': 0, + 'sodium': 0, + 'openssl': 0 + } + # loop for discovering first occurence dependency sources (assumes same search precedence as compiler includes) + for key1 in project_dependencies: + if key1 not in context_tree.keys(): + context_tree[key1] = {} + for key2 in project_dependencies[key1]: + if key2 not in context_tree[key1].keys(): + context_tree[key1][key2] = {} + for key3 in project_dependencies[key1][key2]: + if key3 not in context_tree[key1][key2].keys(): + context_tree[key1][key2][key3] = {} + for key4 in project_dependencies[key1][key2][key3]: + for path in project_dependencies[key1][key2][key3][key4]: + for library in libraries: + if library not in context_tree[key1][key2][key3].keys(): + context_tree[key1][key2][key3][library] = {} + for reference in references: + if reference not in context_tree[key1][key2][key3][library].keys(): + context_tree[key1][key2][key3][library][reference] = 0 + elif not context_tree[key1][key2][key3][library][reference] == 0: + continue + for priority in priorities: + if hints[library][reference][priority] == '': + continue + for hint in hints[library][reference][priority].split('|'): + if is_hint_in_path(hint, path): + context_tree[key1][key2][key3][library][reference] = priority + if context_tree[key1][key2][key3][library][reference] >\ + global_priorities[library]: + global_priorities[library] =\ + context_tree[key1][key2][key3][library][reference] + twrite('{0}'.format(col1)) + for library in libraries: + twrite('{0}{2}'.format(col2, library, global_priorities[library])) + twrite('{0}'.format(col1)) + twrite('') + # loop for dumping 'ConflictTree' + for project in context_tree: + twrite('{0}'.format(col1, project)) + for build in context_tree[project]: + twrite('{0}'.format(col2, build)) + for resource in context_tree[project][build]: + twrite('{0}'.format(col3, resource)) + for library in context_tree[project][build][resource]: + twrite('{0}'.format(col4, library)) + for reference in context_tree[project][build][resource][library]: + twrite( + '{0}{2}'.format( + col5, + reference, + context_tree[project][build][resource][library][reference] + ) + ) + twrite('{0}'.format(col4)) + twrite('{0}'.format(col3)) + twrite('{0}'.format(col2)) + twrite('{0}'.format(col1)) + if QUIET_REPORT is False: + for library in libraries: + rwrite( + '> Global Library \'{0}\' status: \'{1}\' ({2})'.format( + library, + priorities[global_priorities[library]], + global_priorities[library] + ) + ) + # loop for identifying dependency discrepancies + for project in context_tree: + for build in context_tree[project]: + for resource in context_tree[project][build]: + for library in context_tree[project][build][resource]: + if global_priorities[library] == 0: + if QUIET_REPORT is False: + rwrite( + '> No Global Library \'{0}\' .. skipping Project:Build:Resource' + ' "{1}":"{2}":"{3}"'.format( + library, + project, + build, + resource + ) + ) + continue + r_flag = False + for reference in context_tree[project][build][resource][library]: + if context_tree[project][build][resource][library][reference] == 0: + continue + r_flag = True + if not global_priorities[library] == context_tree[project][build][resource][library][reference]: + rwrite( + '> Global-Project Library \'{0}\' mis-match \'{1}!={2}\'' + ' ({3}!={4}) Project:Build:Resource "{5}":"{6}":"{7}"'.format( + library, + priorities[global_priorities[library]], + priorities[context_tree[project][build][resource][library][reference]], + global_priorities[library], + context_tree[project][build][resource][library][reference], + project, + build, + resource + ) + ) + for cross_resource in context_tree[project][build]: + for cross_reference in context_tree[project][build][cross_resource][library]: + if cross_resource == resource and cross_reference == reference: + continue + if context_tree[project][build][cross_resource][library][cross_reference] == 0: + continue + if QUIET_REPORT is False and\ + not context_tree[project][build][cross_resource][library][cross_reference] ==\ + context_tree[project][build][resource][library][reference]: + rwrite( + '> Project Library \'{0}\' mis-match \'{1}:{2}:{3}!={4}:{5}:{6}\'' + ' ({7}!={8}) Project:Build "{9}":"{10}"'.format( + library, + resource, + reference, + priorities[context_tree[project][build][resource][library][reference]], + cross_resource, + cross_reference, + priorities[context_tree[project][build][cross_resource][library] + [cross_reference]], + context_tree[project][build][resource][library][reference], + context_tree[project][build][cross_resource][library][cross_reference], + project, + build + ) + ) + if r_flag is False and QUIET_REPORT is False: + rwrite( + '> No References found for Library \'{0}\' in Project "{1}":"{2}"'.format( + library, + project, + resource + ) + ) + + return + + +def is_hint_in_path(hint, path): + """ + Helper function for parsing and checking for hints in paths + + Hints strings should be split ('|') and passed as a singular hint into this function + + A re-write could allow for nested split models + + """ + + if hint == '' or path == '': + return False + + joined_index = hint.find('##') + pretext_index = hint.find('&&') + if joined_index == -1 and pretext_index == -1: + return hint in path + + elif (not joined_index == -1 and pretext_index == -1) or\ + (not joined_index == -1 and not pretext_index == -1 and joined_index < pretext_index): + start_index = 0 + for partial_hint in hint.split('##', 1): + if partial_hint == '': + continue + if not is_hint_in_path(partial_hint, path[start_index:]): + return False + + start_index = path.find(partial_hint, start_index) + len(partial_hint) + + return True + + elif (joined_index == -1 and not pretext_index == -1) or\ + (not joined_index == -1 and not pretext_index == -1 and joined_index > pretext_index): + partial_hints = hint.split('&&', 1) + found_index = path.find(partial_hints[0]) + if found_index == -1: + return False + + start_index = found_index + len(partial_hints[0]) + for alt_hint in partial_hints[1].split('^'): + if alt_hint == '': + continue + if path[start_index:].find(alt_hint) == 0: + return True + + return False + + else: + return False + + +def close_output_files(): + """ Close all output files """ + + while not len(out_files) == 0: + key = out_files.keys()[0] + out_files[key].close() + del out_files[key] + + return + + +if __name__ == '__main__': + main() From f5da6e18fcd18c2ba24dd8eeb3dd48cb1d9f7746 Mon Sep 17 00:00:00 2001 From: Uleat Date: Mon, 22 Jul 2019 23:27:38 -0400 Subject: [PATCH 091/491] Changed 'vcxproj_dependencies.py' script criteria to allow zero-length pretext headers in multiple-argument hints [skip ci] --- utils/scripts/vcxproj_dependencies.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py index 581103506..6c0453f4a 100644 --- a/utils/scripts/vcxproj_dependencies.py +++ b/utils/scripts/vcxproj_dependencies.py @@ -703,9 +703,11 @@ def is_hint_in_path(hint, path): elif (joined_index == -1 and not pretext_index == -1) or\ (not joined_index == -1 and not pretext_index == -1 and joined_index > pretext_index): partial_hints = hint.split('&&', 1) - found_index = path.find(partial_hints[0]) - if found_index == -1: - return False + found_index = 0 + if not partial_hints[0] == '': + found_index = path.find(partial_hints[0]) + if found_index == -1: + return False start_index = found_index + len(partial_hints[0]) for alt_hint in partial_hints[1].split('^'): From 53ec007459e8d839a07bab997e43eb855c894c48 Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 23 Jul 2019 19:34:35 -0400 Subject: [PATCH 092/491] Fixes and tweaks for 'vcxproj' script [skip ci] (zlib still needs some work) --- utils/scripts/vcxproj_dependencies.py | 144 ++++++++++++++------------ 1 file changed, 79 insertions(+), 65 deletions(-) diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py index 6c0453f4a..fd018991b 100644 --- a/utils/scripts/vcxproj_dependencies.py +++ b/utils/scripts/vcxproj_dependencies.py @@ -340,18 +340,18 @@ def check_for_version_discrepancies(): 'include': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/zlib_x##/include', # 'dependencies' + '/server/dependencies/zlib_x##/include', # 'dependencies' # not sure if this should be '/libs/zlibng' or '/build/libs/zlibng' based on cmake behavior - '/build/libs/zlibng', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' - '/build/libs/zlibng', # 'static' + '/server/libs/zlibng', # 'libs' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/server/build/libs/zlibng', # 'static' '' # 'submodule' ], 'source': [ '', # 'NOT FOUND' '', # 'install' '', # 'dependencies' - '/libs/zlibng', # 'libs' + '/server/libs/zlibng', # 'libs' '', # 'vcpkg' '', # 'static' '' # 'submodule' @@ -359,10 +359,10 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - 'dependencies/zlib_x##/lib/zdll.lib', # 'dependencies' + '/server/dependencies/zlib_x##/lib/zdll.lib', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib^debug/lib/zlibd.lib', # 'vcpkg' - '/build/libs/zlibng/##&&zlibstatic.lib^zlibstaticd.lib', # 'static' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib^debug/lib/zlibd.lib', # 'vcpkg' + '/server/build/libs/zlibng/##&&zlibstatic.lib^zlibstaticd.lib', # 'static' '' # 'submodule' ] }, @@ -399,16 +399,16 @@ def check_for_version_discrepancies(): 'include': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/luaj_x##/src', # 'dependencies' + '/server/dependencies/luaj_x##/src', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '', # 'static' '' # 'submodule' ], 'source': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/luaj_x##/src', # 'dependencies' + '/server/dependencies/luaj_x##/src', # 'dependencies' '', # 'libs' '', # 'vcpkg' '', # 'static' @@ -417,10 +417,10 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/luaj_x##/bin/lua51.lib', # 'dependencies' + '/server/dependencies/luaj_x##/bin/lua51.lib', # 'dependencies' '', # 'libs' # debug lua package likely incorrect..should be 'lua51d.lib' - or whatever debug version is - '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/lua51.lib^debug/lib/lua51.lib', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/lua51.lib^debug/lib/lua51.lib', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -429,9 +429,9 @@ def check_for_version_discrepancies(): 'include': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/boost', # 'dependencies' + '/server/dependencies/boost', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '', # 'static' '' # 'submodule' ], @@ -447,9 +447,9 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/boost', # 'dependencies' + '/server/dependencies/boost', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export', # 'vcpkg' + '/server/vcpkg/vcpkg-export', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -458,9 +458,9 @@ def check_for_version_discrepancies(): 'include': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/libsodium/include', # 'dependencies' + '/server/dependencies/libsodium/include', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '', # 'static' '' # 'submodule' ], @@ -476,10 +476,11 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - 'dependencies/libsodium/##/dynamic/libsodium.lib', # 'dependencies' + '/server/dependencies/libsodium/##/dynamic/libsodium.lib', # 'dependencies' '', # 'libs' # debug libsodium package likely incorrect..should be 'libsodiumd.lib' - or whatever debug version is - '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libsodium.lib^debug/lib/libsodium.lib', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libsodium.lib^' + 'debug/lib/libsodium.lib', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -488,9 +489,9 @@ def check_for_version_discrepancies(): 'include': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/openssl_x##/include', # 'dependencies' + '/server/dependencies/openssl_x##/include', # 'dependencies' '', # 'libs' - '/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '', # 'static' '' # 'submodule' ], @@ -506,12 +507,12 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - '/dependencies/openssl_x##/lib/VC/&&libeay32MD.lib^libeay32MDd.lib^' + '/server/dependencies/openssl_x##/lib/VC/&&libeay32MD.lib^libeay32MDd.lib^' 'ssleay32MD.lib^ssleay32MDd.lib', # 'dependencies' '', # 'libs' # debug openssl package likely incorrect..should be # 'libeay32d.lib' and 'ssleay32d.lib' - or whatever debug versions are - '/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libeay32.lib^' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libeay32.lib^' 'lib/ssleay32.lib^debug/lib/libeay32.lib^debug/lib/ssleay32.lib', # 'vcpkg' '', # 'static' '' # 'submodule' @@ -521,51 +522,61 @@ def check_for_version_discrepancies(): # {[project]:{[build]:{[resource]:{[library]:{[reference]:priority}}}}} context_tree = {} # {[library]:priority} - global_priorities = { - 'mysql': 0, - 'zlib': 0, - 'perl': 0, - 'lua': 0, - 'boost': 0, - 'sodium': 0, - 'openssl': 0 - } + global_priorities = {} + # {[build]:{[library]:priority}} + build_priorities = {} # loop for discovering first occurence dependency sources (assumes same search precedence as compiler includes) - for key1 in project_dependencies: - if key1 not in context_tree.keys(): - context_tree[key1] = {} - for key2 in project_dependencies[key1]: - if key2 not in context_tree[key1].keys(): - context_tree[key1][key2] = {} - for key3 in project_dependencies[key1][key2]: - if key3 not in context_tree[key1][key2].keys(): - context_tree[key1][key2][key3] = {} - for key4 in project_dependencies[key1][key2][key3]: - for path in project_dependencies[key1][key2][key3][key4]: + for project in project_dependencies: + if project not in context_tree.keys(): + context_tree[project] = {} + for build in project_dependencies[project]: + if build not in context_tree[project].keys(): + context_tree[project][build] = {} + if build not in build_priorities.keys(): + build_priorities[build] = {} + for resource in project_dependencies[project][build]: + if resource not in context_tree[project][build].keys(): + context_tree[project][build][resource] = {} + for reference_project in project_dependencies[project][build][resource]: + for path in project_dependencies[project][build][resource][reference_project]: for library in libraries: - if library not in context_tree[key1][key2][key3].keys(): - context_tree[key1][key2][key3][library] = {} + if library not in context_tree[project][build][resource].keys(): + context_tree[project][build][resource][library] = {} + if library not in build_priorities[build].keys(): + build_priorities[build][library] = 0 + if library not in global_priorities.keys(): + global_priorities[library] = 0 for reference in references: - if reference not in context_tree[key1][key2][key3][library].keys(): - context_tree[key1][key2][key3][library][reference] = 0 - elif not context_tree[key1][key2][key3][library][reference] == 0: + if reference not in context_tree[project][build][resource][library].keys(): + context_tree[project][build][resource][library][reference] = 0 + elif not context_tree[project][build][resource][library][reference] == 0: continue for priority in priorities: if hints[library][reference][priority] == '': continue for hint in hints[library][reference][priority].split('|'): if is_hint_in_path(hint, path): - context_tree[key1][key2][key3][library][reference] = priority - if context_tree[key1][key2][key3][library][reference] >\ + context_tree[project][build][resource][library][reference] = priority + if context_tree[project][build][resource][library][reference] >\ + build_priorities[build][library]: + build_priorities[build][library] =\ + context_tree[project][build][resource][library][reference] + if context_tree[project][build][resource][library][reference] >\ global_priorities[library]: global_priorities[library] =\ - context_tree[key1][key2][key3][library][reference] + context_tree[project][build][resource][library][reference] twrite('{0}'.format(col1)) for library in libraries: twrite('{0}{2}'.format(col2, library, global_priorities[library])) twrite('{0}'.format(col1)) twrite('') - # loop for dumping 'ConflictTree' + for build in build_priorities.keys(): + twrite('{0}'.format(col1, build)) + for library in libraries: + twrite('{0}{2}'.format(col2, library, build_priorities[build][library])) + twrite('{0}'.format(col1)) + twrite('') + # loop for dumping 'ContextTree' for project in context_tree: twrite('{0}'.format(col1, project)) for build in context_tree[project]: @@ -612,11 +623,21 @@ def check_for_version_discrepancies(): ) ) continue - r_flag = False + if build_priorities[build][library] == 0: + if QUIET_REPORT is False: + rwrite( + '> No Build Library \'{0}\' .. skipping Project:Build:Resource' + ' "{1}":"{2}":"{3}"'.format( + library, + project, + build, + resource + ) + ) + continue for reference in context_tree[project][build][resource][library]: if context_tree[project][build][resource][library][reference] == 0: continue - r_flag = True if not global_priorities[library] == context_tree[project][build][resource][library][reference]: rwrite( '> Global-Project Library \'{0}\' mis-match \'{1}!={2}\'' @@ -631,6 +652,7 @@ def check_for_version_discrepancies(): resource ) ) + # 'builds' are allowed to have different dependencies..so, we'll start crossing at 'resource' for cross_resource in context_tree[project][build]: for cross_reference in context_tree[project][build][cross_resource][library]: if cross_resource == resource and cross_reference == reference: @@ -657,14 +679,6 @@ def check_for_version_discrepancies(): build ) ) - if r_flag is False and QUIET_REPORT is False: - rwrite( - '> No References found for Library \'{0}\' in Project "{1}":"{2}"'.format( - library, - project, - resource - ) - ) return @@ -716,7 +730,7 @@ def is_hint_in_path(hint, path): if path[start_index:].find(alt_hint) == 0: return True - return False + return False else: return False From 9c9615e8bb3184bc111e0d7807f6271bdfad7163 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Tue, 23 Jul 2019 19:06:11 -0500 Subject: [PATCH 093/491] Fix the manifest [skip ci] --- utils/sql/db_update_manifest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 92bcfd260..4addfe6ce 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -393,7 +393,7 @@ 9137|2018_12_12_client_faction_tables.sql|SHOW TABLES LIKE 'faction_base_data'|empty| 9138|2018_12_12_convert_to_client_functions.sql|SELECT `id` FROM `faction_list` WHERE `id` > 4999|empty| 9139|2019_03_25_optional_npc_model.sql|SHOW COLUMNS FROM `npc_types` LIKE 'model'|empty| -9140|2019_07_03_update_range.sql|SHOW COLUMNS FROM `npc_types` LIKE 'max_movement_update_range'|empty| +9140|2019_07_03_update_range.sql|SHOW COLUMNS FROM `zone` LIKE 'max_movement_update_range'|empty| 9141|2019_07_10_npc_flymode.sql|SHOW COLUMNS FROM `npc_types` LIKE 'flymode'|empty| # Upgrade conditions: From debc2644b11e5697e17843b7994f00f6624a8bfe Mon Sep 17 00:00:00 2001 From: Uleat Date: Tue, 23 Jul 2019 21:11:30 -0400 Subject: [PATCH 094/491] Tweaked CMakeLists.txt so CMake will play nicer with 'vcpkg' dependencies [skip ci] --- CMakeLists.txt | 62 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be92c7d0d..d58e2bd1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,8 @@ #EQEMU_BUILD_CLIENT_FILES #EQEMU_USE_MAP_MMFS #EQEMU_MAP_DIR +#EQEMU_ARCH +#EQEMU_ARCH_ALT CMAKE_MINIMUM_REQUIRED(VERSION 2.8) IF(POLICY CMP0074) @@ -57,33 +59,37 @@ ENDIF(MSVC OR MINGW) IF(MSVC) IF(CMAKE_CL_64) - SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x64") - SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x64") - SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x64") - SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x64") - SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") - IF(MSVC_VERSION GREATER 1800) - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v140/dynamic") - ELSEIF(MSVC_VERSION EQUAL 1800) - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v120/dynamic") - ELSE() - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/x64/Release/v110/dynamic") - ENDIF() + SET(EQEMU_ARCH "x64") + SET(EQEMU_ARCH_ALT "x64") ELSE(CMAKE_CL_64) - SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_x86") - SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_x86") - SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_x86") - SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") - SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_x86") - IF(MSVC_VERSION GREATER 1800) - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v140/dynamic") - ELSEIF(MSVC_VERSION EQUAL 1800) - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v120/dynamic") - ELSE() - SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/Win32/Release/v110/dynamic") - ENDIF() + SET(EQEMU_ARCH "x86") + SET(EQEMU_ARCH_ALT "Win32") ENDIF(CMAKE_CL_64) - + + SET(MYSQL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/mysql_${EQEMU_ARCH}") + + IF(VCPKG_TOOLCHAIN) + IF(NOT MSVC_VERSION GREATER 1800) + SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") + ENDIF() + ELSE(VCPKG_TOOLCHAIN) + SET(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/zlib_${EQEMU_ARCH}") + SET(LUA_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/luaj_${EQEMU_ARCH}") + SET(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/openssl_${EQEMU_ARCH}") + + SET(SODIUM_INCLUDE_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/include") + ENDIF(VCPKG_TOOLCHAIN) + + IF(SODIUM_INCLUDE_HINTS) + IF(MSVC_VERSION GREATER 1800) + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v140/dynamic") + ELSEIF(MSVC_VERSION EQUAL 1800) + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v120/dynamic") + ELSE() + SET(SODIUM_LIBRARY_HINTS "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libsodium/${EQEMU_ARCH_ALT}/Release/v110/dynamic") + ENDIF() + ENDIF(SODIUM_INCLUDE_HINTS) + #disable CRT warnings on windows cause they're annoying as shit and we use C functions everywhere OPTION(EQEMU_DISABLE_CRT_SECURE_WARNINGS "Disable Secure CRT Warnings" ON) IF(EQEMU_DISABLE_CRT_SECURE_WARNINGS) @@ -320,8 +326,14 @@ IF(ZLIB_FOUND) SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY}) ENDIF() ELSE() + # NOTE: This processing chain is broken. + # Path "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" is added to ${SERVER_LIBS}..but, the current CMake process does not + # generate the "${CMAKE_CURRENT_SOURCE_DIR}/build/lib/zlibng" and create the required "zconf.h" file. A path to + # a valid ZLIB package is required to trigger this process. "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng/zconf.h" is not + # valid due to the extension name change to "../zlibng/zconf.h.in" during the ZLIB project creation process. INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic") + MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.") ENDIF() IF(WIN32) From cd32a5a47aad6ef1c8eef1755ceb5c033272d5b3 Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 23 Jul 2019 21:59:22 -0700 Subject: [PATCH 095/491] Make the reconnect code only trigger when there's actually a client IN ZONE and try to clean up otherwise --- common/servertalk.h | 7 +++++++ world/cliententry.cpp | 2 ++ world/clientlist.cpp | 2 -- world/login_server.cpp | 6 +++--- world/zonelist.cpp | 7 +++++++ world/zonelist.h | 1 + world/zoneserver.cpp | 1 + zone/client.cpp | 2 +- zone/entity.cpp | 12 ++++++++++++ zone/entity.h | 1 + zone/worldserver.cpp | 17 +++++++++++++++++ zone/zone.cpp | 16 ++++++++++++++++ zone/zone.h | 2 ++ 13 files changed, 70 insertions(+), 6 deletions(-) diff --git a/common/servertalk.h b/common/servertalk.h index 94eece8ca..3ad7c0cc2 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -80,6 +80,7 @@ #define ServerOP_GroupJoin 0x003e //for joining ooz folks #define ServerOP_UpdateSpawn 0x003f #define ServerOP_SpawnStatusChange 0x0040 +#define ServerOP_DropClient 0x0041 // DropClient #define ServerOP_ReloadTasks 0x0060 #define ServerOP_DepopAllPlayersCorpses 0x0061 #define ServerOP_ReloadTitles 0x0062 @@ -317,11 +318,17 @@ struct ServerZoneIncomingClient_Struct { uint32 accid; int16 admin; uint32 charid; + uint32 lsid; bool tellsoff; char charname[64]; char lskey[30]; }; +struct ServerZoneDropClient_Struct +{ + uint32 lsid; +}; + struct ServerChangeWID_Struct { uint32 charid; uint32 newwid; diff --git a/world/cliententry.cpp b/world/cliententry.cpp index be8916676..1402b1420 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -121,6 +121,8 @@ void ClientListEntry::SetOnline(ZoneServer* iZS, int8 iOnline) { } void ClientListEntry::SetOnline(int8 iOnline) { + Log(Logs::Detail, Logs::World_Server, "ClientListEntry::SetOnline for %s(%i) = %i", AccountName(), AccountID(), iOnline); + if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online) numplayers++; else if (iOnline < CLE_Status_Online && pOnline >= CLE_Status_Online) { diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 2c3a958d2..cc783affd 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -64,8 +64,6 @@ void ClientList::Process() { struct in_addr in; in.s_addr = iterator.GetData()->GetIP(); Log(Logs::Detail, Logs::World_Server,"Removing client from %s:%d", inet_ntoa(in), iterator.GetData()->GetPort()); -//the client destructor should take care of this. -// iterator.GetData()->Free(); iterator.RemoveCurrent(); } else diff --git a/world/login_server.cpp b/world/login_server.cpp index 73cb8a3eb..e0990d964 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -109,14 +109,14 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); if (cle != nullptr) { auto status = cle->GetOnline(); - if (CLE_Status_Zoning == status || CLE_Status_InZone == status) { + if (CLE_Status_InZone == status) { utwrs->response = UserToWorldStatusAlreadyOnline; SendPacket(&outpack); return; } else { - //our existing cle is in a state we can login to, mark the old as stale and remove it. - client_list.RemoveCLEByLSID(utwr->lsaccountid); + zoneserver_list.DropClient(utwrs->lsaccountid); + client_list.RemoveCLEByLSID(utwrs->lsaccountid); } } } diff --git a/world/zonelist.cpp b/world/zonelist.cpp index 84cd87842..1d06071c4 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -708,6 +708,13 @@ void ZSList::WorldShutDown(uint32 time, uint32 interval) } } +void ZSList::DropClient(uint32 lsid) { + ServerPacket packet(ServerOP_DropClient, sizeof(ServerZoneDropClient_Struct)); + auto drop = (ServerZoneDropClient_Struct*)packet.pBuffer; + drop->lsid = lsid; + SendPacket(&packet); +} + void ZSList::OnTick(EQ::Timer *t) { if (!EventSubscriptionWatcher::Get()->IsSubscribed("EQW::ZoneUpdate")) { diff --git a/world/zonelist.h b/world/zonelist.h index 947f75a2b..b99a88e09 100644 --- a/world/zonelist.h +++ b/world/zonelist.h @@ -57,6 +57,7 @@ public: void SOPZoneBootup(const char *adminname, uint32 ZoneServerID, const char *zonename, bool iMakeStatic = false); void UpdateUCSServerAvailable(bool ucss_available = true); void WorldShutDown(uint32 time, uint32 interval); + void DropClient(uint32 lsid); ZoneServer* FindByPort(uint16 port); ZoneServer* FindByID(uint32 ZoneID); diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index 0d0ba2f5d..bb856c75a 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -1457,6 +1457,7 @@ void ZoneServer::IncomingClient(Client* client) { s->accid = client->GetAccountID(); s->admin = client->GetAdmin(); s->charid = client->GetCharID(); + s->lsid = client->GetLSID(); if (client->GetCLE()) s->tellsoff = client->GetCLE()->TellsOff(); strn0cpy(s->charname, client->GetCharName(), sizeof(s->charname)); diff --git a/zone/client.cpp b/zone/client.cpp index e90dafa8a..baf75b0fe 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -446,7 +446,7 @@ Client::~Client() { numclients--; UpdateWindowTitle(); if(zone) - zone->RemoveAuth(GetName()); + zone->RemoveAuth(GetName()); //let the stream factory know were done with this stream eqs->Close(); diff --git a/zone/entity.cpp b/zone/entity.cpp index f7fea532b..1c8de0780 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1713,6 +1713,18 @@ Client *EntityList::GetClientByWID(uint32 iWID) return nullptr; } +Client *EntityList::GetClientByLSID(uint32 iLSID) +{ + auto it = client_list.begin(); + while (it != client_list.end()) { + if (it->second->LSAccountID() == iLSID) { + return it->second; + } + ++it; + } + return nullptr; +} + Client *EntityList::GetRandomClient(const glm::vec3& location, float Distance, Client *ExcludeClient) { std::vector ClientsInRange; diff --git a/zone/entity.h b/zone/entity.h index c50575b5b..a02a8be2e 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -176,6 +176,7 @@ public: } Client *GetClientByCharID(uint32 iCharID); Client *GetClientByWID(uint32 iWID); + Client *GetClientByLSID(uint32 iLSID); Client *GetClient(uint32 ip, uint16 port); Client *GetRandomClient(const glm::vec3& location, float Distance, Client *ExcludeClient = nullptr); Group *GetGroupByMob(Mob* mob); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 94be0eb14..54040ca5c 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -547,6 +547,23 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) } break; } + case ServerOP_DropClient: { + if (pack->size != sizeof(ServerZoneDropClient_Struct)) { + break; + } + + ServerZoneDropClient_Struct* drop = (ServerZoneDropClient_Struct*)pack->pBuffer; + if (zone) { + zone->RemoveAuth(drop->lsid); + + auto client = entity_list.GetClientByLSID(drop->lsid); + if (client) { + client->Kick(); + client->Save(); + } + } + break; + } case ServerOP_ZonePlayer: { ServerZonePlayer_Struct* szp = (ServerZonePlayer_Struct*)pack->pBuffer; Client* client = entity_list.GetClientByName(szp->name); diff --git a/zone/zone.cpp b/zone/zone.cpp index 88b0253a2..01e6ad42e 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1106,6 +1106,7 @@ void Zone::AddAuth(ServerZoneIncomingClient_Struct* szic) { zca->accid = szic->accid; zca->admin = szic->admin; zca->charid = szic->charid; + zca->lsid = szic->lsid; zca->tellsoff = szic->tellsoff; strn0cpy(zca->charname, szic->charname, sizeof(zca->charname)); strn0cpy(zca->lskey, szic->lskey, sizeof(zca->lskey)); @@ -1128,6 +1129,21 @@ void Zone::RemoveAuth(const char* iCharName) } } +void Zone::RemoveAuth(uint32 lsid) +{ + LinkedListIterator iterator(client_auth_list); + + iterator.Reset(); + while (iterator.MoreElements()) { + ZoneClientAuth_Struct* zca = iterator.GetData(); + if (zca->lsid == lsid) { + iterator.RemoveCurrent(); + return; + } + iterator.Advance(); + } +} + void Zone::ResetAuth() { LinkedListIterator iterator(client_auth_list); diff --git a/zone/zone.h b/zone/zone.h index e86fdc339..78bcef0f3 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -52,6 +52,7 @@ struct ZoneClientAuth_Struct { uint32 accid; int16 admin; uint32 charid; + uint32 lsid; bool tellsoff; char charname[64]; char lskey[30]; @@ -244,6 +245,7 @@ public: void ReloadStaticData(); void ReloadWorld(uint32 Option); void RemoveAuth(const char *iCharName); + void RemoveAuth(uint32 lsid); void Repop(uint32 delay = 0); void RepopClose(const glm::vec4 &client_position, uint32 repop_distance); void RequestUCSServerStatus(); From 90eb9e9da2afaa9aeaeb17473fbbc8cf6b48f43d Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 24 Jul 2019 21:59:57 -0400 Subject: [PATCH 096/491] Some more mods and tweaks to 'vcxproj_dependencies' [skip ci] --- utils/scripts/vcxproj_dependencies.py | 129 ++++++++++++++++---------- 1 file changed, 78 insertions(+), 51 deletions(-) diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py index fd018991b..ff53b70f7 100644 --- a/utils/scripts/vcxproj_dependencies.py +++ b/utils/scripts/vcxproj_dependencies.py @@ -66,7 +66,7 @@ def main(): print 'Checking for version discrepancies...' check_for_version_discrepancies() close_output_files() - print '\n..fin' + print '\n__fin__' return @@ -299,11 +299,10 @@ def check_for_version_discrepancies(): # use all lowercase for path description # use forward slash ('/') for directory name breaks # use '|' token for multiple hints ('my_file_path_1|my_file_path_2') + # use '!!' token for explicit argument ('/perl/core!!' will find '../perl/core' but not '../perl/core/perl512.lib') # use '##' token for joined hints ('my_file_##_1') - # use '&&' and '^' tokens for multiple argument hints ('my_file_&&path_1^path_2') - # joined hints may be nested until the multiple argument token is used.. - # ..then, only argument separators ('^') may be used - # (i.e., 'my_file_path_1|my_file_##_2|my_##_##&&_3^_4') + # use '&&', '^' and '@' tokens for multiple argument hints ('my_file_&&path_1^path_2^path_3@') + # (i.e., 'my_file_path_1|my_file_##_2|my_##_##&&_3^_4!!@') # {[library]:{[reference]:[[priority]:hint]}} hints = { # Notes: @@ -342,7 +341,7 @@ def check_for_version_discrepancies(): '', # 'install' '/server/dependencies/zlib_x##/include', # 'dependencies' # not sure if this should be '/libs/zlibng' or '/build/libs/zlibng' based on cmake behavior - '/server/libs/zlibng', # 'libs' + '/server/build/libs/zlibng', # 'libs' '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '/server/build/libs/zlibng', # 'static' '' # 'submodule' @@ -361,15 +360,16 @@ def check_for_version_discrepancies(): '', # 'install' '/server/dependencies/zlib_x##/lib/zdll.lib', # 'dependencies' '', # 'libs' - '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib^debug/lib/zlibd.lib', # 'vcpkg' - '/server/build/libs/zlibng/##&&zlibstatic.lib^zlibstaticd.lib', # 'static' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib!!' + '^debug/lib/zlibd.lib!!@', # 'vcpkg' + '/server/build/libs/zlibng/##&&zlibstatic.lib!!^zlibstaticd.lib!!@', # 'static' '' # 'submodule' ] }, 'perl': { 'include': [ '', # 'NOT FOUND' - '/perl/lib/core', # 'install' + '/perl/lib/core!!', # 'install' '', # 'dependencies' '', # 'libs' '', # 'vcpkg' @@ -420,7 +420,8 @@ def check_for_version_discrepancies(): '/server/dependencies/luaj_x##/bin/lua51.lib', # 'dependencies' '', # 'libs' # debug lua package likely incorrect..should be 'lua51d.lib' - or whatever debug version is - '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/lua51.lib^debug/lib/lua51.lib', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/lua51.lib!!' + '^debug/lib/lua51.lib!!@', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -440,7 +441,7 @@ def check_for_version_discrepancies(): '', # 'install' '', # 'dependencies' '', # 'libs' - '', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' '', # 'static' '' # 'submodule' ], @@ -449,7 +450,7 @@ def check_for_version_discrepancies(): '', # 'install' '/server/dependencies/boost', # 'dependencies' '', # 'libs' - '/server/vcpkg/vcpkg-export', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/lib!!', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -479,8 +480,8 @@ def check_for_version_discrepancies(): '/server/dependencies/libsodium/##/dynamic/libsodium.lib', # 'dependencies' '', # 'libs' # debug libsodium package likely incorrect..should be 'libsodiumd.lib' - or whatever debug version is - '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libsodium.lib^' - 'debug/lib/libsodium.lib', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libsodium.lib!!^' + 'debug/lib/libsodium.lib!!@', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -507,13 +508,13 @@ def check_for_version_discrepancies(): 'library': [ '', # 'NOT FOUND' '', # 'install' - '/server/dependencies/openssl_x##/lib/VC/&&libeay32MD.lib^libeay32MDd.lib^' - 'ssleay32MD.lib^ssleay32MDd.lib', # 'dependencies' + '/server/dependencies/openssl_x##/lib/VC/&&libeay32MD.lib!!^libeay32MDd.lib!!^' + 'ssleay32MD.lib!!^ssleay32MDd.lib!!@', # 'dependencies' '', # 'libs' # debug openssl package likely incorrect..should be # 'libeay32d.lib' and 'ssleay32d.lib' - or whatever debug versions are - '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libeay32.lib^' - 'lib/ssleay32.lib^debug/lib/libeay32.lib^debug/lib/ssleay32.lib', # 'vcpkg' + '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/libeay32.lib!!^' + 'lib/ssleay32.lib!!^debug/lib/libeay32.lib!!^debug/lib/ssleay32.lib!!@', # 'vcpkg' '', # 'static' '' # 'submodule' ] @@ -555,28 +556,31 @@ def check_for_version_discrepancies(): if hints[library][reference][priority] == '': continue for hint in hints[library][reference][priority].split('|'): - if is_hint_in_path(hint, path): - context_tree[project][build][resource][library][reference] = priority - if context_tree[project][build][resource][library][reference] >\ - build_priorities[build][library]: - build_priorities[build][library] =\ - context_tree[project][build][resource][library][reference] - if context_tree[project][build][resource][library][reference] >\ - global_priorities[library]: - global_priorities[library] =\ - context_tree[project][build][resource][library][reference] + if not find_hint_in_path(hint, path) == -1: + if priority > context_tree[project][build][resource][library][reference]: + context_tree[project][build][resource][library][reference] = priority + if context_tree[project][build][resource][library][reference] >\ + build_priorities[build][library]: + build_priorities[build][library] =\ + context_tree[project][build][resource][library][reference] + if context_tree[project][build][resource][library][reference] >\ + global_priorities[library]: + global_priorities[library] =\ + context_tree[project][build][resource][library][reference] + # loop for dumping 'global_priorities' twrite('{0}'.format(col1)) for library in libraries: twrite('{0}{2}'.format(col2, library, global_priorities[library])) twrite('{0}'.format(col1)) twrite('') - for build in build_priorities.keys(): + # loop for dumping 'build_priorities' + for build in build_priorities: twrite('{0}'.format(col1, build)) for library in libraries: twrite('{0}{2}'.format(col2, library, build_priorities[build][library])) twrite('{0}'.format(col1)) twrite('') - # loop for dumping 'ContextTree' + # loop for dumping 'context_tree' for project in context_tree: twrite('{0}'.format(col1, project)) for build in context_tree[project]: @@ -683,23 +687,37 @@ def check_for_version_discrepancies(): return -def is_hint_in_path(hint, path): +def find_hint_in_path(hint, path): """ Helper function for parsing and checking for hints in paths Hints strings should be split ('|') and passed as a singular hint into this function - A re-write could allow for nested split models - """ if hint == '' or path == '': - return False + return -1 joined_index = hint.find('##') pretext_index = hint.find('&&') if joined_index == -1 and pretext_index == -1: - return hint in path + if '^' in hint or '@' in hint: + print '..malformed or improper handling of hint: \'{0}\' path: \'{1}\''.format(hint, path) + + return -1 + + explicit_index = hint.find('!!') + if explicit_index == -1: + return path.find(hint) + + else: + explicit_hint = hint[:explicit_index] + found_index = path.find(explicit_hint) + if (len(explicit_hint) + found_index) == len(path): + return found_index + + else: + return -1 elif (not joined_index == -1 and pretext_index == -1) or\ (not joined_index == -1 and not pretext_index == -1 and joined_index < pretext_index): @@ -707,33 +725,42 @@ def is_hint_in_path(hint, path): for partial_hint in hint.split('##', 1): if partial_hint == '': continue - if not is_hint_in_path(partial_hint, path[start_index:]): - return False + found_index = find_hint_in_path(partial_hint, path[start_index:]) + if found_index == -1: + return found_index - start_index = path.find(partial_hint, start_index) + len(partial_hint) + start_index = found_index + len(partial_hint) - return True + return start_index elif (joined_index == -1 and not pretext_index == -1) or\ (not joined_index == -1 and not pretext_index == -1 and joined_index > pretext_index): - partial_hints = hint.split('&&', 1) + pretext_hints = hint.split('&&', 1) found_index = 0 - if not partial_hints[0] == '': - found_index = path.find(partial_hints[0]) + if not pretext_hints[0] == '': + found_index = find_hint_in_path(pretext_hints[0], path) if found_index == -1: - return False + return found_index - start_index = found_index + len(partial_hints[0]) - for alt_hint in partial_hints[1].split('^'): - if alt_hint == '': + start_index = found_index + len(pretext_hints[0]) + partial_hints = pretext_hints[1].split('@', 1) + for partial_hint in partial_hints: + if partial_hint == '': continue - if path[start_index:].find(alt_hint) == 0: - return True - - return False + for alt_hint in partial_hint.split('^'): + if alt_hint == '': + continue + found_index = find_hint_in_path(alt_hint, path[start_index:]) + if found_index == 0: + if not partial_hints[1] == '': + print '..unhandled hint method: \'{0}\''.format(partial_hints[1]) + else: + return found_index + + return -1 else: - return False + return -1 def close_output_files(): From f3255c17dad779014ab7947a9c4a92591b87bb13 Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 24 Jul 2019 19:20:09 -0700 Subject: [PATCH 097/491] Changes to cle enums, characters will now auto kick on login instead of making you wait at world unless you specifically turn that feature on in the rules. --- common/ruletypes.h | 2 +- world/adventure.cpp | 2 +- world/client.cpp | 14 ++++++----- world/cliententry.cpp | 30 +++++++++++----------- world/cliententry.h | 32 +++++++++++++----------- world/clientlist.cpp | 56 +++++++++++++++++++++--------------------- world/clientlist.h | 2 +- world/login_server.cpp | 18 ++++---------- world/zoneserver.cpp | 6 ++--- zone/client.cpp | 2 +- zone/worldserver.cpp | 1 + zone/zone.cpp | 9 +++---- zone/zone.h | 2 +- 13 files changed, 86 insertions(+), 90 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index 8dfa15f9e..cad8f455f 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -240,7 +240,7 @@ RULE_BOOL (World, IPLimitDisconnectAll, false) RULE_BOOL(World, MaxClientsSimplifiedLogic, false) // New logic that only uses ExemptMaxClientsStatus and MaxClientsPerIP. Done on the loginserver. This mimics the P99-style special IP rules. RULE_INT (World, TellQueueSize, 20) RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone ALWAYS be the same location as your bind? -RULE_BOOL(World, DisallowDuplicateAccountLogins, true) +RULE_BOOL(World, EnforceCharacterLimitAtLogin, false) RULE_CATEGORY_END() RULE_CATEGORY(Zone) diff --git a/world/adventure.cpp b/world/adventure.cpp index c984fa831..af3cfe0e2 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -287,7 +287,7 @@ void Adventure::Finished(AdventureWinStatus ws) ClientListEntry *current = client_list.FindCharacter((*iter).c_str()); if(current) { - if(current->Online() == CLE_Status_InZone) + if(current->Online() == CLE_Status::InZone) { //We can send our packets only. auto pack = diff --git a/world/client.cpp b/world/client.cpp index bc044dae5..3f875cafe 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -115,7 +115,7 @@ Client::Client(EQStreamInterface* ieqs) Client::~Client() { if (RunLoops && cle && zone_id == 0) - cle->SetOnline(CLE_Status_Offline); + cle->SetOnline(CLE_Status::Offline); numclients--; @@ -185,7 +185,7 @@ void Client::SendExpansionInfo() { void Client::SendCharInfo() { if (cle) { - cle->SetOnline(CLE_Status_CharSelect); + cle->SetOnline(CLE_Status::CharSelect); } if (m_ClientVersionBit & EQEmu::versions::maskRoFAndLater) { @@ -461,7 +461,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { // Track who is in and who is out of the game char *inout= (char *) ""; - if (cle->GetOnline() == CLE_Status_Never){ + if (cle->GetOnline() == CLE_Status::Never){ // Desktop -> Char Select inout = (char *) "In"; } @@ -474,7 +474,7 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) { // Either from a fresh client launch or coming back from the game. // Exiting the game entirely does not come through here. // Could use a Logging Out Completely message somewhere. - cle->SetOnline(CLE_Status_CharSelect); + cle->SetOnline(CLE_Status::CharSelect); Log(Logs::General, Logs::World_Server, "Account (%s) Logging(%s) to character select :: LSID: %d ", @@ -1076,7 +1076,7 @@ bool Client::HandlePacket(const EQApplicationPacket *app) { { // I don't see this getting executed on logout eqs->Close(); - cle->SetOnline(CLE_Status_Offline); //allows this player to log in again without an ip restriction. + cle->SetOnline(CLE_Status::Offline); //allows this player to log in again without an ip restriction. return false; } case OP_ZoneChange: @@ -1191,6 +1191,8 @@ void Client::EnterWorld(bool TryBootup) { else zone_server = zoneserver_list.FindByZoneID(zone_id); + //Tell all the zones to drop any client with this lsid because we're coming back in. + zoneserver_list.DropClient(GetLSID()); const char *zone_name = database.GetZoneName(zone_id, true); if (zone_server) { @@ -1344,7 +1346,7 @@ void Client::Clearance(int8 response) safe_delete(outapp); if (cle) - cle->SetOnline(CLE_Status_Zoning); + cle->SetOnline(CLE_Status::Zoning); } void Client::TellClientZoneUnavailable() { diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 1402b1420..67583a614 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -73,7 +73,7 @@ ClientListEntry::ClientListEntry(uint32 in_id, uint32 iAccID, const char* iAccNa memset(pLFGComments, 0, 64); } -ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) +ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline) : id(in_id) { ClearVars(true); @@ -94,7 +94,7 @@ ClientListEntry::ClientListEntry(uint32 in_id, ZoneServer* iZS, ServerClientList pLFGMatchFilter = false; memset(pLFGComments, 0, 64); - if (iOnline >= CLE_Status_Zoning) + if (iOnline >= CLE_Status::Zoning) Update(iZS, scl, iOnline); else SetOnline(iOnline); @@ -115,24 +115,24 @@ void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) { strn0cpy(pname, iCharName, sizeof(pname)); } -void ClientListEntry::SetOnline(ZoneServer* iZS, int8 iOnline) { +void ClientListEntry::SetOnline(ZoneServer* iZS, CLE_Status iOnline) { if (iZS == this->Server()) SetOnline(iOnline); } -void ClientListEntry::SetOnline(int8 iOnline) { - Log(Logs::Detail, Logs::World_Server, "ClientListEntry::SetOnline for %s(%i) = %i", AccountName(), AccountID(), iOnline); +void ClientListEntry::SetOnline(CLE_Status iOnline) { + Log(Logs::General, Logs::World_Server, "ClientListEntry::SetOnline for %s(%i) = %i", AccountName(), AccountID(), iOnline); - if (iOnline >= CLE_Status_Online && pOnline < CLE_Status_Online) + if (iOnline >= CLE_Status::Online && pOnline < CLE_Status::Online) numplayers++; - else if (iOnline < CLE_Status_Online && pOnline >= CLE_Status_Online) { + else if (iOnline < CLE_Status::Online && pOnline >= CLE_Status::Online) { numplayers--; } - if (iOnline != CLE_Status_Online || pOnline < CLE_Status_Online) + if (iOnline != CLE_Status::Online || pOnline < CLE_Status::Online) pOnline = iOnline; - if (iOnline < CLE_Status_Zoning) + if (iOnline < CLE_Status::Zoning) Camp(); - if (pOnline >= CLE_Status_Online) + if (pOnline >= CLE_Status::Online) stale = 0; } void ClientListEntry::LSUpdate(ZoneServer* iZS){ @@ -163,7 +163,7 @@ void ClientListEntry::LSZoneChange(ZoneToZone_Struct* ztz){ safe_delete(pack); } } -void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline) { +void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline) { if (pzoneserver != iZS) { if (pzoneserver){ pzoneserver->RemovePlayer(); @@ -210,7 +210,7 @@ void ClientListEntry::Update(ZoneServer* iZS, ServerClientList_Struct* scl, int8 SetOnline(iOnline); } -void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) { +void ClientListEntry::LeavingZone(ZoneServer* iZS, CLE_Status iOnline) { if (iZS != 0 && iZS != pzoneserver) return; SetOnline(iOnline); @@ -225,7 +225,7 @@ void ClientListEntry::LeavingZone(ZoneServer* iZS, int8 iOnline) { void ClientListEntry::ClearVars(bool iAll) { if (iAll) { - pOnline = CLE_Status_Never; + pOnline = CLE_Status::Never; stale = 0; pLSID = 0; @@ -271,8 +271,8 @@ void ClientListEntry::Camp(ZoneServer* iZS) { bool ClientListEntry::CheckStale() { stale++; if (stale > 20) { - if (pOnline > CLE_Status_Offline) - SetOnline(CLE_Status_Offline); + if (pOnline > CLE_Status::Offline) + SetOnline(CLE_Status::Offline); else return true; } diff --git a/world/cliententry.h b/world/cliententry.h index 24a837ae9..725b7df0d 100644 --- a/world/cliententry.h +++ b/world/cliententry.h @@ -8,13 +8,15 @@ #include "../common/rulesys.h" #include - -#define CLE_Status_Never -1 -#define CLE_Status_Offline 0 -#define CLE_Status_Online 1 // Will not overwrite more specific online status -#define CLE_Status_CharSelect 2 -#define CLE_Status_Zoning 3 -#define CLE_Status_InZone 4 +typedef enum +{ + Never, + Offline, + Online, + CharSelect, + Zoning, + InZone +} CLE_Status; class ZoneServer; struct ServerClientList_Struct; @@ -23,25 +25,25 @@ class ClientListEntry { public: ClientListEntry(uint32 id, uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); ClientListEntry(uint32 id, uint32 iAccID, const char* iAccName, MD5& iMD5Pass, int16 iAdmin = 0); - ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, int8 iOnline); + ClientListEntry(uint32 id, ZoneServer* iZS, ServerClientList_Struct* scl, CLE_Status iOnline); ~ClientListEntry(); bool CheckStale(); - void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, int8 iOnline = CLE_Status_InZone); + void Update(ZoneServer* zoneserver, ServerClientList_Struct* scl, CLE_Status iOnline = CLE_Status::InZone); void LSUpdate(ZoneServer* zoneserver); void LSZoneChange(ZoneToZone_Struct* ztz); bool CheckAuth(uint32 iLSID, const char* key); bool CheckAuth(const char* iName, MD5& iMD5Password); bool CheckAuth(uint32 id, const char* key, uint32 ip); - void SetOnline(ZoneServer* iZS, int8 iOnline); - void SetOnline(int8 iOnline = CLE_Status_Online); + void SetOnline(ZoneServer* iZS, CLE_Status iOnline); + void SetOnline(CLE_Status iOnline = CLE_Status::Online); void SetChar(uint32 iCharID, const char* iCharName); - inline int8 Online() { return pOnline; } + inline CLE_Status Online() { return pOnline; } inline const uint32 GetID() const { return id; } inline const uint32 GetIP() const { return pIP; } inline void SetIP(const uint32& iIP) { pIP = iIP; } inline void KeepAlive() { stale = 0; } inline uint8 GetStaleCounter() const { return stale; } - void LeavingZone(ZoneServer* iZS = 0, int8 iOnline = CLE_Status_Offline); + void LeavingZone(ZoneServer* iZS = 0, CLE_Status iOnline = CLE_Status::Offline); void Camp(ZoneServer* iZS = 0); // Login Server stuff @@ -50,7 +52,7 @@ public: inline const char* LSName() const { return plsname; } inline int16 WorldAdmin() const { return pworldadmin; } inline const char* GetLSKey() const { return plskey; } - inline const int8 GetOnline() const { return pOnline; } + inline const CLE_Status GetOnline() const { return pOnline; } // Account stuff inline uint32 AccountID() const { return paccountid; } @@ -93,7 +95,7 @@ private: const uint32 id; uint32 pIP; - int8 pOnline; + CLE_Status pOnline; uint8 stale; // Login Server stuff diff --git a/world/clientlist.cpp b/world/clientlist.cpp index cc783affd..da14ce71f 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -120,7 +120,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); + countCLEIPs->SetOnline(CLE_Status::Offline); iterator.RemoveCurrent(); continue; } @@ -136,7 +136,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -148,7 +148,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -159,7 +159,7 @@ void ClientList::GetCLEIP(uint32 iIP) { return; } else { Log(Logs::General, Logs::Client_Login, "Disconnect: Account %s on IP %s.", countCLEIPs->LSName(), long2ip(countCLEIPs->GetIP()).c_str()); - countCLEIPs->SetOnline(CLE_Status_Offline); // Remove the connection + countCLEIPs->SetOnline(CLE_Status::Offline); // Remove the connection iterator.RemoveCurrent(); continue; } @@ -180,7 +180,7 @@ uint32 ClientList::GetCLEIPCount(uint32 iIP) { while (iterator.MoreElements()) { countCLEIPs = iterator.GetData(); - if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) && countCLEIPs->Online() >= CLE_Status_Online) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt) + if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) && countCLEIPs->Online() >= CLE_Status::Online) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt) IPInstances++; // Increment the occurences of this IP address } iterator.Advance(); @@ -206,7 +206,7 @@ void ClientList::DisconnectByIP(uint32 iIP) { zoneserver_list.SendPacket(pack); safe_delete(pack); } - countCLEIPs->SetOnline(CLE_Status_Offline); + countCLEIPs->SetOnline(CLE_Status::Offline); iterator.RemoveCurrent(); } iterator.Advance(); @@ -253,19 +253,6 @@ ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) { return nullptr; } -ClientListEntry* ClientList::FindCLEByLSID(uint32 iLSID) { - LinkedListIterator iterator(clientlist); - - iterator.Reset(); - while (iterator.MoreElements()) { - if (iterator.GetData()->LSID() == iLSID) { - return iterator.GetData(); - } - iterator.Advance(); - } - return nullptr; -} - void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName) { LinkedListIterator iterator(clientlist); char* output = 0; @@ -341,10 +328,10 @@ void ClientList::ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* s if (iterator.GetData()->GetID() == scl->wid) { cle = iterator.GetData(); if (scl->remove == 2){ - cle->LeavingZone(zoneserver, CLE_Status_Offline); + cle->LeavingZone(zoneserver, CLE_Status::Offline); } else if (scl->remove == 1) - cle->LeavingZone(zoneserver, CLE_Status_Zoning); + cle->LeavingZone(zoneserver, CLE_Status::Zoning); else cle->Update(zoneserver, scl); return; @@ -352,11 +339,11 @@ void ClientList::ClientUpdate(ZoneServer* zoneserver, ServerClientList_Struct* s iterator.Advance(); } if (scl->remove == 2) - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_Online); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::Online); else if (scl->remove == 1) - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_Zoning); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::Zoning); else - cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status_InZone); + cle = new ClientListEntry(GetNextCLEID(), zoneserver, scl, CLE_Status::InZone); clientlist.Insert(cle); zoneserver->ChangeWID(scl->charid, cle->GetID()); } @@ -536,7 +523,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S countcle = countclients.GetData(); const char* tmpZone = database.GetZoneName(countcle->zone()); if ( - (countcle->Online() >= CLE_Status_Zoning) && + (countcle->Online() >= CLE_Status::Zoning) && (!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) && (whom == 0 || ( ((countcle->Admin() >= 80 && countcle->GetGM()) || whom->gmlookup == 0xFFFF) && @@ -616,7 +603,7 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S const char* tmpZone = database.GetZoneName(cle->zone()); if ( - (cle->Online() >= CLE_Status_Zoning) && + (cle->Online() >= CLE_Status::Zoning) && (!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) && (whom == 0 || ( ((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) && @@ -789,7 +776,7 @@ void ClientList::SendFriendsWho(ServerFriendsWho_Struct *FriendsWho, WorldTCPCon Friend_[Seperator - FriendsPointer] = 0; ClientListEntry* CLE = FindCharacter(Friend_); - if(CLE && CLE->name() && (CLE->Online() >= CLE_Status_Zoning) && !(CLE->GetGM() && CLE->Anon())) { + if(CLE && CLE->name() && (CLE->Online() >= CLE_Status::Zoning) && !(CLE->GetGM() && CLE->Anon())) { FriendsCLEs.push_back(CLE); TotalLength += strlen(CLE->name()); int GuildNameLength = strlen(guild_mgr.GetGuildName(CLE->GuildID())); @@ -1001,7 +988,7 @@ void ClientList::ConsoleSendWhoAll(const char* to, int16 admin, Who_All_Struct* cle = iterator.GetData(); const char* tmpZone = database.GetZoneName(cle->zone()); if ( - (cle->Online() >= CLE_Status_Zoning) + (cle->Online() >= CLE_Status::Zoning) && (whom == 0 || ( ((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) && (whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh)) && @@ -1289,6 +1276,19 @@ void ClientList::RemoveCLEByLSID(uint32 iLSID) } } +bool ClientList::IsAccountInGame(uint32 iLSID) { + LinkedListIterator iterator(clientlist); + + while (iterator.MoreElements()) { + if (iterator.GetData()->LSID() == iLSID && iterator.GetData()->Online() == CLE_Status::InZone) { + return true; + } + iterator.Advance(); + } + + return false; +} + int ClientList::GetClientCount() { return(numplayers); } diff --git a/world/clientlist.h b/world/clientlist.h index 19b8adc05..2ed9c3971 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -57,7 +57,6 @@ public: ClientListEntry* FindCharacter(const char* name); ClientListEntry* FindCLEByAccountID(uint32 iAccID); ClientListEntry* FindCLEByCharacterID(uint32 iCharID); - ClientListEntry* FindCLEByLSID(uint32 iLSID); ClientListEntry* GetCLE(uint32 iID); void GetCLEIP(uint32 iIP); uint32 GetCLEIPCount(uint32 iLSAccountID); @@ -67,6 +66,7 @@ public: void CLEAdd(uint32 iLSID, const char* iLoginName, const char* iLoginKey, int16 iWorldAdmin = 0, uint32 ip = 0, uint8 local=0); void UpdateClientGuild(uint32 char_id, uint32 guild_id); void RemoveCLEByLSID(uint32 iLSID); + bool IsAccountInGame(uint32 iLSID); int GetClientCount(); void GetClients(const char *zone_name, std::vector &into); diff --git a/world/login_server.cpp b/world/login_server.cpp index e0990d964..02e9fdbab 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -105,19 +105,11 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) { return; } - if (RuleB(World, DisallowDuplicateAccountLogins)) { - auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); - if (cle != nullptr) { - auto status = cle->GetOnline(); - if (CLE_Status_InZone == status) { - utwrs->response = UserToWorldStatusAlreadyOnline; - SendPacket(&outpack); - return; - } - else { - zoneserver_list.DropClient(utwrs->lsaccountid); - client_list.RemoveCLEByLSID(utwrs->lsaccountid); - } + if (RuleB(World, EnforceCharacterLimitAtLogin)) { + if (client_list.IsAccountInGame(utwr->lsaccountid)) { + utwrs->response = UserToWorldStatusAlreadyOnline; + SendPacket(&outpack); + return; } } diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index bb856c75a..21c5d8e65 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -437,7 +437,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { } ClientListEntry* cle = client_list.FindCharacter(scm->deliverto); - if (cle == 0 || cle->Online() < CLE_Status_Zoning || + if (cle == 0 || cle->Online() < CLE_Status::Zoning || (cle->TellsOff() && ((cle->Anon() == 1 && scm->fromadmin < cle->Admin()) || scm->fromadmin < 80))) { if (!scm->noreply) { ClientListEntry* sender = client_list.FindCharacter(scm->from); @@ -450,7 +450,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { sender->Server()->SendPacket(pack); } } - else if (cle->Online() == CLE_Status_Zoning) { + else if (cle->Online() == CLE_Status::Zoning) { if (!scm->noreply) { ClientListEntry* sender = client_list.FindCharacter(scm->from); if (cle->TellQueueFull()) { @@ -518,7 +518,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { ClientListEntry* cle = client_list.FindCharacter(svm->To); - if (!cle || (cle->Online() < CLE_Status_Zoning) || !cle->Server()) { + if (!cle || (cle->Online() < CLE_Status::Zoning) || !cle->Server()) { zoneserver_list.SendEmoteMessage(svm->From, 0, 0, 0, "'%s is not online at this time'", svm->To); diff --git a/zone/client.cpp b/zone/client.cpp index baf75b0fe..57f6ba865 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -446,7 +446,7 @@ Client::~Client() { numclients--; UpdateWindowTitle(); if(zone) - zone->RemoveAuth(GetName()); + zone->RemoveAuth(GetName(), lskey); //let the stream factory know were done with this stream eqs->Close(); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 54040ca5c..864f11448 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -534,6 +534,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*)pack->pBuffer; if (is_zone_loaded) { SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); + if (szic->zoneid == zone->GetZoneID()) { zone->AddAuth(szic); // This packet also doubles as "incoming client" notification, lets not shut down before they get here diff --git a/zone/zone.cpp b/zone/zone.cpp index 01e6ad42e..185c0e65b 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1114,16 +1114,16 @@ void Zone::AddAuth(ServerZoneIncomingClient_Struct* szic) { client_auth_list.Insert(zca); } -void Zone::RemoveAuth(const char* iCharName) +void Zone::RemoveAuth(const char* iCharName, const char* iLSKey) { LinkedListIterator iterator(client_auth_list); iterator.Reset(); while (iterator.MoreElements()) { ZoneClientAuth_Struct* zca = iterator.GetData(); - if (strcasecmp(zca->charname, iCharName) == 0) { - iterator.RemoveCurrent(); - return; + if (strcasecmp(zca->charname, iCharName) == 0 && strcasecmp(zca->lskey, iLSKey) == 0) { + iterator.RemoveCurrent(); + return; } iterator.Advance(); } @@ -1138,7 +1138,6 @@ void Zone::RemoveAuth(uint32 lsid) ZoneClientAuth_Struct* zca = iterator.GetData(); if (zca->lsid == lsid) { iterator.RemoveCurrent(); - return; } iterator.Advance(); } diff --git a/zone/zone.h b/zone/zone.h index 78bcef0f3..a7de25ab4 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -244,7 +244,7 @@ public: void LoadZoneDoors(const char *zone, int16 version); void ReloadStaticData(); void ReloadWorld(uint32 Option); - void RemoveAuth(const char *iCharName); + void RemoveAuth(const char *iCharName, const char *iLSKey); void RemoveAuth(uint32 lsid); void Repop(uint32 delay = 0); void RepopClose(const glm::vec4 &client_position, uint32 repop_distance); From 9ac15d7a4ba348f271fcb88c2fb836c688d6c653 Mon Sep 17 00:00:00 2001 From: Uleat Date: Wed, 24 Jul 2019 22:48:51 -0400 Subject: [PATCH 098/491] Fix for false elevation of priority in 'vcxproj_dependencies' [skip ci] --- utils/scripts/vcxproj_dependencies.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py index ff53b70f7..c7bcf0e00 100644 --- a/utils/scripts/vcxproj_dependencies.py +++ b/utils/scripts/vcxproj_dependencies.py @@ -555,18 +555,22 @@ def check_for_version_discrepancies(): for priority in priorities: if hints[library][reference][priority] == '': continue + hint_found = False for hint in hints[library][reference][priority].split('|'): if not find_hint_in_path(hint, path) == -1: - if priority > context_tree[project][build][resource][library][reference]: - context_tree[project][build][resource][library][reference] = priority - if context_tree[project][build][resource][library][reference] >\ - build_priorities[build][library]: - build_priorities[build][library] =\ - context_tree[project][build][resource][library][reference] - if context_tree[project][build][resource][library][reference] >\ - global_priorities[library]: - global_priorities[library] =\ - context_tree[project][build][resource][library][reference] + context_tree[project][build][resource][library][reference] = priority + if context_tree[project][build][resource][library][reference] >\ + build_priorities[build][library]: + build_priorities[build][library] =\ + context_tree[project][build][resource][library][reference] + if context_tree[project][build][resource][library][reference] >\ + global_priorities[library]: + global_priorities[library] =\ + context_tree[project][build][resource][library][reference] + hint_found = True + break + if hint_found is True: + break # loop for dumping 'global_priorities' twrite('{0}'.format(col1)) for library in libraries: From cca5fe328691792f6c16f8ad270162e38e440b14 Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 25 Jul 2019 19:55:42 -0400 Subject: [PATCH 099/491] Fix for multiple-argument with explicit token use in 'vcxproj_dependencies' [skip ci] --- utils/scripts/vcxproj_dependencies.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/utils/scripts/vcxproj_dependencies.py b/utils/scripts/vcxproj_dependencies.py index c7bcf0e00..f50c9aec4 100644 --- a/utils/scripts/vcxproj_dependencies.py +++ b/utils/scripts/vcxproj_dependencies.py @@ -144,7 +144,7 @@ def fixup_path(project_path, dependency_path): leading = leading[:leading.rfind('/')] trailing = trailing[3:] trailing = trailing.lower() - trailing = '{0}/{1};'.format(leading, trailing) + trailing = '{0}/{1}'.format(leading, trailing) else: # unix print '..processing unix-style path fix-up' while '../' in trailing: @@ -297,7 +297,7 @@ def check_for_version_discrepancies(): 6: 'submodule' } # use all lowercase for path description - # use forward slash ('/') for directory name breaks + # use forward slash ('/') for directory name separators # use '|' token for multiple hints ('my_file_path_1|my_file_path_2') # use '!!' token for explicit argument ('/perl/core!!' will find '../perl/core' but not '../perl/core/perl512.lib') # use '##' token for joined hints ('my_file_##_1') @@ -341,16 +341,16 @@ def check_for_version_discrepancies(): '', # 'install' '/server/dependencies/zlib_x##/include', # 'dependencies' # not sure if this should be '/libs/zlibng' or '/build/libs/zlibng' based on cmake behavior - '/server/build/libs/zlibng', # 'libs' + '/server/build/libs/zlibng!!', # 'libs' '/server/vcpkg/vcpkg-export-##/installed/x##-windows/include', # 'vcpkg' - '/server/build/libs/zlibng', # 'static' + '/server/build/libs/zlibng!!', # 'static' '' # 'submodule' ], 'source': [ '', # 'NOT FOUND' '', # 'install' '', # 'dependencies' - '/server/libs/zlibng', # 'libs' + '/server/libs/zlibng!!', # 'libs' '', # 'vcpkg' '', # 'static' '' # 'submodule' @@ -362,7 +362,8 @@ def check_for_version_discrepancies(): '', # 'libs' '/server/vcpkg/vcpkg-export-##/installed/x##-windows/&&lib/zlib.lib!!' '^debug/lib/zlibd.lib!!@', # 'vcpkg' - '/server/build/libs/zlibng/##&&zlibstatic.lib!!^zlibstaticd.lib!!@', # 'static' + '/server/build/libs/zlibng/&&debug/zlibstaticd.lib!!^minsizerel/zlibstatic.lib!!' + '^release/zlibstatic.lib!!^relwithdebinfo/zlibstatic.lib!!@', # 'static' '' # 'submodule' ] }, @@ -571,6 +572,16 @@ def check_for_version_discrepancies(): break if hint_found is True: break + # loop for hack to fix odd behavior caused by 'FindZLIB.cmake' - ref: '../server/build/libs/zlibng/zconf.h' + # this does not change anything in the build files..only silences a false discrepancy due to mixing priority types + if global_priorities['zlib'] == 5: + for project in context_tree: + for build in context_tree[project]: + for resource in context_tree[project][build]: + if context_tree[project][build][resource]['zlib']['source'] == 3: + context_tree[project][build][resource]['zlib']['source'] = 5 + if context_tree[project][build][resource]['zlib']['include'] == 3: + context_tree[project][build][resource]['zlib']['include'] = 5 # loop for dumping 'global_priorities' twrite('{0}'.format(col1)) for library in libraries: From 212f8a30625005b6987ae12ccd1a2f7c3a36c2d9 Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 25 Jul 2019 22:26:56 -0700 Subject: [PATCH 100/491] Minor fixes to CLE stale system --- world/client.cpp | 8 +++----- world/client.h | 1 - world/cliententry.cpp | 4 ++-- world/clientlist.cpp | 2 +- zone/client_packet.cpp | 4 ++-- zone/zone.cpp | 1 + 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/world/client.cpp b/world/client.cpp index 3f875cafe..022bf0d41 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -88,7 +88,6 @@ extern volatile bool UCSServerAvailable_; Client::Client(EQStreamInterface* ieqs) : autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)), - CLE_keepalive_timer(RuleI(World, ClientKeepaliveTimeoutMS)), connect(1000), eqs(ieqs) { @@ -1124,10 +1123,9 @@ bool Client::Process() { SendApproveWorld(); connect.Disable(); } - if (CLE_keepalive_timer.Check()) { - if (cle) - cle->KeepAlive(); - } + + if (cle) + cle->KeepAlive(); /************ Get all packets from packet manager out queue and process them ************/ EQApplicationPacket *app = 0; diff --git a/world/client.h b/world/client.h index d36dc692d..e7ab52fa3 100644 --- a/world/client.h +++ b/world/client.h @@ -94,7 +94,6 @@ private: void SetClassLanguages(PlayerProfile_Struct *pp); ClientListEntry* cle; - Timer CLE_keepalive_timer; Timer connect; bool firstlogin; bool seen_character_select; diff --git a/world/cliententry.cpp b/world/cliententry.cpp index 67583a614..d9ae26730 100644 --- a/world/cliententry.cpp +++ b/world/cliententry.cpp @@ -273,8 +273,8 @@ bool ClientListEntry::CheckStale() { if (stale > 20) { if (pOnline > CLE_Status::Offline) SetOnline(CLE_Status::Offline); - else - return true; + + return true; } return false; } diff --git a/world/clientlist.cpp b/world/clientlist.cpp index da14ce71f..cb05e707d 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -41,7 +41,7 @@ extern ZSList zoneserver_list; uint32 numplayers = 0; //this really wants to be a member variable of ClientList... ClientList::ClientList() -: CLStale_timer(45000) +: CLStale_timer(10000) { NextCLEID = 1; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6cc05a65f..f0eb00d13 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1166,8 +1166,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) */ Client* client = entity_list.GetClientByName(cze->char_name); if (!zone->GetAuth(ip, cze->char_name, &WID, &account_id, &character_id, &admin, lskey, &tellsoff)) { - Log(Logs::General, Logs::Error, "GetAuth() returned false kicking client"); - if (client != 0) { + Log(Logs::General, Logs::Client_Login, "%s failed zone auth check.", cze->char_name); + if (nullptr != client) { client->Save(); client->Kick(); } diff --git a/zone/zone.cpp b/zone/zone.cpp index 185c0e65b..2121642bb 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1138,6 +1138,7 @@ void Zone::RemoveAuth(uint32 lsid) ZoneClientAuth_Struct* zca = iterator.GetData(); if (zca->lsid == lsid) { iterator.RemoveCurrent(); + continue; } iterator.Advance(); } From ff4e549ec0d34480eff01043bd10276f130a2905 Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 26 Jul 2019 18:20:01 -0400 Subject: [PATCH 101/491] Fix for cmake 'zlib not found' defaulting to internal libs not working issue [skip ci] --- CMakeLists.txt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d58e2bd1f..6f3a25301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,14 +326,10 @@ IF(ZLIB_FOUND) SET(SERVER_LIBS ${SERVER_LIBS} ${ZLIB_LIBRARY}) ENDIF() ELSE() - # NOTE: This processing chain is broken. - # Path "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" is added to ${SERVER_LIBS}..but, the current CMake process does not - # generate the "${CMAKE_CURRENT_SOURCE_DIR}/build/lib/zlibng" and create the required "zconf.h" file. A path to - # a valid ZLIB package is required to trigger this process. "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng/zconf.h" is not - # valid due to the extension name change to "../zlibng/zconf.h.in" during the ZLIB project creation process. + MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.") + SET(EQEMU_BUILD_ZLIB ON) INCLUDE_DIRECTORIES(BEFORE SYSTEM "${CMAKE_CURRENT_BINARY_DIR}/libs/zlibng" "${CMAKE_CURRENT_SOURCE_DIR}/libs/zlibng") SET(SERVER_LIBS ${SERVER_LIBS} "zlibstatic") - MESSAGE(STATUS "Could NOT find ZLIB - using ZLIBSTATIC package.") ENDIF() IF(WIN32) From 9297fc38f6816268ed4d031def92f1af117bebc9 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 26 Jul 2019 19:22:29 -0700 Subject: [PATCH 102/491] Log kick events --- zone/aa.cpp | 2 +- zone/client.cpp | 10 ++++++++-- zone/client.h | 2 +- zone/client_packet.cpp | 8 +++----- zone/command.cpp | 6 +++--- zone/inventory.cpp | 4 ++-- zone/lua_client.cpp | 2 +- zone/perl_client.cpp | 2 +- zone/questmgr.cpp | 8 ++++---- zone/trading.cpp | 4 ++-- zone/worldserver.cpp | 2 +- zone/zonedb.cpp | 8 ++++++++ zone/zonedb.h | 1 + 13 files changed, 36 insertions(+), 23 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 48ee715f7..4d9854d86 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -489,7 +489,7 @@ void Client::ResetAA() { database.DeleteCharacterLeadershipAAs(CharacterID()); // undefined for these clients if (ClientVersionBit() & EQEmu::versions::maskTitaniumAndEarlier) - Kick(); + Kick("AA Reset on client that doesn't support it"); } void Client::SendClearAA() diff --git a/zone/client.cpp b/zone/client.cpp index 57f6ba865..17521b769 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -845,7 +845,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s { if(AttemptedMessages > RuleI(Chat, MaxMessagesBeforeKick)) { - Kick(); + Kick("Sent too many chat messages at once."); return; } if(GlobalChatLimiterTimer) @@ -2586,13 +2586,19 @@ void Client::SetPVP(bool toggle, bool message) { Save(); } +void Client::Kick(const std::string &reason) { + client_state = CLIENT_KICKED; + + database.CreateKickEvent(GetName(), reason); +} + void Client::WorldKick() { auto outapp = new EQApplicationPacket(OP_GMKick, sizeof(GMKick_Struct)); GMKick_Struct* gmk = (GMKick_Struct *)outapp->pBuffer; strcpy(gmk->name,GetName()); QueuePacket(outapp); safe_delete(outapp); - Kick(); + Kick("World kick issued"); } void Client::GMKill() { diff --git a/zone/client.h b/zone/client.h index 0272fb21b..586541ca6 100644 --- a/zone/client.h +++ b/zone/client.h @@ -371,9 +371,9 @@ public: inline bool ClientDataLoaded() const { return client_data_loaded; } inline bool Connected() const { return (client_state == CLIENT_CONNECTED); } inline bool InZone() const { return (client_state == CLIENT_CONNECTED || client_state == CLIENT_LINKDEAD); } - inline void Kick() { client_state = CLIENT_KICKED; } inline void Disconnect() { eqs->Close(); client_state = DISCONNECTED; } inline bool IsLD() const { return (bool) (client_state == CLIENT_LINKDEAD); } + void Kick(const std::string &reason); void WorldKick(); inline uint8 GetAnon() const { return m_pp.anon; } inline PlayerProfile_Struct& GetPP() { return m_pp; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f0eb00d13..2c8636014 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1169,10 +1169,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) Log(Logs::General, Logs::Client_Login, "%s failed zone auth check.", cze->char_name); if (nullptr != client) { client->Save(); - client->Kick(); + client->Kick("Failed auth check"); } - //ret = false; // TODO: Can we tell the client to get lost in a good way - client_state = CLIENT_KICKED; return; } @@ -9756,7 +9754,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) casting_spell_id); database.SetMQDetectionFlag(AccountName(), GetName(), detect, zone->GetShortName()); safe_delete_array(detect); - Kick(); // Kick client to prevent client and server from getting out-of-sync inventory slots + Kick("Inventory desync"); // Kick client to prevent client and server from getting out-of-sync inventory slots return; } } @@ -9800,7 +9798,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) void Client::Handle_OP_MoveMultipleItems(const EQApplicationPacket *app) { - Kick(); // TODO: lets not desync though + Kick("Unimplemented move multiple items"); // TODO: lets not desync though } void Client::Handle_OP_OpenContainer(const EQApplicationPacket *app) diff --git a/zone/command.cpp b/zone/command.cpp index bd5aa71c9..16e4edd55 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -1912,7 +1912,7 @@ void command_permaclass(Client *c, const Seperator *sep) Log(Logs::General, Logs::Normal, "Class change request from %s for %s, requested class:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); t->SetBaseClass(atoi(sep->arg[1])); t->Save(); - t->Kick(); + t->Kick("Class was changed."); } } @@ -3895,7 +3895,7 @@ void command_kick(Client *c, const Seperator *sep) client->Message(0, "You have been kicked by %s", c->GetName()); auto outapp = new EQApplicationPacket(OP_GMKick, 0); client->QueuePacket(outapp); - client->Kick(); + client->Kick("Ordered kicked by command"); c->Message(0, "Kick: local: kicking %s", sep->arg[1]); } } @@ -5187,7 +5187,7 @@ void command_name(Client *c, const Seperator *sep) c->Message(0, "Successfully renamed %s to %s", oldname, sep->arg[1]); // until we get the name packet working right this will work c->Message(0, "Sending player to char select."); - target->Kick(); + target->Kick("Name was changed"); } else c->Message(13, "ERROR: Unable to rename %s. Check that the new name '%s' isn't already taken.", oldname, sep->arg[2]); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index ec4f095b0..96f0fe15b 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -1608,7 +1608,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { banker ? banker->GetName() : "UNKNOWN NPC", distance); database.SetMQDetectionFlag(AccountName(), GetName(), hacked_string, zone->GetShortName()); safe_delete_array(hacked_string); - Kick(); // Kicking player to avoid item loss do to client and server inventories not being sync'd + Kick("Inventory desync"); // Kicking player to avoid item loss do to client and server inventories not being sync'd return false; } } @@ -1822,7 +1822,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { // Step 4: Check for entity trade if (dst_slot_id >= EQEmu::invslot::TRADE_BEGIN && dst_slot_id <= EQEmu::invslot::TRADE_END) { if (src_slot_id != EQEmu::invslot::slotCursor) { - Kick(); + Kick("Trade with non-cursor item"); return false; } if (with) { diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 9447c48af..c50f6b2f3 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -47,7 +47,7 @@ bool Lua_Client::InZone() { void Lua_Client::Kick() { Lua_Safe_Call_Void(); - self->Kick(); + self->Kick("Lua Quest"); } void Lua_Client::Disconnect() { diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index be1bf2a8e..f86228feb 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -174,7 +174,7 @@ XS(XS_Client_Kick) { if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->Kick(); + THIS->Kick("Perl Quest"); } XSRETURN_EMPTY; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 79f5af8a5..dafc3f1e6 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -809,7 +809,7 @@ void QuestManager::changedeity(int diety_id) { initiator->SetDeity(diety_id); initiator->Message(15,"Your Deity has been changed/set to: %i", diety_id); initiator->Save(1); - initiator->Kick(); + initiator->Kick("Deity change by QuestManager"); } else { @@ -943,7 +943,7 @@ void QuestManager::permaclass(int class_id) { //Makes the client the class specified initiator->SetBaseClass(class_id); initiator->Save(2); - initiator->Kick(); + initiator->Kick("Base class change by QuestManager"); } void QuestManager::permarace(int race_id) { @@ -951,7 +951,7 @@ void QuestManager::permarace(int race_id) { //Makes the client the race specified initiator->SetBaseRace(race_id); initiator->Save(2); - initiator->Kick(); + initiator->Kick("Base race change by QuestManager"); } void QuestManager::permagender(int gender_id) { @@ -959,7 +959,7 @@ void QuestManager::permagender(int gender_id) { //Makes the client the gender specified initiator->SetBaseGender(gender_id); initiator->Save(2); - initiator->Kick(); + initiator->Kick("Base gender change by QuestManager"); } uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { diff --git a/zone/trading.cpp b/zone/trading.cpp index 154fdf148..fe9a72daa 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -112,7 +112,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { // (it just didn't handle partial stack move actions) if (stack_size > 0) { if (!inst->IsStackable() || !inst2 || !inst2->GetItem() || (inst->GetID() != inst2->GetID()) || (stack_size > inst->GetCharges())) { - client->Kick(); + client->Kick("Error stacking item in trade"); return; } @@ -138,7 +138,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { } else { if (inst2 && inst2->GetID()) { - client->Kick(); + client->Kick("Attempting to add null item to trade"); return; } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 864f11448..c2f913d7d 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -559,7 +559,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) auto client = entity_list.GetClientByLSID(drop->lsid); if (client) { - client->Kick(); + client->Kick("Dropped by world CLE subsystem"); client->Save(); } } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index e2825da5a..acf619aba 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3835,6 +3835,14 @@ void ZoneDatabase::UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type QueryDatabase(query); } +void ZoneDatabase::CreateKickEvent(const std::string &character_name, const std::string &reason) +{ + std::string query = + StringFormat("INSERT INTO character_kick_events (Name, Reason) VALUES ('%s', '%s')", character_name.c_str(), reason.c_str()); + + QueryDatabase(query); +} + void ZoneDatabase::LoadPetInfo(Client *client) { diff --git a/zone/zonedb.h b/zone/zonedb.h index f2103715a..285166042 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -292,6 +292,7 @@ public: void SavePetInfo(Client *c); void RemoveTempFactions(Client *c); void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp); + void CreateKickEvent(const std::string &character_name, const std::string &reason); bool DeleteCharacterAAs(uint32 character_id); bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); From 3f2f7b3929f10e27be6ba3f2accb0263676858d9 Mon Sep 17 00:00:00 2001 From: KimLS Date: Fri, 26 Jul 2019 19:23:47 -0700 Subject: [PATCH 103/491] SQL --- .../sql/git/required/2019_07_26_char_kick_events.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 utils/sql/git/required/2019_07_26_char_kick_events.sql diff --git a/utils/sql/git/required/2019_07_26_char_kick_events.sql b/utils/sql/git/required/2019_07_26_char_kick_events.sql new file mode 100644 index 000000000..0b5308be0 --- /dev/null +++ b/utils/sql/git/required/2019_07_26_char_kick_events.sql @@ -0,0 +1,11 @@ +CREATE TABLE `character_kick_events` ( + `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, + `Name` VARCHAR(64) NOT NULL, + `Reason` TEXT NOT NULL, + `Created` TIMESTAMP NOT NULL DEFAULT '', + PRIMARY KEY (`Id`), + INDEX `Name` (`Name`), + INDEX `Created` (`Created`) +) +ENGINE=InnoDB +; From b754ddbc6728871cf42109928d3b0d84952d45bd Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 27 Jul 2019 20:13:04 -0700 Subject: [PATCH 104/491] Change drop client code to not be two step process --- world/client.cpp | 4 +--- zone/worldserver.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/world/client.cpp b/world/client.cpp index 022bf0d41..393e9959b 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -1118,6 +1118,7 @@ bool Client::Process() { Log(Logs::General, Logs::World_Server, "Zone bootup timer expired, bootup failed or too slow."); TellClientZoneUnavailable(); } + if(connect.Check()){ SendGuildList();// Send OPCode: OP_GuildsList SendApproveWorld(); @@ -1189,9 +1190,6 @@ void Client::EnterWorld(bool TryBootup) { else zone_server = zoneserver_list.FindByZoneID(zone_id); - //Tell all the zones to drop any client with this lsid because we're coming back in. - zoneserver_list.DropClient(GetLSID()); - const char *zone_name = database.GetZoneName(zone_id, true); if (zone_server) { // warn the world we're comming, so it knows not to shutdown diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index c2f913d7d..ffe777808 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -536,6 +536,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); if (szic->zoneid == zone->GetZoneID()) { + auto client = entity_list.GetClientByLSID(szic->lsid); + if (client) { + client->Kick("Dropped by world CLE subsystem"); + client->Save(); + } + + zone->RemoveAuth(szic->lsid); zone->AddAuth(szic); // This packet also doubles as "incoming client" notification, lets not shut down before they get here zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); From 979c8190757a1346ffda7385457136c3f23166bc Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Mon, 29 Jul 2019 17:28:58 -0500 Subject: [PATCH 105/491] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index e1126241c..5e4f919fe 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,9 @@ forum, although pull requests will be much quicker and easier on all parties. * GPL Perl - GPL / ActiveState (under the assumption that this is a free project) * CPPUnit - GLP StringUtilities - Apache * LUA - MIT + +## Contributors + + + + From e56edd923135fc3383f9b83262114a0eb3506fd8 Mon Sep 17 00:00:00 2001 From: KimLS Date: Tue, 30 Jul 2019 19:12:44 -0700 Subject: [PATCH 106/491] Some changes to ordering of login authorization for world<->zone --- world/client.cpp | 30 +++++++++++++++++++++--------- world/client.h | 1 + world/zonelist.cpp | 9 +++++++-- world/zonelist.h | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/world/client.cpp b/world/client.cpp index 393e9959b..c29b7d698 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -104,6 +104,7 @@ Client::Client(EQStreamInterface* ieqs) char_name[0] = 0; charid = 0; zone_waiting_for_bootup = 0; + enter_world_triggered = false; StartInTutorial = false; m_ClientVersion = eqs->ClientVersion(); @@ -1192,8 +1193,16 @@ void Client::EnterWorld(bool TryBootup) { const char *zone_name = database.GetZoneName(zone_id, true); if (zone_server) { - // warn the world we're comming, so it knows not to shutdown - zone_server->IncomingClient(this); + if (false == enter_world_triggered) { + //Drop any clients we own in other zones. + zoneserver_list.DropClient(GetLSID(), zone_server); + + // warn the zone we're coming + zone_server->IncomingClient(this); + + //tell the server not to trigger this multiple times before we get a zone unavailable + enter_world_triggered = true; + } } else { if (TryBootup) { @@ -1212,9 +1221,17 @@ void Client::EnterWorld(bool TryBootup) { return; } } + zone_waiting_for_bootup = 0; - if(!cle) { + if (GetAdmin() < 80 && zoneserver_list.IsZoneLocked(zone_id)) { + Log(Logs::General, Logs::World_Server, "Enter world failed. Zone is locked."); + TellClientZoneUnavailable(); + return; + } + + if (!cle) { + TellClientZoneUnavailable(); return; } @@ -1231,12 +1248,6 @@ void Client::EnterWorld(bool TryBootup) { ); if (seen_character_select) { - if (GetAdmin() < 80 && zoneserver_list.IsZoneLocked(zone_id)) { - Log(Logs::General, Logs::World_Server, "Enter world failed. Zone is locked."); - TellClientZoneUnavailable(); - return; - } - auto pack = new ServerPacket; pack->opcode = ServerOP_AcceptWorldEntrance; pack->size = sizeof(WorldToZone_Struct); @@ -1356,6 +1367,7 @@ void Client::TellClientZoneUnavailable() { zone_id = 0; zone_waiting_for_bootup = 0; + enter_world_triggered = false; autobootup_timeout.Disable(); } diff --git a/world/client.h b/world/client.h index e7ab52fa3..4dbad85c5 100644 --- a/world/client.h +++ b/world/client.h @@ -82,6 +82,7 @@ private: bool is_player_zoning; Timer autobootup_timeout; uint32 zone_waiting_for_bootup; + bool enter_world_triggered; bool StartInTutorial; EQEmu::versions::ClientVersion m_ClientVersion; diff --git a/world/zonelist.cpp b/world/zonelist.cpp index 1d06071c4..77782ee9b 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -708,11 +708,16 @@ void ZSList::WorldShutDown(uint32 time, uint32 interval) } } -void ZSList::DropClient(uint32 lsid) { +void ZSList::DropClient(uint32 lsid, ZoneServer *ignore_zoneserver) { ServerPacket packet(ServerOP_DropClient, sizeof(ServerZoneDropClient_Struct)); auto drop = (ServerZoneDropClient_Struct*)packet.pBuffer; drop->lsid = lsid; - SendPacket(&packet); + + for (auto &zs : zone_server_list) { + if (zs.get() != ignore_zoneserver) { + zs->SendPacket(&packet); + } + } } void ZSList::OnTick(EQ::Timer *t) diff --git a/world/zonelist.h b/world/zonelist.h index b99a88e09..8b8525f57 100644 --- a/world/zonelist.h +++ b/world/zonelist.h @@ -57,7 +57,7 @@ public: void SOPZoneBootup(const char *adminname, uint32 ZoneServerID, const char *zonename, bool iMakeStatic = false); void UpdateUCSServerAvailable(bool ucss_available = true); void WorldShutDown(uint32 time, uint32 interval); - void DropClient(uint32 lsid); + void DropClient(uint32 lsid, ZoneServer *ignore_zoneserver); ZoneServer* FindByPort(uint16 port); ZoneServer* FindByID(uint32 ZoneID); From 9d9374ec194f96ef6ba1b3df017bb36e96c32cc6 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Sat, 3 Aug 2019 01:32:56 -0500 Subject: [PATCH 107/491] Fix #gmzone to actually create bucket flags via version --- zone/command.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/command.cpp b/zone/command.cpp index bd5aa71c9..659acd1a1 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4490,7 +4490,7 @@ void command_gmzone(Client *c, const Seperator *sep) identifier = sep->arg[3]; } - std::string bucket_key = StringFormat("%s-%s-instance", zone_short_name, identifier.c_str()); + std::string bucket_key = StringFormat("%s-%s-%u-instance", zone_short_name, zone_version, identifier.c_str()); std::string existing_zone_instance = DataBucket::GetData(bucket_key); if (existing_zone_instance.length() > 0) { From f5cfec529e97c08078c0f0b30a5d7d692d7fe046 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Sat, 3 Aug 2019 04:10:40 -0500 Subject: [PATCH 108/491] Fix format ordering --- zone/command.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/command.cpp b/zone/command.cpp index 659acd1a1..6dda38f71 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -4490,7 +4490,7 @@ void command_gmzone(Client *c, const Seperator *sep) identifier = sep->arg[3]; } - std::string bucket_key = StringFormat("%s-%s-%u-instance", zone_short_name, zone_version, identifier.c_str()); + std::string bucket_key = StringFormat("%s-%s-%u-instance", zone_short_name, identifier.c_str(), zone_version); std::string existing_zone_instance = DataBucket::GetData(bucket_key); if (existing_zone_instance.length() > 0) { From 4498819fad31bd2ec428460de9a7002fade5de07 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 02:58:26 -0500 Subject: [PATCH 109/491] Abstracted CLI command handling interface, streamlined more logging --- common/CMakeLists.txt | 9 +- common/cli/eqemu_command_handler.cpp | 192 +++++++ common/cli/eqemu_command_handler.h | 76 +++ common/cli/terminal_color.hpp | 557 ++++++++++++++++++++ common/net/servertalk_client_connection.cpp | 10 +- common/net/servertalk_server_connection.cpp | 18 +- loginserver/account_management.cpp | 25 +- loginserver/account_management.h | 4 +- loginserver/database.cpp | 35 ++ loginserver/database.h | 14 + loginserver/loginserver_command_handler.cpp | 157 +++--- loginserver/loginserver_command_handler.h | 10 +- loginserver/loginserver_webserver.cpp | 1 + loginserver/main.cpp | 15 +- world/net.cpp | 20 +- 15 files changed, 1004 insertions(+), 139 deletions(-) create mode 100644 common/cli/eqemu_command_handler.cpp create mode 100644 common/cli/eqemu_command_handler.h create mode 100644 common/cli/terminal_color.hpp diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 54c13d897..e6edcee36 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -3,6 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8) SET(common_sources base_packet.cpp classes.cpp + cli/eqemu_command_handler.cpp compression.cpp condition.cpp crash.cpp @@ -108,8 +109,7 @@ SET(common_sources tinyxml/tinyxmlerror.cpp tinyxml/tinyxmlparser.cpp util/directory.cpp - util/uuid.cpp -) + util/uuid.cpp) SET(common_headers any.h @@ -123,6 +123,8 @@ SET(common_headers crc16.h crc32.h cli/argh.h + cli/eqemu_command_handler.h + cli/terminal_color.hpp data_verification.h database.h dbcore.h @@ -270,8 +272,7 @@ SET(common_headers tinyxml/tinyxml.h util/memory_stream.h util/directory.h - util/uuid.h -) + util/uuid.h) SOURCE_GROUP(Event FILES event/event_loop.h diff --git a/common/cli/eqemu_command_handler.cpp b/common/cli/eqemu_command_handler.cpp new file mode 100644 index 000000000..a45948002 --- /dev/null +++ b/common/cli/eqemu_command_handler.cpp @@ -0,0 +1,192 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "eqemu_command_handler.h" +#include "../platform.h" + +namespace EQEmuCommand { + + std::map function_map; + + /** + * @param cmd + */ + void DisplayDebug(argh::parser &cmd) + { + if (cmd[{"-d", "--debug"}]) { + std::cout << "Positional args:\n"; + for (auto &pos_arg : cmd) + std::cout << '\t' << pos_arg << std::endl; + + std::cout << "Positional args:\n"; + for (auto &pos_arg : cmd.pos_args()) + std::cout << '\t' << pos_arg << std::endl; + + std::cout << "\nFlags:\n"; + for (auto &flag : cmd.flags()) + std::cout << '\t' << flag << std::endl; + + std::cout << "\nParameters:\n"; + for (auto ¶m : cmd.params()) + std::cout << '\t' << param.first << " : " << param.second << std::endl; + } + } + + /** + * @param arguments + * @param options + * @param cmd + * @param argc + * @param argv + */ + void ValidateCmdInput( + std::vector &arguments, + std::vector &options, + argh::parser &cmd, + int argc, + char **argv + ) + { + bool arguments_filled = true; + + for (auto &arg : arguments) { + if (cmd(arg).str().empty()) { + arguments_filled = false; + } + } + + if (!arguments_filled || argc == 2) { + std::string arguments_string; + for (auto &arg : arguments) { + arguments_string += " " + arg + "=*\n"; + } + + std::string options_string; + for (auto &opt : options) { + options_string += " " + opt + "\n"; + } + + std::cout << fmt::format( + "Command\n\n{0} \n\nArgs\n{1}\nOptions\n{2}", + argv[1], + arguments_string, + options_string + ) << std::endl; + + exit(1); + } + } + + /** + * @param in_function_map + * @param cmd + * @param argc + * @param argv + */ + void HandleMenu( + std::map &in_function_map, + argh::parser &cmd, + int argc, + char **argv + ) + { + std::string description; + bool ran_command = false; + for (auto &it: in_function_map) { + if (it.first == argv[1]) { + std::cout << std::endl; + std::cout << "> " << termcolor::cyan << "Executing CLI Command" << termcolor::reset << std::endl; + std::cout << std::endl; + + (it.second)(argc, argv, cmd, description); + ran_command = true; + } + } + + if (cmd[{"-h", "--help"}]) { + std::cout << std::endl; + std::cout << + "> " << + termcolor::yellow << + "EQEmulator [" + GetPlatformName() + "] CLI Menu" << + termcolor::reset + << std::endl + << std::endl; + + /** + * Get max command length for padding length + */ + int max_command_length = 0; + + for (auto &it: in_function_map) { + if (it.first.length() > max_command_length) { + std::stringstream command; + command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset; + max_command_length = command.str().length() + 5; + } + } + + /** + * Display command menu + */ + std::string command_section; + for (auto &it: in_function_map) { + description = ""; + + (it.second)(argc, argv, cmd, description); + + /** + * Print section header + */ + std::string command_prefix = it.first.substr(0, it.first.find(":")); + if (command_section != command_prefix) { + command_section = command_prefix; + std::cout << termcolor::reset << command_prefix << std::endl; + } + + /** + * Print commands + */ + std::stringstream command; + command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset; + printf(" %-*s %s\n", max_command_length, command.str().c_str(), description.c_str()); + } + + std::cout << std::endl; + } + else if (!ran_command) { + std::cerr << "Unknown command [" << argv[1] << "] ! Try --help" << std::endl; + } + + exit(1); + } + +} \ No newline at end of file diff --git a/common/cli/eqemu_command_handler.h b/common/cli/eqemu_command_handler.h new file mode 100644 index 000000000..12d23659d --- /dev/null +++ b/common/cli/eqemu_command_handler.h @@ -0,0 +1,76 @@ +/** + * EQEmulator: Everquest Server Emulator + * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY except by those people which sell it, which + * are required to give you total support for your newly bought product; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef EQEMU_EQEMU_COMMAND_HANDLER_H +#define EQEMU_EQEMU_COMMAND_HANDLER_H + +#include "argh.h" +#include "terminal_color.hpp" + +namespace EQEmuCommand { + + extern std::map function_map; + + /** + * @param arguments + * @param options + * @param cmd + * @param argc + * @param argv + */ + void ValidateCmdInput( + std::vector &arguments, + std::vector &options, + argh::parser &cmd, + int argc, + char **argv + ); + + /** + * @param cmd + */ + void DisplayDebug(argh::parser &cmd); + + /** + * @param in_function_map + * @param cmd + * @param argc + * @param argv + */ + void HandleMenu( + std::map &in_function_map, + argh::parser &cmd, + int argc, + char **argv + ); +}; + + +#endif //EQEMU_EQEMU_COMMAND_HANDLER_H diff --git a/common/cli/terminal_color.hpp b/common/cli/terminal_color.hpp new file mode 100644 index 000000000..a98f2483b --- /dev/null +++ b/common/cli/terminal_color.hpp @@ -0,0 +1,557 @@ +//! +//! termcolor +//! ~~~~~~~~~ +//! +//! termcolor is a header-only c++ library for printing colored messages +//! to the terminal. Written just for fun with a help of the Force. +//! +//! :copyright: (c) 2013 by Ihor Kalnytskyi +//! :license: BSD, see LICENSE for details +//! + +#ifndef TERMCOLOR_HPP_ +#define TERMCOLOR_HPP_ + +// the following snippet of code detects the current OS and +// defines the appropriate macro that is used to wrap some +// platform specific things +#if defined(_WIN32) || defined(_WIN64) +# define TERMCOLOR_OS_WINDOWS +#elif defined(__APPLE__) +# define TERMCOLOR_OS_MACOS +#elif defined(__unix__) || defined(__unix) +# define TERMCOLOR_OS_LINUX +#else +# error unsupported platform +#endif + + +// This headers provides the `isatty()`/`fileno()` functions, +// which are used for testing whether a standart stream refers +// to the terminal. As for Windows, we also need WinApi funcs +// for changing colors attributes of the terminal. +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) +# include +#elif defined(TERMCOLOR_OS_WINDOWS) +# include +# include +#endif + + +#include +#include + + + +namespace termcolor +{ + // Forward declaration of the `_internal` namespace. + // All comments are below. + namespace _internal + { + // An index to be used to access a private storage of I/O streams. See + // colorize / nocolorize I/O manipulators for details. + static int colorize_index = std::ios_base::xalloc(); + + inline FILE* get_standard_stream(const std::ostream& stream); + inline bool is_colorized(std::ostream& stream); + inline bool is_atty(const std::ostream& stream); + +#if defined(TERMCOLOR_OS_WINDOWS) + inline void win_change_attributes(std::ostream& stream, int foreground, int background=-1); +#endif + } + + inline + std::ostream& colorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index) = 1L; + return stream; + } + + inline + std::ostream& nocolorize(std::ostream& stream) + { + stream.iword(_internal::colorize_index) = 0L; + return stream; + } + + inline + std::ostream& reset(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;00m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, -1); +#endif + } + return stream; + } + + + inline + std::ostream& bold(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;1m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& dark(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;2m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& underline(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;4m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& blink(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;5m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& reverse(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;7m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& concealed(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;8m"; +#elif defined(TERMCOLOR_OS_WINDOWS) +#endif + } + return stream; + } + + + inline + std::ostream& grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;30m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + 0 // grey (black) + ); +#endif + } + return stream; + } + + inline + std::ostream& red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;31m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;32m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN + ); +#endif + } + return stream; + } + + inline + std::ostream& yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;33m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_GREEN | FOREGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;34m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE + ); +#endif + } + return stream; + } + + inline + std::ostream& magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;35m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;36m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN + ); +#endif + } + return stream; + } + + inline + std::ostream& white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;37m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED + ); +#endif + } + return stream; + } + + + + inline + std::ostream& on_grey(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;40m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + 0 // grey (black) + ); +#endif + } + return stream; + } + + inline + std::ostream& on_red(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;41m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& on_green(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;42m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN + ); +#endif + } + return stream; + } + + inline + std::ostream& on_yellow(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;43m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& on_blue(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;44m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE + ); +#endif + } + return stream; + } + + inline + std::ostream& on_magenta(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;45m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_BLUE | BACKGROUND_RED + ); +#endif + } + return stream; + } + + inline + std::ostream& on_cyan(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;46m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE + ); +#endif + } + return stream; + } + + inline + std::ostream& on_white(std::ostream& stream) + { + if (_internal::is_colorized(stream)) + { +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + stream << "\e[1;47m"; +#elif defined(TERMCOLOR_OS_WINDOWS) + _internal::win_change_attributes(stream, -1, + BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_RED + ); +#endif + } + + return stream; + } + + + + //! Since C++ hasn't a way to hide something in the header from + //! the outer access, I have to introduce this namespace which + //! is used for internal purpose and should't be access from + //! the user code. + namespace _internal + { + //! Since C++ hasn't a true way to extract stream handler + //! from the a given `std::ostream` object, I have to write + //! this kind of hack. + inline + FILE* get_standard_stream(const std::ostream& stream) + { + if (&stream == &std::cout) + return stdout; + else if ((&stream == &std::cerr) || (&stream == &std::clog)) + return stderr; + + return 0; + } + + // Say whether a given stream should be colorized or not. It's always + // true for ATTY streams and may be true for streams marked with + // colorize flag. + inline + bool is_colorized(std::ostream& stream) + { + return is_atty(stream) || static_cast(stream.iword(colorize_index)); + } + + //! Test whether a given `std::ostream` object refers to + //! a terminal. + inline + bool is_atty(const std::ostream& stream) + { + FILE* std_stream = get_standard_stream(stream); + + // Unfortunately, fileno() ends with segmentation fault + // if invalid file descriptor is passed. So we need to + // handle this case gracefully and assume it's not a tty + // if standard stream is not detected, and 0 is returned. + if (!std_stream) + return false; + +#if defined(TERMCOLOR_OS_MACOS) || defined(TERMCOLOR_OS_LINUX) + return ::isatty(fileno(std_stream)); +#elif defined(TERMCOLOR_OS_WINDOWS) + return ::_isatty(_fileno(std_stream)); +#endif + } + +#if defined(TERMCOLOR_OS_WINDOWS) + //! Change Windows Terminal colors attribute. If some + //! parameter is `-1` then attribute won't changed. + inline void win_change_attributes(std::ostream& stream, int foreground, int background) + { + // yeah, i know.. it's ugly, it's windows. + static WORD defaultAttributes = 0; + + // Windows doesn't have ANSI escape sequences and so we use special + // API to change Terminal output color. That means we can't + // manipulate colors by means of "std::stringstream" and hence + // should do nothing in this case. + if (!_internal::is_atty(stream)) + return; + + // get terminal handle + HANDLE hTerminal = INVALID_HANDLE_VALUE; + if (&stream == &std::cout) + hTerminal = GetStdHandle(STD_OUTPUT_HANDLE); + else if (&stream == &std::cerr) + hTerminal = GetStdHandle(STD_ERROR_HANDLE); + + // save default terminal attributes if it unsaved + if (!defaultAttributes) + { + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + defaultAttributes = info.wAttributes; + } + + // restore all default settings + if (foreground == -1 && background == -1) + { + SetConsoleTextAttribute(hTerminal, defaultAttributes); + return; + } + + // get current settings + CONSOLE_SCREEN_BUFFER_INFO info; + if (!GetConsoleScreenBufferInfo(hTerminal, &info)) + return; + + if (foreground != -1) + { + info.wAttributes &= ~(info.wAttributes & 0x0F); + info.wAttributes |= static_cast(foreground); + } + + if (background != -1) + { + info.wAttributes &= ~(info.wAttributes & 0xF0); + info.wAttributes |= static_cast(background); + } + + SetConsoleTextAttribute(hTerminal, info.wAttributes); + } +#endif // TERMCOLOR_OS_WINDOWS + + } // namespace _internal + +} // namespace termcolor + + +#undef TERMCOLOR_OS_WINDOWS +#undef TERMCOLOR_OS_MACOS +#undef TERMCOLOR_OS_LINUX + +#endif // TERMCOLOR_HPP_ diff --git a/common/net/servertalk_client_connection.cpp b/common/net/servertalk_client_connection.cpp index 676d9d024..6a6fb079e 100644 --- a/common/net/servertalk_client_connection.cpp +++ b/common/net/servertalk_client_connection.cpp @@ -213,7 +213,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p) } } else { - LogF(Logs::General, Logs::Error, "Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); + LogError("Could not process hello, size != {0}", 1 + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES); } } else { @@ -225,7 +225,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p) } } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what()); + LogError("Error parsing hello from server: {0}", ex.what()); m_connection->Disconnect(); if (m_on_connect_cb) { @@ -252,7 +252,7 @@ void EQ::Net::ServertalkClient::ProcessHello(EQ::Net::Packet &p) } } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing hello from server: {0}", ex.what()); + LogError("Error parsing hello from server: {0}", ex.what()); m_connection->Disconnect(); if (m_on_connect_cb) { @@ -275,7 +275,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p) std::unique_ptr decrypted_text(new unsigned char[message_len]); if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key)) { - LogF(Logs::General, Logs::Error, "Error decrypting message from server"); + LogError("Error decrypting message from server"); (*(uint64_t*)&m_nonce_theirs[0])++; return; } @@ -323,7 +323,7 @@ void EQ::Net::ServertalkClient::ProcessMessage(EQ::Net::Packet &p) } } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing message from server: {0}", ex.what()); + LogError("Error parsing message from server: {0}", ex.what()); } } diff --git a/common/net/servertalk_server_connection.cpp b/common/net/servertalk_server_connection.cpp index c211545f0..c0e7ef72c 100644 --- a/common/net/servertalk_server_connection.cpp +++ b/common/net/servertalk_server_connection.cpp @@ -220,7 +220,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)p.Data() + crypto_box_PUBLICKEYBYTES + crypto_box_NONCEBYTES, cipher_len, m_nonce_theirs, m_shared_key)) { - LogF(Logs::General, Logs::Error, "Error decrypting handshake from client, dropping connection."); + LogError("Error decrypting handshake from client, dropping connection."); m_connection->Disconnect(); return; } @@ -229,7 +229,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b std::string credentials = (const char*)&decrypted_text[0] + (m_identifier.length() + 1); if (!m_parent->CheckCredentials(credentials)) { - LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection."); + LogError("Got incoming connection with invalid credentials during handshake, dropping connection."); m_connection->Disconnect(); return; } @@ -239,7 +239,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b } } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what()); + LogError("Error parsing handshake from client: {0}", ex.what()); m_connection->Disconnect(); } } @@ -249,7 +249,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b auto credentials = p.GetCString(m_identifier.length() + 1); if (!m_parent->CheckCredentials(credentials)) { - LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection."); + LogError("Got incoming connection with invalid credentials during handshake, dropping connection."); m_connection->Disconnect(); return; } @@ -257,7 +257,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b m_parent->ConnectionIdentified(this); } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what()); + LogError("Error parsing handshake from client: {0}", ex.what()); m_connection->Disconnect(); } } @@ -267,7 +267,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b auto credentials = p.GetCString(m_identifier.length() + 1); if (!m_parent->CheckCredentials(credentials)) { - LogF(Logs::General, Logs::Error, "Got incoming connection with invalid credentials during handshake, dropping connection."); + LogError("Got incoming connection with invalid credentials during handshake, dropping connection."); m_connection->Disconnect(); return; } @@ -275,7 +275,7 @@ void EQ::Net::ServertalkServerConnection::ProcessHandshake(EQ::Net::Packet &p, b m_parent->ConnectionIdentified(this); } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing handshake from client: {0}", ex.what()); + LogError("Error parsing handshake from client: {0}", ex.what()); m_connection->Disconnect(); } #endif @@ -295,7 +295,7 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p) if (crypto_box_open_easy_afternm(&decrypted_text[0], (unsigned char*)&data[0], length, m_nonce_theirs, m_shared_key)) { - LogF(Logs::General, Logs::Error, "Error decrypting message from client"); + LogError("Error decrypting message from client"); (*(uint64_t*)&m_nonce_theirs[0])++; return; } @@ -343,6 +343,6 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p) } } catch (std::exception &ex) { - LogF(Logs::General, Logs::Error, "Error parsing message from client: {0}", ex.what()); + LogError("Error parsing message from client: {0}", ex.what()); } } diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 2ac3c07b5..61c57c68e 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -26,11 +26,13 @@ extern LoginServer server; /** * @param username * @param password + * @param email * @return */ -bool AccountManagement::CreateLocalLoginServerAccount( +uint32 AccountManagement::CreateLocalLoginServerAccount( std::string username, - std::string password + std::string password, + std::string email ) { auto mode = server.options.GetEncryptionMode(); @@ -46,29 +48,32 @@ bool AccountManagement::CreateLocalLoginServerAccount( unsigned int db_id = 0; std::string db_loginserver = server.options.GetDefaultLoginServerName(); if (server.db->DoesLoginServerAccountExist(username, hash, db_loginserver, 1)) { - LogInfo( + LogWarning( "Attempting to create local login account for user [{0}] login [{1}] db_id [{2}] but already exists!", username, db_loginserver, db_id ); - return false; + return 0; } - if (server.db->CreateLoginData(username, hash, db_loginserver, db_id)) { + uint32 created_account_id = server.db->CreateLoginAccount(username, hash, db_loginserver, email); + if (created_account_id > 0) { LogInfo( - "Account creation success for user [{0}] encryption algorithm [{1}] ({2})", + "Account creation success for user [{0}] encryption algorithm [{1}] ({2}) id: [{3}]", username, GetEncryptionByModeId(mode), - mode + mode, + created_account_id ); - return true; + + return created_account_id; } LogError("Failed to create local login account for user [{0}]!", username); - return false; + return 0; } /** @@ -97,7 +102,7 @@ bool AccountManagement::CreateLoginserverWorldAdminAccount( ); if (server.db->DoesLoginserverWorldAdminAccountExist(username)) { - LogInfo( + LogWarning( "Attempting to create world admin account for user [{0}] but already exists!", username ); diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 360ecb4b0..3bd14873a 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -21,6 +21,7 @@ #define EQEMU_ACCOUNT_MANAGEMENT_H #include "iostream" +#include "../common/types.h" class AccountManagement { public: @@ -28,9 +29,10 @@ public: /** * @param username * @param password + * @param email * @return */ - static bool CreateLocalLoginServerAccount(std::string username, std::string password); + static uint32 CreateLocalLoginServerAccount(std::string username, std::string password, std::string email = ""); /** * @param username diff --git a/loginserver/database.cpp b/loginserver/database.cpp index ce1de51ce..9f8e5a6c7 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -226,6 +226,41 @@ bool Database::CreateLoginData( return CreateLoginDataWithID(name, password, loginserver, free_id); } +/** + * @param name + * @param password + * @param loginserver + * @param email + * @return + */ +uint32 Database::CreateLoginAccount( + const std::string &name, + const std::string &password, + const std::string &loginserver, + const std::string &email +) +{ + uint32 free_id = GetFreeID(loginserver); + + if (free_id <= 0) { + return 0; + } + + auto query = fmt::format( + "INSERT INTO login_accounts (id, source_loginserver, account_name, account_password, account_email, last_login_date, last_ip_address, created_at) " + "VALUES ({0}, '{1}', '{2}', '{3}', '{4}', NOW(), '127.0.0.1', NOW())", + free_id, + EscapeString(loginserver), + EscapeString(name), + EscapeString(password), + EscapeString(email) + ); + + auto results = QueryDatabase(query); + + return (results.Success() ? free_id : 0); +} + /** * @param in_account_name * @param in_account_password diff --git a/loginserver/database.h b/loginserver/database.h index fec7ad797..aa3d2911b 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -248,6 +248,20 @@ public: Database::DbLoginServerAdmin GetLoginServerAdmin(const std::string &account_name); + /** + * @param name + * @param password + * @param loginserver + * @param email + * @return + */ + uint32 CreateLoginAccount( + const std::string &name, + const std::string &password, + const std::string &loginserver = "local", + const std::string &email = "local_creation" + ); + protected: std::string user, pass, host, port, name; MYSQL *database{}; diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 3337a52e9..c8a60037d 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -30,30 +30,6 @@ extern LoginServer server; namespace LoginserverCommandHandler { - /** - * @param cmd - */ - void DisplayDebug(argh::parser &cmd) - { - if (cmd[{"-d", "--debug"}]) { - std::cout << "Positional args:\n"; - for (auto &pos_arg : cmd) - std::cout << '\t' << pos_arg << std::endl; - - std::cout << "Positional args:\n"; - for (auto &pos_arg : cmd.pos_args()) - std::cout << '\t' << pos_arg << std::endl; - - std::cout << "\nFlags:\n"; - for (auto &flag : cmd.flags()) - std::cout << '\t' << flag << std::endl; - - std::cout << "\nParameters:\n"; - for (auto ¶m : cmd.params()) - std::cout << '\t' << param.first << " : " << param.second << std::endl; - } - } - /** * @param argc * @param argv @@ -64,74 +40,46 @@ namespace LoginserverCommandHandler { argh::parser cmd; cmd.parse(argc, argv, argh::parser::PREFER_PARAM_FOR_UNREG_OPTION); - LoginserverCommandHandler::DisplayDebug(cmd); + EQEmuCommand::DisplayDebug(cmd); /** * Declare command mapping */ - std::map function_map; + auto function_map = EQEmuCommand::function_map; - function_map["create-loginserver-account"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; - function_map["create-loginserver-api-token"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["create-loginserver-world-admin-account"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; - function_map["list-loginserver-api-tokens"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + /** + * Register commands + */ + function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; - std::map::const_iterator it = function_map.begin(); - - std::map::const_iterator end = function_map.end(); - - bool ran_command = false; - while (it != end) { - if (it->first == argv[1]) { - std::cout << std::endl; - std::cout << "###########################################################" << std::endl; - std::cout << "# Executing CLI Command" << std::endl; - std::cout << "###########################################################" << std::endl; - std::cout << std::endl; - - (it->second)(argc, argv, cmd); - ran_command = true; - } - ++it; - } - - if (cmd[{"-h", "--help"}] || !ran_command) { - std::cout << std::endl; - std::cout << "###########################################################" << std::endl; - std::cout << "# Loginserver CLI Menu" << std::endl; - std::cout << "###########################################################" << std::endl; - std::cout << std::endl; - std::cout << "# API" << std::endl; - std::cout << "> create-loginserver-api-token --write --read" << std::endl; - std::cout << "> list-loginserver-api-tokens" << std::endl; - std::cout << std::endl; - std::cout << "# User Accounts" << std::endl; - std::cout << "> create-loginserver-account --username=* --password=*" << std::endl; - std::cout << std::endl; - std::cout << "# World Accounts" << std::endl; - std::cout << "> create-loginserver-world-admin-account --username=* --password=* --email=*" << std::endl; - std::cout << std::endl; - std::cout << std::endl; - } - - exit(1); + EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); } /** * @param argc * @param argv * @param cmd + * @param description */ - void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd) + void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd, std::string &description) { + description = "Creates Loginserver API Token"; + + if (cmd[{"-h", "--help"}]) { + return; + } + + std::vector arguments = {}; + std::vector options = { + "--read", + "--write" + }; + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + bool can_read = cmd[{"-r", "--read"}]; bool can_write = cmd[{"-w", "--write"}]; @@ -150,9 +98,16 @@ namespace LoginserverCommandHandler { * @param argc * @param argv * @param cmd + * @param description */ - void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd) + void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd, std::string &description) { + description = "Lists Loginserver API Tokens"; + + if (cmd[{"-h", "--help"}]) { + return; + } + for (auto &it : server.token_manager->loaded_api_tokens) { LogInfo( "token [{0}] can_write [{1}] can_read [{2}]", @@ -167,17 +122,30 @@ namespace LoginserverCommandHandler { * @param argc * @param argv * @param cmd + * @param description */ - void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd) + void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description) { - if (cmd("--username").str().empty() || cmd("--password").str().empty()) { - LogInfo("Command Example: create-loginserver-account --username=user --password=password"); - exit(1); + description = "Creates Local Loginserver Account"; + + std::vector arguments = { + "--username", + "--password" + }; + std::vector options = { + "--email=*" + }; + + if (cmd[{"-h", "--help"}]) { + return; } + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + AccountManagement::CreateLocalLoginServerAccount( cmd("--username").str(), - cmd("--password").str() + cmd("--password").str(), + cmd("--email").str() ); } @@ -185,18 +153,25 @@ namespace LoginserverCommandHandler { * @param argc * @param argv * @param cmd + * @param description */ - void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd) + void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description) { - if ( - cmd("--username").str().empty() || - cmd("--password").str().empty() || - cmd("--email").str().empty()) { + description = "Creates Loginserver World Administrator Account"; - LogInfo("Command Example: create-loginserver-world-admin-account --username=* --password=* --email=*"); - exit(1); + std::vector arguments = { + "--username", + "--password" + "--email" + }; + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; } + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + AccountManagement::CreateLoginserverWorldAdminAccount( cmd("--username").str(), cmd("--password").str(), diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index e37432807..44d46e83e 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -19,17 +19,17 @@ */ #include "iostream" -#include "../common/cli/argh.h" +#include "../common/cli/eqemu_command_handler.h" #ifndef EQEMU_LOGINSERVER_COMMAND_HANDLER_H #define EQEMU_LOGINSERVER_COMMAND_HANDLER_H namespace LoginserverCommandHandler { void CommandHandler(int argc, char **argv); - void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd); - void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd); - void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd); - void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd); + void CreateLoginserverApiToken(int argc, char **argv, argh::parser &cmd, std::string &description); + void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd, std::string &description); + void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description); + void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description); }; diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index ca8d00404..45900c7d1 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -67,6 +67,7 @@ namespace LoginserverWebserver { Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); + std::string email = request_body.get("email", "").asString(); Json::Value response; if (username.empty() || password.empty()) { diff --git a/loginserver/main.cpp b/loginserver/main.cpp index f94bdd0c7..9884e6c2a 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -48,10 +48,12 @@ int main(int argc, char** argv) RegisterExecutablePlatform(ExePlatformLogin); set_exception_handler(); - LogSys.LoadLogSettingsDefaults(); - LogInfo("Logging System Init"); + if (argc == 1) { + LogSys.LoadLogSettingsDefaults(); + } + server.config = EQ::JsonConfigFile::Load("login.json"); LogInfo("Config System Init"); @@ -123,7 +125,9 @@ int main(int argc, char** argv) server.config.GetVariableString("database", "db", "peq") ); - server.db->LoadLogSettings(LogSys.log_settings); + if (argc == 1) { + server.db->LoadLogSettings(LogSys.log_settings); + } /** * make sure our database got created okay, otherwise cleanup and exit @@ -186,7 +190,10 @@ int main(int argc, char** argv) LoginserverWebserver::RegisterRoutes(api); } - LoginserverCommandHandler::CommandHandler(argc, argv); + if (argc > 1) { + LogSys.LoadLogSettingsDefaults(); + LoginserverCommandHandler::CommandHandler(argc, argv); + } LogInfo("[Config] [Logging] IsTraceOn [{0}]", server.options.IsTraceOn()); LogInfo("[Config] [Logging] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn()); diff --git a/world/net.cpp b/world/net.cpp index 515f50b66..20248343f 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -427,7 +427,7 @@ int main(int argc, char** argv) { Log(Logs::General, Logs::World_Server, "Server (TCP) listener started."); server_connection->OnConnectionIdentified("Zone", [&console](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "New Zone Server connection from {2} at {0}:{1}", + LogInfo("New Zone Server connection from {2} at {0}:{1}", connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); numzones++; @@ -435,7 +435,7 @@ int main(int argc, char** argv) { }); server_connection->OnConnectionRemoved("Zone", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "Removed Zone Server connection from {0}", + LogInfo("Removed Zone Server connection from {0}", connection->GetUUID()); numzones--; @@ -443,35 +443,35 @@ int main(int argc, char** argv) { }); server_connection->OnConnectionIdentified("Launcher", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "New Launcher connection from {2} at {0}:{1}", + LogInfo("New Launcher connection from {2} at {0}:{1}", connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); launcher_list.Add(connection); }); server_connection->OnConnectionRemoved("Launcher", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "Removed Launcher connection from {0}", + LogInfo("Removed Launcher connection from {0}", connection->GetUUID()); launcher_list.Remove(connection); }); server_connection->OnConnectionIdentified("QueryServ", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "New Query Server connection from {2} at {0}:{1}", + LogInfo("New Query Server connection from {2} at {0}:{1}", connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); QSLink.AddConnection(connection); }); server_connection->OnConnectionRemoved("QueryServ", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "Removed Query Server connection from {0}", + LogInfo("Removed Query Server connection from {0}", connection->GetUUID()); QSLink.RemoveConnection(connection); }); server_connection->OnConnectionIdentified("UCS", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "New UCS Server connection from {2} at {0}:{1}", + LogInfo("New UCS Server connection from {2} at {0}:{1}", connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); UCSLink.SetConnection(connection); @@ -480,7 +480,7 @@ int main(int argc, char** argv) { }); server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "Removed Query Server connection from {0}", + LogInfo("Removed Query Server connection from {0}", connection->GetUUID()); UCSLink.SetConnection(nullptr); @@ -489,14 +489,14 @@ int main(int argc, char** argv) { }); server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "New WebInterface Server connection from {2} at {0}:{1}", + LogInfo("New WebInterface Server connection from {2} at {0}:{1}", connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID()); web_interface.AddConnection(connection); }); server_connection->OnConnectionRemoved("WebInterface", [](std::shared_ptr connection) { - LogF(Logs::General, Logs::World_Server, "Removed WebInterface Server connection from {0}", + LogInfo("Removed WebInterface Server connection from {0}", connection->GetUUID()); web_interface.RemoveConnection(connection); From 63e1599e9b07e0325804ce46709cff3eb73fdf44 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 03:06:09 -0500 Subject: [PATCH 110/491] Remove colon from bearer API key --- loginserver/loginserver_webserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 45900c7d1..f0ead7092 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -202,7 +202,7 @@ namespace LoginserverWebserver { auto header_value = header.second; if (header_key == "Authorization") { authorization_key = header.second; - find_replace(authorization_key, "Bearer: ", ""); + find_replace(authorization_key, "Bearer ", ""); if (LoginserverWebserver::TokenManager::TokenExists(authorization_key)) { user_token = server.token_manager->GetToken(authorization_key); } From 5ff0f4851e62b0132ff86813af0ff32572547acd Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 03:11:30 -0500 Subject: [PATCH 111/491] Add path to http request logging, add email to local account creation through web endpoint --- loginserver/loginserver_webserver.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index f0ead7092..925e03430 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -76,7 +76,7 @@ namespace LoginserverWebserver { return; } - bool account_created = AccountManagement::CreateLocalLoginServerAccount(username, password); + bool account_created = AccountManagement::CreateLocalLoginServerAccount(username, password, email); if (account_created) { response["message"] = "Account created successfully!"; } @@ -218,10 +218,11 @@ namespace LoginserverWebserver { } LogDebug( - "Authentication Request | remote_address [{0}] user_agent [{1}] authorization_key [{2}]", + "Authentication Request | remote_address [{0}] user_agent [{1}] authorization_key [{2}] request_path [{3}]", user_token.remote_address, user_token.user_agent, - authorization_key + authorization_key, + request.path ); return user_token; From b0d33f094ddd7402f66fc4ff090be7ea19639d72 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 04:16:14 -0500 Subject: [PATCH 112/491] Add local credential validation logic --- common/eqemu_logsys.cpp | 3 +- loginserver/account_management.cpp | 55 +++++++++++++++++++++ loginserver/account_management.h | 11 +++++ loginserver/database.cpp | 37 ++++++++++++++ loginserver/database.h | 18 +++++++ loginserver/loginserver_command_handler.cpp | 36 ++++++++++++-- loginserver/loginserver_command_handler.h | 1 + loginserver/loginserver_webserver.cpp | 37 ++++++++++++-- 8 files changed, 189 insertions(+), 9 deletions(-) diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 36246ae32..f9b9bcb81 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -143,6 +143,7 @@ void EQEmuLogSys::LoadLogSettingsDefaults() log_settings[Logs::Warning].log_to_console = static_cast(Logs::General); log_settings[Logs::Notice].log_to_console = static_cast(Logs::General); log_settings[Logs::Info].log_to_console = static_cast(Logs::General); + log_settings[Logs::Debug].log_to_console = static_cast(Logs::General); /** * Set Category enabled status on defaults @@ -470,7 +471,7 @@ void EQEmuLogSys::Out( prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line); } - auto msg_cstr = message.c_str(); + auto msg_cstr = message.c_str(); va_list args; va_start(args, msg_cstr); std::string output_message = vStringFormat(msg_cstr, args); diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 61c57c68e..be17ac149 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -134,3 +134,58 @@ bool AccountManagement::CreateLoginserverWorldAdminAccount( return false; } + +/** + * @param in_account_username + * @param in_account_password + * @return + */ +bool AccountManagement::CheckLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password, + const std::string &source_loginserver +) +{ + auto mode = server.options.GetEncryptionMode(); + + Database::DbLoginServerAccount + login_server_admin = server.db->GetLoginServerAccountByAccountName( + in_account_username, + source_loginserver + ); + + if (!login_server_admin.loaded) { + LogError( + "CheckLoginUserCredentials account [{0}] source_loginserver [{1}] not found!", + in_account_username, + source_loginserver + ); + + return false; + } + + bool validated_credentials = eqcrypt_verify_hash( + in_account_username, + in_account_password, + login_server_admin.account_password, + mode + ); + + if (!validated_credentials) { + LogError( + "CheckLoginUserCredentials account [{0}] source_loginserver [{1}] invalid credentials!", + in_account_username, + source_loginserver + ); + + return false; + } + + LogDebug( + "CheckLoginUserCredentials account [{0}] source_loginserver [{1}] credentials validated success!", + in_account_username, + source_loginserver + ); + + return validated_credentials; +} diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 3bd14873a..64b22349c 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -48,6 +48,17 @@ public: const std::string &last_name = "", const std::string &ip_address = "" ); + + /** + * @param in_account_username + * @param in_account_password + * @return + */ + static bool CheckLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password, + const std::string &source_loginserver = "local" + ); }; diff --git a/loginserver/database.cpp b/loginserver/database.cpp index 9f8e5a6c7..b795f708a 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -730,3 +730,40 @@ Database::DbLoginServerAdmin Database::GetLoginServerAdmin(const std::string &ac return login_server_admin; } + +/** + * @param account_name + * @return + */ +Database::DbLoginServerAccount Database::GetLoginServerAccountByAccountName( + const std::string &account_name, + const std::string &source_loginserver +) +{ + auto query = fmt::format( + "SELECT id, account_name, account_password, account_email, source_loginserver, last_ip_address, last_login_date, " + "created_at, updated_at" + " FROM login_accounts WHERE account_name = '{0}' and source_loginserver = '{1}' LIMIT 1", + EscapeString(account_name), + EscapeString(source_loginserver) + ); + + auto results = QueryDatabase(query); + + Database::DbLoginServerAccount login_server_account{}; + if (results.RowCount() == 1) { + auto row = results.begin(); + login_server_account.loaded = true; + login_server_account.id = std::stoi(row[0]); + login_server_account.account_name = row[1]; + login_server_account.account_password = row[2]; + login_server_account.account_email = row[3]; + login_server_account.source_loginserver = row[4]; + login_server_account.last_ip_address = row[5]; + login_server_account.last_login_date = row[6]; + login_server_account.created_at = row[7]; + login_server_account.updated_at = row[8]; + } + + return login_server_account; +} \ No newline at end of file diff --git a/loginserver/database.h b/loginserver/database.h index aa3d2911b..5d8237fbd 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -248,6 +248,24 @@ public: Database::DbLoginServerAdmin GetLoginServerAdmin(const std::string &account_name); + struct DbLoginServerAccount { + bool loaded = false; + uint32 id; + std::string account_name; + std::string account_password; + std::string account_email; + std::string source_loginserver; + std::string last_login_date; + std::string last_ip_address; + std::string created_at; + std::string updated_at; + }; + + Database::DbLoginServerAccount GetLoginServerAccountByAccountName( + const std::string &account_name, + const std::string &source_loginserver = "local" + ); + /** * @param name * @param password diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index c8a60037d..2ba40f264 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -50,10 +50,11 @@ namespace LoginserverCommandHandler { /** * Register commands */ - function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; - function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; - function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; + function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; + function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); } @@ -179,4 +180,31 @@ namespace LoginserverCommandHandler { ); } + /** + * @param argc + * @param argv + * @param cmd + * @param description + */ + void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description) + { + description = "Check user login credentials"; + + std::vector arguments = { + "--username", + "--password" + }; + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + AccountManagement::CheckLoginserverUserCredentials( + cmd("--username").str(), + cmd("--password").str() + ); + } } diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index 44d46e83e..0e46b78eb 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -30,6 +30,7 @@ namespace LoginserverCommandHandler { void ListLoginserverApiTokens(int argc, char **argv, argh::parser &cmd, std::string &description); void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description); + void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); }; diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 925e03430..a9d38a736 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -87,6 +87,37 @@ namespace LoginserverWebserver { LoginserverWebserver::SendResponse(response, res); } ); + + api.Post( + "/account/credentials/validate/local", [](const httplib::Request &request, httplib::Response &res) { + LoginserverWebserver::TokenManager::AuthCanRead(request, res); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); + std::string email = request_body.get("email", "").asString(); + + Json::Value response; + if (username.empty() || password.empty()) { + response["message"] = "Username or password not set"; + LoginserverWebserver::SendResponse(response, res); + return; + } + + bool credentials_valid = AccountManagement::CheckLoginserverUserCredentials( + username, + password + ); + + if (credentials_valid) { + response["message"] = "Credentials valid!"; + } + else { + response["error"] = "Credentials invalid!"; + } + + LoginserverWebserver::SendResponse(response, res); + } + ); } /** @@ -146,8 +177,7 @@ namespace LoginserverWebserver { res.set_header("response_set", "true"); LogWarning( - "AuthCanRead access failure | token [{0}] remote_address [{1}] user_agent [{2}]", - user_token.token, + "AuthCanRead access failure remote_address [{0}] user_agent [{1}]", user_token.remote_address, user_token.user_agent ); @@ -174,8 +204,7 @@ namespace LoginserverWebserver { res.set_header("response_set", "true"); LogWarning( - "AuthCanWrite access failure | token [{0}] remote_address [{1}] user_agent [{2}]", - user_token.token, + "AuthCanWrite access failure remote_address [{0}] user_agent [{1}]", user_token.remote_address, user_token.user_agent ); From ba6009730b6e84f8f430aa0b2377999fa767ef9e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 05:04:34 -0500 Subject: [PATCH 113/491] Add CLI and Web endpoints to change local login account password --- common/eqemu_logsys.cpp | 1 - loginserver/account_management.cpp | 49 +++++++++++++++ loginserver/account_management.h | 11 ++++ loginserver/client.cpp | 69 ++++++++++++++------- loginserver/client.h | 16 ++--- loginserver/database.cpp | 2 +- loginserver/database.h | 5 +- loginserver/loginserver_command_handler.cpp | 38 ++++++++++-- loginserver/loginserver_command_handler.h | 1 + loginserver/loginserver_webserver.cpp | 42 ++++++++++++- loginserver/main.cpp | 14 ++++- 11 files changed, 204 insertions(+), 44 deletions(-) diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index f9b9bcb81..87d4465b4 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -143,7 +143,6 @@ void EQEmuLogSys::LoadLogSettingsDefaults() log_settings[Logs::Warning].log_to_console = static_cast(Logs::General); log_settings[Logs::Notice].log_to_console = static_cast(Logs::General); log_settings[Logs::Info].log_to_console = static_cast(Logs::General); - log_settings[Logs::Debug].log_to_console = static_cast(Logs::General); /** * Set Category enabled status on defaults diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index be17ac149..2817b09ff 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -189,3 +189,52 @@ bool AccountManagement::CheckLoginserverUserCredentials( return validated_credentials; } + + +/** + * @param in_account_username + * @param in_account_password + * @return + */ +bool AccountManagement::UpdateLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password, + const std::string &source_loginserver +) +{ + auto mode = server.options.GetEncryptionMode(); + + Database::DbLoginServerAccount + login_server_account = server.db->GetLoginServerAccountByAccountName( + in_account_username, + source_loginserver + ); + + if (!login_server_account.loaded) { + LogError( + "ChangeLoginserverUserCredentials account [{0}] source_loginserver [{1}] not found!", + in_account_username, + source_loginserver + ); + + return false; + } + + server.db->UpdateLoginserverAccountPasswordHash( + in_account_username, + source_loginserver, + eqcrypt_hash( + in_account_username, + in_account_password, + mode + ) + ); + + LogDebug( + "ChangeLoginserverUserCredentials account [{0}] source_loginserver [{1}] credentials updated!", + in_account_username, + source_loginserver + ); + + return true; +} diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 64b22349c..3ab179405 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -59,6 +59,17 @@ public: const std::string &in_account_password, const std::string &source_loginserver = "local" ); + + /** + * @param in_account_username + * @param in_account_password + * @return + */ + static bool UpdateLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password, + const std::string &source_loginserver = "local" + ); }; diff --git a/loginserver/client.cpp b/loginserver/client.cpp index 5e82dea74..cd0999f5c 100644 --- a/loginserver/client.cpp +++ b/loginserver/client.cpp @@ -486,21 +486,21 @@ void Client::DoFailedLogin() /** * Verifies a login hash, will also attempt to update a login hash if needed * - * @param user - * @param loginserver - * @param cred - * @param hash + * @param account_username + * @param source_loginserver + * @param account_password + * @param password_hash * @return */ bool Client::VerifyLoginHash( - const std::string &user, - const std::string &loginserver, - const std::string &cred, - const std::string &hash + const std::string &account_username, + const std::string &source_loginserver, + const std::string &account_password, + const std::string &password_hash ) { auto mode = server.options.GetEncryptionMode(); - if (eqcrypt_verify_hash(user, cred, hash, mode)) { + if (eqcrypt_verify_hash(account_username, account_password, password_hash, mode)) { return true; } else { @@ -509,46 +509,67 @@ bool Client::VerifyLoginHash( mode = EncryptionModeArgon2; } - if (hash.length() == 32) { //md5 is insecure + if (password_hash.length() == 32) { //md5 is insecure for (int i = EncryptionModeMD5; i <= EncryptionModeMD5Triple; ++i) { - if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + if (i != mode && eqcrypt_verify_hash(account_username, account_password, password_hash, i)) { LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", - user, - loginserver, + account_username, + source_loginserver, mode ); - server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + server.db->UpdateLoginserverAccountPasswordHash( + account_username, + source_loginserver, + eqcrypt_hash( + account_username, + account_password, + mode + )); return true; } } } - else if (hash.length() == 40) { //sha1 is insecure + else if (password_hash.length() == 40) { //sha1 is insecure for (int i = EncryptionModeSHA; i <= EncryptionModeSHATriple; ++i) { - if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + if (i != mode && eqcrypt_verify_hash(account_username, account_password, password_hash, i)) { LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", - user, - loginserver, + account_username, + source_loginserver, mode ); - server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + server.db->UpdateLoginserverAccountPasswordHash( + account_username, + source_loginserver, + eqcrypt_hash( + account_username, + account_password, + mode + )); return true; } } } - else if (hash.length() == 128) { //sha2-512 is insecure + else if (password_hash.length() == 128) { //sha2-512 is insecure for (int i = EncryptionModeSHA512; i <= EncryptionModeSHA512Triple; ++i) { - if (i != mode && eqcrypt_verify_hash(user, cred, hash, i)) { + if (i != mode && eqcrypt_verify_hash(account_username, account_password, password_hash, i)) { LogDebug( "user [{0}] loginserver [{1}] mode [{2}]", - user, - loginserver, + account_username, + source_loginserver, mode ); - server.db->UpdateLoginHash(user, loginserver, eqcrypt_hash(user, cred, mode)); + server.db->UpdateLoginserverAccountPasswordHash( + account_username, + source_loginserver, + eqcrypt_hash( + account_username, + account_password, + mode + )); return true; } } diff --git a/loginserver/client.h b/loginserver/client.h index d95b3c286..b8f092db3 100644 --- a/loginserver/client.h +++ b/loginserver/client.h @@ -177,17 +177,17 @@ public: /** * Verifies a login hash, will also attempt to update a login hash if needed * - * @param user - * @param loginserver - * @param cred - * @param hash + * @param account_username + * @param source_loginserver + * @param account_password + * @param password_hash * @return */ bool VerifyLoginHash( - const std::string &user, - const std::string &loginserver, - const std::string &cred, - const std::string &hash + const std::string &account_username, + const std::string &source_loginserver, + const std::string &account_password, + const std::string &password_hash ); void DoSuccessfulLogin(const std::string in_account_name, int db_account_id, const std::string &db_loginserver); diff --git a/loginserver/database.cpp b/loginserver/database.cpp index b795f708a..4b224061c 100644 --- a/loginserver/database.cpp +++ b/loginserver/database.cpp @@ -330,7 +330,7 @@ bool Database::DoesLoginServerAccountExist( * @param loginserver * @param hash */ -void Database::UpdateLoginHash( +void Database::UpdateLoginserverAccountPasswordHash( const std::string &name, const std::string &loginserver, const std::string &hash diff --git a/loginserver/database.h b/loginserver/database.h index 5d8237fbd..ef1d7bfe0 100644 --- a/loginserver/database.h +++ b/loginserver/database.h @@ -121,7 +121,10 @@ public: * @param loginserver * @param hash */ - void UpdateLoginHash(const std::string &name, const std::string &loginserver, const std::string &hash); + void UpdateLoginserverAccountPasswordHash( + const std::string &name, + const std::string &loginserver, + const std::string &hash); /** * @param name diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 2ba40f264..dadf93e34 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -50,11 +50,12 @@ namespace LoginserverCommandHandler { /** * Register commands */ - function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; - function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; - function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; - function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; + function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; + function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["login-user:update-credentials"] = &LoginserverCommandHandler::UpdateLoginserverUserCredentials; + function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); } @@ -207,4 +208,31 @@ namespace LoginserverCommandHandler { cmd("--password").str() ); } + + /** + * @param argc + * @param argv + * @param cmd + * @param description + void UpdateLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description) + { + description = "Change user login credentials"; + + std::vector arguments = { + "--username", + "--password" + }; + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + AccountManagement::UpdateLoginserverUserCredentials( + cmd("--username").str(), + cmd("--password").str() + ); + } } diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index 0e46b78eb..d155c8a0c 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -31,6 +31,7 @@ namespace LoginserverCommandHandler { void CreateLocalLoginserverAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); + void UpdateLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); }; diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index a9d38a736..3c2b8c72e 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -94,7 +94,6 @@ namespace LoginserverWebserver { Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); - std::string email = request_body.get("email", "").asString(); Json::Value response; if (username.empty() || password.empty()) { @@ -118,6 +117,47 @@ namespace LoginserverWebserver { LoginserverWebserver::SendResponse(response, res); } ); + + api.Post( + "/account/credentials/update/local", [](const httplib::Request &request, httplib::Response &res) { + LoginserverWebserver::TokenManager::AuthCanWrite(request, res); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); + + Json::Value response; + if (username.empty() || password.empty()) { + response["message"] = "Username or password not set"; + LoginserverWebserver::SendResponse(response, res); + return; + } + + Database::DbLoginServerAccount + login_server_account = server.db->GetLoginServerAccountByAccountName( + username + ); + + if (!login_server_account.loaded) { + response["error"] = "Failed to find associated loginserver account!"; + LoginserverWebserver::SendResponse(response, res); + return; + } + + bool credentials_valid = AccountManagement::UpdateLoginserverUserCredentials( + username, + password + ); + + if (credentials_valid) { + response["message"] = "Loginserver account credentials updated!"; + } + else { + response["error"] = "Failed to update loginserver account credentials!"; + } + + LoginserverWebserver::SendResponse(response, res); + } + ); } /** diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 9884e6c2a..217929ea2 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -43,7 +43,7 @@ void CatchSignal(int sig_num) { } -int main(int argc, char** argv) +int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformLogin); set_exception_handler(); @@ -68,7 +68,12 @@ int main(int argc, char** argv) /** * options: worldservers */ - server.options.RejectDuplicateServers(server.config.GetVariableBool("worldservers", "reject_duplicate_servers", false)); + server.options.RejectDuplicateServers( + server.config.GetVariableBool( + "worldservers", + "reject_duplicate_servers", + false + )); server.options.AllowUnregistered(server.config.GetVariableBool("worldservers", "unregistered_allowed", true)); /** @@ -154,7 +159,7 @@ int main(int argc, char** argv) * create client manager */ LogInfo("Client Manager Init"); - server.client_manager = new ClientManager(); + server.client_manager = new ClientManager(); if (!server.client_manager) { LogError("Client Manager Failed to Start"); LogInfo("Server Manager Shutdown"); @@ -192,6 +197,9 @@ int main(int argc, char** argv) if (argc > 1) { LogSys.LoadLogSettingsDefaults(); + LogSys.log_settings[Logs::Debug].log_to_console = static_cast(Logs::General); + LogSys.log_settings[Logs::Debug].is_category_enabled = 1; + LoginserverCommandHandler::CommandHandler(argc, argv); } From 4de85ff836e96883eb194a9ef9e6fcbe9fca23d0 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 05:04:55 -0500 Subject: [PATCH 114/491] Add CLI and Web endpoints to change local login account password --- loginserver/loginserver_command_handler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index dadf93e34..e4a316a5f 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -214,6 +214,7 @@ namespace LoginserverCommandHandler { * @param argv * @param cmd * @param description + */ void UpdateLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description) { description = "Change user login credentials"; From 4ec210c41121f2f95a0b14958383dac35ea3a782 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 4 Aug 2019 05:09:05 -0500 Subject: [PATCH 115/491] Update web api errors --- loginserver/loginserver_webserver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 3c2b8c72e..07d680fa1 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -71,7 +71,7 @@ namespace LoginserverWebserver { Json::Value response; if (username.empty() || password.empty()) { - response["message"] = "Username or password not set"; + response["error"] = "Username or password not set"; LoginserverWebserver::SendResponse(response, res); return; } @@ -97,7 +97,7 @@ namespace LoginserverWebserver { Json::Value response; if (username.empty() || password.empty()) { - response["message"] = "Username or password not set"; + response["error"] = "Username or password not set"; LoginserverWebserver::SendResponse(response, res); return; } @@ -127,7 +127,7 @@ namespace LoginserverWebserver { Json::Value response; if (username.empty() || password.empty()) { - response["message"] = "Username or password not set"; + response["error"] = "Username or password not set"; LoginserverWebserver::SendResponse(response, res); return; } From 4aa8cecc55eba244e5fc2b721978ae5cfa660c49 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 4 Aug 2019 22:36:24 -0400 Subject: [PATCH 116/491] Fix for SoF client not being able to login --- common/patches/sof.cpp | 6 ++++++ common/patches/sof_limits.h | 4 ++++ common/patches/sof_structs.h | 6 +++--- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 7569b4c5d..bb310a76c 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -1116,7 +1116,10 @@ namespace SoF } OUT(deity); OUT(intoxication); + OUT_array(spellSlotRefresh, spells::SPELL_GEM_COUNT); + eq->spellSlotRefresh[9] = 0; // 10th slot is not valid in this release + OUT(abilitySlotRefresh); OUT(points); // Relocation Test // OUT(unknown0166[4]); @@ -1177,7 +1180,10 @@ namespace SoF } // OUT(unknown4184[128]); + OUT_array(mem_spells, spells::SPELL_GEM_COUNT); + eq->mem_spells[9] = 0xFFFFFFFFU; // 10th slot is not valid in this release + // OUT(unknown04396[32]); OUT(platinum); OUT(gold); diff --git a/common/patches/sof_limits.h b/common/patches/sof_limits.h index 399ff8c1a..a03676f2d 100644 --- a/common/patches/sof_limits.h +++ b/common/patches/sof_limits.h @@ -328,7 +328,11 @@ namespace SoF const int SPELL_ID_MAX = 15999; const int SPELLBOOK_SIZE = 480; + // Be careful not to confuse these two..SoF disc release has a special requirement... + // - The number of available spell gems HAS NOT increased from 9 at this point + // - The profile allocation HAS increased to 10 at this point const int SPELL_GEM_COUNT = static_cast(CastingSlot::MaxGems); + const int SPELL_GEM_PROFILE_SIZE = 10; // special case declaration const int LONG_BUFFS = 25; const int SHORT_BUFFS = 15; diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 93b185e23..4d4a591e1 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -885,7 +885,7 @@ struct PlayerProfile_Struct //23576 Octets /*00060*/ BindStruct binds[5]; // Bind points (primary is first) /*00160*/ uint32 deity; // deity /*00164*/ uint32 intoxication; // Alcohol level (in ticks till sober?) -/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_COUNT]; // Refresh time (millis) - 4 Octets Each +/*00168*/ uint32 spellSlotRefresh[spells::SPELL_GEM_PROFILE_SIZE]; // Refresh time (millis) - 4 Octets Each /*00208*/ uint32 abilitySlotRefresh; /*00212*/ uint8 haircolor; // Player hair color /*00213*/ uint8 beardcolor; // Player beard color @@ -912,7 +912,7 @@ struct PlayerProfile_Struct //23576 Octets /*04173*/ uint8 unknown02264[147]; // was [139] /*04312*/ uint32 spell_book[spells::SPELLBOOK_SIZE]; // List of the Spells in spellbook 480 = 60 pages /*06232*/ uint8 unknown4184[128]; // was [136] -/*06396*/ uint32 mem_spells[spells::SPELL_GEM_COUNT]; // List of spells memorized +/*06396*/ uint32 mem_spells[spells::SPELL_GEM_PROFILE_SIZE]; // List of spells memorized /*06436*/ uint8 unknown04396[28]; //#### uint8 unknown04396[32]; in Titanium ####[28] /*06464*/ uint32 platinum; // Platinum Pieces on player /*06468*/ uint32 gold; // Gold Pieces on player @@ -3768,7 +3768,7 @@ struct AnnoyingZoneUnknown_Struct { }; struct LoadSpellSet_Struct { - uint32 spell[spells::SPELL_GEM_COUNT]; + uint32 spell[spells::SPELL_GEM_PROFILE_SIZE]; uint32 unknown; }; From 8065cdb89dea85d1c755c707c4b5e5d105f18849 Mon Sep 17 00:00:00 2001 From: Uleat Date: Sun, 4 Aug 2019 22:54:22 -0400 Subject: [PATCH 117/491] Give Erudites their head coverings back (forced until we can sort out the packet building process...) --- zone/mob.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zone/mob.cpp b/zone/mob.cpp index ca844d459..3a307bf3f 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1128,7 +1128,10 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) UpdateActiveLight(); ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive]; - ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0; + if (IsNPC() && race == ERUDITE) + ns->spawn.showhelm = 1; + else + ns->spawn.showhelm = (helmtexture && helmtexture != 0xFF) ? 1 : 0; ns->spawn.invis = (invisible || hidden) ? 1 : 0; // TODO: load this before spawning players ns->spawn.NPC = IsClient() ? 0 : 1; From b62944c5fb54019742fdfc354cc914e93e43997d Mon Sep 17 00:00:00 2001 From: KimLS Date: Mon, 5 Aug 2019 01:12:31 -0700 Subject: [PATCH 118/491] Fix for windows compile issue --- common/cli/eqemu_command_handler.cpp | 3 ++- common/cli/eqemu_command_handler.h | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/cli/eqemu_command_handler.cpp b/common/cli/eqemu_command_handler.cpp index a45948002..79e87dfd8 100644 --- a/common/cli/eqemu_command_handler.cpp +++ b/common/cli/eqemu_command_handler.cpp @@ -20,6 +20,7 @@ #include #include "eqemu_command_handler.h" +#include "terminal_color.hpp" #include "../platform.h" namespace EQEmuCommand { @@ -189,4 +190,4 @@ namespace EQEmuCommand { exit(1); } -} \ No newline at end of file +} diff --git a/common/cli/eqemu_command_handler.h b/common/cli/eqemu_command_handler.h index 12d23659d..d0b0b5b5e 100644 --- a/common/cli/eqemu_command_handler.h +++ b/common/cli/eqemu_command_handler.h @@ -22,7 +22,6 @@ #define EQEMU_EQEMU_COMMAND_HANDLER_H #include "argh.h" -#include "terminal_color.hpp" namespace EQEmuCommand { From 06fbd7103e8859aa5ba59ced74bf102f8e43ef86 Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Mon, 5 Aug 2019 09:24:22 -0400 Subject: [PATCH 119/491] Update client_packet.cpp --- zone/client_packet.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f0eb00d13..728d687b6 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -2851,12 +2851,17 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) // Poisons that don't proc until a level higher than the // rogue simply won't apply at all, no skill check done. - if (ChanceRoll < (.9 + GetLevel()/1000)) { + uint16 applyskill=GetSkill(EQEmu::skills::SkillApplyPoison); + + if (ChanceRoll < (.75 + applyskill/1000)) { ApplyPoisonSuccessResult = 1; AddProcToWeapon(poison->Proc.Effect, false, (GetDEX() / 100) + 103); } } + else { + Message(13, "A piercing weapon must be wielded to apply poison."); + } // Live always deletes the item, success or failure. Even if too high. DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true); From d3641be6c0476e8f0a00bc4dce5942f49dbf1e6e Mon Sep 17 00:00:00 2001 From: Paul Coene Date: Mon, 5 Aug 2019 09:30:57 -0400 Subject: [PATCH 120/491] Update loottables.cpp --- zone/loottables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zone/loottables.cpp b/zone/loottables.cpp index e7c9624f1..816eb2ee4 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -352,7 +352,7 @@ void NPC::AddLootDrop(const EQEmu::ItemData *item2, ItemList* itemlist, int16 ch } else if (foundslot == EQEmu::invslot::slotSecondary && (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) && - (item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield)) + (item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield || item2->ItemType == EQEmu::item::ItemTypeLight)) { if (item2->Proc.Effect!=0) CastToMob()->AddProcToWeapon(item2->Proc.Effect, true); From b117be29fb94828e2c0d0ddb81ff6afbab1c0cfd Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Aug 2019 01:59:54 -0500 Subject: [PATCH 121/491] Movement code readability --- .../submodules/libuv/CTestTestfile.cmake | 6 + zone/mob_movement_manager.cpp | 885 +++++++++++------- zone/mob_movement_manager.h | 26 +- 3 files changed, 569 insertions(+), 348 deletions(-) create mode 100644 cmake-build-debug/submodules/libuv/CTestTestfile.cmake diff --git a/cmake-build-debug/submodules/libuv/CTestTestfile.cmake b/cmake-build-debug/submodules/libuv/CTestTestfile.cmake new file mode 100644 index 000000000..22e3caa8a --- /dev/null +++ b/cmake-build-debug/submodules/libuv/CTestTestfile.cmake @@ -0,0 +1,6 @@ +# CMake generated Testfile for +# Source directory: /Users/cmiles/code/eqemu-docker-cloud/code/submodules/libuv +# Build directory: /Users/cmiles/code/eqemu-docker-cloud/code/cmake-build-debug/submodules/libuv +# +# This file includes the relevant testing commands required for +# testing this directory and lists subdirectories to be tested as well. diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 1fcc19187..398cd9c2a 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -14,40 +14,41 @@ #include extern double frame_time; -extern Zone *zone; +extern Zone *zone; -class IMovementCommand -{ +class IMovementCommand { public: IMovementCommand() = default; virtual ~IMovementCommand() = default; - virtual bool Process(MobMovementManager *mgr, Mob *m) = 0; + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) = 0; virtual bool Started() const = 0; }; -class RotateToCommand : public IMovementCommand -{ +class RotateToCommand : public IMovementCommand { public: - RotateToCommand(double rotate_to, double dir, MobMovementMode mode) { - m_rotate_to = rotate_to; - m_rotate_to_dir = dir; + RotateToCommand(double rotate_to, double dir, MobMovementMode mode) + { + m_rotate_to = rotate_to; + m_rotate_to_dir = dir; m_rotate_to_mode = mode; - m_started = false; + m_started = false; } - virtual ~RotateToCommand() { + virtual ~RotateToCommand() + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) { - if (!m->IsAIControlled()) { + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) + { + if (!mob->IsAIControlled()) { return true; } - auto rotate_to_speed = m_rotate_to_mode == MovementRunning ? 200.0 : 16.0; //todo: get this from mob + auto rotate_to_speed = m_rotate_to_mode == MovementRunning ? 200.0 : 16.0; //todo: get this from mob - auto from = FixHeading(m->GetHeading()); - auto to = FixHeading(m_rotate_to); + auto from = FixHeading(mob->GetHeading()); + auto to = FixHeading(m_rotate_to); auto diff = to - from; while (diff < -256.0) { @@ -62,265 +63,282 @@ public: if (!m_started) { m_started = true; - m->SetMoving(true); - + mob->SetMoving(true); + if (dist > 15.0f && rotate_to_speed > 0.0 && rotate_to_speed <= 25.0) { //send basic rotation - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, m_rotate_to_dir * rotate_to_speed, 0, ClientRangeClose); + mob_movement_manager->SendCommandToClients( + mob, + 0.0, + 0.0, + 0.0, + m_rotate_to_dir * rotate_to_speed, + 0, + ClientRangeClose + ); } } - + auto td = rotate_to_speed * 19.0 * frame_time; - + if (td >= dist) { - m->SetHeading(to); - m->SetMoving(false); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); + mob->SetHeading(to); + mob->SetMoving(false); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); return true; } - + from += td * m_rotate_to_dir; - m->SetHeading(FixHeading(from)); + mob->SetHeading(FixHeading(from)); return false; } - virtual bool Started() const { + virtual bool Started() const + { return m_started; } private: - double m_rotate_to; - double m_rotate_to_dir; + double m_rotate_to; + double m_rotate_to_dir; MobMovementMode m_rotate_to_mode; - bool m_started; + bool m_started; }; -class MoveToCommand : public IMovementCommand -{ +class MoveToCommand : public IMovementCommand { public: - MoveToCommand(float x, float y, float z, MobMovementMode mode) { + MoveToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) + { m_distance_moved_since_correction = 0.0; - m_move_to_x = x; - m_move_to_y = y; - m_move_to_z = z; - m_move_to_mode = mode; - m_last_sent_time = 0.0; - m_last_sent_speed = 0; - m_started = false; - m_total_h_dist = 0.0; - m_total_v_dist = 0.0; + m_move_to_x = x; + m_move_to_y = y; + m_move_to_z = z; + m_move_to_mode = mob_movement_mode; + m_last_sent_time = 0.0; + m_last_sent_speed = 0; + m_started = false; + m_total_h_dist = 0.0; + m_total_v_dist = 0.0; } - virtual ~MoveToCommand() { + virtual ~MoveToCommand() + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) { - if (!m->IsAIControlled()) { + /** + * @param mob_movement_manager + * @param mob + * @return + */ + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) + { + if (!mob->IsAIControlled()) { return true; } //Send a movement packet when you start moving - double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; - int current_speed = 0; + double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; + int current_speed = 0; if (m_move_to_mode == MovementRunning) { - if (m->IsFeared()) { - current_speed = m->GetFearSpeed(); + if (mob->IsFeared()) { + current_speed = mob->GetFearSpeed(); } else { - current_speed = m->GetRunspeed(); + current_speed = mob->GetRunspeed(); } } else { - current_speed = m->GetWalkspeed(); + current_speed = mob->GetWalkspeed(); } if (!m_started) { m_started = true; //rotate to the point - m->SetMoving(true); - m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); + mob->SetMoving(true); + mob->SetHeading(mob->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - m_total_h_dist = DistanceNoZ(m->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f)); - m_total_v_dist = m_move_to_z - m->GetZ(); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + m_total_h_dist = DistanceNoZ(mob->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f)); + m_total_v_dist = m_move_to_z - mob->GetZ(); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } //When speed changes if (current_speed != m_last_sent_speed) { if (RuleB(Map, FixZWhenPathing)) { - m->FixZ(); + mob->FixZ(); } m_distance_moved_since_correction = 0.0; m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } //If x seconds have passed without sending an update. if (current_time - m_last_sent_time >= 5.0) { if (RuleB(Map, FixZWhenPathing)) { - m->FixZ(); + mob->FixZ(); } m_distance_moved_since_correction = 0.0; m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } - auto &p = m->GetPosition(); + auto &p = mob->GetPosition(); glm::vec2 tar(m_move_to_x, m_move_to_y); glm::vec2 pos(p.x, p.y); - double len = glm::distance(pos, tar); + double len = glm::distance(pos, tar); if (len == 0) { return true; } - m->SetMoved(true); + mob->SetMoved(true); - glm::vec2 dir = tar - pos; - glm::vec2 ndir = glm::normalize(dir); - double distance_moved = frame_time * current_speed * 0.4f * 1.45f; + glm::vec2 dir = tar - pos; + glm::vec2 ndir = glm::normalize(dir); + double distance_moved = frame_time * current_speed * 0.4f * 1.45f; - if (distance_moved > len) { - if (m->IsNPC()) { - entity_list.ProcessMove(m->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z); + if (distance_moved > len) { + if (mob->IsNPC()) { + entity_list.ProcessMove(mob->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z); } - m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); - + mob->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); + if (RuleB(Map, FixZWhenPathing)) { - m->FixZ(); + mob->FixZ(); } return true; } else { glm::vec2 npos = pos + (ndir * static_cast(distance_moved)); - + len -= distance_moved; double total_distance_traveled = m_total_h_dist - len; - double start_z = m_move_to_z - m_total_v_dist; - double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist)); + double start_z = m_move_to_z - m_total_v_dist; + double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist)); - if (m->IsNPC()) { - entity_list.ProcessMove(m->CastToNPC(), npos.x, npos.y, z_at_pos); + if (mob->IsNPC()) { + entity_list.ProcessMove(mob->CastToNPC(), npos.x, npos.y, z_at_pos); } - m->SetPosition(npos.x, npos.y, z_at_pos); + mob->SetPosition(npos.x, npos.y, z_at_pos); if (RuleB(Map, FixZWhenPathing)) { m_distance_moved_since_correction += distance_moved; if (m_distance_moved_since_correction > RuleR(Map, DistanceCanTravelBeforeAdjustment)) { m_distance_moved_since_correction = 0.0; - m->FixZ(); + mob->FixZ(); } } } - + return false; } - virtual bool Started() const { + virtual bool Started() const + { return m_started; } protected: - double m_distance_moved_since_correction; - double m_move_to_x; - double m_move_to_y; - double m_move_to_z; + double m_distance_moved_since_correction; + double m_move_to_x; + double m_move_to_y; + double m_move_to_z; MobMovementMode m_move_to_mode; - bool m_started; + bool m_started; double m_last_sent_time; - int m_last_sent_speed; + int m_last_sent_speed; double m_total_h_dist; double m_total_v_dist; }; -class SwimToCommand : public MoveToCommand -{ +class SwimToCommand : public MoveToCommand { public: - SwimToCommand(float x, float y, float z, MobMovementMode mode) : MoveToCommand(x, y, z, mode) { + SwimToCommand(float x, float y, float z, MobMovementMode mode) : MoveToCommand(x, y, z, mode) + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) { - if (!m->IsAIControlled()) { + if (!mob->IsAIControlled()) { return true; } - //Send a movement packet when you start moving - double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; - int current_speed = 0; + //Send a movement packet when you start moving + double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; + int current_speed = 0; if (m_move_to_mode == MovementRunning) { - if (m->IsFeared()) { - current_speed = m->GetFearSpeed(); + if (mob->IsFeared()) { + current_speed = mob->GetFearSpeed(); } else { - current_speed = m->GetRunspeed(); + current_speed = mob->GetRunspeed(); } } else { - current_speed = m->GetWalkspeed(); + current_speed = mob->GetWalkspeed(); } if (!m_started) { m_started = true; //rotate to the point - m->SetMoving(true); - m->SetHeading(m->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); + mob->SetMoving(true); + mob->SetHeading(mob->CalculateHeadingToTarget(m_move_to_x, m_move_to_y)); m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - m_total_h_dist = DistanceNoZ(m->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f)); - m_total_v_dist = m_move_to_z - m->GetZ(); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + m_total_h_dist = DistanceNoZ(mob->GetPosition(), glm::vec4(m_move_to_x, m_move_to_y, 0.0f, 0.0f)); + m_total_v_dist = m_move_to_z - mob->GetZ(); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } //When speed changes if (current_speed != m_last_sent_speed) { m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } //If x seconds have passed without sending an update. if (current_time - m_last_sent_time >= 1.5) { m_last_sent_speed = current_speed; - m_last_sent_time = current_time; - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); + m_last_sent_time = current_time; + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, current_speed, ClientRangeCloseMedium); } - auto &p = m->GetPosition(); + auto &p = mob->GetPosition(); glm::vec2 tar(m_move_to_x, m_move_to_y); glm::vec2 pos(p.x, p.y); - double len = glm::distance(pos, tar); + double len = glm::distance(pos, tar); if (len == 0) { return true; } - m->SetMoved(true); + mob->SetMoved(true); - glm::vec2 dir = tar - pos; - glm::vec2 ndir = glm::normalize(dir); - double distance_moved = frame_time * current_speed * 0.4f * 1.45f; + glm::vec2 dir = tar - pos; + glm::vec2 ndir = glm::normalize(dir); + double distance_moved = frame_time * current_speed * 0.4f * 1.45f; if (distance_moved > len) { - if (m->IsNPC()) { - entity_list.ProcessMove(m->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z); + if (mob->IsNPC()) { + entity_list.ProcessMove(mob->CastToNPC(), m_move_to_x, m_move_to_y, m_move_to_z); } - m->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); + mob->SetPosition(m_move_to_x, m_move_to_y, m_move_to_z); return true; } else { @@ -328,51 +346,54 @@ public: len -= distance_moved; double total_distance_traveled = m_total_h_dist - len; - double start_z = m_move_to_z - m_total_v_dist; - double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist)); + double start_z = m_move_to_z - m_total_v_dist; + double z_at_pos = start_z + (m_total_v_dist * (total_distance_traveled / m_total_h_dist)); - if (m->IsNPC()) { - entity_list.ProcessMove(m->CastToNPC(), npos.x, npos.y, z_at_pos); + if (mob->IsNPC()) { + entity_list.ProcessMove(mob->CastToNPC(), npos.x, npos.y, z_at_pos); } - m->SetPosition(npos.x, npos.y, z_at_pos); + mob->SetPosition(npos.x, npos.y, z_at_pos); } return false; } }; -class TeleportToCommand : public IMovementCommand -{ +class TeleportToCommand : public IMovementCommand { public: - TeleportToCommand(float x, float y, float z, float heading) { - m_teleport_to_x = x; - m_teleport_to_y = y; - m_teleport_to_z = z; + TeleportToCommand(float x, float y, float z, float heading) + { + m_teleport_to_x = x; + m_teleport_to_y = y; + m_teleport_to_z = z; m_teleport_to_heading = heading; } - virtual ~TeleportToCommand() { + virtual ~TeleportToCommand() + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) { - if (!m->IsAIControlled()) { + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) + { + if (!mob->IsAIControlled()) { return true; } - if (m->IsNPC()) { - entity_list.ProcessMove(m->CastToNPC(), m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); + if (mob->IsNPC()) { + entity_list.ProcessMove(mob->CastToNPC(), m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); } - m->SetPosition(m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); - m->SetHeading(mgr->FixHeading(m_teleport_to_heading)); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); + mob->SetPosition(m_teleport_to_x, m_teleport_to_y, m_teleport_to_z); + mob->SetHeading(mob_movement_manager->FixHeading(m_teleport_to_heading)); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny); return true; } - virtual bool Started() const { + virtual bool Started() const + { return false; } @@ -384,93 +405,99 @@ private: double m_teleport_to_heading; }; -class StopMovingCommand : public IMovementCommand -{ +class StopMovingCommand : public IMovementCommand { public: - StopMovingCommand() { + StopMovingCommand() + { } - virtual ~StopMovingCommand() { + virtual ~StopMovingCommand() + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) { - if (!m->IsAIControlled()) { + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) + { + if (!mob->IsAIControlled()) { return true; } - if (m->IsMoving()) { - m->SetMoving(false); + if (mob->IsMoving()) { + mob->SetMoving(false); if (RuleB(Map, FixZWhenPathing)) { - m->FixZ(); + mob->FixZ(); } - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); } return true; } - virtual bool Started() const { + virtual bool Started() const + { return false; } }; -class EvadeCombatCommand : public IMovementCommand -{ +class EvadeCombatCommand : public IMovementCommand { public: - EvadeCombatCommand() { + EvadeCombatCommand() + { } - virtual ~EvadeCombatCommand() { + virtual ~EvadeCombatCommand() + { } - virtual bool Process(MobMovementManager *mgr, Mob *m) { - if (!m->IsAIControlled()) { + virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob) + { + if (!mob->IsAIControlled()) { return true; } - if (m->IsMoving()) { - m->SetMoving(false); - mgr->SendCommandToClients(m, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); + if (mob->IsMoving()) { + mob->SetMoving(false); + mob_movement_manager->SendCommandToClients(mob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeCloseMedium); } - m->BuffFadeAll(); - m->WipeHateList(); - m->Heal(); + mob->BuffFadeAll(); + mob->WipeHateList(); + mob->Heal(); return true; } - virtual bool Started() const { + virtual bool Started() const + { return false; } }; -struct MovementStats -{ - MovementStats() { - LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; - TotalSent = 0ULL; +struct MovementStats { + MovementStats() + { + LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; + TotalSent = 0ULL; TotalSentMovement = 0ULL; TotalSentPosition = 0ULL; - TotalSentHeading = 0ULL; + TotalSentHeading = 0ULL; } - double LastResetTime; + double LastResetTime; uint64_t TotalSent; uint64_t TotalSentMovement; uint64_t TotalSentPosition; uint64_t TotalSentHeading; }; -struct NavigateTo -{ - NavigateTo() { - navigate_to_x = 0.0; - navigate_to_y = 0.0; - navigate_to_z = 0.0; +struct NavigateTo { + NavigateTo() + { + navigate_to_x = 0.0; + navigate_to_y = 0.0; + navigate_to_z = 0.0; navigate_to_heading = 0.0; - last_set_time = 0.0; + last_set_time = 0.0; } double navigate_to_x; @@ -480,13 +507,13 @@ struct NavigateTo double last_set_time; }; -struct MobMovementEntry -{ +struct MobMovementEntry { std::deque> Commands; - NavigateTo NavTo; + NavigateTo NavTo; }; -void AdjustRoute(std::list &nodes, Mob *who) { +void AdjustRoute(std::list &nodes, Mob *who) +{ if (!zone->HasMap() || !zone->HasWaterMap()) { return; } @@ -494,7 +521,7 @@ void AdjustRoute(std::list &nodes, Mob *who) { auto offset = who->GetZOffset(); for (auto &node : nodes) { - if(!zone->watermap->InLiquid(node.pos)) { + if (!zone->watermap->InLiquid(node.pos)) { auto best_z = zone->zonemap->FindBestZ(node.pos, nullptr); if (best_z != BEST_Z_INVALID) { node.pos.z = best_z + offset; @@ -503,11 +530,10 @@ void AdjustRoute(std::list &nodes, Mob *who) { } } -struct MobMovementManager::Implementation -{ - std::map Entries; - std::vector Clients; - MovementStats Stats; +struct MobMovementManager::Implementation { + std::map Entries; + std::vector Clients; + MovementStats Stats; }; MobMovementManager::MobMovementManager() @@ -522,12 +548,12 @@ MobMovementManager::~MobMovementManager() void MobMovementManager::Process() { for (auto &iter : _impl->Entries) { - auto &ent = iter.second; + auto &ent = iter.second; auto &commands = ent.Commands; while (true != commands.empty()) { auto &cmd = commands.front(); - auto r = cmd->Process(this, iter.first); + auto r = cmd->Process(this, iter.first); if (true != r) { break; @@ -538,35 +564,49 @@ void MobMovementManager::Process() } } -void MobMovementManager::AddMob(Mob *m) +void MobMovementManager::AddMob(Mob *mob) { - _impl->Entries.insert(std::make_pair(m, MobMovementEntry())); + _impl->Entries.insert(std::make_pair(mob, MobMovementEntry())); } -void MobMovementManager::RemoveMob(Mob *m) +/** + * @param mob + */ +void MobMovementManager::RemoveMob(Mob *mob) { - _impl->Entries.erase(m); + _impl->Entries.erase(mob); } -void MobMovementManager::AddClient(Client *c) +/** + * @param client + */ +void MobMovementManager::AddClient(Client *client) { - _impl->Clients.push_back(c); + _impl->Clients.push_back(client); } -void MobMovementManager::RemoveClient(Client *c) +/** + * @param client + */ +void MobMovementManager::RemoveClient(Client *client) { auto iter = _impl->Clients.begin(); while (iter != _impl->Clients.end()) { - if (c == *iter) { + if (client == *iter) { _impl->Clients.erase(iter); return; } - + ++iter; } } -void MobMovementManager::RotateTo(Mob *who, float to, MobMovementMode mode) +/** + * @param who + * @param to + * @param mob_movement_mode + */ +void MobMovementManager::RotateTo(Mob *who, float to, MobMovementMode mob_movement_mode) { auto iter = _impl->Entries.find(who); auto &ent = (*iter); @@ -574,20 +614,34 @@ void MobMovementManager::RotateTo(Mob *who, float to, MobMovementMode mode) if (true != ent.second.Commands.empty()) { return; } - - PushRotateTo(ent.second, who, to, mode); + + PushRotateTo(ent.second, who, to, mob_movement_mode); } +/** + * @param who + * @param x + * @param y + * @param z + * @param heading + */ void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float heading) { auto iter = _impl->Entries.find(who); auto &ent = (*iter); - + ent.second.Commands.clear(); PushTeleportTo(ent.second, x, y, z, heading); } +/** + * @param who + * @param x + * @param y + * @param z + * @param mode + */ void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode) { if (IsPositionEqualWithinCertainZ(glm::vec3(x, y, z), glm::vec3(who->GetX(), who->GetY(), who->GetZ()), 6.0f)) { @@ -601,8 +655,13 @@ void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMove double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; if ((current_time - nav.last_set_time) > 0.5) { //Can potentially recalc - - auto within = IsPositionWithinSimpleCylinder(glm::vec3(x, y, z), glm::vec3(nav.navigate_to_x, nav.navigate_to_y, nav.navigate_to_z), 1.5f, 6.0f); + + auto within = IsPositionWithinSimpleCylinder( + glm::vec3(x, y, z), + glm::vec3(nav.navigate_to_x, nav.navigate_to_y, nav.navigate_to_z), + 1.5f, + 6.0f + ); auto heading_match = IsHeadingEqual(0.0, nav.navigate_to_heading); if (false == within || false == heading_match || ent.second.Commands.size() == 0) { @@ -610,23 +669,27 @@ void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMove //Path is no longer valid, calculate a new path UpdatePath(who, x, y, z, mode); - nav.navigate_to_x = x; - nav.navigate_to_y = y; - nav.navigate_to_z = z; + nav.navigate_to_x = x; + nav.navigate_to_y = y; + nav.navigate_to_z = z; nav.navigate_to_heading = 0.0; - nav.last_set_time = current_time; + nav.last_set_time = current_time; } } } -void MobMovementManager::StopNavigation(Mob *who) { +/** + * @param who + */ +void MobMovementManager::StopNavigation(Mob *who) +{ auto iter = _impl->Entries.find(who); auto &ent = (*iter); auto &nav = ent.second.NavTo; - nav.navigate_to_x = 0.0; - nav.navigate_to_y = 0.0; - nav.navigate_to_z = 0.0; + nav.navigate_to_x = 0.0; + nav.navigate_to_y = 0.0; + nav.navigate_to_z = 0.0; nav.navigate_to_heading = 0.0; if (true == ent.second.Commands.empty()) { @@ -643,15 +706,33 @@ void MobMovementManager::StopNavigation(Mob *who) { PushStopMoving(ent.second); } -void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float dz, float dh, int anim, ClientRange range) +/** + * @param mob + * @param delta_x + * @param delta_y + * @param delta_z + * @param delta_heading + * @param anim + * @param range + */ +void MobMovementManager::SendCommandToClients( + Mob *mob, + float delta_x, + float delta_y, + float delta_z, + float delta_heading, + int anim, + ClientRange range +) { if (range == ClientRangeNone) { return; } EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - FillCommandStruct(spu, m, dx, dy, dz, dh, anim); + auto *spu = (PlayerPositionUpdateServer_Struct *) outapp.pBuffer; + + FillCommandStruct(spu, mob, delta_x, delta_y, delta_z, delta_heading, anim); if (range == ClientRangeAny) { for (auto &c : _impl->Clients) { @@ -660,7 +741,7 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float if (anim != 0) { _impl->Stats.TotalSentMovement++; } - else if (dh != 0) { + else if (delta_heading != 0) { _impl->Stats.TotalSentHeading++; } else { @@ -672,26 +753,26 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float } else { float short_range = RuleR(Pathing, ShortMovementUpdateRange); - float long_range = zone->GetMaxMovementUpdateRange(); + float long_range = zone->GetMaxMovementUpdateRange(); for (auto &c : _impl->Clients) { - float dist = c->CalculateDistance(m->GetX(), m->GetY(), m->GetZ()); + float distance = c->CalculateDistance(mob->GetX(), mob->GetY(), mob->GetZ()); bool match = false; if (range & ClientRangeClose) { - if (dist < short_range) { + if (distance < short_range) { match = true; } } if (!match && range & ClientRangeMedium) { - if (dist >= short_range && dist < long_range) { + if (distance >= short_range && distance < long_range) { match = true; } } if (!match && range & ClientRangeLong) { - if (dist >= long_range) { + if (distance >= long_range) { match = true; } } @@ -702,7 +783,7 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float if (anim != 0) { _impl->Stats.TotalSentMovement++; } - else if (dh != 0) { + else if (delta_heading != 0) { _impl->Stats.TotalSentHeading++; } else { @@ -715,6 +796,10 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float } } +/** + * @param in + * @return + */ float MobMovementManager::FixHeading(float in) { auto h = in; @@ -729,83 +814,139 @@ float MobMovementManager::FixHeading(float in) return h; } -void MobMovementManager::DumpStats(Client *to) +/** + * @param client + */ +void MobMovementManager::DumpStats(Client *client) { auto current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; - auto total_time = current_time - _impl->Stats.LastResetTime; + auto total_time = current_time - _impl->Stats.LastResetTime; - to->Message(MT_System, "Dumping Movement Stats:"); - to->Message(MT_System, "Total Sent: %u (%.2f / sec)", _impl->Stats.TotalSent, static_cast(_impl->Stats.TotalSent) / total_time); - to->Message(MT_System, "Total Heading: %u (%.2f / sec)", _impl->Stats.TotalSentHeading, static_cast(_impl->Stats.TotalSentHeading) / total_time); - to->Message(MT_System, "Total Movement: %u (%.2f / sec)", _impl->Stats.TotalSentMovement, static_cast(_impl->Stats.TotalSentMovement) / total_time); - to->Message(MT_System, "Total Position: %u (%.2f / sec)", _impl->Stats.TotalSentPosition, static_cast(_impl->Stats.TotalSentPosition) / total_time); + client->Message(MT_System, "Dumping Movement Stats:"); + client->Message( + MT_System, + "Total Sent: %u (%.2f / sec)", + _impl->Stats.TotalSent, + static_cast(_impl->Stats.TotalSent) / total_time + ); + client->Message( + MT_System, + "Total Heading: %u (%.2f / sec)", + _impl->Stats.TotalSentHeading, + static_cast(_impl->Stats.TotalSentHeading) / total_time + ); + client->Message( + MT_System, + "Total Movement: %u (%.2f / sec)", + _impl->Stats.TotalSentMovement, + static_cast(_impl->Stats.TotalSentMovement) / total_time + ); + client->Message( + MT_System, + "Total Position: %u (%.2f / sec)", + _impl->Stats.TotalSentPosition, + static_cast(_impl->Stats.TotalSentPosition) / total_time + ); } void MobMovementManager::ClearStats() { - _impl->Stats.LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; - _impl->Stats.TotalSent = 0; - _impl->Stats.TotalSentHeading = 0; + _impl->Stats.LastResetTime = static_cast(Timer::GetCurrentTime()) / 1000.0; + _impl->Stats.TotalSent = 0; + _impl->Stats.TotalSentHeading = 0; _impl->Stats.TotalSentMovement = 0; _impl->Stats.TotalSentPosition = 0; } -void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim) +/** + * @param position_update_server_struct + * @param mob + * @param delta_x + * @param delta_y + * @param delta_z + * @param delta_heading + * @param anim + */ +void MobMovementManager::FillCommandStruct( + PlayerPositionUpdateServer_Struct *position_update_server_struct, + Mob *mob, + float delta_x, + float delta_y, + float delta_z, + float delta_heading, + int anim +) { - memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); - spu->spawn_id = m->GetID(); - spu->x_pos = FloatToEQ19(m->GetX()); - spu->y_pos = FloatToEQ19(m->GetY()); - spu->z_pos = FloatToEQ19(m->GetZ()); - spu->heading = FloatToEQ12(m->GetHeading()); - spu->delta_x = FloatToEQ13(dx); - spu->delta_y = FloatToEQ13(dy); - spu->delta_z = FloatToEQ13(dz); - spu->delta_heading = FloatToEQ10(dh); - spu->animation = (m->IsBot() ? (int)((float)anim / 1.785714f) : anim); + memset(position_update_server_struct, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); + position_update_server_struct->spawn_id = mob->GetID(); + position_update_server_struct->x_pos = FloatToEQ19(mob->GetX()); + position_update_server_struct->y_pos = FloatToEQ19(mob->GetY()); + position_update_server_struct->z_pos = FloatToEQ19(mob->GetZ()); + position_update_server_struct->heading = FloatToEQ12(mob->GetHeading()); + position_update_server_struct->delta_x = FloatToEQ13(delta_x); + position_update_server_struct->delta_y = FloatToEQ13(delta_y); + position_update_server_struct->delta_z = FloatToEQ13(delta_z); + position_update_server_struct->delta_heading = FloatToEQ10(delta_heading); + position_update_server_struct->animation = (mob->IsBot() ? (int) ((float) anim / 1.785714f) : anim); } -void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode) +/** + * @param who + * @param x + * @param y + * @param z + * @param mob_movement_mode + */ +void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode) { if (!zone->HasMap() || !zone->HasWaterMap()) { auto iter = _impl->Entries.find(who); auto &ent = (*iter); - - PushMoveTo(ent.second, x, y, z, mode); + + PushMoveTo(ent.second, x, y, z, mob_movement_mode); PushStopMoving(ent.second); return; } - + if (who->IsBoat()) { - UpdatePathBoat(who, x, y, z, mode); - } else if (who->IsUnderwaterOnly()) { - UpdatePathUnderwater(who, x, y, z, mode); + UpdatePathBoat(who, x, y, z, mob_movement_mode); + } + else if (who->IsUnderwaterOnly()) { + UpdatePathUnderwater(who, x, y, z, mob_movement_mode); } else { - UpdatePathGround(who, x, y, z, mode); + UpdatePathGround(who, x, y, z, mob_movement_mode); } } -void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, MobMovementMode mode) +/** + * @param who + * @param x + * @param y + * @param z + * @param mode + */ +void MobMovementManager::UpdatePathGround(Mob *who, float x, float y, float z, MobMovementMode mode) { PathfinderOptions opts; opts.smooth_path = true; - opts.step_size = RuleR(Pathing, NavmeshStepSize); - opts.offset = who->GetZOffset(); - opts.flags = PathingNotDisabled ^ PathingZoneLine; + opts.step_size = RuleR(Pathing, NavmeshStepSize); + opts.offset = who->GetZOffset(); + opts.flags = PathingNotDisabled ^ PathingZoneLine; //This is probably pointless since the nav mesh tool currently sets zonelines to disabled anyway auto partial = false; - auto stuck = false; - auto route = zone->pathing->FindPath( + auto stuck = false; + auto route = zone->pathing->FindPath( glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck, - opts); + opts + ); auto eiter = _impl->Entries.find(who); - auto &ent = (*eiter); + auto &ent = (*eiter); if (route.size() == 0) { HandleStuckBehavior(who, x, y, z, mode); @@ -813,31 +954,28 @@ void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, } AdjustRoute(route, who); - - - + + + //avoid doing any processing if the mob is stuck to allow normal stuck code to work. - if (!stuck) - { + if (!stuck) { //there are times when the routes returned are no differen than where the mob is currently standing. What basically happens - //is a mob will get 'stuck' in such a way that it should be moving but the 'moving' place is the exact same spot it is at. - //this is a problem and creates an area of ground that if a mob gets to, will stay there forever. If socal this creates a - //"Ball of Death" (tm). This code tries to prevent this by simply warping the mob to the requested x/y. Better to have a warp than + //is a mob will get 'stuck' in such a way that it should be moving but the 'moving' place is the exact same spot it is at. + //this is a problem and creates an area of ground that if a mob gets to, will stay there forever. If socal this creates a + //"Ball of Death" (tm). This code tries to prevent this by simply warping the mob to the requested x/y. Better to have a warp than //have stuck mobs. - auto routeNode = route.begin(); + auto routeNode = route.begin(); bool noValidPath = true; while (routeNode != route.end() && noValidPath == true) { auto ¤tNode = (*routeNode); - if (routeNode == route.end()) - { + if (routeNode == route.end()) { continue; } - if (!(currentNode.pos.x == who->GetX() && currentNode.pos.y == who->GetY())) - { + if (!(currentNode.pos.x == who->GetX() && currentNode.pos.y == who->GetY())) { //if one of the nodes to move to, is not our current node, pass it. noValidPath = false; break; @@ -847,47 +985,62 @@ void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, } - if (noValidPath) - { + if (noValidPath) { //we are 'stuck' in a path, lets just get out of this by 'teleporting' to the next position. - PushTeleportTo(ent.second, x, y, z, - CalculateHeadingAngleBetweenPositions(who->GetX(), who->GetY(), x, y)); + PushTeleportTo( + ent.second, + x, + y, + z, + CalculateHeadingAngleBetweenPositions(who->GetX(), who->GetY(), x, y) + ); + return; } } - + auto iter = route.begin(); + glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ()); + bool first_node = true; - - while (iter != route.end()) { auto ¤t_node = (*iter); - + iter++; - + if (iter == route.end()) { continue; } - + previous_pos = current_node.pos; auto &next_node = (*iter); - + if (first_node) { - + if (mode == MovementWalking) { auto h = who->CalculateHeadingToTarget(next_node.pos.x, next_node.pos.y); PushRotateTo(ent.second, who, h, mode); } - + first_node = false; } - + //move to / teleport to node + 1 if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) { - PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, - CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y)); + PushTeleportTo( + ent.second, + next_node.pos.x, + next_node.pos.y, + next_node.pos.z, + CalculateHeadingAngleBetweenPositions( + current_node.pos.x, + current_node.pos.y, + next_node.pos.x, + next_node.pos.y + ) + ); } else { if (zone->watermap->InLiquid(previous_pos)) { @@ -907,41 +1060,50 @@ void MobMovementManager::UpdatePathGround(Mob * who, float x, float y, float z, } } -void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode mode) +/** + * @param who + * @param x + * @param y + * @param z + * @param movement_mode + */ +void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode movement_mode) { auto eiter = _impl->Entries.find(who); - auto &ent = (*eiter); - if (zone->watermap->InLiquid(who->GetPosition()) && zone->watermap->InLiquid(glm::vec3(x, y, z)) && zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z))) { - PushSwimTo(ent.second, x, y, z, mode); + auto &ent = (*eiter); + if (zone->watermap->InLiquid(who->GetPosition()) && zone->watermap->InLiquid(glm::vec3(x, y, z)) && + zone->zonemap->CheckLoS(who->GetPosition(), glm::vec3(x, y, z))) { + PushSwimTo(ent.second, x, y, z, movement_mode); PushStopMoving(ent.second); return; } PathfinderOptions opts; opts.smooth_path = true; - opts.step_size = RuleR(Pathing, NavmeshStepSize); - opts.offset = who->GetZOffset(); - opts.flags = PathingNotDisabled ^ PathingZoneLine; + opts.step_size = RuleR(Pathing, NavmeshStepSize); + opts.offset = who->GetZOffset(); + opts.flags = PathingNotDisabled ^ PathingZoneLine; auto partial = false; - auto stuck = false; - auto route = zone->pathing->FindPath( + auto stuck = false; + auto route = zone->pathing->FindPath( glm::vec3(who->GetX(), who->GetY(), who->GetZ()), glm::vec3(x, y, z), partial, stuck, - opts); + opts + ); if (route.size() == 0) { - HandleStuckBehavior(who, x, y, z, mode); + HandleStuckBehavior(who, x, y, z, movement_mode); return; } AdjustRoute(route, who); - auto iter = route.begin(); + auto iter = route.begin(); glm::vec3 previous_pos(who->GetX(), who->GetY(), who->GetZ()); - bool first_node = true; + bool first_node = true; while (iter != route.end()) { auto ¤t_node = (*iter); @@ -961,7 +1123,7 @@ void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float } if (route.size() == 0) { - HandleStuckBehavior(who, x, y, z, mode); + HandleStuckBehavior(who, x, y, z, movement_mode); return; } @@ -981,9 +1143,9 @@ void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float if (first_node) { - if (mode == MovementWalking) { + if (movement_mode == MovementWalking) { auto h = who->CalculateHeadingToTarget(next_node.pos.x, next_node.pos.y); - PushRotateTo(ent.second, who, h, mode); + PushRotateTo(ent.second, who, h, movement_mode); } first_node = false; @@ -991,46 +1153,86 @@ void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float //move to / teleport to node + 1 if (next_node.teleport && next_node.pos.x != 0.0f && next_node.pos.y != 0.0f) { - PushTeleportTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, - CalculateHeadingAngleBetweenPositions(current_node.pos.x, current_node.pos.y, next_node.pos.x, next_node.pos.y)); + PushTeleportTo( + ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, + CalculateHeadingAngleBetweenPositions( + current_node.pos.x, + current_node.pos.y, + next_node.pos.x, + next_node.pos.y + )); } else { - PushSwimTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, mode); + PushSwimTo(ent.second, next_node.pos.x, next_node.pos.y, next_node.pos.z, movement_mode); } } if (stuck) { - HandleStuckBehavior(who, x, y, z, mode); + HandleStuckBehavior(who, x, y, z, movement_mode); } else { PushStopMoving(ent.second); } } +/** + * @param who + * @param x + * @param y + * @param z + * @param mode + */ void MobMovementManager::UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode) { auto eiter = _impl->Entries.find(who); - auto &ent = (*eiter); + auto &ent = (*eiter); PushSwimTo(ent.second, x, y, z, mode); PushStopMoving(ent.second); } +/** + * @param ent + * @param x + * @param y + * @param z + * @param heading + */ void MobMovementManager::PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading) { ent.Commands.push_back(std::unique_ptr(new TeleportToCommand(x, y, z, heading))); } +/** + * @param ent + * @param x + * @param y + * @param z + * @param mode + */ void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode) { ent.Commands.push_back(std::unique_ptr(new MoveToCommand(x, y, z, mode))); } +/** + * @param ent + * @param x + * @param y + * @param z + * @param mode + */ void MobMovementManager::PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode) { ent.Commands.push_back(std::unique_ptr(new SwimToCommand(x, y, z, mode))); } +/** + * @param ent + * @param who + * @param to + * @param mode + */ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode) { auto from = FixHeading(who->GetHeading()); @@ -1053,43 +1255,56 @@ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, ent.Commands.push_back(std::unique_ptr(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mode))); } -void MobMovementManager::PushStopMoving(MobMovementEntry &ent) +/** + * @param mob_movement_entry + */ +void MobMovementManager::PushStopMoving(MobMovementEntry &mob_movement_entry) { - ent.Commands.push_back(std::unique_ptr(new StopMovingCommand())); + mob_movement_entry.Commands.push_back(std::unique_ptr(new StopMovingCommand())); } -void MobMovementManager::PushEvadeCombat(MobMovementEntry &ent) +/** + * @param mob_movement_entry + */ +void MobMovementManager::PushEvadeCombat(MobMovementEntry &mob_movement_entry) { - ent.Commands.push_back(std::unique_ptr(new EvadeCombatCommand())); + mob_movement_entry.Commands.push_back(std::unique_ptr(new EvadeCombatCommand())); } -void MobMovementManager::HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mode) +/** + * @param who + * @param x + * @param y + * @param z + * @param mob_movement_mode + */ +void MobMovementManager::HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode) { - auto sb = who->GetStuckBehavior(); + auto sb = who->GetStuckBehavior(); MobStuckBehavior behavior = RunToTarget; if (sb >= 0 && sb < MaxStuckBehavior) { - behavior = (MobStuckBehavior)sb; + behavior = (MobStuckBehavior) sb; } auto eiter = _impl->Entries.find(who); - auto &ent = (*eiter); + auto &ent = (*eiter); switch (sb) { - case RunToTarget: - PushMoveTo(ent.second, x, y, z, mode); - PushStopMoving(ent.second); - break; - case WarpToTarget: - PushTeleportTo(ent.second, x, y, z, 0.0f); - PushStopMoving(ent.second); - break; - case TakeNoAction: - PushStopMoving(ent.second); - break; - case EvadeCombat: - //PushEvadeCombat(ent.second); - PushStopMoving(ent.second); - break; + case RunToTarget: + PushMoveTo(ent.second, x, y, z, mob_movement_mode); + PushStopMoving(ent.second); + break; + case WarpToTarget: + PushTeleportTo(ent.second, x, y, z, 0.0f); + PushStopMoving(ent.second); + break; + case TakeNoAction: + PushStopMoving(ent.second); + break; + case EvadeCombat: + //PushEvadeCombat(ent.second); + PushStopMoving(ent.second); + break; } } diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index d9b2e7845..04c639ea1 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -41,18 +41,18 @@ class MobMovementManager public: ~MobMovementManager(); void Process(); - void AddMob(Mob *m); - void RemoveMob(Mob *m); - void AddClient(Client *c); - void RemoveClient(Client *c); + void AddMob(Mob *mob); + void RemoveMob(Mob *mob); + void AddClient(Client *client); + void RemoveClient(Client *client); - void RotateTo(Mob *who, float to, MobMovementMode mode = MovementRunning); + void RotateTo(Mob *who, float to, MobMovementMode mob_movement_mode = MovementRunning); void Teleport(Mob *who, float x, float y, float z, float heading); void NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode = MovementRunning); void StopNavigation(Mob *who); - void SendCommandToClients(Mob *m, float dx, float dy, float dz, float dh, int anim, ClientRange range); + void SendCommandToClients(Mob *mob, float delta_x, float delta_y, float delta_z, float delta_heading, int anim, ClientRange range); float FixHeading(float in); - void DumpStats(Client *to); + void DumpStats(Client *client); void ClearStats(); static MobMovementManager &Get() { @@ -65,18 +65,18 @@ private: MobMovementManager(const MobMovementManager&); MobMovementManager& operator=(const MobMovementManager&); - void FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim); - void UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode); + void FillCommandStruct(PlayerPositionUpdateServer_Struct *position_update_server_struct, Mob *mob, float delta_x, float delta_y, float delta_z, float delta_heading, int anim); + void UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode); void UpdatePathGround(Mob *who, float x, float y, float z, MobMovementMode mode); - void UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode mode); + void UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode movement_mode); void UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode); void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading); void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode); - void PushStopMoving(MobMovementEntry &ent); - void PushEvadeCombat(MobMovementEntry &ent); - void HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mode); + void PushStopMoving(MobMovementEntry &mob_movement_entry); + void PushEvadeCombat(MobMovementEntry &mob_movement_entry); + void HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode); struct Implementation; std::unique_ptr _impl; From 9f6976e852c147693a96119395f3343f14e7f87c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Aug 2019 03:24:59 -0500 Subject: [PATCH 122/491] More readability changes --- zone/mob_movement_manager.cpp | 67 ++++++++++++++++++++--------------- zone/mob_movement_manager.h | 21 ++++++++--- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 398cd9c2a..df1a38168 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -26,11 +26,11 @@ public: class RotateToCommand : public IMovementCommand { public: - RotateToCommand(double rotate_to, double dir, MobMovementMode mode) + RotateToCommand(double rotate_to, double dir, MobMovementMode mob_movement_mode) { m_rotate_to = rotate_to; m_rotate_to_dir = dir; - m_rotate_to_mode = mode; + m_rotate_to_mode = mob_movement_mode; m_started = false; } @@ -265,7 +265,7 @@ protected: class SwimToCommand : public MoveToCommand { public: - SwimToCommand(float x, float y, float z, MobMovementMode mode) : MoveToCommand(x, y, z, mode) + SwimToCommand(float x, float y, float z, MobMovementMode mob_movement_mode) : MoveToCommand(x, y, z, mob_movement_mode) { } @@ -564,6 +564,9 @@ void MobMovementManager::Process() } } +/** + * @param mob + */ void MobMovementManager::AddMob(Mob *mob) { _impl->Entries.insert(std::make_pair(mob, MobMovementEntry())); @@ -714,6 +717,7 @@ void MobMovementManager::StopNavigation(Mob *who) * @param delta_heading * @param anim * @param range + * @param single_client */ void MobMovementManager::SendCommandToClients( Mob *mob, @@ -722,7 +726,8 @@ void MobMovementManager::SendCommandToClients( float delta_z, float delta_heading, int anim, - ClientRange range + ClientRange range, + Client* single_client ) { if (range == ClientRangeNone) { @@ -736,6 +741,10 @@ void MobMovementManager::SendCommandToClients( if (range == ClientRangeAny) { for (auto &c : _impl->Clients) { + if (single_client && c != single_client) { + continue; + } + _impl->Stats.TotalSent++; if (anim != 0) { @@ -756,6 +765,10 @@ void MobMovementManager::SendCommandToClients( float long_range = zone->GetMaxMovementUpdateRange(); for (auto &c : _impl->Clients) { + if (single_client && c != single_client) { + continue; + } + float distance = c->CalculateDistance(mob->GetX(), mob->GetY(), mob->GetZ()); bool match = false; @@ -859,7 +872,7 @@ void MobMovementManager::ClearStats() } /** - * @param position_update_server_struct + * @param position_update * @param mob * @param delta_x * @param delta_y @@ -868,7 +881,7 @@ void MobMovementManager::ClearStats() * @param anim */ void MobMovementManager::FillCommandStruct( - PlayerPositionUpdateServer_Struct *position_update_server_struct, + PlayerPositionUpdateServer_Struct *position_update, Mob *mob, float delta_x, float delta_y, @@ -877,17 +890,17 @@ void MobMovementManager::FillCommandStruct( int anim ) { - memset(position_update_server_struct, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); - position_update_server_struct->spawn_id = mob->GetID(); - position_update_server_struct->x_pos = FloatToEQ19(mob->GetX()); - position_update_server_struct->y_pos = FloatToEQ19(mob->GetY()); - position_update_server_struct->z_pos = FloatToEQ19(mob->GetZ()); - position_update_server_struct->heading = FloatToEQ12(mob->GetHeading()); - position_update_server_struct->delta_x = FloatToEQ13(delta_x); - position_update_server_struct->delta_y = FloatToEQ13(delta_y); - position_update_server_struct->delta_z = FloatToEQ13(delta_z); - position_update_server_struct->delta_heading = FloatToEQ10(delta_heading); - position_update_server_struct->animation = (mob->IsBot() ? (int) ((float) anim / 1.785714f) : anim); + memset(position_update, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); + position_update->spawn_id = mob->GetID(); + position_update->x_pos = FloatToEQ19(mob->GetX()); + position_update->y_pos = FloatToEQ19(mob->GetY()); + position_update->z_pos = FloatToEQ19(mob->GetZ()); + position_update->heading = FloatToEQ12(mob->GetHeading()); + position_update->delta_x = FloatToEQ13(delta_x); + position_update->delta_y = FloatToEQ13(delta_y); + position_update->delta_z = FloatToEQ13(delta_z); + position_update->delta_heading = FloatToEQ10(delta_heading); + position_update->animation = (mob->IsBot() ? (int) ((float) anim / 1.785714f) : anim); } /** @@ -955,8 +968,6 @@ void MobMovementManager::UpdatePathGround(Mob *who, float x, float y, float z, M AdjustRoute(route, who); - - //avoid doing any processing if the mob is stuck to allow normal stuck code to work. if (!stuck) { @@ -1208,11 +1219,11 @@ void MobMovementManager::PushTeleportTo(MobMovementEntry &ent, float x, float y, * @param x * @param y * @param z - * @param mode + * @param mob_movement_mode */ -void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode) +void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode) { - ent.Commands.push_back(std::unique_ptr(new MoveToCommand(x, y, z, mode))); + ent.Commands.push_back(std::unique_ptr(new MoveToCommand(x, y, z, mob_movement_mode))); } /** @@ -1220,20 +1231,20 @@ void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, flo * @param x * @param y * @param z - * @param mode + * @param mob_movement_mode */ -void MobMovementManager::PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode) +void MobMovementManager::PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode) { - ent.Commands.push_back(std::unique_ptr(new SwimToCommand(x, y, z, mode))); + ent.Commands.push_back(std::unique_ptr(new SwimToCommand(x, y, z, mob_movement_mode))); } /** * @param ent * @param who * @param to - * @param mode + * @param mob_movement_mode */ -void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode) +void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode) { auto from = FixHeading(who->GetHeading()); to = FixHeading(to); @@ -1252,7 +1263,7 @@ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, diff -= 512.0; } - ent.Commands.push_back(std::unique_ptr(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mode))); + ent.Commands.push_back(std::unique_ptr(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode))); } /** diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 04c639ea1..3c616cc5a 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -50,7 +50,18 @@ public: void Teleport(Mob *who, float x, float y, float z, float heading); void NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode = MovementRunning); void StopNavigation(Mob *who); - void SendCommandToClients(Mob *mob, float delta_x, float delta_y, float delta_z, float delta_heading, int anim, ClientRange range); + + void SendCommandToClients( + Mob *mob, + float delta_x, + float delta_y, + float delta_z, + float delta_heading, + int anim, + ClientRange range, + Client* single_client = nullptr + ); + float FixHeading(float in); void DumpStats(Client *client); void ClearStats(); @@ -65,15 +76,15 @@ private: MobMovementManager(const MobMovementManager&); MobMovementManager& operator=(const MobMovementManager&); - void FillCommandStruct(PlayerPositionUpdateServer_Struct *position_update_server_struct, Mob *mob, float delta_x, float delta_y, float delta_z, float delta_heading, int anim); + void FillCommandStruct(PlayerPositionUpdateServer_Struct *position_update, Mob *mob, float delta_x, float delta_y, float delta_z, float delta_heading, int anim); void UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode); void UpdatePathGround(Mob *who, float x, float y, float z, MobMovementMode mode); void UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode movement_mode); void UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode); void PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading); - void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); - void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mode); - void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mode); + void PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode); + void PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode); + void PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode); void PushStopMoving(MobMovementEntry &mob_movement_entry); void PushEvadeCombat(MobMovementEntry &mob_movement_entry); void HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode); From 8fa76b91542fe8617a05cc29b548b3220a4218e2 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Aug 2019 03:27:33 -0500 Subject: [PATCH 123/491] Optimizations to movement updates to eliminate ghosting possibilities in larger zones --- changelog.txt | 3 +++ zone/client.cpp | 1 + zone/client.h | 1 + zone/client_packet.cpp | 35 +++++++++++++++++++++++++++++++---- zone/client_process.cpp | 5 +++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/changelog.txt b/changelog.txt index 6b9d00a80..3f69bf570 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 8/6/2019 == +Akkadius: Optimizations to movement updates to eliminate ghosting possibilities in larger zones + == 7/22/2019 == Uleat: Added script 'vcxproj_dependencies.py' - a script to help determine conflicting project dependencies (alpha-stage) diff --git a/zone/client.cpp b/zone/client.cpp index 57f6ba865..ac696247a 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -136,6 +136,7 @@ Client::Client(EQStreamInterface* ieqs) forget_timer(0), autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000), client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000), + client_zone_wide_full_position_update_timer(5 * 60 * 1000), tribute_timer(Tribute_duration), proximity_timer(ClientProximity_interval), TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000), diff --git a/zone/client.h b/zone/client.h index 0272fb21b..7b37c2b47 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1517,6 +1517,7 @@ private: Timer forget_timer; // our 2 min everybody forgets you timer Timer autosave_timer; Timer client_scan_npc_aggro_timer; + Timer client_zone_wide_full_position_update_timer; Timer tribute_timer; Timer proximity_timer; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f0eb00d13..2dc5cdbf9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -60,6 +60,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "water_map.h" #include "worldserver.h" #include "zone.h" +#include "mob_movement_manager.h" #ifdef BOTS #include "bot.h" @@ -4466,16 +4467,16 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { /* Handle client aggro scanning timers NPCs */ is_client_moving = (ppu->y_pos == m_Position.y && ppu->x_pos == m_Position.x) ? false : true; - + if (is_client_moving) { Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u", client_scan_npc_aggro_timer.GetDuration()); if (client_scan_npc_aggro_timer.GetDuration() > 1000) { client_scan_npc_aggro_timer.Disable(); client_scan_npc_aggro_timer.Start(500); - } - } else { + } + else { Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u", client_scan_npc_aggro_timer.GetDuration()); if (client_scan_npc_aggro_timer.GetDuration() < 1000) { @@ -4483,7 +4484,33 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { client_scan_npc_aggro_timer.Start(3000); } } - + + /** + * On a normal basis we limit mob movement updates based on distance + * This ensures we send a periodic full zone update to a client that has started + * moving after 5 or so minutes + */ + if (is_client_moving && client_zone_wide_full_position_update_timer.Check()) { + Log(Logs::Detail, Logs::Normal, "[%s] Client Zone Wide Position Update NPCs", GetCleanName()); + + auto &mob_movement_manager = MobMovementManager::Get(); + auto &mob_list = entity_list.GetMobList(); + + for (auto &it : mob_list) { + Mob *entity = it.second; + if (!entity->IsNPC()) { + continue; + } + + float distance_from_client_to_ignore = zone->GetMaxMovementUpdateRange() - 100; + if (CalculateDistance(entity->GetX(), entity->GetY(), entity->GetZ()) <= distance_from_client_to_ignore) { + continue; + } + + mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, this); + } + } + float new_heading = EQ12toFloat(ppu->heading); int32 new_animation = ppu->animation; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 5c750f03a..244f36580 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -592,8 +592,8 @@ bool Client::Process() { // only if client is not feigned if (zone->CanDoCombat() && ret && !GetFeigned() && client_scan_npc_aggro_timer.Check()) { int npc_scan_count = 0; - for (auto it = close_mobs.begin(); it != close_mobs.end(); ++it) { - Mob *mob = it->first; + for (auto & close_mob : close_mobs) { + Mob *mob = close_mob.first; if (!mob) continue; @@ -604,6 +604,7 @@ bool Client::Process() { if (mob->CheckWillAggro(this) && !mob->CheckAggro(this)) { mob->AddToHateList(this, 25); } + npc_scan_count++; } Log(Logs::General, Logs::Aggro, "Checking Reverse Aggro (client->npc) scanned_npcs (%i)", npc_scan_count); From 2014b6c251b9fbd88e78cc4e7f4235c20910ab9e Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Tue, 6 Aug 2019 03:28:17 -0500 Subject: [PATCH 124/491] Delete CTestTestfile.cmake --- cmake-build-debug/submodules/libuv/CTestTestfile.cmake | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 cmake-build-debug/submodules/libuv/CTestTestfile.cmake diff --git a/cmake-build-debug/submodules/libuv/CTestTestfile.cmake b/cmake-build-debug/submodules/libuv/CTestTestfile.cmake deleted file mode 100644 index 22e3caa8a..000000000 --- a/cmake-build-debug/submodules/libuv/CTestTestfile.cmake +++ /dev/null @@ -1,6 +0,0 @@ -# CMake generated Testfile for -# Source directory: /Users/cmiles/code/eqemu-docker-cloud/code/submodules/libuv -# Build directory: /Users/cmiles/code/eqemu-docker-cloud/code/cmake-build-debug/submodules/libuv -# -# This file includes the relevant testing commands required for -# testing this directory and lists subdirectories to be tested as well. From f1ee042de6291ae4fb8c383aed8954d1da103d9c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Tue, 6 Aug 2019 04:07:37 -0500 Subject: [PATCH 125/491] Add bulk force update by distance as well which we had similarily before the movement overhaul --- zone/client.cpp | 13 +++++++++++++ zone/client.h | 4 ++++ zone/client_packet.cpp | 21 ++++++++++++++++++--- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index ac696247a..3f0e33d2f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -9116,3 +9116,16 @@ bool Client::GotoPlayer(std::string player_name) return false; } + +glm::vec4 &Client::GetLastPositionBeforeBulkUpdate() +{ + return last_position_before_bulk_update; +} + +/** + * @param in_last_position_before_bulk_update + */ +void Client::SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update) +{ + Client::last_position_before_bulk_update = in_last_position_before_bulk_update; +} \ No newline at end of file diff --git a/zone/client.h b/zone/client.h index 7b37c2b47..2ea27b108 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1309,6 +1309,9 @@ public: uint32 trapid; //ID of trap player has triggered. This is cleared when the player leaves the trap's radius, or it despawns. + void SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update); + glm::vec4 &GetLastPositionBeforeBulkUpdate(); + protected: friend class Mob; void CalcItemBonuses(StatBonuses* newbon); @@ -1540,6 +1543,7 @@ private: Timer position_update_timer; /* Timer used when client hasn't updated within a 10 second window */ glm::vec3 m_Proximity; + glm::vec4 last_position_before_bulk_update; void BulkSendInventoryItems(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 2dc5cdbf9..688a448eb 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -806,6 +806,8 @@ void Client::CompleteConnect() parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0); + SetLastPositionBeforeBulkUpdate(GetPosition()); + /* This sub event is for if a player logs in for the first time since entering world. */ if (firstlogon == 1) { parse->EventPlayer(EVENT_CONNECT, this, "", 0); @@ -4487,10 +4489,21 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { /** * On a normal basis we limit mob movement updates based on distance - * This ensures we send a periodic full zone update to a client that has started - * moving after 5 or so minutes + * This ensures we send a periodic full zone update to a client that has started moving after 5 or so minutes + * + * For very large zones we will also force a full update based on distance + * + * We ignore a small distance around us so that we don't interrupt already pathing deltas as those npcs will appear + * to full stop when they are actually still pathing */ - if (is_client_moving && client_zone_wide_full_position_update_timer.Check()) { + + float distance_moved = DistanceNoZ(GetLastPositionBeforeBulkUpdate(), GetPosition()); + bool moved_far_enough_before_bulk_update = distance_moved >= 1200; + bool is_ready_to_update = ( + client_zone_wide_full_position_update_timer.Check() || moved_far_enough_before_bulk_update + ); + + if (is_client_moving && is_ready_to_update) { Log(Logs::Detail, Logs::Normal, "[%s] Client Zone Wide Position Update NPCs", GetCleanName()); auto &mob_movement_manager = MobMovementManager::Get(); @@ -4509,6 +4522,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, this); } + + SetLastPositionBeforeBulkUpdate(GetPosition()); } float new_heading = EQ12toFloat(ppu->heading); From d9eeb00dead215f9fd2951d85c09fd9f0341fdd0 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Wed, 7 Aug 2019 18:54:53 -0500 Subject: [PATCH 126/491] Adjust ghosting algorithm to work much better for super large zones as well --- zone/client_packet.cpp | 6 +-- zone/mob_movement_manager.cpp | 2 +- zone/zone.cpp | 70 +++++++++++++++++++++++++++++++++-- zone/zone.h | 7 +++- 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 688a448eb..4f819e7a4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4498,7 +4498,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { */ float distance_moved = DistanceNoZ(GetLastPositionBeforeBulkUpdate(), GetPosition()); - bool moved_far_enough_before_bulk_update = distance_moved >= 1200; + bool moved_far_enough_before_bulk_update = distance_moved >= zone->GetNpcPositionUpdateDistance(); bool is_ready_to_update = ( client_zone_wide_full_position_update_timer.Check() || moved_far_enough_before_bulk_update ); @@ -4515,8 +4515,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { continue; } - float distance_from_client_to_ignore = zone->GetMaxMovementUpdateRange() - 100; - if (CalculateDistance(entity->GetX(), entity->GetY(), entity->GetZ()) <= distance_from_client_to_ignore) { + float distance_from_client_to_ignore = zone->GetNpcPositionUpdateDistance(); + if (entity->IsMoving() && CalculateDistance(entity->GetX(), entity->GetY(), entity->GetZ()) <= distance_from_client_to_ignore) { continue; } diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index df1a38168..4bf1663d3 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -762,7 +762,7 @@ void MobMovementManager::SendCommandToClients( } else { float short_range = RuleR(Pathing, ShortMovementUpdateRange); - float long_range = zone->GetMaxMovementUpdateRange(); + float long_range = zone->GetNpcPositionUpdateDistance(); for (auto &c : _impl->Clients) { if (single_client && c != single_client) { diff --git a/zone/zone.cpp b/zone/zone.cpp index 2121642bb..d20b2934e 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -55,6 +55,7 @@ #include "zone_config.h" #include "mob_movement_manager.h" #include "npc_scale_manager.h" +#include "../common/data_verification.h" #include #include @@ -864,6 +865,8 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) m_last_ucss_update = 0; mMovementManager = &MobMovementManager::Get(); + + SetNpcPositionUpdateDistance(0); } Zone::~Zone() { @@ -1194,9 +1197,9 @@ uint32 Zone::CountAuth() { bool Zone::Process() { spawn_conditions.Process(); - if(spawn2_timer.Check()) { + if (spawn2_timer.Check()) { - LinkedListIterator iterator(spawn2_list); + LinkedListIterator iterator(spawn2_list); EQEmu::InventoryProfile::CleanDirty(); @@ -1212,10 +1215,15 @@ bool Zone::Process() { } } - if(adv_data && !did_adventure_actions) + if (adv_data && !did_adventure_actions) { DoAdventureActions(); + } + if (GetNpcPositionUpdateDistance() == 0) { + CalculateNpcUpdateDistanceSpread(); + } } + if(initgrids_timer.Check()) { //delayed grid loading stuff. initgrids_timer.Disable(); @@ -2365,3 +2373,59 @@ void Zone::SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp) { if (m_last_ucss_update < update_timestamp) m_ucss_available = ucss_available; } + +int Zone::GetNpcPositionUpdateDistance() const +{ + return npc_position_update_distance; +} + +void Zone::SetNpcPositionUpdateDistance(int in_npc_position_update_distance) +{ + Zone::npc_position_update_distance = in_npc_position_update_distance; +} + +void Zone::CalculateNpcUpdateDistanceSpread() +{ + float max_x = 0; + float max_y = 0; + float min_x = 0; + float min_y = 0; + + auto &mob_list = entity_list.GetMobList(); + + for (auto &it : mob_list) { + Mob *entity = it.second; + if (!entity->IsNPC()) { + continue; + } + + if (entity->GetX() <= min_x) { + min_x = entity->GetX(); + } + + if (entity->GetY() <= min_y) { + min_y = entity->GetY(); + } + + if (entity->GetX() >= max_x) { + max_x = entity->GetX(); + } + + if (entity->GetY() >= max_y) { + max_y = entity->GetY(); + } + } + + int x_spread = int(abs(max_x - min_x)); + int y_spread = int(abs(max_y - min_y)); + int combined_spread = int(abs((x_spread + y_spread) / 2)); + int update_distance = EQEmu::ClampLower(int(combined_spread / 4), int(zone->GetMaxMovementUpdateRange())); + + SetNpcPositionUpdateDistance(update_distance); + + Log(Logs::General, Logs::Debug, + "NPC update spread distance set to [%i] combined_spread [%i]", + update_distance, + combined_spread + ); +} \ No newline at end of file diff --git a/zone/zone.h b/zone/zone.h index a7de25ab4..176fe0cb3 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -126,6 +126,9 @@ public: bool Process(); bool SaveZoneCFG(); + int GetNpcPositionUpdateDistance() const; + void SetNpcPositionUpdateDistance(int in_npc_position_update_distance); + char *adv_data; const char *GetSpellBlockedMessage(uint32 spell_id, const glm::vec3 &location); @@ -219,6 +222,7 @@ public: void ChangeWeather(); void ClearBlockedSpells(); void ClearNPCTypeCache(int id); + void CalculateNpcUpdateDistanceSpread(); void DelAggroMob() { aggroedmobs--; } void DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, uint32 zoneID); void Despawn(uint32 spawngroupID); @@ -290,7 +294,7 @@ public: */ find_replace(message, std::string("%"), std::string(".")); - if (message.find("\n") != std::string::npos) { + if (message.find('\n') != std::string::npos) { auto message_split = SplitString(message, '\n'); entity_list.MessageStatus( 0, @@ -345,6 +349,7 @@ private: glm::vec4 m_Graveyard; int default_ruleset; int totalBS; + int npc_position_update_distance; int32 aggroedmobs; uint8 zone_type; uint16 instanceversion; From 8df7bcc2c8df71c9867e3248e096128ddb7bbc94 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Thu, 8 Aug 2019 14:26:08 -0400 Subject: [PATCH 127/491] Fix double free in queryserv --- queryserv/database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queryserv/database.cpp b/queryserv/database.cpp index fcda884e4..1e06f229e 100644 --- a/queryserv/database.cpp +++ b/queryserv/database.cpp @@ -379,6 +379,7 @@ void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint3 } +// this function does not delete the ServerPacket, so it must be handled at call site void Database::GeneralQueryReceive(ServerPacket *pack) { /* These are general queries passed from anywhere in zone instead of packing structures and breaking them down again and again @@ -393,7 +394,6 @@ void Database::GeneralQueryReceive(ServerPacket *pack) { Log(Logs::Detail, Logs::QS_Server, "%s", query.c_str()); } - safe_delete(pack); safe_delete_array(queryBuffer); } From 880de837d90bfc80832f5b744a3123681e08ee5a Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 8 Aug 2019 15:55:14 -0700 Subject: [PATCH 128/491] Crash and compile issues on windows --- common/cli/eqemu_command_handler.cpp | 4 ++-- common/eqemu_logsys.cpp | 7 +++---- common/eqemu_logsys.h | 4 ++-- loginserver/loginserver_command_handler.cpp | 2 +- zone/embparser_api.cpp | 6 +++--- zone/lua_general.cpp | 4 ++-- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/common/cli/eqemu_command_handler.cpp b/common/cli/eqemu_command_handler.cpp index 79e87dfd8..6c08edeff 100644 --- a/common/cli/eqemu_command_handler.cpp +++ b/common/cli/eqemu_command_handler.cpp @@ -81,12 +81,12 @@ namespace EQEmuCommand { if (!arguments_filled || argc == 2) { std::string arguments_string; - for (auto &arg : arguments) { + for (auto &arg : arguments) { arguments_string += " " + arg + "=*\n"; } std::string options_string; - for (auto &opt : options) { + for (auto &opt : options) { options_string += " " + opt + "\n"; } diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index 87d4465b4..d35592aa4 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -440,7 +440,7 @@ void EQEmuLogSys::Out( const char *file, const char *func, int line, - const std::string &message, + const char *message, ... ) { @@ -470,10 +470,9 @@ void EQEmuLogSys::Out( prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line); } - auto msg_cstr = message.c_str(); va_list args; - va_start(args, msg_cstr); - std::string output_message = vStringFormat(msg_cstr, args); + va_start(args, message); + std::string output_message = vStringFormat(message, args); va_end(args); std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message); diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index f3c48ae88..f2c68c09b 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -272,7 +272,7 @@ public: const char *file, const char *func, int line, - const std::string &message, + const char *message, ... ); @@ -410,7 +410,7 @@ void OutF( ) { std::string log_str = fmt::format(fmt, args...); - ls.Out(debug_level, log_category, file, func, line, log_str); + ls.Out(debug_level, log_category, file, func, line, log_str.c_str()); } #endif diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index e4a316a5f..68cd3ea5d 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -163,7 +163,7 @@ namespace LoginserverCommandHandler { std::vector arguments = { "--username", - "--password" + "--password", "--email" }; std::vector options = {}; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index bdb190e9c..cf2feabcf 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3618,11 +3618,11 @@ XS(XS__debug) { return; if (debug_level == Logs::General) { - Log(Logs::General, Logs::QuestDebug, log_message); + Log(Logs::General, Logs::QuestDebug, log_message.c_str()); } else if (debug_level == Logs::Moderate) { - Log(Logs::Moderate, Logs::QuestDebug, log_message); + Log(Logs::Moderate, Logs::QuestDebug, log_message.c_str()); } else if (debug_level == Logs::Detail) { - Log(Logs::Detail, Logs::QuestDebug, log_message); + Log(Logs::Detail, Logs::QuestDebug, log_message.c_str()); } } XSRETURN_EMPTY; diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index ef9180b68..295fa260e 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -1368,14 +1368,14 @@ double lua_clock() { } void lua_debug(std::string message) { - Log(Logs::General, Logs::QuestDebug, message); + Log(Logs::General, Logs::QuestDebug, message.c_str()); } void lua_debug(std::string message, int level) { if (level < Logs::General || level > Logs::Detail) return; - Log(static_cast(level), Logs::QuestDebug, message); + Log(static_cast(level), Logs::QuestDebug, message.c_str()); } void lua_update_zone_header(std::string type, std::string value) { From 19c92173d2b9f1b905849f80c3558dcf50b1ec72 Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 8 Aug 2019 20:38:24 -0400 Subject: [PATCH 129/491] Added signal check for player EVENT_CAST_BEGIN --- zone/spells.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zone/spells.cpp b/zone/spells.cpp index 8b1a08d19..fa09727a2 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -298,7 +298,8 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, if(IsClient()) { char temp[64]; sprintf(temp, "%d", spell_id); - parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), temp, 0); + if (parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), temp, 0) != 0) + return false; } else if(IsNPC()) { char temp[64]; sprintf(temp, "%d", spell_id); From 6a64d845c2cee9acddd511f5f46c9d0a8250292a Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 8 Aug 2019 18:45:10 -0700 Subject: [PATCH 130/491] Async eqemu login credential lookup --- common/event/task_scheduler.h | 114 ++++++++++++++++++++ loginserver/account_management.cpp | 101 +++++++++++++++++ loginserver/account_management.h | 10 ++ loginserver/loginserver_command_handler.cpp | 35 +++++- loginserver/loginserver_command_handler.h | 1 + loginserver/loginserver_webserver.cpp | 32 +++++- 6 files changed, 291 insertions(+), 2 deletions(-) create mode 100644 common/event/task_scheduler.h diff --git a/common/event/task_scheduler.h b/common/event/task_scheduler.h new file mode 100644 index 000000000..6cfe15f00 --- /dev/null +++ b/common/event/task_scheduler.h @@ -0,0 +1,114 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace EQ +{ + namespace Event + { + class TaskScheduler + { + public: + static const int DefaultThreadCount = 4; + + TaskScheduler() : _running(false) + { + Start(DefaultThreadCount); + } + + TaskScheduler(size_t threads) : _running(false) + { + Start(threads); + } + + ~TaskScheduler() { + Stop(); + } + + void Start(size_t threads) { + if (true == _running) { + return; + } + + _running = true; + + for (size_t i = 0; i < threads; ++i) { + _threads.push_back(std::thread(std::bind(&TaskScheduler::ProcessWork, this))); + } + } + + void Stop() { + if (false == _running) { + return; + } + + { + std::unique_lock lock(_lock); + _running = false; + } + + _cv.notify_all(); + + for (auto &t : _threads) { + t.join(); + } + } + + template + auto Enqueue(Fn&& fn, Args&&... args) -> std::future::type> { + using return_type = typename std::result_of::type; + + auto task = std::make_shared>( + std::bind(std::forward(fn), std::forward(args)...) + ); + + std::future res = task->get_future(); + { + std::unique_lock lock(_lock); + + if (false == _running) { + throw std::runtime_error("Enqueue on stopped scheduler."); + } + + _tasks.emplace([task]() { (*task)(); }); + } + + _cv.notify_one(); + return res; + } + + private: + void ProcessWork() { + for (;;) { + std::function work; + + { + std::unique_lock lock(_lock); + _cv.wait(lock, [this] { return !_running || !_tasks.empty(); }); + + if (false == _running) { + return; + } + + work = std::move(_tasks.front()); + _tasks.pop(); + } + + work(); + } + + } + + bool _running = true; + std::vector _threads; + std::mutex _lock; + std::condition_variable _cv; + std::queue> _tasks; + }; + } +} diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 2817b09ff..139fe9690 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -20,8 +20,12 @@ #include "account_management.h" #include "login_server.h" +#include "../common/event/task_scheduler.h" +#include "../common/event/event_loop.h" +#include "../common/net/dns.h" extern LoginServer server; +EQ::Event::TaskScheduler task_runner; /** * @param username @@ -238,3 +242,100 @@ bool AccountManagement::UpdateLoginserverUserCredentials( return true; } + +bool AccountManagement::CheckExternalLoginserverUserCredentials(const std::string &in_account_username, const std::string &in_account_password) +{ + auto res = task_runner.Enqueue([&]() -> bool { + bool running = true; + bool ret = false; + EQ::Net::DaybreakConnectionManager mgr; + std::shared_ptr c; + + mgr.OnNewConnection([&](std::shared_ptr connection) { + c = connection; + }); + + mgr.OnConnectionStateChange([&](std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) { + if (EQ::Net::StatusConnected == to) { + EQ::Net::DynamicPacket p; + p.PutUInt16(0, 1); //OP_SessionReady + p.PutUInt32(2, 2); + c->QueuePacket(p); + } + else if (EQ::Net::StatusDisconnected == to) { + running = false; + } + }); + + mgr.OnPacketRecv([&](std::shared_ptr conn, const EQ::Net::Packet &p) { + auto opcode = p.GetUInt16(0); + switch (opcode) { + case 0x0017: //OP_ChatMessage + { + size_t buffer_len = in_account_username.length() + in_account_password.length() + 2; + std::unique_ptr buffer(new char[buffer_len]); + + strcpy(&buffer[0], in_account_username.c_str()); + strcpy(&buffer[in_account_username.length() + 1], in_account_password.c_str()); + + size_t encrypted_len = buffer_len; + + if (encrypted_len % 8 > 0) { + encrypted_len = ((encrypted_len / 8) + 1) * 8; + } + + EQ::Net::DynamicPacket p; + p.Resize(12 + encrypted_len); + p.PutUInt16(0, 2); //OP_Login + p.PutUInt32(2, 3); + + eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true); + c->QueuePacket(p); + break; + } + case 0x0018: + { + auto encrypt_size = p.Length() - 12; + if (encrypt_size % 8 > 0) { + encrypt_size = (encrypt_size / 8) * 8; + } + + std::unique_ptr decrypted(new char[encrypt_size]); + + eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false); + + EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); + auto response_error = sp.GetUInt16(1); + + if (response_error > 101) { + ret = false; + running = false; + } + else { + ret = true; + running = false; + } + break; + } + } + }); + + EQ::Net::DNSLookup("login.eqemulator.net", 5999, false, [&](const std::string &addr) { + if (addr == "") { + ret = false; + running = false; + } + + mgr.Connect(addr, 5999); + }); + + auto &loop = EQ::EventLoop::Get(); + while (true == running) { + loop.Process(); + } + + return ret; + }); + + return res.get(); +} diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 3ab179405..680122213 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -70,6 +70,16 @@ public: const std::string &in_account_password, const std::string &source_loginserver = "local" ); + + /** + * @param in_account_username + * @param in_account_password + * @return + */ + static bool CheckExternalLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password + ); }; diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 68cd3ea5d..81647d60d 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -51,6 +51,7 @@ namespace LoginserverCommandHandler { * Register commands */ function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; + function_map["login-user:check-external-credentials"] = &LoginserverCommandHandler::CheckExternalLoginserverUserCredentials; function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; function_map["login-user:update-credentials"] = &LoginserverCommandHandler::UpdateLoginserverUserCredentials; function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; @@ -203,10 +204,12 @@ namespace LoginserverCommandHandler { EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); - AccountManagement::CheckLoginserverUserCredentials( + auto res = AccountManagement::CheckLoginserverUserCredentials( cmd("--username").str(), cmd("--password").str() ); + + LogInfo("Credentials were {0}", res == true ? "accepted" : "not accepted"); } /** @@ -236,4 +239,34 @@ namespace LoginserverCommandHandler { cmd("--password").str() ); } + + /** + * @param argc + * @param argv + * @param cmd + * @param description + */ + void CheckExternalLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description) + { + description = "Check user external login credentials"; + + std::vector arguments = { + "--username", + "--password" + }; + std::vector options = {}; + + if (cmd[{"-h", "--help"}]) { + return; + } + + EQEmuCommand::ValidateCmdInput(arguments, options, cmd, argc, argv); + + auto res = AccountManagement::CheckExternalLoginserverUserCredentials( + cmd("--username").str(), + cmd("--password").str() + ); + + LogInfo("Credentials were {0}", res == true ? "accepted" : "not accepted"); + } } diff --git a/loginserver/loginserver_command_handler.h b/loginserver/loginserver_command_handler.h index d155c8a0c..c7abc50a6 100644 --- a/loginserver/loginserver_command_handler.h +++ b/loginserver/loginserver_command_handler.h @@ -32,6 +32,7 @@ namespace LoginserverCommandHandler { void CreateLoginserverWorldAdminAccount(int argc, char **argv, argh::parser &cmd, std::string &description); void CheckLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); void UpdateLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); + void CheckExternalLoginserverUserCredentials(int argc, char **argv, argh::parser &cmd, std::string &description); }; diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 07d680fa1..a26115075 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -158,6 +158,36 @@ namespace LoginserverWebserver { LoginserverWebserver::SendResponse(response, res); } ); + + api.Post( + "/account/credentials/validate/external", [](const httplib::Request &request, httplib::Response &res) { + LoginserverWebserver::TokenManager::AuthCanRead(request, res); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); + + Json::Value response; + if (username.empty() || password.empty()) { + response["error"] = "Username or password not set"; + LoginserverWebserver::SendResponse(response, res); + return; + } + + bool credentials_valid = AccountManagement::CheckExternalLoginserverUserCredentials( + username, + password + ); + + if (credentials_valid) { + response["message"] = "Credentials valid!"; + } + else { + response["error"] = "Credentials invalid!"; + } + + LoginserverWebserver::SendResponse(response, res); + } + ); } /** @@ -351,4 +381,4 @@ namespace LoginserverWebserver { return {}; } -} \ No newline at end of file +} From 5fce042a31da9b91a87bd847f8e9ed47b966ba1b Mon Sep 17 00:00:00 2001 From: KimLS Date: Thu, 8 Aug 2019 18:49:21 -0700 Subject: [PATCH 131/491] Up stale connection ms again --- common/net/daybreak_connection.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index b4f3ca41c..883ecefac 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -257,7 +257,7 @@ namespace EQ resend_delay_min = 150; resend_delay_max = 5000; connect_delay_ms = 500; - stale_connection_ms = 30000; + stale_connection_ms = 60000; connect_stale_ms = 5000; crc_length = 2; max_packet_size = 512; From ea15e9bc5fdae9341b79a0ac89b90fc81572c8eb Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 9 Aug 2019 00:43:25 -0500 Subject: [PATCH 132/491] Fix bug with command length --- common/cli/eqemu_command_handler.cpp | 8 +- loginserver/account_management.cpp | 171 +++++++++++--------- loginserver/loginserver_command_handler.cpp | 14 +- loginserver/loginserver_webserver.cpp | 46 +++--- 4 files changed, 126 insertions(+), 113 deletions(-) diff --git a/common/cli/eqemu_command_handler.cpp b/common/cli/eqemu_command_handler.cpp index 6c08edeff..ef46e0d9f 100644 --- a/common/cli/eqemu_command_handler.cpp +++ b/common/cli/eqemu_command_handler.cpp @@ -148,10 +148,10 @@ namespace EQEmuCommand { int max_command_length = 0; for (auto &it: in_function_map) { - if (it.first.length() > max_command_length) { - std::stringstream command; - command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset; - max_command_length = command.str().length() + 5; + std::stringstream command; + command << termcolor::colorize << termcolor::yellow << it.first << termcolor::reset; + if (command.str().length() > max_command_length) { + max_command_length = command.str().length() + 1; } } diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 139fe9690..cca68a150 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -24,7 +24,7 @@ #include "../common/event/event_loop.h" #include "../common/net/dns.h" -extern LoginServer server; +extern LoginServer server; EQ::Event::TaskScheduler task_runner; /** @@ -243,99 +243,112 @@ bool AccountManagement::UpdateLoginserverUserCredentials( return true; } -bool AccountManagement::CheckExternalLoginserverUserCredentials(const std::string &in_account_username, const std::string &in_account_password) +bool AccountManagement::CheckExternalLoginserverUserCredentials( + const std::string &in_account_username, + const std::string &in_account_password +) { - auto res = task_runner.Enqueue([&]() -> bool { - bool running = true; - bool ret = false; - EQ::Net::DaybreakConnectionManager mgr; - std::shared_ptr c; + auto res = task_runner.Enqueue( + [&]() -> bool { + bool running = true; + bool ret = false; + EQ::Net::DaybreakConnectionManager mgr; + std::shared_ptr c; - mgr.OnNewConnection([&](std::shared_ptr connection) { - c = connection; - }); - - mgr.OnConnectionStateChange([&](std::shared_ptr conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to) { - if (EQ::Net::StatusConnected == to) { - EQ::Net::DynamicPacket p; - p.PutUInt16(0, 1); //OP_SessionReady - p.PutUInt32(2, 2); - c->QueuePacket(p); - } - else if (EQ::Net::StatusDisconnected == to) { - running = false; - } - }); - - mgr.OnPacketRecv([&](std::shared_ptr conn, const EQ::Net::Packet &p) { - auto opcode = p.GetUInt16(0); - switch (opcode) { - case 0x0017: //OP_ChatMessage - { - size_t buffer_len = in_account_username.length() + in_account_password.length() + 2; - std::unique_ptr buffer(new char[buffer_len]); - - strcpy(&buffer[0], in_account_username.c_str()); - strcpy(&buffer[in_account_username.length() + 1], in_account_password.c_str()); - - size_t encrypted_len = buffer_len; - - if (encrypted_len % 8 > 0) { - encrypted_len = ((encrypted_len / 8) + 1) * 8; + mgr.OnNewConnection( + [&](std::shared_ptr connection) { + c = connection; } + ); - EQ::Net::DynamicPacket p; - p.Resize(12 + encrypted_len); - p.PutUInt16(0, 2); //OP_Login - p.PutUInt32(2, 3); - - eqcrypt_block(&buffer[0], buffer_len, (char*)p.Data() + 12, true); - c->QueuePacket(p); - break; - } - case 0x0018: - { - auto encrypt_size = p.Length() - 12; - if (encrypt_size % 8 > 0) { - encrypt_size = (encrypt_size / 8) * 8; + mgr.OnConnectionStateChange( + [&]( + std::shared_ptr conn, + EQ::Net::DbProtocolStatus from, + EQ::Net::DbProtocolStatus to + ) { + if (EQ::Net::StatusConnected == to) { + EQ::Net::DynamicPacket p; + p.PutUInt16(0, 1); //OP_SessionReady + p.PutUInt32(2, 2); + c->QueuePacket(p); + } + else if (EQ::Net::StatusDisconnected == to) { + running = false; + } } + ); - std::unique_ptr decrypted(new char[encrypt_size]); + mgr.OnPacketRecv( + [&](std::shared_ptr conn, const EQ::Net::Packet &p) { + auto opcode = p.GetUInt16(0); + switch (opcode) { + case 0x0017: //OP_ChatMessage + { + size_t buffer_len = + in_account_username.length() + in_account_password.length() + 2; + std::unique_ptr buffer(new char[buffer_len]); - eqcrypt_block((char*)p.Data() + 12, encrypt_size, &decrypted[0], false); + strcpy(&buffer[0], in_account_username.c_str()); + strcpy(&buffer[in_account_username.length() + 1], in_account_password.c_str()); - EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); - auto response_error = sp.GetUInt16(1); + size_t encrypted_len = buffer_len; - if (response_error > 101) { - ret = false; - running = false; + if (encrypted_len % 8 > 0) { + encrypted_len = ((encrypted_len / 8) + 1) * 8; + } + + EQ::Net::DynamicPacket p; + p.Resize(12 + encrypted_len); + p.PutUInt16(0, 2); //OP_Login + p.PutUInt32(2, 3); + + eqcrypt_block(&buffer[0], buffer_len, (char *) p.Data() + 12, true); + c->QueuePacket(p); + break; + } + case 0x0018: { + auto encrypt_size = p.Length() - 12; + if (encrypt_size % 8 > 0) { + encrypt_size = (encrypt_size / 8) * 8; + } + + std::unique_ptr decrypted(new char[encrypt_size]); + + eqcrypt_block((char *) p.Data() + 12, encrypt_size, &decrypted[0], false); + + EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); + auto response_error = sp.GetUInt16(1); + + { + ret = response_error <= 101; + running = false; + } + break; + } + } } - else { - ret = true; - running = false; + ); + + EQ::Net::DNSLookup( + "login.eqemulator.net", 5999, false, [&](const std::string &addr) { + if (addr.empty()) { + ret = false; + running = false; + } + + mgr.Connect(addr, 5999); } - break; - } - } - }); + ); - EQ::Net::DNSLookup("login.eqemulator.net", 5999, false, [&](const std::string &addr) { - if (addr == "") { - ret = false; - running = false; + auto &loop = EQ::EventLoop::Get(); + while (running) { + loop.Process(); } - mgr.Connect(addr, 5999); - }); - - auto &loop = EQ::EventLoop::Get(); - while (true == running) { - loop.Process(); + return ret; } - - return ret; - }); + ); return res.get(); } diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 81647d60d..59398d495 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -50,13 +50,13 @@ namespace LoginserverCommandHandler { /** * Register commands */ - function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; - function_map["login-user:check-external-credentials"] = &LoginserverCommandHandler::CheckExternalLoginserverUserCredentials; - function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; - function_map["login-user:update-credentials"] = &LoginserverCommandHandler::UpdateLoginserverUserCredentials; - function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; - function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; - function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; + function_map["login-user:check-credentials"] = &LoginserverCommandHandler::CheckLoginserverUserCredentials; + function_map["login-user:check-external-credentials"] = &LoginserverCommandHandler::CheckExternalLoginserverUserCredentials; + function_map["login-user:create"] = &LoginserverCommandHandler::CreateLocalLoginserverAccount; + function_map["login-user:update-credentials"] = &LoginserverCommandHandler::UpdateLoginserverUserCredentials; + function_map["web-api-token:create"] = &LoginserverCommandHandler::CreateLoginserverApiToken; + function_map["web-api-token:list"] = &LoginserverCommandHandler::ListLoginserverApiTokens; + function_map["world-admin:create"] = &LoginserverCommandHandler::CreateLoginserverWorldAdminAccount; EQEmuCommand::HandleMenu(function_map, cmd, argc, argv); } diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index a26115075..3a26cfb97 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -161,32 +161,32 @@ namespace LoginserverWebserver { api.Post( "/account/credentials/validate/external", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanRead(request, res); - Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); - std::string username = request_body.get("username", "").asString(); - std::string password = request_body.get("password", "").asString(); + LoginserverWebserver::TokenManager::AuthCanRead(request, res); + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); + std::string username = request_body.get("username", "").asString(); + std::string password = request_body.get("password", "").asString(); + + Json::Value response; + if (username.empty() || password.empty()) { + response["error"] = "Username or password not set"; + LoginserverWebserver::SendResponse(response, res); + return; + } + + bool credentials_valid = AccountManagement::CheckExternalLoginserverUserCredentials( + username, + password + ); + + if (credentials_valid) { + response["message"] = "Credentials valid!"; + } + else { + response["error"] = "Credentials invalid!"; + } - Json::Value response; - if (username.empty() || password.empty()) { - response["error"] = "Username or password not set"; LoginserverWebserver::SendResponse(response, res); - return; } - - bool credentials_valid = AccountManagement::CheckExternalLoginserverUserCredentials( - username, - password - ); - - if (credentials_valid) { - response["message"] = "Credentials valid!"; - } - else { - response["error"] = "Credentials invalid!"; - } - - LoginserverWebserver::SendResponse(response, res); - } ); } From 0d76e224fd3a4aea2ef41cc6b88bf712bbd184ab Mon Sep 17 00:00:00 2001 From: Uleat Date: Fri, 9 Aug 2019 21:28:07 -0400 Subject: [PATCH 133/491] Updated eqemu_server.pl login server config example to json standard [skip ci] --- utils/scripts/eqemu_server.pl | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index f05c2c266..b2a53b864 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -1587,22 +1587,24 @@ sub add_login_server_firewall_rules { print "If firewall rules don't add you must run this script (eqemu_server.pl) as administrator\n"; print "\n"; print "[Install] Instructions \n"; - print "[Install] In order to connect your server to the loginserver you must point your eqemu_config.xml to your local server similar to the following:\n"; + print "[Install] In order to connect your server to the loginserver you must point your eqemu_config.json to your local server similar to the following:\n"; print " - - login.eqemulator.net - 5998 - - - - - 127.0.0.1 - 5998 - - - + \"loginserver1\" : { + \"account\" : \"\", + \"host\" : \"login.eqemulator.net\", + \"password\" : \"\", + \"port\" : \"5998\", + \"legacy\": \"1\" + }, + \"loginserver2\" : { + \"account\" : \"\", + \"host\" : \"192.168.197.129\", + \"password\" : \"\", + \"port\" : \"5998\" + }, + \"localaddress\" : \"192.168.197.129\", "; - print "[Install] When done, make sure your EverQuest client points to your loginserver's IP (In this case it would be 127.0.0.1) in the eqhosts.txt file\n"; + print "[Install] When done, make sure your EverQuest client points to your loginserver's IP (In this case it would be 192.168.197.129) in the eqhosts.txt file\n"; } } From 461931f5bd360b5d112c733b776174ae97c60a6f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 01:59:58 -0500 Subject: [PATCH 134/491] Fix remainder of ghosting --- zone/client_packet.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 4f819e7a4..1cac556d9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4515,12 +4515,17 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { continue; } - float distance_from_client_to_ignore = zone->GetNpcPositionUpdateDistance(); - if (entity->IsMoving() && CalculateDistance(entity->GetX(), entity->GetY(), entity->GetZ()) <= distance_from_client_to_ignore) { - continue; + int animation_speed = 0; + if (entity->IsMoving()) { + if (entity->IsRunning()) { + animation_speed = (entity->IsFeared() ? entity->GetFearSpeed() : entity->GetRunspeed()); + } + else { + animation_speed = entity->GetWalkspeed(); + } } - mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, this); + mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, animation_speed, ClientRangeAny, this); } SetLastPositionBeforeBulkUpdate(GetPosition()); From 0884c57928344766654af632a4cfe1e6d842c07a Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 02:27:07 -0500 Subject: [PATCH 135/491] Update minimum status for devtools --- common/emu_constants.h | 4 ++++ zone/client_packet.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/common/emu_constants.h b/common/emu_constants.h index 384aa3768..c6491b3b3 100644 --- a/common/emu_constants.h +++ b/common/emu_constants.h @@ -77,6 +77,10 @@ namespace EQEmu } // namespace invtype + namespace DevTools { + const int32 GM_ACCOUNT_STATUS_LEVEL = 150; + } + namespace popupresponse { const int32 SERVER_INTERNAL_USE_BASE = 2000000000; const int32 MOB_INFO_DISMISS = 2000000001; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 1cac556d9..39f959677 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1684,7 +1684,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app) /** * DevTools Load Settings */ - if (Admin() >= 200) { + if (Admin() >= EQEmu::DevTools::GM_ACCOUNT_STATUS_LEVEL) { std::string dev_tools_window_key = StringFormat("%i-dev-tools-window-disabled", AccountID()); if (DataBucket::GetData(dev_tools_window_key) == "true") { dev_tools_window_enabled = false; From 17c8af3814ffc216df90575def00c9385709986e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 02:47:08 -0500 Subject: [PATCH 136/491] Drop db logging, up stale connections --- common/net/daybreak_connection.h | 2 +- ucs/clientlist.cpp | 2 +- .../sql/git/required/2019_07_26_char_kick_events.sql | 11 ----------- zone/client.cpp | 2 +- zone/zonedb.cpp | 8 -------- zone/zonedb.h | 1 - 6 files changed, 3 insertions(+), 23 deletions(-) delete mode 100644 utils/sql/git/required/2019_07_26_char_kick_events.sql diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index b4f3ca41c..883ecefac 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -257,7 +257,7 @@ namespace EQ resend_delay_min = 150; resend_delay_max = 5000; connect_delay_ms = 500; - stale_connection_ms = 30000; + stale_connection_ms = 60000; connect_stale_ms = 5000; crc_length = 2; max_packet_size = 512; diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index a433705e6..26ef62b82 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -471,7 +471,7 @@ static void ProcessCommandIgnore(Client *c, std::string Ignoree) { Clientlist::Clientlist(int ChatPort) { EQStreamManagerInterfaceOptions chat_opts(ChatPort, false, false); chat_opts.opcode_size = 1; - chat_opts.daybreak_options.stale_connection_ms = 300000; + chat_opts.daybreak_options.stale_connection_ms = 600000; chat_opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS); chat_opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor); chat_opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS); diff --git a/utils/sql/git/required/2019_07_26_char_kick_events.sql b/utils/sql/git/required/2019_07_26_char_kick_events.sql deleted file mode 100644 index 0b5308be0..000000000 --- a/utils/sql/git/required/2019_07_26_char_kick_events.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE TABLE `character_kick_events` ( - `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, - `Name` VARCHAR(64) NOT NULL, - `Reason` TEXT NOT NULL, - `Created` TIMESTAMP NOT NULL DEFAULT '', - PRIMARY KEY (`Id`), - INDEX `Name` (`Name`), - INDEX `Created` (`Created`) -) -ENGINE=InnoDB -; diff --git a/zone/client.cpp b/zone/client.cpp index 60a6d1d8c..7e6baf180 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2590,7 +2590,7 @@ void Client::SetPVP(bool toggle, bool message) { void Client::Kick(const std::string &reason) { client_state = CLIENT_KICKED; - database.CreateKickEvent(GetName(), reason); + Log(Logs::General, Logs::Client_Login, "Client [%s] kicked, reason [%s]", GetCleanName(), reason.c_str()); } void Client::WorldKick() { diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index acf619aba..e2825da5a 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3835,14 +3835,6 @@ void ZoneDatabase::UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type QueryDatabase(query); } -void ZoneDatabase::CreateKickEvent(const std::string &character_name, const std::string &reason) -{ - std::string query = - StringFormat("INSERT INTO character_kick_events (Name, Reason) VALUES ('%s', '%s')", character_name.c_str(), reason.c_str()); - - QueryDatabase(query); -} - void ZoneDatabase::LoadPetInfo(Client *client) { diff --git a/zone/zonedb.h b/zone/zonedb.h index 285166042..f2103715a 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -292,7 +292,6 @@ public: void SavePetInfo(Client *c); void RemoveTempFactions(Client *c); void UpdateItemRecastTimestamps(uint32 char_id, uint32 recast_type, uint32 timestamp); - void CreateKickEvent(const std::string &character_name, const std::string &reason); bool DeleteCharacterAAs(uint32 character_id); bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); From d2e7cf96bd829d79f6fc4e2794b5430f354d8e2f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 02:49:55 -0500 Subject: [PATCH 137/491] Update .gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fd81b92bc..a21ef251d 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,7 @@ logs/ vcpkg/ .idea/* -*cbp \ No newline at end of file +*cbp + +submodules/* +cmake-build-debug/ \ No newline at end of file From 2081b0e2149b77e304aee67c399dfbd369552066 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 03:26:51 -0500 Subject: [PATCH 138/491] Merge changes --- world/clientlist.cpp | 13 +++++++++++++ world/clientlist.h | 1 + world/login_server.cpp | 18 +++++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 4ac74e3b3..953f806fe 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -253,6 +253,19 @@ ClientListEntry* ClientList::FindCLEByCharacterID(uint32 iCharID) { return nullptr; } +ClientListEntry* ClientList::FindCLEByLSID(uint32 iLSID) { + LinkedListIterator iterator(clientlist); + + iterator.Reset(); + while (iterator.MoreElements()) { + if (iterator.GetData()->LSID() == iLSID) { + return iterator.GetData(); + } + iterator.Advance(); + } + return nullptr; +} + void ClientList::SendCLEList(const int16& admin, const char* to, WorldTCPConnection* connection, const char* iName) { LinkedListIterator iterator(clientlist); char* output = 0; diff --git a/world/clientlist.h b/world/clientlist.h index 16259e2e0..3386a6f14 100644 --- a/world/clientlist.h +++ b/world/clientlist.h @@ -55,6 +55,7 @@ public: ClientListEntry* FindCharacter(const char* name); ClientListEntry* FindCLEByAccountID(uint32 iAccID); ClientListEntry* FindCLEByCharacterID(uint32 iCharID); + ClientListEntry* FindCLEByLSID(uint32 iLSID); ClientListEntry* GetCLE(uint32 iID); void GetCLEIP(uint32 iIP); uint32 GetCLEIPCount(uint32 iLSAccountID); diff --git a/world/login_server.cpp b/world/login_server.cpp index 112a7c92f..f6c680afe 100644 --- a/world/login_server.cpp +++ b/world/login_server.cpp @@ -168,19 +168,11 @@ void LoginServer::ProcessUsertoWorldReq(uint16_t opcode, EQ::Net::Packet &p) return; } - if (RuleB(World, DisallowDuplicateAccountLogins)) { - auto cle = client_list.FindCLEByLSID(utwr->lsaccountid); - if (cle != nullptr) { - auto status = cle->GetOnline(); - if (CLE_Status_Zoning == status || CLE_Status_InZone == status) { - utwrs->response = UserToWorldStatusAlreadyOnline; - SendPacket(&outpack); - return; - } - else { - //our existing cle is in a state we can login to, mark the old as stale and remove it. - client_list.RemoveCLEByLSID(utwr->lsaccountid); - } + if (RuleB(World, EnforceCharacterLimitAtLogin)) { + if (client_list.IsAccountInGame(utwr->lsaccountid)) { + utwrs->response = UserToWorldStatusAlreadyOnline; + SendPacket(&outpack); + return; } } From 8a2fce83e0147a7fb7dacd7d29f9423a99faf977 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 04:56:50 -0500 Subject: [PATCH 139/491] Adjust API handlers --- loginserver/account_management.cpp | 11 +++-- loginserver/account_management.h | 2 +- loginserver/loginserver_command_handler.cpp | 2 +- loginserver/loginserver_webserver.cpp | 48 +++++++++++++++------ loginserver/loginserver_webserver.h | 4 +- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index cca68a150..c2c0e5fa2 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -33,7 +33,7 @@ EQ::Event::TaskScheduler task_runner; * @param email * @return */ -uint32 AccountManagement::CreateLocalLoginServerAccount( +int32 AccountManagement::CreateLocalLoginServerAccount( std::string username, std::string password, std::string email @@ -53,13 +53,12 @@ uint32 AccountManagement::CreateLocalLoginServerAccount( std::string db_loginserver = server.options.GetDefaultLoginServerName(); if (server.db->DoesLoginServerAccountExist(username, hash, db_loginserver, 1)) { LogWarning( - "Attempting to create local login account for user [{0}] login [{1}] db_id [{2}] but already exists!", + "Attempting to create local login account for user [{0}] login [{1}] but already exists!", username, - db_loginserver, - db_id + db_loginserver ); - return 0; + return -1; } uint32 created_account_id = server.db->CreateLoginAccount(username, hash, db_loginserver, email); @@ -72,7 +71,7 @@ uint32 AccountManagement::CreateLocalLoginServerAccount( created_account_id ); - return created_account_id; + return (int32) created_account_id; } LogError("Failed to create local login account for user [{0}]!", username); diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 680122213..4ab3d8973 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -32,7 +32,7 @@ public: * @param email * @return */ - static uint32 CreateLocalLoginServerAccount(std::string username, std::string password, std::string email = ""); + static int32 CreateLocalLoginServerAccount(std::string username, std::string password, std::string email = ""); /** * @param username diff --git a/loginserver/loginserver_command_handler.cpp b/loginserver/loginserver_command_handler.cpp index 59398d495..75b0dbfcd 100644 --- a/loginserver/loginserver_command_handler.cpp +++ b/loginserver/loginserver_command_handler.cpp @@ -267,6 +267,6 @@ namespace LoginserverCommandHandler { cmd("--password").str() ); - LogInfo("Credentials were {0}", res == true ? "accepted" : "not accepted"); + LogInfo("Credentials were {0}", res ? "accepted" : "not accepted"); } } diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 3a26cfb97..6a0bd4314 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -39,7 +39,9 @@ namespace LoginserverWebserver { api.Get( "/servers/list", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanRead(request, res); + if (!LoginserverWebserver::TokenManager::AuthCanRead(request, res)) { + return; + } Json::Value response; auto iter = server.server_manager->getWorldServers().begin(); @@ -63,7 +65,10 @@ namespace LoginserverWebserver { api.Post( "/account/create", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanWrite(request, res); + if (!LoginserverWebserver::TokenManager::AuthCanWrite(request, res)) { + return; + } + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); @@ -76,12 +81,16 @@ namespace LoginserverWebserver { return; } - bool account_created = AccountManagement::CreateLocalLoginServerAccount(username, password, email); - if (account_created) { - response["message"] = "Account created successfully!"; + int32 account_created_id = AccountManagement::CreateLocalLoginServerAccount(username, password, email); + if (account_created_id > 0) { + response["message"] = "Account created successfully!"; + response["data"]["account_id"] = account_created_id; + } + else if (account_created_id == -1) { + response["error"] = "Account already exists!"; } else { - response["message"] = "Account failed to create!"; + response["error"] = "Account failed to create!"; } LoginserverWebserver::SendResponse(response, res); @@ -90,7 +99,10 @@ namespace LoginserverWebserver { api.Post( "/account/credentials/validate/local", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanRead(request, res); + if (!LoginserverWebserver::TokenManager::AuthCanRead(request, res)) { + return; + } + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); @@ -120,7 +132,10 @@ namespace LoginserverWebserver { api.Post( "/account/credentials/update/local", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanWrite(request, res); + if (!LoginserverWebserver::TokenManager::AuthCanWrite(request, res)) { + return; + } + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); @@ -161,7 +176,10 @@ namespace LoginserverWebserver { api.Post( "/account/credentials/validate/external", [](const httplib::Request &request, httplib::Response &res) { - LoginserverWebserver::TokenManager::AuthCanRead(request, res); + if (!LoginserverWebserver::TokenManager::AuthCanRead(request, res)) { + return; + } + Json::Value request_body = LoginserverWebserver::ParseRequestBody(request); std::string username = request_body.get("username", "").asString(); std::string password = request_body.get("password", "").asString(); @@ -233,7 +251,7 @@ namespace LoginserverWebserver { * @param request * @param res */ - void LoginserverWebserver::TokenManager::AuthCanRead(const httplib::Request &request, httplib::Response &res) + bool LoginserverWebserver::TokenManager::AuthCanRead(const httplib::Request &request, httplib::Response &res) { LoginserverWebserver::TokenManager::token_data user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); @@ -252,15 +270,17 @@ namespace LoginserverWebserver { user_token.user_agent ); - return; + return false; } + + return true; } /** * @param request * @param res */ - void LoginserverWebserver::TokenManager::AuthCanWrite(const httplib::Request &request, httplib::Response &res) + bool LoginserverWebserver::TokenManager::AuthCanWrite(const httplib::Request &request, httplib::Response &res) { LoginserverWebserver::TokenManager::token_data user_token = LoginserverWebserver::TokenManager::CheckApiAuthorizationHeaders(request); @@ -279,8 +299,10 @@ namespace LoginserverWebserver { user_token.user_agent ); - return; + return false; } + + return true; } /** diff --git a/loginserver/loginserver_webserver.h b/loginserver/loginserver_webserver.h index 2c5d07866..b0cdb88c2 100644 --- a/loginserver/loginserver_webserver.h +++ b/loginserver/loginserver_webserver.h @@ -46,8 +46,8 @@ namespace LoginserverWebserver { static bool TokenExists(const std::string &token); token_data GetToken(const std::string &token); static token_data CheckApiAuthorizationHeaders(const httplib::Request &request); - static void AuthCanRead(const httplib::Request &request, httplib::Response &res); - static void AuthCanWrite(const httplib::Request &request, httplib::Response &res); + static bool AuthCanRead(const httplib::Request &request, httplib::Response &res); + static bool AuthCanWrite(const httplib::Request &request, httplib::Response &res); }; void RegisterRoutes(httplib::Server &api); From 9708bd38c482d61e40015f87bb48a20763805425 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 05:14:12 -0500 Subject: [PATCH 140/491] Remove legacy loginserver config --- loginserver/config.cpp | 197 ----------------------------------------- loginserver/config.h | 64 ------------- 2 files changed, 261 deletions(-) delete mode 100644 loginserver/config.cpp delete mode 100644 loginserver/config.h diff --git a/loginserver/config.cpp b/loginserver/config.cpp deleted file mode 100644 index 88daab757..000000000 --- a/loginserver/config.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "../common/global_define.h" -#include "../common/eqemu_logsys.h" -#include "config.h" - -/** - * Retrieves the variable we want from our title or theme - * First gets the map from the title, then gets the argument from the map we got from title - * - * @param title - * @param parameter - * @return - */ -std::string Config::GetVariable(std::string title, std::string parameter) -{ - std::map >::iterator iter = vars.find(title); - if (iter != vars.end()) { - std::map::iterator arg_iter = iter->second.find(parameter); - if (arg_iter != iter->second.end()) { - return arg_iter->second; - } - } - - return std::string(""); -} - -/** - * Opens a file and passes it to the tokenizer - * Then it parses the tokens returned and puts them into titles and variables - * - * @param file_name - */ -void Config::Parse(const char *file_name) -{ - if (file_name == nullptr) { - LogError("Config::Parse(), file_name passed was null"); - return; - } - - vars.clear(); - FILE *input = fopen(file_name, "r"); - if (input) { - std::list tokens; - Tokenize(input, tokens); - - char mode = 0; - std::string title, param, arg; - - std::list::iterator iter = tokens.begin(); - while (iter != tokens.end()) { - if ((*iter).compare("[") == 0) { - title.clear(); - bool first = true; - ++iter; - if (iter == tokens.end()) { - LogError("Config::Parse(), EOF before title done parsing"); - fclose(input); - vars.clear(); - return; - } - - while ((*iter).compare("]") != 0 && iter != tokens.end()) { - if (!first) { - title += " "; - } - else { - first = false; - } - - title += (*iter); - ++iter; - } - ++iter; - } - - if (mode == 0) { - param = (*iter); - mode++; - } - else if (mode == 1) { - mode++; - if ((*iter).compare("=") != 0) { - LogError("Config::Parse(), invalid parse token where = should be"); - fclose(input); - vars.clear(); - return; - } - } - else { - arg = (*iter); - mode = 0; - std::map >::iterator map_iter = vars.find(title); - if (map_iter != vars.end()) { - map_iter->second[param] = arg; - vars[title] = map_iter->second; - } - else { - std::map var_map; - var_map[param] = arg; - vars[title] = var_map; - } - } - ++iter; - } - fclose(input); - } - else { - LogError("Config::Parse(), file was unable to be opened for parsing"); - } -} - -/** - * Pretty basic lexical analyzer - * Breaks up the input character stream into tokens and puts them into the list provided - * Ignores # as a line comment - * - * @param input - * @param tokens - */ -void Config::Tokenize(FILE *input, std::list &tokens) -{ - auto c = fgetc(input); - std::string lexeme; - - while (c != EOF) { - if (isspace(c)) { - if (lexeme.size() > 0) { - tokens.push_back(lexeme); - lexeme.clear(); - } - c = fgetc(input); - continue; - } - - if (isalnum(c)) { - lexeme += c; - c = fgetc(input); - continue; - } - - switch (c) { - case '#': { - if (lexeme.size() > 0) { - tokens.push_back(lexeme); - lexeme.clear(); - } - - while (c != '\n' && c != EOF) { - c = fgetc(input); - } - break; - } - case '[': - case ']': - case '=': { - if (lexeme.size() > 0) { - tokens.push_back(lexeme); - lexeme.clear(); - } - - lexeme += c; - tokens.push_back(lexeme); - lexeme.clear(); - break; - } - default: { - lexeme += c; - } - } - - c = fgetc(input); - } - - if (lexeme.size() > 0) { - tokens.push_back(lexeme); - } -} - diff --git a/loginserver/config.h b/loginserver/config.h deleted file mode 100644 index 549b32693..000000000 --- a/loginserver/config.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY except by those people which sell it, which - * are required to give you total support for your newly bought product; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef EQEMU_CONFIG_H -#define EQEMU_CONFIG_H - -#include -#include -#include -#include - -/** - * Keeps track of all the configuration for the application with a small parser. - * Note: This is not a thread safe class, but only parse writes to variables in the class. - * Thus making it mostly safe so long as you're careful with where you call Parse() - */ -class Config -{ -public: - Config() { } - ~Config() { } - - /** - * Parses the selected file for variables, will clear current variables if selected. - */ - virtual void Parse(const char *file_name); - - /** - * Gets a variable if it exists. - */ - std::string GetVariable(std::string title, std::string parameter); - -protected: - std::map > vars; - -private: - /** - * Breaks our input up into tokens for Parse(). - * This is private because it's not intended to be overloaded by a derived class which - * may get it's input from other places than a C file pointer. (a http get request for example). - * The programmer of a derived class would be expected to make their own Tokenize function for their own Parse(). - */ - void Tokenize(FILE* input, std::list &tokens); -}; - -#endif - From 661ad0929156df049eba376433779cd8363cf204 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 05:14:25 -0500 Subject: [PATCH 141/491] Remove legacy loginserver config --- loginserver/world_server.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/loginserver/world_server.cpp b/loginserver/world_server.cpp index 9fd5d4763..f89c6a8d8 100644 --- a/loginserver/world_server.cpp +++ b/loginserver/world_server.cpp @@ -21,7 +21,6 @@ #include "world_server.h" #include "login_server.h" #include "login_structures.h" -#include "config.h" #include "../common/eqemu_logsys.h" #include "../common/ip_util.h" From f06ff14f9ef09b1387d559ff2c2519cde3270772 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 05:14:39 -0500 Subject: [PATCH 142/491] Squash exception in ParseRequestBody --- loginserver/loginserver_webserver.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 6a0bd4314..28f4e0fa7 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -239,10 +239,18 @@ namespace LoginserverWebserver { */ Json::Value ParseRequestBody(const httplib::Request &request) { - std::stringstream ss; - ss.str(request.body); Json::Value request_body; - ss >> request_body; + + try { + std::stringstream ss; + ss.str(request.body); + ss >> request_body; + } + catch (std::exception&) { + request_body["error"] = "Payload invalid"; + + return request_body; + } return request_body; } From f39684b7f78ded66c259f56eeec81d120b204b4f Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 05:36:22 -0500 Subject: [PATCH 143/491] API adjustments --- loginserver/account_management.cpp | 19 +++++++++++-------- loginserver/account_management.h | 2 +- loginserver/loginserver_webserver.cpp | 9 +++++---- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index c2c0e5fa2..131fb1ad0 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -242,15 +242,16 @@ bool AccountManagement::UpdateLoginserverUserCredentials( return true; } -bool AccountManagement::CheckExternalLoginserverUserCredentials( +uint32 AccountManagement::CheckExternalLoginserverUserCredentials( const std::string &in_account_username, const std::string &in_account_password ) { auto res = task_runner.Enqueue( - [&]() -> bool { - bool running = true; - bool ret = false; + [&]() -> uint32 { + bool running = true; + uint32 ret = 0; + EQ::Net::DaybreakConnectionManager mgr; std::shared_ptr c; @@ -284,8 +285,9 @@ bool AccountManagement::CheckExternalLoginserverUserCredentials( switch (opcode) { case 0x0017: //OP_ChatMessage { - size_t buffer_len = - in_account_username.length() + in_account_password.length() + 2; + size_t buffer_len = + in_account_username.length() + in_account_password.length() + 2; + std::unique_ptr buffer(new char[buffer_len]); strcpy(&buffer[0], in_account_username.c_str()); @@ -318,9 +320,10 @@ bool AccountManagement::CheckExternalLoginserverUserCredentials( EQ::Net::StaticPacket sp(&decrypted[0], encrypt_size); auto response_error = sp.GetUInt16(1); + auto m_dbid = sp.GetUInt32(8); { - ret = response_error <= 101; + ret = (response_error <= 101 ? m_dbid : 0); running = false; } break; @@ -332,7 +335,7 @@ bool AccountManagement::CheckExternalLoginserverUserCredentials( EQ::Net::DNSLookup( "login.eqemulator.net", 5999, false, [&](const std::string &addr) { if (addr.empty()) { - ret = false; + ret = 0; running = false; } diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 4ab3d8973..17bdfafba 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -76,7 +76,7 @@ public: * @param in_account_password * @return */ - static bool CheckExternalLoginserverUserCredentials( + static uint32 CheckExternalLoginserverUserCredentials( const std::string &in_account_username, const std::string &in_account_password ); diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index 28f4e0fa7..dbc41c6a4 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -191,13 +191,14 @@ namespace LoginserverWebserver { return; } - bool credentials_valid = AccountManagement::CheckExternalLoginserverUserCredentials( + uint32 account_id = AccountManagement::CheckExternalLoginserverUserCredentials( username, password ); - if (credentials_valid) { - response["message"] = "Credentials valid!"; + if (account_id > 0) { + response["message"] = "Credentials valid!"; + response["data"]["account_id"] = account_id; } else { response["error"] = "Credentials invalid!"; @@ -246,7 +247,7 @@ namespace LoginserverWebserver { ss.str(request.body); ss >> request_body; } - catch (std::exception&) { + catch (std::exception &) { request_body["error"] = "Payload invalid"; return request_body; From 66ee0dc9bd29a1a87b0eff016cfe457d713c8c4e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 06:59:45 -0500 Subject: [PATCH 144/491] Update DefaultLoginServerName --- loginserver/main.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/loginserver/main.cpp b/loginserver/main.cpp index 217929ea2..dbd35b5bc 100644 --- a/loginserver/main.cpp +++ b/loginserver/main.cpp @@ -90,6 +90,7 @@ int main(int argc, char **argv) "login.eqemulator.net:5999" ) ); +#endif server.options.DefaultLoginServerName( server.config.GetVariableString( @@ -98,8 +99,6 @@ int main(int argc, char **argv) "local" ) ); -#endif - #ifdef ENABLE_SECURITY server.options.EncryptionMode(server.config.GetVariableInt("security", "mode", 13)); From 25a5310f49d2be6fd7faff75842474e303b5b6af Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sat, 10 Aug 2019 07:04:52 -0500 Subject: [PATCH 145/491] Add login account_id in validation response --- loginserver/account_management.cpp | 6 +++--- loginserver/account_management.h | 2 +- loginserver/loginserver_webserver.cpp | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/loginserver/account_management.cpp b/loginserver/account_management.cpp index 131fb1ad0..0377506f6 100644 --- a/loginserver/account_management.cpp +++ b/loginserver/account_management.cpp @@ -143,7 +143,7 @@ bool AccountManagement::CreateLoginserverWorldAdminAccount( * @param in_account_password * @return */ -bool AccountManagement::CheckLoginserverUserCredentials( +uint32 AccountManagement::CheckLoginserverUserCredentials( const std::string &in_account_username, const std::string &in_account_password, const std::string &source_loginserver @@ -181,7 +181,7 @@ bool AccountManagement::CheckLoginserverUserCredentials( source_loginserver ); - return false; + return 0; } LogDebug( @@ -190,7 +190,7 @@ bool AccountManagement::CheckLoginserverUserCredentials( source_loginserver ); - return validated_credentials; + return login_server_admin.id; } diff --git a/loginserver/account_management.h b/loginserver/account_management.h index 17bdfafba..009112431 100644 --- a/loginserver/account_management.h +++ b/loginserver/account_management.h @@ -54,7 +54,7 @@ public: * @param in_account_password * @return */ - static bool CheckLoginserverUserCredentials( + static uint32 CheckLoginserverUserCredentials( const std::string &in_account_username, const std::string &in_account_password, const std::string &source_loginserver = "local" diff --git a/loginserver/loginserver_webserver.cpp b/loginserver/loginserver_webserver.cpp index dbc41c6a4..3771923e1 100644 --- a/loginserver/loginserver_webserver.cpp +++ b/loginserver/loginserver_webserver.cpp @@ -114,13 +114,14 @@ namespace LoginserverWebserver { return; } - bool credentials_valid = AccountManagement::CheckLoginserverUserCredentials( + uint32 login_account_id = AccountManagement::CheckLoginserverUserCredentials( username, password ); - if (credentials_valid) { - response["message"] = "Credentials valid!"; + if (login_account_id > 0) { + response["message"] = "Credentials valid!"; + response["data"]["account_id"] = login_account_id; } else { response["error"] = "Credentials invalid!"; From 57354579aade5339a0aa80e3572c01cf7fd09c0e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 00:00:55 -0500 Subject: [PATCH 146/491] Unify chat constants usage --- common/database.h | 2 + common/database_conversions.cpp | 2 +- common/eq_constants.h | 300 +++++--------- common/eqemu_logsys.cpp | 22 +- common/string_util.cpp | 11 + common/string_util.h | 1 + world/adventure.cpp | 2 +- world/net.cpp | 6 +- zone/aa.cpp | 14 +- zone/attack.cpp | 84 ++-- zone/aura.cpp | 16 +- zone/bot.cpp | 140 +++---- zone/bot_command.cpp | 20 +- zone/client.cpp | 188 ++++----- zone/client.h | 17 - zone/client_packet.cpp | 684 ++++++++++++++++---------------- zone/client_process.cpp | 58 +-- zone/corpse.cpp | 30 +- zone/doors.cpp | 22 +- zone/effects.cpp | 40 +- zone/embparser_api.cpp | 2 +- zone/entity.cpp | 25 +- zone/exp.cpp | 66 +-- zone/forage.cpp | 40 +- zone/guild_mgr.cpp | 2 +- zone/horse.cpp | 2 +- zone/inventory.cpp | 84 ++-- zone/lua_general.cpp | 172 ++++---- zone/lua_mob.cpp | 4 +- zone/merc.cpp | 8 +- zone/mob.cpp | 18 +- zone/mob_ai.cpp | 24 +- zone/mob_movement_manager.cpp | 10 +- zone/npc.cpp | 10 +- zone/oldcode.cpp | 2 +- zone/pathing.cpp | 6 +- zone/pets.cpp | 4 +- zone/questmgr.cpp | 36 +- zone/special_attacks.cpp | 30 +- zone/spell_effects.cpp | 96 ++--- zone/spells.cpp | 232 +++++------ zone/tasks.cpp | 34 +- zone/tradeskills.cpp | 64 +-- zone/trading.cpp | 80 ++-- zone/trap.cpp | 4 +- zone/tribute.cpp | 6 +- zone/tune.cpp | 10 +- zone/worldserver.cpp | 20 +- zone/zonedb.cpp | 8 +- zone/zoning.cpp | 26 +- 50 files changed, 1352 insertions(+), 1432 deletions(-) diff --git a/common/database.h b/common/database.h index 307390edf..71ebe3315 100644 --- a/common/database.h +++ b/common/database.h @@ -94,6 +94,8 @@ class PTimerList; # define _ISNAN_(a) std::isnan(a) #endif +#define SQL(...) #__VA_ARGS__ + class Database : public DBcore { public: Database(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp index 9850dfac1..ec973d9af 100644 --- a/common/database_conversions.cpp +++ b/common/database_conversions.cpp @@ -476,7 +476,7 @@ bool Database::CheckDatabaseConversions() { CheckDatabaseConvertCorpseDeblob(); /* Run EQEmu Server script (Checks for database updates) */ - system("perl eqemu_server.pl ran_from_world"); + if(system("perl eqemu_server.pl ran_from_world")); return true; } diff --git a/common/eq_constants.h b/common/eq_constants.h index 657db450e..bf65f2bfb 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -87,200 +87,114 @@ typedef enum { _eaMaxAppearance } EmuAppearance; -#define MT_NPCQuestSay 10 -// msg_type's for custom usercolors -#define MT_Say 256 -#define MT_Tell 257 -#define MT_Group 258 -#define MT_Guild 259 -#define MT_OOC 260 -#define MT_Auction 261 -#define MT_Shout 262 -#define MT_Emote 263 -#define MT_Spells 264 -#define MT_YouHitOther 265 -#define MT_OtherHitsYou 266 -#define MT_YouMissOther 267 -#define MT_OtherMissesYou 268 -#define MT_Broadcasts 269 -#define MT_Skills 270 -#define MT_Disciplines 271 -#define MT_Unused1 272 -#define MT_DefaultText 273 -#define MT_Unused2 274 -#define MT_MerchantOffer 275 -#define MT_MerchantBuySell 276 -#define MT_YourDeath 277 -#define MT_OtherDeath 278 -#define MT_OtherHits 279 -#define MT_OtherMisses 280 -#define MT_Who 281 -#define MT_YellForHelp 282 -#define MT_NonMelee 283 -#define MT_WornOff 284 -#define MT_MoneySplit 285 -#define MT_LootMessages 286 -#define MT_DiceRoll 287 -#define MT_OtherSpells 288 -#define MT_SpellFailure 289 -#define MT_Chat 290 -#define MT_Channel1 291 -#define MT_Channel2 292 -#define MT_Channel3 293 -#define MT_Channel4 294 -#define MT_Channel5 295 -#define MT_Channel6 296 -#define MT_Channel7 297 -#define MT_Channel8 298 -#define MT_Channel9 299 -#define MT_Channel10 300 -#define MT_CritMelee 301 -#define MT_SpellCrits 302 -#define MT_TooFarAway 303 -#define MT_NPCRampage 304 -#define MT_NPCFlurry 305 -#define MT_NPCEnrage 306 -#define MT_SayEcho 307 -#define MT_TellEcho 308 -#define MT_GroupEcho 309 -#define MT_GuildEcho 310 -#define MT_OOCEcho 311 -#define MT_AuctionEcho 312 -#define MT_ShoutECho 313 -#define MT_EmoteEcho 314 -#define MT_Chat1Echo 315 -#define MT_Chat2Echo 316 -#define MT_Chat3Echo 317 -#define MT_Chat4Echo 318 -#define MT_Chat5Echo 319 -#define MT_Chat6Echo 320 -#define MT_Chat7Echo 321 -#define MT_Chat8Echo 322 -#define MT_Chat9Echo 323 -#define MT_Chat10Echo 324 -#define MT_DoTDamage 325 -#define MT_ItemLink 326 -#define MT_RaidSay 327 -#define MT_MyPet 328 -#define MT_DS 329 -#define MT_Leadership 330 -#define MT_PetFlurry 331 -#define MT_PetCrit 332 -#define MT_FocusEffect 333 -#define MT_Experience 334 -#define MT_System 335 -#define MT_PetSpell 336 -#define MT_PetResponse 337 -#define MT_ItemSpeech 338 -#define MT_StrikeThrough 339 -#define MT_Stun 340 +namespace Chat { + const uint16 White = 0; + const uint16 DimGray = 1; + const uint16 Default = 1; + const uint16 Green = 2; + const uint16 BrightBlue = 3; + const uint16 LightBlue = 4; + const uint16 Magenta = 5; + const uint16 Gray = 6; + const uint16 LightGray = 7; + const uint16 NPCQuestSay = 10; + const uint16 DarkGray = 12; + const uint16 Red = 13; + const uint16 Lime = 14; + const uint16 Yellow = 15; + const uint16 Blue = 16; + const uint16 LightNavy = 17; + const uint16 Cyan = 18; + const uint16 Black = 20; -// TODO: Really should combine above and below into one - -//from showeq -enum ChatColor -{ - /* - CC_Default = 0, - CC_DarkGrey = 1, - CC_DarkGreen = 2, - CC_DarkBlue = 3, - CC_Purple = 5, - CC_LightGrey = 6, - */ - - CC_WhiteSmoke = 0, // FF|F0F0F0 - CC_Green = 2, // FF|008000 - CC_BrightBlue = 3, // FF|0040FF - CC_Magenta = 5, // FF|F000F0 - CC_Gray = 6, // FF|808080 - CC_LightGray = 7, // FF|E0E0E0 - //CC_WhiteSmoke2 = 10, // FF|F0F0F0 - CC_DarkGray = 12, // FF|A0A0A0 - CC_Red = 13, // FF|F00000 - CC_Lime = 14, // FF|00F000 - CC_Yellow = 15, // FF|F0F000 - CC_Blue = 16, // FF|0000F0 - CC_LightNavy = 17, // FF|0000AF - CC_Cyan = 18, // FF|00F0F0 - CC_Black = 20, // FF|000000 - - // any index <= 255 that is not defined above - CC_DimGray = 1, // FF|606060 - CC_Default = 1, - - CC_User_Say = 256, - CC_User_Tell = 257, - CC_User_Group = 258, - CC_User_Guild = 259, - CC_User_OOC = 260, - CC_User_Auction = 261, - CC_User_Shout = 262, - CC_User_Emote = 263, - CC_User_Spells = 264, - CC_User_YouHitOther = 265, - CC_User_OtherHitYou = 266, - CC_User_YouMissOther = 267, - CC_User_OtherMissYou = 268, - CC_User_Duels = 269, - CC_User_Skills = 270, - CC_User_Disciplines = 271, - CC_User_Default = 273, - CC_User_MerchantOffer = 275, - CC_User_MerchantExchange = 276, - CC_User_YourDeath = 277, - CC_User_OtherDeath = 278, - CC_User_OtherHitOther = 279, - CC_User_OtherMissOther = 280, - CC_User_Who = 281, - CC_User_Yell = 282, - CC_User_NonMelee = 283, - CC_User_SpellWornOff = 284, - CC_User_MoneySplit = 285, - CC_User_Loot = 286, - CC_User_Random = 287, - CC_User_OtherSpells = 288, - CC_User_SpellFailure = 289, - CC_User_ChatChannel = 290, - CC_User_Chat1 = 291, - CC_User_Chat2 = 292, - CC_User_Chat3 = 293, - CC_User_Chat4 = 294, - CC_User_Chat5 = 295, - CC_User_Chat6 = 296, - CC_User_Chat7 = 297, - CC_User_Chat8 = 298, - CC_User_Chat9 = 299, - CC_User_Chat10 = 300, - CC_User_MeleeCrit = 301, - CC_User_SpellCrit = 302, - CC_User_TooFarAway = 303, - CC_User_NPCRampage = 304, - CC_User_NPCFurry = 305, - CC_User_NPCEnrage = 306, - CC_User_EchoSay = 307, - CC_User_EchoTell = 308, - CC_User_EchoGroup = 309, - CC_User_EchoGuild = 310, - CC_User_EchoOOC = 311, - CC_User_EchoAuction = 312, - CC_User_EchoShout = 313, - CC_User_EchoEmote = 314, - CC_User_EchoChat1 = 315, - CC_User_EchoChat2 = 316, - CC_User_EchoChat3 = 317, - CC_User_EchoChat4 = 318, - CC_User_EchoChat5 = 319, - CC_User_EchoChat6 = 320, - CC_User_EchoChat7 = 321, - CC_User_EchoChat8 = 322, - CC_User_EchoChat9 = 323, - CC_User_EchoChat10 = 324, - CC_User_UnusedAtThisTime = 325, - CC_User_ItemTags = 326, - CC_User_RaidSay = 327, - CC_User_MyPet = 328, - CC_User_DamageShield = 329, + /** + * User colors + */ + const uint16 Say = 256; + const uint16 Tell = 257; + const uint16 Group = 258; + const uint16 Guild = 259; + const uint16 OOC = 260; + const uint16 Auction = 261; + const uint16 Shout = 262; + const uint16 Emote = 263; + const uint16 Spells = 264; + const uint16 YouHitOther = 265; + const uint16 OtherHitYou = 266; + const uint16 YouMissOther = 267; + const uint16 OtherMissYou = 268; + const uint16 Broadcasts = 269; + const uint16 Skills = 270; + const uint16 Disciplines = 271; + const uint16 Unused1 = 272; + const uint16 DefaultText = 273; + const uint16 Unused2 = 274; + const uint16 MerchantOffer = 275; + const uint16 MerchantExchange = 276; + const uint16 YourDeath = 277; + const uint16 OtherDeath = 278; + const uint16 OtherHitOther = 279; + const uint16 OtherMissOther = 280; + const uint16 Who = 281; + const uint16 YellForHelp = 282; + const uint16 NonMelee = 283; + const uint16 SpellWornOff = 284; + const uint16 MoneySplit = 285; + const uint16 Loot = 286; + const uint16 DiceRoll = 287; + const uint16 OtherSpells = 288; + const uint16 SpellFailure = 289; + const uint16 ChatChannel = 290; + const uint16 Chat1 = 291; + const uint16 Chat2 = 292; + const uint16 Chat3 = 293; + const uint16 Chat4 = 294; + const uint16 Chat5 = 295; + const uint16 Chat6 = 296; + const uint16 Chat7 = 297; + const uint16 Chat8 = 298; + const uint16 Chat9 = 299; + const uint16 Chat10 = 300; + const uint16 MeleeCrit = 301; + const uint16 SpellCrit = 302; + const uint16 TooFarAway = 303; + const uint16 NPCRampage = 304; + const uint16 NPCFlurry = 305; + const uint16 NPCEnrage = 306; + const uint16 EchoSay = 307; + const uint16 EchoTell = 308; + const uint16 EchoGroup = 309; + const uint16 EchoGuild = 310; + const uint16 EchoOOC = 311; + const uint16 EchoAuction = 312; + const uint16 EchoShout = 313; + const uint16 EchoEmote = 314; + const uint16 EchoChat1 = 315; + const uint16 EchoChat2 = 316; + const uint16 EchoChat3 = 317; + const uint16 EchoChat4 = 318; + const uint16 EchoChat5 = 319; + const uint16 EchoChat6 = 320; + const uint16 EchoChat7 = 321; + const uint16 EchoChat8 = 322; + const uint16 EchoChat9 = 323; + const uint16 EchoChat10 = 324; + const uint16 DotDamage = 325; + const uint16 ItemLink = 326; + const uint16 RaidSay = 327; + const uint16 MyPet = 328; + const uint16 DamageShield = 329; + const uint16 LeaderShip = 330; + const uint16 PetFlurry = 331; + const uint16 PetCritical = 332; + const uint16 FocusEffect = 333; + const uint16 Experience = 334; + const uint16 System = 335; + const uint16 PetSpell = 336; + const uint16 PetResponse = 337; + const uint16 ItemSpeech = 338; + const uint16 StrikeThrough = 339; + const uint16 Stun = 340; }; //ZoneChange_Struct->success values diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp index d614415ea..f84e0839c 100644 --- a/common/eqemu_logsys.cpp +++ b/common/eqemu_logsys.cpp @@ -81,14 +81,6 @@ namespace Console { }; } -enum GameChatColor { - yellow = 15, - red = 13, - light_green = 14, - light_cyan = 258, - light_purple = 5 -}; - /** * EQEmuLogSys Constructor */ @@ -306,22 +298,22 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) switch (log_category) { case Logs::Status: case Logs::Normal: - return GameChatColor::yellow; + return Chat::Yellow; case Logs::MySQLError: case Logs::Error: - return GameChatColor::red; + return Chat::Red; case Logs::MySQLQuery: case Logs::Debug: - return GameChatColor::light_green; + return Chat::Lime; case Logs::Quests: - return GameChatColor::light_cyan; + return Chat::Group; case Logs::Commands: case Logs::Mercenaries: - return GameChatColor::light_purple; + return Chat::Magenta; case Logs::Crash: - return GameChatColor::red; + return Chat::Red; default: - return GameChatColor::yellow; + return Chat::Yellow; } } diff --git a/common/string_util.cpp b/common/string_util.cpp index 508304ce1..b12811159 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -123,6 +123,17 @@ std::vector SplitString(const std::string &str, char delim) { return ret; } +static std::string implode(char *sep, std::vector src) +{ + std::ostringstream output; + std::vector::iterator src_iter; + + for (src_iter = src.begin(); src_iter != src.end(); src_iter++) + output << *src_iter << sep; + + return output.str(); +} + std::string EscapeString(const std::string &s) { std::string ret; diff --git a/common/string_util.h b/common/string_util.h index 03848813c..cf1dbc761 100644 --- a/common/string_util.h +++ b/common/string_util.h @@ -30,6 +30,7 @@ const std::string ucfirst(std::string s); std::vector split(std::string str_to_split, char delimiter); const std::string StringFormat(const char* format, ...); const std::string vStringFormat(const char* format, va_list args); +static std::string implode(char *sep, std::vector src); std::vector SplitString(const std::string &s, char delim); std::string EscapeString(const char *src, size_t sz); std::string EscapeString(const std::string &s); diff --git a/world/adventure.cpp b/world/adventure.cpp index af3cfe0e2..3b784cd6e 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -122,7 +122,7 @@ bool Adventure::Process() else if(status == AS_WaitingForPrimaryEndTime) { //Do partial failure: send a message to the clients that they can only get a certain amount of points. - SendAdventureMessage(13, "You failed to complete your adventure in time. Complete your adventure goal within 30 minutes to " + SendAdventureMessage(Chat::Red, "You failed to complete your adventure in time. Complete your adventure goal within 30 minutes to " "receive a lesser reward. This adventure will end in 30 minutes and your party will be ejected from the dungeon."); SetStatus(AS_WaitingForSecondaryEndTime); } diff --git a/world/net.cpp b/world/net.cpp index ce5900d30..8278f9437 100644 --- a/world/net.cpp +++ b/world/net.cpp @@ -123,7 +123,7 @@ int main(int argc, char** argv) { if (!std::ifstream("eqemu_config.json")) { CheckForServerScript(true); /* Run EQEmu Server script (Checks for database updates) */ - system("perl eqemu_server.pl convert_xml"); + if(system("perl eqemu_server.pl convert_xml")); } else { /* Download EQEmu Server Maintenance Script if doesn't exist */ @@ -627,9 +627,9 @@ void CheckForServerScript(bool force_download) { std::cout << "Pulling down EQEmu Server Maintenance Script (eqemu_server.pl)..." << std::endl; #ifdef _WIN32 - system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\""); + if(system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"")); #else - system("wget -N --no-check-certificate --quiet -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl"); + if(system("wget -N --no-check-certificate --quiet -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl")); #endif } } diff --git a/zone/aa.cpp b/zone/aa.cpp index 4d9854d86..5696bd445 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -58,7 +58,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u if (!database.GetPoweredPetEntry(spells[spell_id].teleport_zone, act_power, &record)) { Log(Logs::General, Logs::Error, "Unknown swarm pet spell id: %d, check pets table", spell_id); - Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone); + Message(Chat::Red, "Unable to find data for pet %s", spells[spell_id].teleport_zone); return; } @@ -1091,7 +1091,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost SendAlternateAdvancementStats(); if(rank->prev) { - Message_StringID(15, AA_IMPROVE, + Message_StringID(Chat::Yellow, AA_IMPROVE, std::to_string(rank->title_sid).c_str(), std::to_string(rank->prev->current_value).c_str(), std::to_string(cost).c_str(), @@ -1104,7 +1104,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost } } else { - Message_StringID(15, AA_GAIN_ABILITY, + Message_StringID(Chat::Yellow, AA_GAIN_ABILITY, std::to_string(rank->title_sid).c_str(), std::to_string(cost).c_str(), cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()); @@ -1179,11 +1179,11 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { uint32 aaremain_sec = aaremain % 60; if(aaremain_hr >= 1) { - Message(13, "You can use this ability again in %u hour(s) %u minute(s) %u seconds", + Message(Chat::Red, "You can use this ability again in %u hour(s) %u minute(s) %u seconds", aaremain_hr, aaremain_min, aaremain_sec); } else { - Message(13, "You can use this ability again in %u minute(s) %u seconds", + Message(Chat::Red, "You can use this ability again in %u minute(s) %u seconds", aaremain_min, aaremain_sec); } @@ -1200,7 +1200,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { CommonBreakInvisible(); if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) { - Message_StringID(MT_SpellFailure, SNEAK_RESTRICT); + Message_StringID(Chat::SpellFailure, SNEAK_RESTRICT); return; } // @@ -1214,7 +1214,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { SetAppearance(eaStanding, false); if (GetAppearance() != eaStanding) { - Message_StringID(MT_SpellFailure, STAND_TO_CAST); + Message_StringID(Chat::SpellFailure, STAND_TO_CAST); return; } } diff --git a/zone/attack.cpp b/zone/attack.cpp index a51cd3163..d555e4458 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1319,7 +1319,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) if (other->AvoidDamage(this, hit)) { int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough; if (strike_through && zone->random.Roll(strike_through)) { - Message_StringID(MT_StrikeThrough, + Message_StringID(Chat::StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses! hit.damage_done = 1; // set to one, we will check this to continue } @@ -1340,9 +1340,9 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist; int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist; if (zone->random.Roll(stun_resist2)) { - other->Message_StringID(MT_Stun, AVOID_STUNNING_BLOW); + other->Message_StringID(Chat::Stun, AVOID_STUNNING_BLOW); } else if (zone->random.Roll(stun_resist)) { - other->Message_StringID(MT_Stun, SHAKE_OFF_STUN); + other->Message_StringID(Chat::Stun, SHAKE_OFF_STUN); } else { other->Stun(3000); // yuck -- 3 seconds } @@ -1392,7 +1392,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm Log(Logs::Detail, Logs::Combat, "Attack canceled, Divine Aura is in effect."); - Message_StringID(MT_DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable! + Message_StringID(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable! return false; } @@ -1619,7 +1619,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk this, /* Sender */ false, /* Skip Sender */ RuleI(Range, DamageMessages), - MT_NonMelee, /* 283 */ + Chat::NonMelee, /* 283 */ HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ killerMob->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ @@ -2129,7 +2129,7 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, EQEmu::skills::Skill { if (IsLDoNTrapped()) { - Message_StringID(13, LDON_ACCIDENT_SETOFF2); + Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); SpellFinished(GetLDoNTrapSpellID(), other, EQEmu::spells::CastingSlot::Item, 0, -1, spells[GetLDoNTrapSpellID()].ResistDiff, false); SetLDoNTrapSpellID(0); SetLDoNTrapped(false); @@ -2173,7 +2173,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil this, /* Sender */ false, /* Skip Sender */ RuleI(Range, DamageMessages), - MT_NonMelee, /* 283 */ + Chat::NonMelee, /* 283 */ HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ killer_mob->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ @@ -3425,7 +3425,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const //we used to do a message to the client, but its gone now. // emote goes with every one ... even npcs - entity_list.MessageClose(this, true, RuleI(Range, SpellMessages), MT_Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName()); + entity_list.MessageClose(this, true, RuleI(Range, SpellMessages), Chat::Emote, "%s beams a smile at %s", attacker->GetCleanName(), this->GetCleanName()); } } //end `if there is some damage being done and theres anattacker person involved` @@ -3439,7 +3439,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const Log(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName()); pet->AddToHateList(attacker, 1, 0, true, false, false, spell_id); pet->SetTarget(attacker); - Message_StringID(10, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); + Message_StringID(Chat::NPCQuestSay, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); } } @@ -3459,7 +3459,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const damage = AffectMagicalDamage(damage, spell_id, iBuffTic, attacker); if (origdmg != damage && attacker && attacker->IsClient()) { if (attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide) - attacker->Message(15, "The Spellshield absorbed %d of %d points of damage", origdmg - damage, origdmg); + attacker->Message(Chat::Yellow, "The Spellshield absorbed %d of %d points of damage", origdmg - damage, origdmg); } if (damage == 0 && attacker && origdmg != damage && IsClient()) { //Kayen: Probably need to add a filter for this - Not sure if this msg is correct but there should be a message for spell negate/runes. @@ -3511,7 +3511,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const this, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), - MT_WornOff, /* 284 */ + Chat::SpellWornOff, /* 284 */ HAS_BEEN_AWAKENED, // %1 has been awakened by %2. GetCleanName(), /* Message1 */ attacker->GetCleanName() /* Message2 */ @@ -3564,13 +3564,13 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const else { // stun resist passed! if (IsClient()) - Message_StringID(MT_Stun, SHAKE_OFF_STUN); + Message_StringID(Chat::Stun, SHAKE_OFF_STUN); } } else { // stun resist 2 passed! if (IsClient()) - Message_StringID(MT_Stun, AVOID_STUNNING_BLOW); + Message_StringID(Chat::Stun, AVOID_STUNNING_BLOW); } } else { @@ -3650,7 +3650,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const if (((spell_id != SPELL_UNKNOWN) || (FromDamageShield)) && damage>0) { //special crap for spell damage, looks hackish to me char val1[20] = { 0 }; - owner->Message_StringID(MT_NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); + owner->Message_StringID(Chat::NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); } else { if (damage > 0) { @@ -3680,14 +3680,14 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const char val1[20] = { 0 }; if (FromDamageShield) { if (attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide) - attacker->Message_StringID(MT_DS, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); + attacker->Message_StringID(Chat::DamageShield, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); } else { entity_list.MessageClose_StringID( this, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), - MT_NonMelee, /* 283 */ + Chat::NonMelee, /* 283 */ HIT_NON_MELEE, /* %1 hit %2 for %3 points of non-melee damage. */ attacker->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ @@ -3754,7 +3754,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const // So we can see our dot dmg like live shows it. if (spell_id != SPELL_UNKNOWN && damage > 0 && attacker && attacker != this && attacker->IsClient()) { //might filter on (attack_skill>200 && attack_skill<250), but I dont think we need it - attacker->FilteredMessage_StringID(attacker, MT_DoTDamage, FilterDOT, + attacker->FilteredMessage_StringID(attacker, Chat::DotDamage, FilterDOT, YOUR_HIT_DOT, GetCleanName(), itoa(damage), spells[spell_id].name); /* older clients don't have the below String ID, but it will be filtered */ @@ -3762,14 +3762,14 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const attacker, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), - MT_DoTDamage, /* Type: 325 */ + Chat::DotDamage, /* Type: 325 */ FilterDOT, /* FilterType: 19 */ OTHER_HIT_DOT, /* MessageFormat: %1 has taken %2 damage from %3 by %4. */ GetCleanName(), /* Message1 */ itoa(damage), /* Message2 */ attacker->GetCleanName(), /* Message3 */ spells[spell_id].name /* Message4 */ - ); + ); } } //end packet sending @@ -3792,42 +3792,42 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id) // message to caster if (caster->IsClient() && caster == this) { if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime, + FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, HOT_HEAL_SELF, itoa(acthealed), spells[spell_id].name); else - FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime, + FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, YOU_HEALED, GetCleanName(), itoa(acthealed)); } else if (caster->IsClient() && caster != this) { if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - caster->FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime, + caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, HOT_HEAL_OTHER, GetCleanName(), itoa(acthealed), spells[spell_id].name); else - caster->FilteredMessage_StringID(caster, MT_NonMelee, FilterHealOverTime, + caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, YOU_HEAL, GetCleanName(), itoa(acthealed)); } // message to target if (IsClient() && caster != this) { if (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - FilteredMessage_StringID(this, MT_NonMelee, FilterHealOverTime, + FilteredMessage_StringID(this, Chat::NonMelee, FilterHealOverTime, HOT_HEALED_OTHER, caster->GetCleanName(), itoa(acthealed), spells[spell_id].name); else - FilteredMessage_StringID(this, MT_NonMelee, FilterHealOverTime, + FilteredMessage_StringID(this, Chat::NonMelee, FilterHealOverTime, YOU_HEALED, caster->GetCleanName(), itoa(acthealed)); } } else { // normal heals - FilteredMessage_StringID(caster, MT_NonMelee, FilterSpellDamage, + FilteredMessage_StringID(caster, Chat::NonMelee, FilterSpellDamage, YOU_HEALED, caster->GetCleanName(), itoa(acthealed)); if (caster != this) - caster->FilteredMessage_StringID(caster, MT_NonMelee, FilterSpellDamage, + caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterSpellDamage, YOU_HEAL, GetCleanName(), itoa(acthealed)); } } else { - Message(MT_NonMelee, "You have been healed for %d points of damage.", acthealed); + Message(Chat::NonMelee, "You have been healed for %d points of damage.", acthealed); } } @@ -3993,10 +3993,10 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * if (IsPet()) { Mob *own = GetOwner(); if (own) - own->Message_StringID(13, PROC_PETTOOLOW); + own->Message_StringID(Chat::Red, PROC_PETTOOLOW); } else { - Message_StringID(13, PROC_TOOLOW); + Message_StringID(Chat::Red, PROC_TOOLOW); } } else { @@ -4030,10 +4030,10 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * if (IsPet()) { Mob *own = GetOwner(); if (own) - own->Message_StringID(13, PROC_PETTOOLOW); + own->Message_StringID(Chat::Red, PROC_PETTOOLOW); } else { - Message_StringID(13, PROC_TOOLOW); + Message_StringID(Chat::Red, PROC_TOOLOW); } } else { @@ -4187,7 +4187,7 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit) this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ GetCleanName(), /* Message1 */ @@ -4247,7 +4247,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ FEMALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses her target!(%2) */ GetCleanName(), /* Message1 */ @@ -4260,7 +4260,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ MALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses his target!(%2) */ GetCleanName(), /* Message1 */ @@ -4344,7 +4344,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ DEADLY_STRIKE, /* MessageFormat: %1 scores a Deadly Strike!(%2) */ GetCleanName(), /* Message1 */ @@ -4372,7 +4372,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ CRIPPLING_BLOW, /* MessageFormat: %1 lands a Crippling Blow!(%2) */ GetCleanName(), /* Message1 */ @@ -4394,7 +4394,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ GetCleanName(), /* Message1 */ @@ -4431,7 +4431,7 @@ bool Mob::TryFinishingBlow(Mob *defender, int &damage) this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), - MT_CritMelee, /* Type: 301 */ + Chat::MeleeCrit, /* Type: 301 */ FilterMeleeCrits, /* FilterType: 12 */ FINISHING_BLOW, /* MessageFormat: %1 scores a Finishing Blow!!) */ GetCleanName() /* Message1 */ @@ -4453,7 +4453,7 @@ void Mob::DoRiposte(Mob *defender) // so ahhh the angle you can riposte is larger than the angle you can hit :P if (!defender->IsFacingMob(this)) { - defender->Message_StringID(MT_TooFarAway, CANT_SEE_TARGET); + defender->Message_StringID(Chat::TooFarAway, CANT_SEE_TARGET); return; } @@ -5042,7 +5042,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac else if (GetClass() == RANGER && GetLevel() > 50) { // no double dmg on headshot if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) { hit.damage_done *= 2; - Message_StringID(MT_CritMelee, BOW_DOUBLE_DAMAGE); + Message_StringID(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE); } } } @@ -5347,7 +5347,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell) Attack(target, hand, false, false, IsFromSpell); if (zone->random.Roll(flurrychance)) Attack(target, hand, false, false, IsFromSpell); - Message_StringID(MT_NPCFlurry, YOU_FLURRY); + Message_StringID(Chat::NPCFlurry, YOU_FLURRY); } } } diff --git a/zone/aura.cpp b/zone/aura.cpp index d4aee01cb..223b5dcb4 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -710,13 +710,13 @@ void Mob::MakeAura(uint16 spell_id) AuraRecord record; if (!database.GetAuraEntry(spell_id, record)) { - Message(13, "Unable to find data for aura %s", spells[spell_id].name); + Message(Chat::Red, "Unable to find data for aura %s", spells[spell_id].name); Log(Logs::General, Logs::Error, "Unable to find data for aura %d, check auras table.", spell_id); return; } if (!IsValidSpell(record.spell_id)) { - Message(13, "Casted spell (%d) is not valid for aura %s", record.spell_id, spells[spell_id].name); + Message(Chat::Red, "Casted spell (%d) is not valid for aura %s", record.spell_id, spells[spell_id].name); Log(Logs::General, Logs::Error, "Casted spell (%d) is not valid for aura %d, check auras table.", record.spell_id, spell_id); return; @@ -744,7 +744,7 @@ void Mob::MakeAura(uint16 spell_id) const auto base = database.LoadNPCTypesData(record.npc_type); if (base == nullptr) { - Message(13, "Unable to load NPC data for aura %s", spells[spell_id].teleport_zone); + Message(Chat::Red, "Unable to load NPC data for aura %s", spells[spell_id].teleport_zone); Log(Logs::General, Logs::Error, "Unable to load NPC data for aura %s (NPC ID %d), check auras and npc_types tables.", spells[spell_id].teleport_zone, record.npc_type); @@ -841,10 +841,10 @@ void Mob::AddTrap(Aura *aura, AuraRecord &record) bool Mob::CanSpawnAura(bool trap) { if (trap && !HasFreeTrapSlots()) { - Message_StringID(MT_SpellFailure, NO_MORE_TRAPS); + Message_StringID(Chat::SpellFailure, NO_MORE_TRAPS); return false; } else if (!trap && !HasFreeAuraSlots()) { - Message_StringID(MT_SpellFailure, NO_MORE_AURAS); + Message_StringID(Chat::SpellFailure, NO_MORE_AURAS); return false; } @@ -878,8 +878,6 @@ void Mob::RemoveAllAuras() } trap_mgr.count = 0; - - return; } void Mob::RemoveAura(int spawn_id, bool skip_strip, bool expired) @@ -891,7 +889,7 @@ void Mob::RemoveAura(int spawn_id, bool skip_strip, bool expired) aura.aura->Depop(skip_strip); if (expired && IsClient()) { CastToClient()->SendColoredText( - CC_Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color + Chat::Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color // need to update client UI too auto app = new EQApplicationPacket(OP_UpdateAura, sizeof(AuraDestory_Struct)); auto ads = (AuraDestory_Struct *)app->pBuffer; @@ -920,7 +918,7 @@ void Mob::RemoveAura(int spawn_id, bool skip_strip, bool expired) aura.aura->Depop(skip_strip); if (expired && IsClient()) CastToClient()->SendColoredText( - CC_Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color + Chat::Yellow, StringFormat("%s has expired.", aura.name)); // TODO: verify color while (trap_mgr.count - 1 > i) { i++; aura.spawn_id = trap_mgr.auras[i].spawn_id; diff --git a/zone/bot.cpp b/zone/bot.cpp index b47694103..7265492aa 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -159,9 +159,9 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to bool stance_flag = false; if (!database.botdb.LoadStance(this, stance_flag) && bot_owner) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadStance(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadStance(), GetCleanName()); if (!stance_flag && bot_owner) - bot_owner->Message(13, "Could not locate stance for '%s'", GetCleanName()); + bot_owner->Message(Chat::Red, "Could not locate stance for '%s'", GetCleanName()); SetTaunting((GetClass() == WARRIOR || GetClass() == PALADIN || GetClass() == SHADOWKNIGHT) && (GetBotStance() == EQEmu::constants::stanceAggressive)); SetPauseAI(false); @@ -178,17 +178,17 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to memset(&_botInspectMessage, 0, sizeof(InspectMessage_Struct)); if (!database.botdb.LoadInspectMessage(GetBotID(), _botInspectMessage) && bot_owner) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadInspectMessage(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadInspectMessage(), GetCleanName()); if (!database.botdb.LoadGuildMembership(GetBotID(), _guildId, _guildRank, _guildName) && bot_owner) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadGuildMembership(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadGuildMembership(), GetCleanName()); std::string error_message; EquipBot(&error_message); if(!error_message.empty()) { if(bot_owner) - bot_owner->Message(13, error_message.c_str()); + bot_owner->Message(Chat::Red, error_message.c_str()); error_message.clear(); } @@ -206,12 +206,12 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to GenerateBaseStats(); if (!database.botdb.LoadTimers(this) && bot_owner) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadTimers(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadTimers(), GetCleanName()); LoadAAs(); if (!database.botdb.LoadBuffs(this) && bot_owner) - bot_owner->Message(13, "&s for '%s'", BotDatabase::fail::LoadBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "&s for '%s'", BotDatabase::fail::LoadBuffs(), GetCleanName()); CalcBotStats(false); hp_regen = CalcHPRegen(); @@ -1701,28 +1701,28 @@ bool Bot::Save() if(!GetBotID()) { // New bot record uint32 bot_id = 0; if (!database.botdb.SaveNewBot(this, bot_id) || !bot_id) { - bot_owner->Message(13, "%s '%s'", BotDatabase::fail::SaveNewBot(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s '%s'", BotDatabase::fail::SaveNewBot(), GetCleanName()); return false; } SetBotID(bot_id); } else { // Update existing bot record if (!database.botdb.SaveBot(this)) { - bot_owner->Message(13, "%s '%s'", BotDatabase::fail::SaveBot(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s '%s'", BotDatabase::fail::SaveBot(), GetCleanName()); return false; } } // All of these continue to process if any fail if (!database.botdb.SaveBuffs(this)) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::SaveBuffs(), GetCleanName()); if (!database.botdb.SaveTimers(this)) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveTimers(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::SaveTimers(), GetCleanName()); if (!database.botdb.SaveStance(this)) - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveStance(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::SaveStance(), GetCleanName()); if (!SavePet()) - bot_owner->Message(13, "Failed to save pet for '%s'", GetCleanName()); + bot_owner->Message(Chat::Red, "Failed to save pet for '%s'", GetCleanName()); return true; } @@ -1734,26 +1734,26 @@ bool Bot::DeleteBot() return false; if (!database.botdb.DeleteHealRotation(GetBotID())) { - bot_owner->Message(13, "%s", BotDatabase::fail::DeleteHealRotation()); + bot_owner->Message(Chat::Red, "%s", BotDatabase::fail::DeleteHealRotation()); return false; } std::string query = StringFormat("DELETE FROM `bot_heal_rotation_members` WHERE `bot_id` = '%u'", GetBotID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - bot_owner->Message(13, "Failed to delete heal rotation member '%s'", GetCleanName()); + bot_owner->Message(Chat::Red, "Failed to delete heal rotation member '%s'", GetCleanName()); return false; } query = StringFormat("DELETE FROM `bot_heal_rotation_targets` WHERE `target_name` LIKE '%s'", GetCleanName()); results = database.QueryDatabase(query); if (!results.Success()) { - bot_owner->Message(13, "Failed to delete heal rotation target '%s'", GetCleanName()); + bot_owner->Message(Chat::Red, "Failed to delete heal rotation target '%s'", GetCleanName()); return false; } if (!DeletePet()) { - bot_owner->Message(13, "Failed to delete pet for '%s'", GetCleanName()); + bot_owner->Message(Chat::Red, "Failed to delete pet for '%s'", GetCleanName()); return false; } @@ -1763,32 +1763,32 @@ bool Bot::DeleteBot() std::string error_message; if (!database.botdb.RemoveMemberFromBotGroup(GetBotID())) { - bot_owner->Message(13, "%s - '%s'", BotDatabase::fail::RemoveMemberFromBotGroup(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s - '%s'", BotDatabase::fail::RemoveMemberFromBotGroup(), GetCleanName()); return false; } if (!database.botdb.DeleteItems(GetBotID())) { - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteItems(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::DeleteItems(), GetCleanName()); return false; } if (!database.botdb.DeleteTimers(GetBotID())) { - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteTimers(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::DeleteTimers(), GetCleanName()); return false; } if (!database.botdb.DeleteBuffs(GetBotID())) { - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::DeleteBuffs(), GetCleanName()); return false; } if (!database.botdb.DeleteStance(GetBotID())) { - bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteStance(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::DeleteStance(), GetCleanName()); return false; } if (!database.botdb.DeleteBot(GetBotID())) { - bot_owner->Message(13, "%s '%s'", BotDatabase::fail::DeleteBot(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s '%s'", BotDatabase::fail::DeleteBot(), GetCleanName()); return false; } @@ -1832,7 +1832,7 @@ bool Bot::LoadPet() uint32 pet_index = 0; if (!database.botdb.LoadPetIndex(GetBotID(), pet_index)) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetIndex(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::LoadPetIndex(), GetCleanName()); return false; } if (!pet_index) @@ -1840,10 +1840,10 @@ bool Bot::LoadPet() uint32 saved_pet_spell_id = 0; if (!database.botdb.LoadPetSpellID(GetBotID(), saved_pet_spell_id)) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetSpellID(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::LoadPetSpellID(), GetCleanName()); } if (!IsValidSpell(saved_pet_spell_id)) { - bot_owner->Message(13, "Invalid spell id for %s's pet", GetCleanName()); + bot_owner->Message(Chat::Red, "Invalid spell id for %s's pet", GetCleanName()); DeletePet(); return false; } @@ -1854,7 +1854,7 @@ bool Bot::LoadPet() uint32 pet_spell_id = 0; if (!database.botdb.LoadPetStats(GetBotID(), pet_name, pet_mana, pet_hp, pet_spell_id)) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetStats(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::LoadPetStats(), GetCleanName()); return false; } @@ -1869,12 +1869,12 @@ bool Bot::LoadPet() SpellBuff_Struct pet_buffs[PET_BUFF_COUNT]; memset(pet_buffs, 0, (sizeof(SpellBuff_Struct) * PET_BUFF_COUNT)); if (!database.botdb.LoadPetBuffs(GetBotID(), pet_buffs)) - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::LoadPetBuffs(), GetCleanName()); uint32 pet_items[EQEmu::invslot::EQUIPMENT_COUNT]; memset(pet_items, 0, (sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT)); if (!database.botdb.LoadPetItems(GetBotID(), pet_items)) - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetItems(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::LoadPetItems(), GetCleanName()); pet_inst->SetPetState(pet_buffs, pet_items); pet_inst->CalcBonuses(); @@ -1913,14 +1913,14 @@ bool Bot::SavePet() std::string error_message; if (!database.botdb.SavePetStats(GetBotID(), pet_name_str, pet_inst->GetMana(), pet_inst->GetHP(), pet_inst->GetPetSpellID())) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetStats(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::SavePetStats(), GetCleanName()); return false; } if (!database.botdb.SavePetBuffs(GetBotID(), pet_buffs)) - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::SavePetBuffs(), GetCleanName()); if (!database.botdb.SavePetItems(GetBotID(), pet_items)) - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetItems(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::SavePetItems(), GetCleanName()); return true; } @@ -1934,15 +1934,15 @@ bool Bot::DeletePet() std::string error_message; if (!database.botdb.DeletePetItems(GetBotID())) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetItems(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::DeletePetItems(), GetCleanName()); return false; } if (!database.botdb.DeletePetBuffs(GetBotID())) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetBuffs(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::DeletePetBuffs(), GetCleanName()); return false; } if (!database.botdb.DeletePetStats(GetBotID())) { - bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetStats(), GetCleanName()); + bot_owner->Message(Chat::Red, "%s for %s's pet", BotDatabase::fail::DeletePetStats(), GetCleanName()); return false; } @@ -2808,7 +2808,7 @@ void Bot::AI_Process() { int32 flurrychance = (aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance); if (flurrychance) { if (zone->random.Int(0, 100) < flurrychance) { - Message_StringID(MT_NPCFlurry, YOU_FLURRY); + Message_StringID(Chat::NPCFlurry, YOU_FLURRY); Attack(tar, EQEmu::invslot::slotPrimary, false); TEST_TARGET(); @@ -3258,7 +3258,7 @@ bool Bot::Spawn(Client* botCharacterOwner) { if(this->Save()) this->GetBotOwner()->CastToClient()->Message(0, "%s saved.", this->GetCleanName()); else - this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName()); + this->GetBotOwner()->CastToClient()->Message(Chat::Red, "%s save failed!", this->GetCleanName()); // Spawn the bot at the bow owner's loc this->m_Position.x = botCharacterOwner->GetX(); @@ -3331,7 +3331,7 @@ uint32 Bot::GetBotItemBySlot(uint32 slotID) if (!database.botdb.LoadItemBySlot(GetBotID(), slotID, item_id)) { if (GetBotOwner() && GetBotOwner()->IsClient()) - GetBotOwner()->CastToClient()->Message(13, "%s", BotDatabase::fail::LoadItemBySlot()); + GetBotOwner()->CastToClient()->Message(Chat::Red, "%s", BotDatabase::fail::LoadItemBySlot()); } return item_id; @@ -3434,7 +3434,7 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) { std::list ActiveBots; // Modified LoadGroupedBotsByGroupID to require a CharacterID if (!database.botdb.LoadGroupedBotsByGroupID(botOwner->CharacterID(), TempGroupId, ActiveBots)) { - botOwner->Message(13, "%s", BotDatabase::fail::LoadGroupedBotsByGroupID()); + botOwner->Message(Chat::Red, "%s", BotDatabase::fail::LoadGroupedBotsByGroupID()); return; } @@ -4165,17 +4165,17 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli // trade messages for (const auto& return_iterator : client_return) { if (return_iterator.failedItemName.size()) - client->Message(MT_Tell, "%s tells you, \"%s, I can't use this '%s.'\"", GetCleanName(), client->GetName(), return_iterator.failedItemName.c_str()); + client->Message(Chat::Tell, "%s tells you, \"%s, I can't use this '%s.'\"", GetCleanName(), client->GetName(), return_iterator.failedItemName.c_str()); } for (const auto& trade_iterator : client_trade) { if (trade_iterator.acceptedItemName.size()) - client->Message(MT_Tell, "%s tells you, \"Thank you for the '%s,' %s!\"", GetCleanName(), trade_iterator.acceptedItemName.c_str(), client->GetName()); + client->Message(Chat::Tell, "%s tells you, \"Thank you for the '%s,' %s!\"", GetCleanName(), trade_iterator.acceptedItemName.c_str(), client->GetName()); } size_t accepted_count = client_trade.size(); size_t returned_count = client_return.size(); - client->Message(CC_Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s")); + client->Message(Chat::Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s")); if (accepted_count) CalcBotStats(client->GetBotOptionStatsUpdate()); @@ -4281,7 +4281,7 @@ void Bot::Damage(Mob *from, int32 damage, uint16 spell_id, EQEmu::skills::SkillT int healed = GetActSpellHealing(spell_id, damage); Log(Logs::Detail, Logs::Combat, "Applying lifetap heal of %d to %s", healed, GetCleanName()); HealDamage(healed); - entity_list.MessageClose(this, true, 300, MT_Spells, "%s beams a smile at %s", GetCleanName(), from->GetCleanName() ); + entity_list.MessageClose(this, true, 300, Chat::Spells, "%s beams a smile at %s", GetCleanName(), from->GetCleanName() ); } CommonDamage(from, damage, spell_id, attack_skill, avoidable, buffslot, iBuffTic, special); @@ -5364,7 +5364,7 @@ bool Bot::TryFinishingBlow(Mob *defender, int &damage) if (defender->GetLevel() <= levelreq && (chance >= zone->random.Int(1, 1000))) { Log(Logs::Detail, Logs::Combat, "Landed a finishing blow: levelreq at %d, other level %d", levelreq, defender->GetLevel()); - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FINISHING_BLOW, GetName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, FINISHING_BLOW, GetName()); damage = fb_damage; return true; } else { @@ -5572,7 +5572,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { if (bIsBehind || bCanFrontalBS) { int chance = (10 + (GetDEX() / 10) + (itembonuses.HeroicDEX / 10)); if(level >= 60 && other->GetLevel() <= 45 && !other->CastToNPC()->IsEngaged() && other->GetHP()<= 32000 && other->IsNPC() && zone->random.Real(0, 99) < chance) { - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, ASSASSINATES, GetName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, ASSASSINATES, GetName()); RogueAssassinate(other); } else { RogueBackstab(other); @@ -5940,12 +5940,12 @@ void Bot::ProcessGuildInvite(Client* guildOfficer, Bot* botToGuild) { if(guildOfficer && botToGuild) { if(!botToGuild->IsInAGuild()) { if (!guild_mgr.CheckPermission(guildOfficer->GuildID(), guildOfficer->GuildRank(), GUILD_INVITE)) { - guildOfficer->Message(13, "You dont have permission to invite."); + guildOfficer->Message(Chat::Red, "You dont have permission to invite."); return; } if (!database.botdb.SaveGuildMembership(botToGuild->GetBotID(), guildOfficer->GuildID(), GUILD_MEMBER)) { - guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::SaveGuildMembership(), botToGuild->GetCleanName()); + guildOfficer->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::SaveGuildMembership(), botToGuild->GetCleanName()); return; } @@ -5958,7 +5958,7 @@ void Bot::ProcessGuildInvite(Client* guildOfficer, Bot* botToGuild) { safe_delete(pack); } else { - guildOfficer->Message(13, "Bot is in a guild."); + guildOfficer->Message(Chat::Red, "Bot is in a guild."); return; } } @@ -5974,10 +5974,10 @@ bool Bot::ProcessGuildRemoval(Client* guildOfficer, std::string botName) { } else { uint32 ownerId = 0; if (!database.botdb.LoadOwnerID(botName, ownerId)) - guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::LoadOwnerID(), botName.c_str()); + guildOfficer->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadOwnerID(), botName.c_str()); uint32 botId = 0; if (!database.botdb.LoadBotID(ownerId, botName, botId)) - guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::LoadBotID(), botName.c_str()); + guildOfficer->Message(Chat::Red, "%s for '%s'", BotDatabase::fail::LoadBotID(), botName.c_str()); if (botId && database.botdb.SaveGuildMembership(botId, 0, 0)) Result = true; } @@ -6125,7 +6125,7 @@ int32 Bot::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { if(itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) value += (GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, value) * ratio / 100); - entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s delivers a critical blast! (%d)", GetName(), -value); + entity_list.MessageClose(this, false, 100, Chat::SpellCrit, "%s delivers a critical blast! (%d)", GetName(), -value); return value; } @@ -6179,7 +6179,7 @@ int32 Bot::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { value += (value * target->GetHealRate(spell_id, this) / 100); if (Critical) - entity_list.MessageClose(this, false, 100, MT_SpellCrits, "%s performs an exceptional heal! (%d)", GetName(), value); + entity_list.MessageClose(this, false, 100, Chat::SpellCrit, "%s performs an exceptional heal! (%d)", GetName(), value); return value; } else { @@ -6444,11 +6444,11 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlo if(!IsValidSpell(spell_id) || casting_spell_id || delaytimer || spellend_timer.Enabled() || IsStunned() || IsFeared() || IsMezzed() || (IsSilenced() && !IsDiscipline(spell_id)) || (IsAmnesiad() && IsDiscipline(spell_id))) { Log(Logs::Detail, Logs::Spells, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced() ); if(IsSilenced() && !IsDiscipline(spell_id)) - Message_StringID(13, SILENCED_STRING); + Message_StringID(Chat::Red, SILENCED_STRING); if(IsAmnesiad() && IsDiscipline(spell_id)) - Message_StringID(13, MELEE_SILENCE); + Message_StringID(Chat::Red, MELEE_SILENCE); if(casting_spell_id) AI_Event_SpellCastFinished(false, static_cast(casting_spell_slot)); @@ -6458,7 +6458,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlo } if(IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()){ - Message_StringID(13, SPELL_WOULDNT_HOLD); + Message_StringID(Chat::Red, SPELL_WOULDNT_HOLD); if(casting_spell_id) AI_Event_SpellCastFinished(false, static_cast(casting_spell_slot)); @@ -8155,13 +8155,13 @@ void Bot::CalcBotStats(bool showtext) { return; if(showtext) { - GetBotOwner()->Message(15, "Updating %s...", GetCleanName()); + GetBotOwner()->Message(Chat::Yellow, "Updating %s...", GetCleanName()); } if(!IsValidRaceClassCombo()) { - GetBotOwner()->Message(15, "A %s - %s bot was detected. Is this Race/Class combination allowed?.", GetRaceIDName(GetRace()), GetClassIDName(GetClass(), GetLevel())); - GetBotOwner()->Message(15, "Previous Bots Code releases did not check Race/Class combinations during create."); - GetBotOwner()->Message(15, "Unless you are experiencing heavy lag, you should delete and remake this bot."); + GetBotOwner()->Message(Chat::Yellow, "A %s - %s bot was detected. Is this Race/Class combination allowed?.", GetRaceIDName(GetRace()), GetClassIDName(GetClass(), GetLevel())); + GetBotOwner()->Message(Chat::Yellow, "Previous Bots Code releases did not check Race/Class combinations during create."); + GetBotOwner()->Message(Chat::Yellow, "Unless you are experiencing heavy lag, you should delete and remake this bot."); } if(GetBotOwner()->GetLevel() != GetLevel()) @@ -8170,37 +8170,37 @@ void Bot::CalcBotStats(bool showtext) { GenerateSpecialAttacks(); if(showtext) { - GetBotOwner()->Message(15, "Base stats:"); - GetBotOwner()->Message(15, "Level: %i HP: %i AC: %i Mana: %i STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetLevel(), base_hp, AC, max_mana, STR, STA, DEX, AGI, INT, WIS, CHA); - GetBotOwner()->Message(15, "Resists-- Magic: %i, Poison: %i, Fire: %i, Cold: %i, Disease: %i, Corruption: %i.",MR,PR,FR,CR,DR,Corrup); + GetBotOwner()->Message(Chat::Yellow, "Base stats:"); + GetBotOwner()->Message(Chat::Yellow, "Level: %i HP: %i AC: %i Mana: %i STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetLevel(), base_hp, AC, max_mana, STR, STA, DEX, AGI, INT, WIS, CHA); + GetBotOwner()->Message(Chat::Yellow, "Resists-- Magic: %i, Poison: %i, Fire: %i, Cold: %i, Disease: %i, Corruption: %i.",MR,PR,FR,CR,DR,Corrup); // Test Code if(GetClass() == BARD) - GetBotOwner()->Message(15, "Bard Skills-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", + GetBotOwner()->Message(Chat::Yellow, "Bard Skills-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", GetSkill(EQEmu::skills::SkillBrassInstruments), GetSkill(EQEmu::skills::SkillPercussionInstruments), GetSkill(EQEmu::skills::SkillSinging), GetSkill(EQEmu::skills::SkillStringedInstruments), GetSkill(EQEmu::skills::SkillWindInstruments)); } //if(this->Save()) // this->GetBotOwner()->CastToClient()->Message(0, "%s saved.", this->GetCleanName()); //else - // this->GetBotOwner()->CastToClient()->Message(13, "%s save failed!", this->GetCleanName()); + // this->GetBotOwner()->CastToClient()->Message(Chat::Red, "%s save failed!", this->GetCleanName()); CalcBonuses(); AI_AddNPCSpells(this->GetBotSpellID()); if(showtext) { - GetBotOwner()->Message(15, "%s has been updated.", GetCleanName()); - GetBotOwner()->Message(15, "Level: %i HP: %i AC: %i Mana: %i STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetLevel(), max_hp, GetAC(), max_mana, GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); - GetBotOwner()->Message(15, "Resists-- Magic: %i, Poison: %i, Fire: %i, Cold: %i, Disease: %i, Corruption: %i.",GetMR(),GetPR(),GetFR(),GetCR(),GetDR(),GetCorrup()); + GetBotOwner()->Message(Chat::Yellow, "%s has been updated.", GetCleanName()); + GetBotOwner()->Message(Chat::Yellow, "Level: %i HP: %i AC: %i Mana: %i STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetLevel(), max_hp, GetAC(), max_mana, GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); + GetBotOwner()->Message(Chat::Yellow, "Resists-- Magic: %i, Poison: %i, Fire: %i, Cold: %i, Disease: %i, Corruption: %i.",GetMR(),GetPR(),GetFR(),GetCR(),GetDR(),GetCorrup()); // Test Code if(GetClass() == BARD) { - GetBotOwner()->Message(15, "Bard Skills-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", + GetBotOwner()->Message(Chat::Yellow, "Bard Skills-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", GetSkill(EQEmu::skills::SkillBrassInstruments) + GetBrassMod(), GetSkill(EQEmu::skills::SkillPercussionInstruments) + GetPercMod(), GetSkill(EQEmu::skills::SkillSinging) + GetSingMod(), GetSkill(EQEmu::skills::SkillStringedInstruments) + GetStringMod(), GetSkill(EQEmu::skills::SkillWindInstruments) + GetWindMod()); - GetBotOwner()->Message(15, "Bard Skill Mods-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", GetBrassMod(), GetPercMod(), GetSingMod(), GetStringMod(), GetWindMod()); + GetBotOwner()->Message(Chat::Yellow, "Bard Skill Mods-- Brass: %i, Percussion: %i, Singing: %i, Stringed: %i, Wind: %i", GetBrassMod(), GetPercMod(), GetSingMod(), GetStringMod(), GetWindMod()); } } } @@ -9070,7 +9070,7 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag) if (!database.botdb.SaveEquipmentColor(GetBotID(), save_slot, rgb)) { if (GetBotOwner() && GetBotOwner()->IsClient()) - GetBotOwner()->CastToClient()->Message(13, "%s", BotDatabase::fail::SaveEquipmentColor()); + GetBotOwner()->CastToClient()->Message(Chat::Red, "%s", BotDatabase::fail::SaveEquipmentColor()); return false; } } diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 69191d991..da17b78d8 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -84,12 +84,12 @@ namespace { //#define BCSTSPELLDUMP // only needed if you're adding/tailoring bot command spells and need a file dump -#define m_message CC_WhiteSmoke -#define m_action CC_Yellow -#define m_note CC_Gray -#define m_usage CC_Cyan -#define m_fail CC_Red -#define m_unknown CC_Magenta +#define m_message Chat::WhiteSmoke +#define m_action Chat::Yellow +#define m_note Chat::Gray +#define m_usage Chat::Cyan +#define m_fail Chat::Red +#define m_unknown Chat::Magenta #define HP_RATIO_DELTA 5.0f @@ -4833,7 +4833,7 @@ void bot_subcommand_bot_inspect_message(Client *c, const Seperator *sep) set_flag = true; } else if (strcasecmp(sep->arg[1], "clear")) { - c->Message(15, "This command requires a [set | clear] argument"); + c->Message(Chat::Yellow, "This command requires a [set | clear] argument"); return; } @@ -7284,7 +7284,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName); if (c->GetTradeskillObject() || (c->trade->state == Trading)) { - c->Message_StringID(MT_Tell, MERCHANT_BUSY); + c->Message_StringID(Chat::Tell, MERCHANT_BUSY); return; } @@ -7310,7 +7310,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) itm = itminst->GetItem(); if (itminst && itm && c->CheckLoreConflict(itm)) { - c->Message_StringID(0, PICK_LORE); + c->Message_StringID(Chat::WhiteSmoke, PICK_LORE); return; } @@ -7324,7 +7324,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) if (!c->CheckLoreConflict(itma->GetItem())) continue; - c->Message_StringID(0, PICK_LORE); + c->Message_StringID(Chat::WhiteSmoke, PICK_LORE); return; } diff --git a/zone/client.cpp b/zone/client.cpp index 7e6baf180..18385fe30 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -914,7 +914,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s { case ChatChannel_Guild: { /* Guild Chat */ if (!IsInAGuild()) - Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild. + Message_StringID(Chat::DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild. else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK)) Message(0, "Error: You dont have permission to speak to the guild."); else if (!worldserver.SendChannelMessage(this, targetname, chan_num, GuildID(), language, lang_skill, message)) @@ -1097,11 +1097,11 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s if(parse->PlayerHasQuestSub(EVENT_COMMAND)) { int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); if(i == 0 && !RuleB(Chat, SuppressCommandErrors)) { - Message(13, "Command '%s' not recognized.", message); + Message(Chat::Red, "Command '%s' not recognized.", message); } } else { if(!RuleB(Chat, SuppressCommandErrors)) - Message(13, "Command '%s' not recognized.", message); + Message(Chat::Red, "Command '%s' not recognized.", message); } } break; @@ -1116,12 +1116,12 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s if (parse->PlayerHasQuestSub(EVENT_COMMAND)) { int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); if (i == 0 && !RuleB(Chat, SuppressCommandErrors)) { - Message(13, "Bot command '%s' not recognized.", message); + Message(Chat::Red, "Bot command '%s' not recognized.", message); } } else { if (!RuleB(Chat, SuppressCommandErrors)) - Message(13, "Bot command '%s' not recognized.", message); + Message(Chat::Red, "Bot command '%s' not recognized.", message); } } break; @@ -1265,11 +1265,11 @@ void Client::ChannelMessageSend(const char* from, const char* to, uint8 chan_num } void Client::Message(uint32 type, const char* message, ...) { - if (GetFilter(FilterSpellDamage) == FilterHide && type == MT_NonMelee) + if (GetFilter(FilterSpellDamage) == FilterHide && type == Chat::NonMelee) return; - if (GetFilter(FilterMeleeCrits) == FilterHide && type == MT_CritMelee) //98 is self... + if (GetFilter(FilterMeleeCrits) == FilterHide && type == Chat::MeleeCrit) //98 is self... return; - if (GetFilter(FilterSpellCrits) == FilterHide && type == MT_SpellCrits) + if (GetFilter(FilterSpellCrits) == FilterHide && type == Chat::SpellCrit) return; va_list argptr; @@ -1509,7 +1509,7 @@ void Client::IncreaseLanguageSkill(int skill_id, int value) { QueuePacket(outapp); safe_delete(outapp); - Message_StringID( MT_Skills, LANG_SKILL_IMPROVED ); //Notify client + Message_StringID( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify client } void Client::AddSkill(EQEmu::skills::SkillType skillid, uint16 value) { @@ -2047,7 +2047,7 @@ bool Client::ChangeFirstName(const char* in_firstname, const char* gmname) void Client::SetGM(bool toggle) { m_pp.gm = toggle ? 1 : 0; m_inv.SetGMInventory((bool)m_pp.gm); - Message(13, "You are %s a GM.", m_pp.gm ? "now" : "no longer"); + Message(Chat::Red, "You are %s a GM.", m_pp.gm ? "now" : "no longer"); SendAppearancePacket(AT_GM, m_pp.gm); Save(); UpdateWho(); @@ -2550,7 +2550,7 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(EQEmu::skills::SkillType skil } else { - Message(13, "Your spell casting specializations skills have been reset. " + Message(Chat::Red, "Your spell casting specializations skills have been reset. " "Only %i primary specialization skill is allowed.", MaxSpecializations); for (int i = EQEmu::skills::SkillSpecializeAbjure; i <= EQEmu::skills::SkillSpecializeEvocation; ++i) @@ -2578,9 +2578,9 @@ void Client::SetPVP(bool toggle, bool message) { if (message) { if(GetPVP()) - this->Message_StringID(MT_Shout,PVP_ON); + this->Message_StringID(Chat::Shout,PVP_ON); else - Message(13, "You no longer follow the ways of discord."); + Message(Chat::Red, "You no longer follow the ways of discord."); } SendAppearancePacket(AT_PVP, GetPVP()); @@ -2714,22 +2714,22 @@ void Client::Disarm(Client* disarmer, int chance) { if (matslot != EQEmu::textures::materialInvalid) SendWearChange(matslot); } - Message_StringID(MT_Skills, DISARMED); + Message_StringID(Chat::Skills, DISARMED); if (disarmer != this) - disarmer->Message_StringID(MT_Skills, DISARM_SUCCESS, this->GetCleanName()); + disarmer->Message_StringID(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); if (chance != 1000) disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); CalcBonuses(); // CalcEnduranceWeightFactor(); return; } - disarmer->Message_StringID(MT_Skills, DISARM_FAILED); + disarmer->Message_StringID(Chat::Skills, DISARM_FAILED); if (chance != 1000) disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); return; } } - disarmer->Message_StringID(MT_Skills, DISARM_FAILED); + disarmer->Message_StringID(Chat::Skills, DISARM_FAILED); } bool Client::BindWound(Mob *bindmob, bool start, bool fail) @@ -2771,7 +2771,7 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) } else { // send bindmob "stand still" if (!bindmob->IsAIControlled() && bindmob != this) { - bindmob->CastToClient()->Message_StringID(clientMessageYellow, + bindmob->CastToClient()->Message_StringID(Chat::Yellow, YOU_ARE_BEING_BANDAGED); } else if (bindmob->IsAIControlled() && bindmob != this) { ; // Tell IPC to stand still? @@ -2855,7 +2855,7 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) } else { // I dont have the real, live - Message(15, "You cannot bind wounds above %d%% hitpoints.", + Message(Chat::Yellow, "You cannot bind wounds above %d%% hitpoints.", max_percent); if (bindmob != this && bindmob->IsClient()) bindmob->CastToClient()->Message( @@ -2916,9 +2916,9 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) bindmob->SendHPUpdate(); } else { - Message(15, "You cannot bind wounds above %d%% hitpoints", max_percent); + Message(Chat::Yellow, "You cannot bind wounds above %d%% hitpoints", max_percent); if (bindmob != this && bindmob->IsClient()) - bindmob->CastToClient()->Message(15, "You cannot have your wounds bound above %d%% hitpoints", max_percent); + bindmob->CastToClient()->Message(Chat::Yellow, "You cannot have your wounds bound above %d%% hitpoints", max_percent); } } } @@ -3077,11 +3077,11 @@ void Client::ServerFilter(SetServerFilter_Struct* filter){ // this version is for messages with no parameters void Client::Message_StringID(uint32 type, uint32 string_id, uint32 distance) { - if (GetFilter(FilterSpellDamage) == FilterHide && type == MT_NonMelee) + if (GetFilter(FilterSpellDamage) == FilterHide && type == Chat::NonMelee) return; - if (GetFilter(FilterMeleeCrits) == FilterHide && type == MT_CritMelee) //98 is self... + if (GetFilter(FilterMeleeCrits) == FilterHide && type == Chat::MeleeCrit) //98 is self... return; - if (GetFilter(FilterSpellCrits) == FilterHide && type == MT_SpellCrits) + if (GetFilter(FilterSpellCrits) == FilterHide && type == Chat::SpellCrit) return; auto outapp = new EQApplicationPacket(OP_SimpleMessage, 12); SimpleMessage_Struct* sms = (SimpleMessage_Struct*)outapp->pBuffer; @@ -3108,20 +3108,20 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message const char* message5,const char* message6,const char* message7, const char* message8,const char* message9, uint32 distance) { - if (GetFilter(FilterSpellDamage) == FilterHide && type == MT_NonMelee) + if (GetFilter(FilterSpellDamage) == FilterHide && type == Chat::NonMelee) return; - if (GetFilter(FilterMeleeCrits) == FilterHide && type == MT_CritMelee) //98 is self... + if (GetFilter(FilterMeleeCrits) == FilterHide && type == Chat::MeleeCrit) //98 is self... return; - if (GetFilter(FilterSpellCrits) == FilterHide && type == MT_SpellCrits) + if (GetFilter(FilterSpellCrits) == FilterHide && type == Chat::SpellCrit) return; - if (GetFilter(FilterDamageShields) == FilterHide && type == MT_DS) + if (GetFilter(FilterDamageShields) == FilterHide && type == Chat::DamageShield) return; int i = 0, argcount = 0, length = 0; char *bufptr = nullptr; const char *message_arg[9] = {0}; - if(type==MT_Emote) + if(type==Chat::Emote) type=4; if(!message1) @@ -3236,7 +3236,7 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil char *bufptr = nullptr; const char *message_arg[9] = {0}; - if (type == MT_Emote) + if (type == Chat::Emote) type = 4; if (!message1) { @@ -3281,7 +3281,7 @@ void Client::Tell_StringID(uint32 string_id, const char *who, const char *messag char string_id_str[10]; snprintf(string_id_str, 10, "%d", string_id); - Message_StringID(MT_TellEcho, TELL_QUEUED_MESSAGE, who, string_id_str, message); + Message_StringID(Chat::EchoTell, TELL_QUEUED_MESSAGE, who, string_id_str, message); } void Client::SetTint(int16 in_slot, uint32 color) { @@ -3344,7 +3344,7 @@ void Client::SetLanguageSkill(int langid, int value) QueuePacket(outapp); safe_delete(outapp); - Message_StringID( MT_Skills, LANG_SKILL_IMPROVED ); //Notify the client + Message_StringID( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify the client } void Client::LinkDead() @@ -3432,7 +3432,7 @@ void Client::Escape() entity_list.RemoveFromTargets(this, true); SetInvisible(1); - Message_StringID(MT_Skills, ESCAPE); + Message_StringID(Chat::Skills, ESCAPE); } float Client::CalcPriceMod(Mob* other, bool reverse) @@ -3828,9 +3828,9 @@ void Client::EnteringMessages(Client* client) uint8 flag = database.GetAgreementFlag(client->AccountID()); if(!flag) { - client->Message(13,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); - client->Message(13,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); - client->Message(13,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); + client->Message(Chat::Red,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); + client->Message(Chat::Red,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); + client->Message(Chat::Red,"You must agree to the Rules, before you can move. (type #serverrules to view the rules)"); client->SendAppearancePacket(AT_Anim, ANIM_FREEZE); } } @@ -3872,13 +3872,13 @@ void Client::SacrificeConfirm(Client *caster) } if (GetLevel() < RuleI(Spells, SacrificeMinLevel)) { - caster->Message_StringID(13, SAC_TOO_LOW); // This being is not a worthy sacrifice. + caster->Message_StringID(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. safe_delete(outapp); return; } if (GetLevel() > RuleI(Spells, SacrificeMaxLevel)) { - caster->Message_StringID(13, SAC_TOO_HIGH); + caster->Message_StringID(Chat::Red, SAC_TOO_HIGH); safe_delete(outapp); return; } @@ -3947,7 +3947,7 @@ void Client::Sacrifice(Client *caster) caster->SummonItem(RuleI(Spells, SacrificeItemID)); } } else { - caster->Message_StringID(13, SAC_TOO_LOW); // This being is not a worthy sacrifice. + caster->Message_StringID(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. } } @@ -4222,7 +4222,7 @@ void Client::KeyRingAdd(uint32 item_id) return; } - Message(4,"Added to keyring."); + Message(Chat::LightBlue,"Added to keyring."); keyring.push_back(item_id); } @@ -4238,11 +4238,11 @@ bool Client::KeyRingCheck(uint32 item_id) void Client::KeyRingList() { - Message(4,"Keys on Keyring:"); + Message(Chat::LightBlue,"Keys on Keyring:"); const EQEmu::ItemData *item = nullptr; for (auto iter = keyring.begin(); iter != keyring.end(); ++iter) { if ((item = database.GetItem(*iter))!=nullptr) { - Message(4,item->Name); + Message(Chat::LightBlue,item->Name); } } } @@ -4414,8 +4414,8 @@ bool Client::GroupFollow(Client* inviter) { if (group->GetID() == 0) { - Message(13, "Unable to get new group id. Cannot create group."); - inviter->Message(13, "Unable to get new group id. Cannot create group."); + Message(Chat::Red, "Unable to get new group id. Cannot create group."); + inviter->Message(Chat::Red, "Unable to get new group id. Cannot create group."); return false; } @@ -4924,7 +4924,7 @@ void Client::HandleLDoNOpen(NPC *target) { Log(Logs::General, Logs::None, "%s tried to open %s but %s was out of range", GetName(), target->GetName(), target->GetName()); - Message(13, "Treasure chest out of range."); + Message(Chat::Red, "Treasure chest out of range."); return; } @@ -4932,7 +4932,7 @@ void Client::HandleLDoNOpen(NPC *target) { if(target->GetLDoNTrapSpellID() != 0) { - Message_StringID(13, LDON_ACCIDENT_SETOFF2); + Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -4948,7 +4948,7 @@ void Client::HandleLDoNOpen(NPC *target) if(target->IsLDoNLocked()) { - Message_StringID(MT_Skills, LDON_STILL_LOCKED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_STILL_LOCKED, target->GetCleanName()); return; } else @@ -4982,13 +4982,13 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) { if((target->GetLDoNTrapType() == LDoNTypeCursed || target->GetLDoNTrapType() == LDoNTypeMagical) && type != target->GetLDoNTrapType()) { - Message_StringID(MT_Skills, LDON_CANT_DETERMINE_TRAP, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_CANT_DETERMINE_TRAP, target->GetCleanName()); return; } if(target->IsLDoNTrapDetected()) { - Message_StringID(MT_Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); } else { @@ -4997,10 +4997,10 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) { case -1: case 0: - Message_StringID(MT_Skills, LDON_DONT_KNOW_TRAPPED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_DONT_KNOW_TRAPPED, target->GetCleanName()); break; case 1: - Message_StringID(MT_Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); target->SetLDoNTrapDetected(true); break; default: @@ -5010,7 +5010,7 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) } else { - Message_StringID(MT_Skills, LDON_CERTAIN_NOT_TRAP, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_CERTAIN_NOT_TRAP, target->GetCleanName()); } } } @@ -5023,13 +5023,13 @@ void Client::HandleLDoNDisarm(NPC *target, uint16 skill, uint8 type) { if(!target->IsLDoNTrapped()) { - Message_StringID(MT_Skills, LDON_WAS_NOT_TRAPPED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_WAS_NOT_TRAPPED, target->GetCleanName()); return; } if((target->GetLDoNTrapType() == LDoNTypeCursed || target->GetLDoNTrapType() == LDoNTypeMagical) && type != target->GetLDoNTrapType()) { - Message_StringID(MT_Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); return; } @@ -5048,13 +5048,13 @@ void Client::HandleLDoNDisarm(NPC *target, uint16 skill, uint8 type) target->SetLDoNTrapDetected(false); target->SetLDoNTrapped(false); target->SetLDoNTrapSpellID(0); - Message_StringID(MT_Skills, LDON_HAVE_DISARMED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_HAVE_DISARMED, target->GetCleanName()); break; case 0: - Message_StringID(MT_Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); break; case -1: - Message_StringID(13, LDON_ACCIDENT_SETOFF2); + Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -5073,7 +5073,7 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) { if(target->IsLDoNTrapped()) { - Message_StringID(13, LDON_ACCIDENT_SETOFF2); + Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -5082,13 +5082,13 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) if(!target->IsLDoNLocked()) { - Message_StringID(MT_Skills, LDON_WAS_NOT_LOCKED, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_WAS_NOT_LOCKED, target->GetCleanName()); return; } if((target->GetLDoNTrapType() == LDoNTypeCursed || target->GetLDoNTrapType() == LDoNTypeMagical) && type != target->GetLDoNTrapType()) { - Message(MT_Skills, "You cannot unlock %s with this skill.", target->GetCleanName()); + Message(Chat::Skills, "You cannot unlock %s with this skill.", target->GetCleanName()); return; } @@ -5098,11 +5098,11 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) { case 0: case -1: - Message_StringID(MT_Skills, LDON_PICKLOCK_FAILURE, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_PICKLOCK_FAILURE, target->GetCleanName()); break; case 1: target->SetLDoNLocked(false); - Message_StringID(MT_Skills, LDON_PICKLOCK_SUCCESS, target->GetCleanName()); + Message_StringID(Chat::Skills, LDON_PICKLOCK_SUCCESS, target->GetCleanName()); break; } } @@ -5161,7 +5161,7 @@ void Client::SummonAndRezzAllCorpses() int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetPosition()); if(CorpseCount <= 0) { - Message(clientMessageYellow, "You have no corpses to summnon."); + Message(Chat::Yellow, "You have no corpses to summnon."); return; } @@ -5170,7 +5170,7 @@ void Client::SummonAndRezzAllCorpses() if(RezzExp > 0) SetEXP(GetEXP() + RezzExp, GetAAXP(), true); - Message(clientMessageYellow, "All your corpses have been summoned to your feet and have received a 100% resurrection."); + Message(Chat::Yellow, "All your corpses have been summoned to your feet and have received a 100% resurrection."); } void Client::SummonAllCorpses(const glm::vec4& position) @@ -5250,7 +5250,7 @@ void Client::SetStartZone(uint32 zoneid, float x, float y, float z) // setting city to zero allows the player to use /setstartcity to set the city themselves if(zoneid == 0) { m_pp.binds[4].zoneId = 0; - this->Message(15,"Your starting city has been reset. Use /setstartcity to choose a new one"); + this->Message(Chat::Yellow,"Your starting city has been reset. Use /setstartcity to choose a new one"); return; } @@ -5579,7 +5579,7 @@ void Client::SuspendMinion() if(m_suspendedminion.SpellID > 0) { if (m_suspendedminion.SpellID >= SPDAT_RECORDS) { - Message(13, "Invalid suspended minion spell id (%u).", m_suspendedminion.SpellID); + Message(Chat::Red, "Invalid suspended minion spell id (%u).", m_suspendedminion.SpellID); memset(&m_suspendedminion, 0, sizeof(PetInfo)); return; } @@ -5591,7 +5591,7 @@ void Client::SuspendMinion() if(!CurrentPet) { - Message(13, "Failed to recall suspended minion."); + Message(Chat::Red, "Failed to recall suspended minion."); return; } @@ -5607,7 +5607,7 @@ void Client::SuspendMinion() CurrentPet->SetMana(m_suspendedminion.Mana); - Message_StringID(clientMessageTell, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName()); + Message_StringID(Chat::Magenta, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName()); memset(&m_suspendedminion, 0, sizeof(struct PetInfo)); // TODO: These pet command states need to be synced ... @@ -5637,19 +5637,19 @@ void Client::SuspendMinion() { if(m_suspendedminion.SpellID > 0) { - Message_StringID(clientMessageError,ONLY_ONE_PET); + Message_StringID(Chat::Red,ONLY_ONE_PET); return; } else if(CurrentPet->IsEngaged()) { - Message_StringID(clientMessageError,SUSPEND_MINION_FIGHTING); + Message_StringID(Chat::Red,SUSPEND_MINION_FIGHTING); return; } else if(entity_list.Fighting(CurrentPet)) { - Message_StringID(clientMessageBlue,SUSPEND_MINION_HAS_AGGRO); + Message_StringID(Chat::Blue,SUSPEND_MINION_HAS_AGGRO); } else { @@ -5666,7 +5666,7 @@ void Client::SuspendMinion() else strn0cpy(m_suspendedminion.Name, CurrentPet->GetName(), 64); // Name stays even at rank 1 - Message_StringID(clientMessageTell, SUSPEND_MINION_SUSPEND, CurrentPet->GetCleanName()); + Message_StringID(Chat::Magenta, SUSPEND_MINION_SUSPEND, CurrentPet->GetCleanName()); CurrentPet->Depop(false); @@ -5675,7 +5675,7 @@ void Client::SuspendMinion() } else { - Message_StringID(clientMessageError, ONLY_SUMMONED_PETS); + Message_StringID(Chat::Red, ONLY_SUMMONED_PETS); return; } @@ -6149,16 +6149,16 @@ void Client::LocateCorpse() if(ClosestCorpse) { - Message_StringID(MT_Spells, SENSE_CORPSE_DIRECTION); + Message_StringID(Chat::Spells, SENSE_CORPSE_DIRECTION); SetHeading(CalculateHeadingToTarget(ClosestCorpse->GetX(), ClosestCorpse->GetY())); SetTarget(ClosestCorpse); SendTargetCommand(ClosestCorpse->GetID()); SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else if(!GetTarget()) - Message_StringID(clientMessageError, SENSE_CORPSE_NONE); + Message_StringID(Chat::Red, SENSE_CORPSE_NONE); else - Message_StringID(clientMessageError, SENSE_CORPSE_NOT_NAME); + Message_StringID(Chat::Red, SENSE_CORPSE_NOT_NAME); } void Client::NPCSpawn(NPC *target_npc, const char *identifier, uint32 extra) @@ -6218,7 +6218,7 @@ void Client::DragCorpses() if (!corpse || !corpse->IsPlayerCorpse() || corpse->CastToCorpse()->IsBeingLooted() || !corpse->CastToCorpse()->Summon(this, false, false)) { - Message_StringID(MT_DefaultText, CORPSEDRAG_STOP); + Message_StringID(Chat::DefaultText, CORPSEDRAG_STOP); It = DraggedCorpses.erase(It); if (It == DraggedCorpses.end()) break; @@ -6235,7 +6235,7 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record)) { Log(Logs::General, Logs::Error, "Unknown doppelganger spell id: %d, check pets table", spell_id); - Message(13, "Unable to find data for pet %s", spells[spell_id].teleport_zone); + Message(Chat::Red, "Unable to find data for pet %s", spells[spell_id].teleport_zone); return; } @@ -6850,11 +6850,11 @@ void Client::SendStatsWindow(Client* client, bool use_window) goto Extra_Info; } else { - client->Message(15, "The window has exceeded its character limit, displaying stats to chat window:"); + client->Message(Chat::Yellow, "The window has exceeded its character limit, displaying stats to chat window:"); } } - client->Message(15, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName()); + client->Message(Chat::Yellow, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName()); client->Message(0, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR()); client->Message(0, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap()); client->Message(0, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0)); @@ -7623,7 +7623,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID) { if (!(m_ClientVersionBit & EQEmu::versions::maskRoFAndLater)) { - Message_StringID(0, PICK_LORE); + Message_StringID(Chat::White, PICK_LORE); return; } @@ -7632,7 +7632,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID) if(!item) return; - Message_StringID(0, PICK_LORE, item->Name); + Message_StringID(Chat::White, PICK_LORE, item->Name); } void Client::GarbleMessage(char *message, uint8 variance) @@ -7796,7 +7796,7 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui UpdatePersonalFaction(char_id, npc_value[i], faction_id[i], ¤t_value, temp[i], this_faction_min, this_faction_max); - //Message(14, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); + //Message(Chat::Lime, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); SendFactionMessage(npc_value[i], faction_id[i], faction_before_hit, current_value, temp[i], this_faction_min, this_faction_max); } @@ -7839,7 +7839,7 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class UpdatePersonalFaction(char_id, value, faction_id, ¤t_value, temp, this_faction_min, this_faction_max); - //Message(14, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); + //Message(Chat::Lime, "Min(%d) Max(%d) Before(%d), After(%d)\n", this_faction_min, this_faction_max, faction_before_hit, current_value); SendFactionMessage(value, faction_id, faction_before_hit, current_value, temp, this_faction_min, this_faction_max); } @@ -8031,15 +8031,15 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ if (tmpvalue == 0 || temp == 1 || temp == 2) return; else if (faction_value >= this_faction_max) - Message_StringID(15, FACTION_BEST, name); + Message_StringID(Chat::Yellow, FACTION_BEST, name); else if (faction_value <= this_faction_min) - Message_StringID(15, FACTION_WORST, name); + Message_StringID(Chat::Yellow, FACTION_WORST, name); else if (tmpvalue > 0 && faction_value < this_faction_max && !RuleB(Client, UseLiveFactionMessage)) - Message_StringID(15, FACTION_BETTER, name); + Message_StringID(Chat::Yellow, FACTION_BETTER, name); else if (tmpvalue < 0 && faction_value > this_faction_min && !RuleB(Client, UseLiveFactionMessage)) - Message_StringID(15, FACTION_WORSE, name); + Message_StringID(Chat::Yellow, FACTION_WORSE, name); else if (RuleB(Client, UseLiveFactionMessage)) - Message(15, "Your faction standing with %s has been adjusted by %i.", name, tmpvalue); //New Live faction message (14261) + Message(Chat::Yellow, "Your faction standing with %s has been adjusted by %i.", name, tmpvalue); //New Live faction message (14261) return; } @@ -8428,7 +8428,7 @@ void Client::ExpeditionSay(const char *str, int ExpID) { return; if(results.RowCount() == 0) { - this->Message(14, "You say to the expedition, '%s'", str); + this->Message(Chat::Lime, "You say to the expedition, '%s'", str); return; } @@ -8531,7 +8531,7 @@ void Client::SendHPUpdateMarquee(){ return; std::string health_update_notification = StringFormat("Health: %u%%", health_percentage); - this->SendMarqueeMessage(15, 510, 0, 3000, 3000, health_update_notification); + this->SendMarqueeMessage(Chat::Yellow, 510, 0, 3000, 3000, health_update_notification); } uint32 Client::GetMoney(uint8 type, uint8 subtype) { @@ -9044,7 +9044,7 @@ void Client::SetPrimaryWeaponOrnamentation(uint32 model_id) SendItemPacket(EQEmu::invslot::slotPrimary, primary_item, ItemPacketTrade); WearChange(EQEmu::textures::weaponPrimary, static_cast(model_id), 0); - Message(15, "Your primary weapon appearance has been modified"); + Message(Chat::Yellow, "Your primary weapon appearance has been modified"); } } @@ -9067,7 +9067,7 @@ void Client::SetSecondaryWeaponOrnamentation(uint32 model_id) SendItemPacket(EQEmu::invslot::slotSecondary, secondary_item, ItemPacketTrade); WearChange(EQEmu::textures::weaponSecondary, static_cast(model_id), 0); - Message(15, "Your secondary weapon appearance has been modified"); + Message(Chat::Yellow, "Your secondary weapon appearance has been modified"); } } @@ -9107,7 +9107,7 @@ bool Client::GotoPlayer(std::string player_name) auto heading = static_cast(atof(row[5])); if (instance_id > 0 && !database.CheckInstanceExists(instance_id)) { - this->Message(15, "Instance no longer exists..."); + this->Message(Chat::Yellow, "Instance no longer exists..."); return false; } diff --git a/zone/client.h b/zone/client.h index 29632d667..c22f18419 100644 --- a/zone/client.h +++ b/zone/client.h @@ -90,23 +90,6 @@ public: bool ack_req; }; -enum { //Type arguments to the Message* routines. - //all not explicitly listed are the same grey color - clientMessageWhite0 = 0, - clientMessageLoot = 2, //dark green - clientMessageTradeskill = 4, //light blue - clientMessageTell = 5, //magenta - clientMessageWhite = 7, - clientMessageWhite2 = 10, - clientMessageLightGrey = 12, - clientMessageError = 13, //red - clientMessageGreen = 14, - clientMessageYellow = 15, - clientMessageBlue = 16, - clientMessageGroup = 18, //cyan - clientMessageWhite3 = 20, -}; - #define SPELLBAR_UNLOCK 0x2bc enum { //scribing argument to MemorizeSpell memSpellUnknown = -1, // this modifies some state data diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 2bd6ed1ac..cf0633033 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -541,7 +541,7 @@ void Client::CompleteConnect() //SendAATable(); - if (GetHideMe()) Message(13, "[GM] You are currently hidden to all clients"); + if (GetHideMe()) Message(Chat::Red, "[GM] You are currently hidden to all clients"); uint32 raidid = database.GetRaidID(GetName()); Raid *raid = nullptr; @@ -711,7 +711,7 @@ void Client::CompleteConnect() { SendAppearancePacket(AT_Levitate, 0); BuffFadeByEffect(SE_Levitate); - Message(13, "You can't levitate in this zone."); + Message(Chat::Red, "You can't levitate in this zone."); } } else { @@ -836,19 +836,19 @@ void Client::CompleteConnect() uint32 minute = (ttime / 60000) % 60; uint32 second = (ttime / 1000) % 60; if (day) { - Message(15, "%s(%u) will expire in %u days, %u hours, %u minutes, and %u seconds.", + Message(Chat::Yellow, "%s(%u) will expire in %u days, %u hours, %u minutes, and %u seconds.", zone->GetLongName(), zone->GetInstanceID(), day, hour, minute, second); } else if (hour) { - Message(15, "%s(%u) will expire in %u hours, %u minutes, and %u seconds.", + Message(Chat::Yellow, "%s(%u) will expire in %u hours, %u minutes, and %u seconds.", zone->GetLongName(), zone->GetInstanceID(), hour, minute, second); } else if (minute) { - Message(15, "%s(%u) will expire in %u minutes, and %u seconds.", + Message(Chat::Yellow, "%s(%u) will expire in %u minutes, and %u seconds.", zone->GetLongName(), zone->GetInstanceID(), minute, second); } else { - Message(15, "%s(%u) will expire in in %u seconds.", + Message(Chat::Yellow, "%s(%u) will expire in in %u seconds.", zone->GetLongName(), zone->GetInstanceID(), second); } } @@ -948,7 +948,7 @@ void Client::Handle_Connect_OP_ClientError(const EQApplicationPacket *app) ClientError_Struct* error = (ClientError_Struct*)app->pBuffer; Log(Logs::General, Logs::Error, "Client error: %s", error->character_name); Log(Logs::General, Logs::Error, "Error message: %s", error->message); - Message(13, error->message); + Message(Chat::Red, error->message); #if (EQDEBUG>=5) DumpPacket(app); #endif @@ -1752,14 +1752,14 @@ void Client::Handle_OP_AAAction(const EQApplicationPacket *app) } else if (action->action == aaActionDisableEXP) { //Turn Off AA Exp if (m_epp.perAA > 0) - Message_StringID(0, AA_OFF); + Message_StringID(Chat::White, AA_OFF); m_epp.perAA = 0; SendAlternateAdvancementStats(); } else if (action->action == aaActionSetEXP) { if (m_epp.perAA == 0) - Message_StringID(0, AA_ON); + Message_StringID(Chat::White, AA_ON); m_epp.perAA = action->exp_value; if (m_epp.perAA < 0 || m_epp.perAA > 100) m_epp.perAA = 0; // stop exploit with sanity check @@ -1897,14 +1897,14 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) } } if (!item || !found) { - Message(13, "Error: The item you purchased does not exist!"); + Message(Chat::Red, "Error: The item you purchased does not exist!"); return; } if (aps->Type == LDoNMerchant) { if (m_pp.ldon_points_available < int32(item->LDoNPrice)) { - Message(13, "You cannot afford that item."); + Message(Chat::Red, "You cannot afford that item."); return; } @@ -1914,7 +1914,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (m_pp.ldon_points_tak < int32(item->LDoNPrice)) { - Message(13, "You need at least %u points in tak to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u points in tak to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1922,7 +1922,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (m_pp.ldon_points_ruj < int32(item->LDoNPrice)) { - Message(13, "You need at least %u points in ruj to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u points in ruj to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1930,7 +1930,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (m_pp.ldon_points_mmc < int32(item->LDoNPrice)) { - Message(13, "You need at least %u points in mmc to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u points in mmc to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1938,7 +1938,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (m_pp.ldon_points_mir < int32(item->LDoNPrice)) { - Message(13, "You need at least %u points in mir to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u points in mir to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1946,7 +1946,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (m_pp.ldon_points_guk < int32(item->LDoNPrice)) { - Message(13, "You need at least %u points in guk to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u points in guk to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1956,7 +1956,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (GetPVPPoints() < item->LDoNPrice) { - Message(13, "You need at least %u PVP points to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u PVP points to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1964,7 +1964,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (GetRadiantCrystals() < item->LDoNPrice) { - Message(13, "You need at least %u Radiant Crystals to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u Radiant Crystals to purchase this item.", int32(item->LDoNPrice)); return; } } @@ -1972,20 +1972,20 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app) { if (GetEbonCrystals() < item->LDoNPrice) { - Message(13, "You need at least %u Ebon Crystals to purchase this item.", int32(item->LDoNPrice)); + Message(Chat::Red, "You need at least %u Ebon Crystals to purchase this item.", int32(item->LDoNPrice)); return; } } else { - Message(13, "Unknown Adventure Merchant type."); + Message(Chat::Red, "Unknown Adventure Merchant type."); return; } if (CheckLoreConflict(item)) { - Message(15, "You can only have one of a lore item."); + Message(Chat::Yellow, "You can only have one of a lore item."); return; } @@ -2128,13 +2128,13 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) if (vendor == 0 || !vendor->IsNPC() || ((vendor->GetClass() != ADVENTUREMERCHANT) && (vendor->GetClass() != NORRATHS_KEEPERS_MERCHANT) && (vendor->GetClass() != DARK_REIGN_MERCHANT))) { - Message(13, "Vendor was not found."); + Message(Chat::Red, "Vendor was not found."); return; } if (DistanceSquared(m_Position, vendor->GetPosition()) > USE_NPC_RANGE2) { - Message(13, "Vendor is out of range."); + Message(Chat::Red, "Vendor is out of range."); return; } @@ -2142,14 +2142,14 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) if (itemid == 0) { - Message(13, "Found no item at that slot."); + Message(Chat::Red, "Found no item at that slot."); return; } const EQEmu::ItemData* item = database.GetItem(itemid); EQEmu::ItemInstance* inst = GetInv().GetItem(ams_in->slot); if (!item || !inst) { - Message(13, "You seemed to have misplaced that item..."); + Message(Chat::Red, "You seemed to have misplaced that item..."); return; } @@ -2168,13 +2168,13 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) // that case here. if (item->LDoNSold == 0) { - Message(13, "The merchant does not want that item."); + Message(Chat::Red, "The merchant does not want that item."); return; } if (item->LDoNPrice == 0) { - Message(13, "The merchant does not want that item."); + Message(Chat::Red, "The merchant does not want that item."); return; } @@ -2183,7 +2183,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) if (price == 0) { - Message(13, "The merchant does not want that item."); + Message(Chat::Red, "The merchant does not want that item."); return; } @@ -2203,7 +2203,7 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app) if (ams_in->charges == 0) { - Message(13, "Charge mismatch error."); + Message(Chat::Red, "Charge mismatch error."); return; } @@ -2523,18 +2523,18 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) } if (!item || !found) { - Message(13, "Error: The item you purchased does not exist!"); + Message(Chat::Red, "Error: The item you purchased does not exist!"); return; } if (cost > current_currency) { - Message(13, "You cannot afford that item right now."); + Message(Chat::Red, "You cannot afford that item right now."); return; } if (CheckLoreConflict(item)) { - Message(15, "You can only have one of a lore item."); + Message(Chat::Yellow, "You can only have one of a lore item."); return; } @@ -2689,7 +2689,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) if (sell->charges == 0) { - Message(13, "Charge mismatch error."); + Message(Chat::Red, "Charge mismatch error."); return; } @@ -2834,7 +2834,7 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) if (poison->Proc.Level2 > GetLevel()) { // Poison is too high to apply. - Message_StringID(clientMessageTradeskill, POISON_TOO_HIGH); + Message_StringID(Chat::LightBlue, POISON_TOO_HIGH); } else if ((primary && primary->ItemType == EQEmu::item::ItemType1HPiercing) || @@ -2951,7 +2951,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if ((in_augment->container_slot < EQEmu::invslot::EQUIPMENT_BEGIN || in_augment->container_slot > EQEmu::invslot::GENERAL_END) && (in_augment->container_slot < EQEmu::invbag::GENERAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::invbag::GENERAL_BAGS_END)) { - Message(13, "The server does not allow augmentation actions from this slot."); + Message(Chat::Red, "The server does not allow augmentation actions from this slot."); auto cursor_item = m_inv[EQEmu::invslot::slotCursor]; auto augmented_item = m_inv[in_augment->container_slot]; SendItemPacket(EQEmu::invslot::slotCursor, cursor_item, ItemPacketCharInventory); @@ -2974,7 +2974,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (item_slot == INVALID_INDEX || solvent_slot == INVALID_INDEX) { - Message(13, "Error: Invalid Aug Index."); + Message(Chat::Red, "Error: Invalid Aug Index."); return; } @@ -2983,7 +2983,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!tobe_auged) { - Message(13, "Error: Invalid item passed for augmenting."); + Message(Chat::Red, "Error: Invalid item passed for augmenting."); return; } @@ -2996,7 +2996,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) old_aug = tobe_auged->GetAugment(in_augment->augment_index); if (!old_aug || old_aug->GetItem()->AugDistiller != 0) { Log(Logs::General, Logs::Error, "Player tried to safely remove an augment without a distiller."); - Message(13, "Error: Missing an augmentation distiller for safely removing this augment."); + Message(Chat::Red, "Error: Missing an augmentation distiller for safely removing this augment."); return; } } @@ -3007,20 +3007,20 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!old_aug) { Log(Logs::General, Logs::Error, "Player tried to safely remove a nonexistent augment."); - Message(13, "Error: No augment found in slot %i for safely removing.", in_augment->augment_index); + Message(Chat::Red, "Error: No augment found in slot %i for safely removing.", in_augment->augment_index); return; } else if (solvent->GetItem()->ID != old_aug->GetItem()->AugDistiller) { Log(Logs::General, Logs::Error, "Player tried to safely remove an augment with the wrong distiller (item %u vs expected %u).", solvent->GetItem()->ID, old_aug->GetItem()->AugDistiller); - Message(13, "Error: Wrong augmentation distiller for safely removing this augment."); + Message(Chat::Red, "Error: Wrong augmentation distiller for safely removing this augment."); return; } } else if (solvent->GetItem()->ItemType != EQEmu::item::ItemTypePerfectedAugmentationDistiller) { Log(Logs::General, Logs::Error, "Player tried to safely remove an augment with a non-distiller item."); - Message(13, "Error: Invalid augmentation distiller for safely removing this augment."); + Message(Chat::Red, "Error: Invalid augmentation distiller for safely removing this augment."); return; } } @@ -3034,7 +3034,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!new_aug) // Shouldn't get the OP code without the augment on the user's cursor, but maybe it's h4x. { Log(Logs::General, Logs::Error, "AugmentItem OpCode with 'Insert' or 'Swap' action received, but no augment on client's cursor."); - Message(13, "Error: No augment found on cursor for inserting."); + Message(Chat::Red, "Error: No augment found on cursor for inserting."); return; } else @@ -3073,7 +3073,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } else { - Message(13, "Error: Could not properly insert augmentation into augment slot %i. Aborting.", in_augment->augment_index); + Message(Chat::Red, "Error: Could not properly insert augmentation into augment slot %i. Aborting.", in_augment->augment_index); return; } @@ -3101,7 +3101,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!PutItemInInventory(EQEmu::invslot::slotCursor, *itemTwoToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning old augment to player's cursor after augmentation swap."); - Message(15, "Error: Failed to retrieve old augment after augmentation swap!"); + Message(Chat::Yellow, "Error: Failed to retrieve old augment after augmentation swap!"); } } @@ -3118,17 +3118,17 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } else { - Message(13, "Error: No available slot for end result. Please free up the augment slot."); + Message(Chat::Red, "Error: No available slot for end result. Please free up the augment slot."); } } else { - Message(13, "Error in cloning item for augment. Aborted."); + Message(Chat::Red, "Error in cloning item for augment. Aborted."); } } else { - Message(13, "Error: No available slot for augment in that item."); + Message(Chat::Red, "Error: No available slot for augment in that item."); } } break; @@ -3148,7 +3148,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } else { - Message(13, "Error: Could not find augmentation to remove at index %i. Aborting.", in_augment->augment_index); + Message(Chat::Red, "Error: Could not find augmentation to remove at index %i. Aborting.", in_augment->augment_index); return; } @@ -3172,7 +3172,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!PutItemInInventory(item_slot, *itemOneToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning equipment item to player's inventory after safe augment removal."); - Message(15, "Error: Failed to return item after de-augmentation!"); + Message(Chat::Yellow, "Error: Failed to return item after de-augmentation!"); } CalcBonuses(); @@ -3186,7 +3186,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!PutItemInInventory(EQEmu::invslot::slotCursor, *itemTwoToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning augment to player's cursor after safe removal."); - Message(15, "Error: Failed to return augment after removal from item!"); + Message(Chat::Yellow, "Error: Failed to return augment after removal from item!"); return; } } @@ -3211,7 +3211,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) } else { - Message(13, "Error: Could not find augmentation to remove at index %i. Aborting."); + Message(Chat::Red, "Error: Could not find augmentation to remove at index %i. Aborting."); return; } @@ -3226,7 +3226,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app) if (!PutItemInInventory(item_slot, *itemOneToPush, true)) { Log(Logs::General, Logs::Error, "Problem returning equipment item to player's inventory after augment deletion."); - Message(15, "Error: Failed to return item after destroying augment!"); + Message(Chat::Yellow, "Error: Failed to return item after destroying augment!"); } } @@ -3470,7 +3470,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) else { Buf = (char *)app->pBuffer; VARSTRUCT_ENCODE_TYPE(uint32, Buf, Barter_BuyerModeOff); - Message(13, "You cannot be a Trader and Buyer at the same time."); + Message(Chat::Red, "You cannot be a Trader and Buyer at the same time."); } QueuePacket(app); break; @@ -3526,7 +3526,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) const EQEmu::ItemData* item = database.GetItem(bislr->ItemID); if (!item) - Message(13, "Error: This item does not exist!"); + Message(Chat::Red, "Error: This item does not exist!"); else { EQEmu::ItemInstance* inst = database.CreateItem(item); @@ -3559,7 +3559,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) const EQEmu::ItemData* item = database.GetItem(bislr->ItemID); if (!item) - Message(13, "Error: This item does not exist!"); + Message(Chat::Red, "Error: This item does not exist!"); else { EQEmu::ItemInstance* inst = database.CreateItem(item); @@ -3579,7 +3579,7 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app) } default: - Message(13, "Unrecognised Barter action."); + Message(Chat::Red, "Unrecognised Barter action."); Log(Logs::Detail, Logs::Trading, "Unrecognised Barter Action %i", Action); } @@ -3598,7 +3598,7 @@ void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app) const EQEmu::ItemData* item = database.GetItem(bis->ItemID); if (!item) { - Message(13, "Error: This item does not exist!"); + Message(Chat::Red, "Error: This item does not exist!"); return; } @@ -3653,7 +3653,7 @@ void Client::Handle_OP_Begging(const EQApplicationPacket *app) { if (!p_timers.Expired(&database, pTimerBeggingPickPocket, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); auto outapp = new EQApplicationPacket(OP_Begging, sizeof(BeggingResponse_Struct)); BeggingResponse_Struct *brs = (BeggingResponse_Struct*)outapp->pBuffer; @@ -4023,8 +4023,8 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) return; } if (IsAIControlled()) { - this->Message_StringID(13, NOT_IN_CONTROL); - //Message(13, "You cant cast right now, you arent in control of yourself!"); + this->Message_StringID(Chat::Red, NOT_IN_CONTROL); + //Message(Chat::Red, "You cant cast right now, you arent in control of yourself!"); return; } @@ -4139,7 +4139,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) if (castspell->spell_id == SPELL_LAY_ON_HANDS && GetClass() == PALADIN) { if (!p_timers.Expired(&database, pTimerLayHands)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); InterruptSpell(castspell->spell_id); return; } @@ -4149,7 +4149,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) else if ((castspell->spell_id == SPELL_HARM_TOUCH || castspell->spell_id == SPELL_HARM_TOUCH2) && GetClass() == SHADOWKNIGHT) { if (!p_timers.Expired(&database, pTimerHarmTouch)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); InterruptSpell(castspell->spell_id); return; } @@ -4178,7 +4178,7 @@ void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app) return; } if (IsAIControlled()) { - Message(13, "You try to speak but cant move your mouth!"); + Message(Chat::Red, "You try to speak but cant move your mouth!"); return; } @@ -4625,7 +4625,7 @@ void Client::Handle_OP_Consent(const EQApplicationPacket *app) safe_delete(pack); } else { - Message_StringID(0, CONSENT_YOURSELF); + Message_StringID(Chat::White, CONSENT_YOURSELF); } } return; @@ -4664,7 +4664,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) if (tmob->GetClass() == LDON_TREASURE) { - Message(15, "%s", tmob->GetCleanName()); + Message(Chat::Yellow, "%s", tmob->GetCleanName()); return; } @@ -4765,10 +4765,10 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) // this could be done better, but this is only called when you con so w/e // Shroud of Stealth has a special message if (improved_hidden && (!tmob->see_improved_hide && (tmob->see_invis || tmob->see_hide))) - Message_StringID(10, SOS_KEEPS_HIDDEN); + Message_StringID(Chat::NPCQuestSay, SOS_KEEPS_HIDDEN); // we are trying to hide but they can see us else if ((invisible || invisible_undead || hidden || invisible_animals) && !IsInvisible(tmob)) - Message_StringID(10, SUSPECT_SEES_YOU); + Message_StringID(Chat::NPCQuestSay, SUSPECT_SEES_YOU); safe_delete(outapp); @@ -4791,10 +4791,10 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) min = (ttime / 60000) % 60; // Total seconds / 60 drop .00 char val1[20] = { 0 }; char val2[20] = { 0 }; - Message_StringID(10, CORPSE_DECAY1, ConvertArray(min, val1), ConvertArray(sec, val2)); + Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY1, ConvertArray(min, val1), ConvertArray(sec, val2)); } else { - Message_StringID(10, CORPSE_DECAY_NOW); + Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY_NOW); } } else if (tcorpse && tcorpse->IsPlayerCorpse()) { @@ -4825,12 +4825,12 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) Message(0, "This corpse can be resurrected for %i minutes and %i seconds.", min, sec); } else { - Message_StringID(0, CORPSE_TOO_OLD); + Message_StringID(Chat::WhiteSmoke, CORPSE_TOO_OLD); } */ } else { - Message_StringID(10, CORPSE_DECAY_NOW); + Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY_NOW); } } } @@ -4932,7 +4932,7 @@ void Client::Handle_OP_ControlBoat(const EQApplicationPacket *app) boat->SetTarget(this); } else { - this->Message_StringID(13, IN_USE); + this->Message_StringID(Chat::Red, IN_USE); return; } } @@ -4950,7 +4950,7 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) { if (DraggedCorpses.size() >= (unsigned int)RuleI(Character, MaxDraggedCorpses)) { - Message_StringID(13, CORPSEDRAG_LIMIT); + Message_StringID(Chat::Red, CORPSEDRAG_LIMIT); return; } @@ -4968,9 +4968,9 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) if (c) { if (c == this) - Message_StringID(MT_DefaultText, CORPSEDRAG_ALREADY, corpse->GetCleanName()); + Message_StringID(Chat::DefaultText, CORPSEDRAG_ALREADY, corpse->GetCleanName()); else - Message_StringID(MT_DefaultText, CORPSEDRAG_SOMEONE_ELSE, corpse->GetCleanName()); + Message_StringID(Chat::DefaultText, CORPSEDRAG_SOMEONE_ELSE, corpse->GetCleanName()); return; } @@ -4980,14 +4980,14 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) DraggedCorpses.push_back(std::pair(cds->CorpseName, corpse->GetID())); - Message_StringID(MT_DefaultText, CORPSEDRAG_BEGIN, cds->CorpseName); + Message_StringID(Chat::DefaultText, CORPSEDRAG_BEGIN, cds->CorpseName); } void Client::Handle_OP_CorpseDrop(const EQApplicationPacket *app) { if (app->size == 1) { - Message_StringID(MT_DefaultText, CORPSEDRAG_STOPALL); + Message_StringID(Chat::DefaultText, CORPSEDRAG_STOPALL); ClearDraggedCorpses(); return; } @@ -4996,7 +4996,7 @@ void Client::Handle_OP_CorpseDrop(const EQApplicationPacket *app) { if (!strcasecmp(Iterator->first.c_str(), (const char *)app->pBuffer)) { - Message_StringID(MT_DefaultText, CORPSEDRAG_STOP); + Message_StringID(Chat::DefaultText, CORPSEDRAG_STOP); Iterator = DraggedCorpses.erase(Iterator); return; } @@ -5227,7 +5227,7 @@ void Client::Handle_OP_Disarm(const EQApplicationPacket *app) { Disarm_Struct *disarm = (Disarm_Struct *)app->pBuffer; if (!p_timers.Expired(&database, pTimerCombatAbility2, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -5300,7 +5300,7 @@ void Client::Handle_OP_Disarm(const EQApplicationPacket *app) { return; } // Trying to disarm something we can't disarm - Message_StringID(MT_Skills, DISARM_NO_TARGET); + Message_StringID(Chat::Skills, DISARM_NO_TARGET); return; } @@ -5334,7 +5334,7 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app) return; if (!p_timers.Expired(&database, pTimerDisarmTraps, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -5358,14 +5358,14 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app) if ((zone->random.Int(0, 49) + uskill) >= (zone->random.Int(0, 49) + trap->skill)) { success = SKILLUP_SUCCESS; - Message_StringID(MT_Skills, DISARMED_TRAP); + Message_StringID(Chat::Skills, DISARMED_TRAP); trap->disarmed = true; Log(Logs::General, Logs::Traps, "Trap %d is disarmed.", trap->trap_id); trap->UpdateTrap(); } else { - Message_StringID(MT_Skills, FAIL_DISARM_DETECTED_TRAP); + Message_StringID(Chat::Skills, FAIL_DISARM_DETECTED_TRAP); if (zone->random.Int(0, 99) < 25) { trap->Trigger(this); } @@ -5375,12 +5375,12 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app) } else { - Message_StringID(MT_Skills, TRAP_TOO_FAR); + Message_StringID(Chat::Skills, TRAP_TOO_FAR); } } else { - Message_StringID(MT_Skills, LDON_SENSE_TRAP2); + Message_StringID(Chat::Skills, LDON_SENSE_TRAP2); } return; @@ -5464,9 +5464,9 @@ void Client::Handle_OP_DuelResponse(const EQApplicationPacket *app) initiator->CastToClient()->SetDuelTarget(0); initiator->CastToClient()->SetDueling(false); if (GetID() == initiator->GetID()) - entity->CastToClient()->Message_StringID(10, DUEL_DECLINE, initiator->GetName()); + entity->CastToClient()->Message_StringID(Chat::NPCQuestSay, DUEL_DECLINE, initiator->GetName()); else - initiator->CastToClient()->Message_StringID(10, DUEL_DECLINE, entity->GetName()); + initiator->CastToClient()->Message_StringID(Chat::NPCQuestSay, DUEL_DECLINE, entity->GetName()); return; } @@ -5589,7 +5589,7 @@ void Client::Handle_OP_EndLootRequest(const EQApplicationPacket *app) Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer)); if (entity == 0) { - Message(13, "Error: OP_EndLootRequest: Corpse not found (ent = 0)"); + Message(Chat::Red, "Error: OP_EndLootRequest: Corpse not found (ent = 0)"); if (ClientVersion() >= EQEmu::versions::ClientVersion::SoD) Corpse::SendEndLootErrorPacket(this); else @@ -5597,7 +5597,7 @@ void Client::Handle_OP_EndLootRequest(const EQApplicationPacket *app) return; } else if (!entity->IsCorpse()) { - Message(13, "Error: OP_EndLootRequest: Corpse not found (!entity->IsCorpse())"); + Message(Chat::Red, "Error: OP_EndLootRequest: Corpse not found (!entity->IsCorpse())"); Corpse::SendLootReqErrorPacket(this); return; } @@ -5636,12 +5636,12 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app) damage = 31337; if (admin >= minStatusToAvoidFalling && GetGM()) { - Message(13, "Your GM status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); + Message(Chat::Red, "Your GM status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); SetHP(GetHP() - 1);//needed or else the client wont acknowledge return; } else if (GetInvul()) { - Message(13, "Your invuln status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); + Message(Chat::Red, "Your invuln status protects you from %i points of type %i environmental damage.", ed->damage, ed->dmgtype); SetHP(GetHP() - 1);//needed or else the client wont acknowledge return; } @@ -5690,8 +5690,8 @@ void Client::Handle_OP_FaceChange(const EQApplicationPacket *app) m_pp.drakkin_tattoo = fc->drakkin_tattoo; m_pp.drakkin_details = fc->drakkin_details; Save(); - Message_StringID(13, FACE_ACCEPTED); - //Message(13, "Facial features updated."); + Message_StringID(Chat::Red, FACE_ACCEPTED); + //Message(Chat::Red, "Facial features updated."); return; } @@ -5700,7 +5700,7 @@ void Client::Handle_OP_FeignDeath(const EQApplicationPacket *app) if (GetClass() != MONK) return; if (!p_timers.Expired(&database, pTimerFeignDeath, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -5756,7 +5756,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app) if (!RuleB(Pathing, Find) && RuleB(Bazaar, EnableWarpToTrader) && target->IsClient() && (target->CastToClient()->Trader || target->CastToClient()->Buyer)) { - Message(15, "Moving you to Trader %s", target->GetName()); + Message(Chat::Yellow, "Moving you to Trader %s", target->GetName()); MovePC(zone->GetZoneID(), zone->GetInstanceID(), target->GetX(), target->GetY(), target->GetZ(), 0.0f); } @@ -5849,7 +5849,7 @@ void Client::Handle_OP_FindPersonRequest(const EQApplicationPacket *app) void Client::Handle_OP_Fishing(const EQApplicationPacket *app) { if (!p_timers.Expired(&database, pTimerFishing, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -5869,7 +5869,7 @@ void Client::Handle_OP_Forage(const EQApplicationPacket *app) { if (!p_timers.Expired(&database, pTimerForaging, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } p_timers.Start(pTimerForaging, ForagingReuseTime - 1); @@ -5909,7 +5909,7 @@ void Client::Handle_OP_GetGuildsList(const EQApplicationPacket *app) void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app) { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/becomenpc"); return; } @@ -5929,7 +5929,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app) cli->SendAppearancePacket(AT_NPCName, 1, true); cli->CastToClient()->SetBecomeNPC(true); cli->CastToClient()->SetBecomeNPCLevel(bnpc->maxlevel); - cli->Message_StringID(0, TOGGLE_OFF); + cli->Message_StringID(Chat::White, TOGGLE_OFF); cli->CastToClient()->tellsoff = true; //TODO: Make this toggle a BecomeNPC flag so that it gets updated when people zone in as well; Make combat work with this. return; @@ -5940,7 +5940,7 @@ void Client::Handle_OP_GMDelCorpse(const EQApplicationPacket *app) if (app->size != sizeof(GMDelCorpse_Struct)) return; if (this->Admin() < commandEditPlayerCorpses) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/delcorpse"); return; } @@ -5954,14 +5954,14 @@ void Client::Handle_OP_GMDelCorpse(const EQApplicationPacket *app) } corpse->CastToCorpse()->Delete(); std::cout << name << " deleted corpse " << dc->corpsename << std::endl; - Message(13, "Corpse %s deleted.", dc->corpsename); + Message(Chat::Red, "Corpse %s deleted.", dc->corpsename); return; } void Client::Handle_OP_GMEmoteZone(const EQApplicationPacket *app) { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/emote"); return; } @@ -5994,7 +5994,7 @@ void Client::Handle_OP_GMEndTraining(const EQApplicationPacket *app) void Client::Handle_OP_GMFind(const EQApplicationPacket *app) { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/find"); return; } @@ -6032,7 +6032,7 @@ void Client::Handle_OP_GMGoto(const EQApplicationPacket *app) return; } if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/goto"); return; } @@ -6059,7 +6059,7 @@ void Client::Handle_OP_GMGoto(const EQApplicationPacket *app) void Client::Handle_OP_GMHideMe(const EQApplicationPacket *app) { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/hideme"); return; } @@ -6068,7 +6068,7 @@ void Client::Handle_OP_GMHideMe(const EQApplicationPacket *app) return; } SpawnAppearance_Struct* sa = (SpawnAppearance_Struct*)app->pBuffer; - Message(13, "#: %i, %i", sa->type, sa->parameter); + Message(Chat::Red, "#: %i, %i", sa->type, sa->parameter); SetHideMe(!sa->parameter); return; @@ -6079,7 +6079,7 @@ void Client::Handle_OP_GMKick(const EQApplicationPacket *app) if (app->size != sizeof(GMKick_Struct)) return; if (this->Admin() < minStatusToKick) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/kick"); return; } @@ -6109,7 +6109,7 @@ void Client::Handle_OP_GMKick(const EQApplicationPacket *app) void Client::Handle_OP_GMKill(const EQApplicationPacket *app) { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/kill"); return; } @@ -6152,16 +6152,16 @@ void Client::Handle_OP_GMLastName(const EQApplicationPacket *app) } GMLastName_Struct* gmln = (GMLastName_Struct*)app->pBuffer; if (strlen(gmln->lastname) >= 64) { - Message(13, "/LastName: New last name too long. (max=63)"); + Message(Chat::Red, "/LastName: New last name too long. (max=63)"); } else { Client* client = entity_list.GetClientByName(gmln->name); if (client == 0) { - Message(13, "/LastName: %s not found", gmln->name); + Message(Chat::Red, "/LastName: %s not found", gmln->name); } else { if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(client->account_name, client->name, "/lastname"); return; } @@ -6186,7 +6186,7 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app) } const GMName_Struct* gmn = (const GMName_Struct *)app->pBuffer; if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/name"); return; } @@ -6194,15 +6194,15 @@ void Client::Handle_OP_GMNameChange(const EQApplicationPacket *app) Log(Logs::General, Logs::Status, "GM(%s) changeing players name. Old:%s New:%s", GetName(), gmn->oldname, gmn->newname); bool usedname = database.CheckUsedName((const char*)gmn->newname); if (client == 0) { - Message(13, "%s not found for name change. Operation failed!", gmn->oldname); + Message(Chat::Red, "%s not found for name change. Operation failed!", gmn->oldname); return; } if ((strlen(gmn->newname) > 63) || (strlen(gmn->newname) == 0)) { - Message(13, "Invalid number of characters in new name (%s).", gmn->newname); + Message(Chat::Red, "Invalid number of characters in new name (%s).", gmn->newname); return; } if (!usedname) { - Message(13, "%s is already in use. Operation failed!", gmn->newname); + Message(Chat::Red, "%s is already in use. Operation failed!", gmn->newname); return; } @@ -6258,9 +6258,9 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) return; if (results.RowCount() == maxResults) - Message(clientMessageError, "Your search found too many results; some are not displayed."); + Message(Chat::Red, "Your search found too many results; some are not displayed."); else - Message(clientMessageYellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); + Message(Chat::Yellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); char charName[64], time_of_death[20]; @@ -6287,7 +6287,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); if (popupText.size() > 4000) { - Message(clientMessageError, "Unable to display all the results."); + Message(Chat::Red, "Unable to display all the results."); break; } @@ -6330,19 +6330,19 @@ void Client::Handle_OP_GMToggle(const EQApplicationPacket *app) return; } if (this->Admin() < minStatusToUseGMCommands) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/toggle"); return; } GMToggle_Struct *ts = (GMToggle_Struct *)app->pBuffer; if (ts->toggle == 0) { - this->Message_StringID(0, TOGGLE_OFF); + this->Message_StringID(Chat::White, TOGGLE_OFF); //Message(0, "Turning tells OFF"); tellsoff = true; } else if (ts->toggle == 1) { //Message(0, "Turning tells ON"); - this->Message_StringID(0, TOGGLE_ON); + this->Message_StringID(Chat::White, TOGGLE_ON); tellsoff = false; } else { @@ -6381,7 +6381,7 @@ void Client::Handle_OP_GMZoneRequest(const EQApplicationPacket *app) return; } if (this->Admin() < minStatusToBeGM) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/zone"); return; } @@ -6429,7 +6429,7 @@ void Client::Handle_OP_GMZoneRequest(const EQApplicationPacket *app) void Client::Handle_OP_GMZoneRequest2(const EQApplicationPacket *app) { if (this->Admin() < minStatusToBeGM) { - Message(13, "Your account has been reported for hacking."); + Message(Chat::Red, "Your account has been reported for hacking."); database.SetHackerFlag(this->account_name, this->name, "/zone"); return; } @@ -6736,7 +6736,7 @@ void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app) if (Invitee == this) { - Message_StringID(clientMessageWhite, GROUP_INVITEE_SELF); + Message_StringID(Chat::LightGray, GROUP_INVITEE_SELF); return; } @@ -6928,7 +6928,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if ((int)zone->GetZoneID() != RuleI(World, GuildBankZoneID)) { - Message(13, "The Guild Bank is not available in this zone."); + Message(Chat::Red, "The Guild Bank is not available in this zone."); return; } @@ -6946,7 +6946,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (!IsInAGuild()) { - Message(13, "You must be in a Guild to use the Guild Bank."); + Message(Chat::Red, "You must be in a Guild to use the Guild Bank."); if (Action == GuildBankDeposit) GuildBankDepositAck(true, sentAction); @@ -6974,7 +6974,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GuildBanks->IsAreaFull(GuildID(), GuildBankMainArea)) { - Message_StringID(13, GUILD_BANK_FULL); + Message_StringID(Chat::Red, GUILD_BANK_FULL); GuildBankDepositAck(true, sentAction); @@ -6991,12 +6991,12 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (inst) { - Message_StringID(clientMessageWhite, GUILD_BANK_TRANSFERRED, inst->GetItem()->Name); + Message_StringID(Chat::LightGray, GUILD_BANK_TRANSFERRED, inst->GetItem()->Name); safe_delete(inst); } } else - Message(13, "Unexpected error while moving item into Guild Bank."); + Message(Chat::Red, "Unexpected error while moving item into Guild Bank."); GuildBankAck(); @@ -7023,7 +7023,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GuildBanks->IsAreaFull(GuildID(), GuildBankDepositArea)) { - Message_StringID(13, GUILD_BANK_FULL); + Message_StringID(Chat::Red, GUILD_BANK_FULL); GuildBankDepositAck(true, sentAction); @@ -7036,7 +7036,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (!CursorItemInst) { - Message(13, "No Item on the cursor."); + Message(Chat::Red, "No Item on the cursor."); GuildBankDepositAck(true, sentAction); @@ -7068,7 +7068,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (!Allowed) { - Message_StringID(13, GUILD_BANK_CANNOT_DEPOSIT); + Message_StringID(Chat::Red, GUILD_BANK_CANNOT_DEPOSIT); GuildBankDepositAck(true, sentAction); return; @@ -7101,7 +7101,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GetInv()[EQEmu::invslot::slotCursor]) { - Message_StringID(13, GUILD_BANK_EMPTY_HANDS); + Message_StringID(Chat::Red, GUILD_BANK_EMPTY_HANDS); GuildBankAck(); @@ -7132,7 +7132,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (CheckLoreConflict(inst->GetItem())) { - Message_StringID(13, DUP_LORE); + Message_StringID(Chat::Red, DUP_LORE); GuildBankAck(); @@ -7164,7 +7164,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) case GuildBankSplitStacks: { if (GuildBanks->IsAreaFull(GuildID(), GuildBankMainArea)) - Message_StringID(13, GUILD_BANK_FULL); + Message_StringID(Chat::Red, GUILD_BANK_FULL); else { GuildBankWithdrawItem_Struct *gbwis = (GuildBankWithdrawItem_Struct*)app->pBuffer; @@ -7190,7 +7190,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) default: { - Message(13, "Unexpected GuildBank action."); + Message(Chat::Red, "Unexpected GuildBank action."); Log(Logs::General, Logs::Error, "Received unexpected guild bank action code %i from %s", Action, GetName()); } @@ -7201,13 +7201,13 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) { if (IsInAGuild()) { - Message(clientMessageError, "You are already in a guild!"); + Message(Chat::Red, "You are already in a guild!"); return; } if (!RuleB(Guild, PlayerCreationAllowed)) { - Message(clientMessageError, "This feature is disabled on this server. Contact a GM or post on your server message boards to create a guild."); + Message(Chat::Red, "This feature is disabled on this server. Contact a GM or post on your server message boards to create a guild."); return; } @@ -7215,7 +7215,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) (GetLevel() < RuleI(Guild, PlayerCreationRequiredLevel)) || (database.GetTotalTimeEntitledOnAccount(AccountID()) < (unsigned int)RuleI(Guild, PlayerCreationRequiredTime))) { - Message(clientMessageError, "Your status, level or time playing on this account are insufficient to use this feature."); + Message(Chat::Red, "Your status, level or time playing on this account are insufficient to use this feature."); return; } @@ -7234,7 +7234,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) if (strnlen(GuildName, 64) > 60) #endif // DARWIN { - Message(clientMessageError, "Guild name too long."); + Message(Chat::Red, "Guild name too long."); return; } @@ -7242,7 +7242,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) { if (!isalpha(GuildName[i]) && (GuildName[i] != ' ')) { - Message(clientMessageError, "Invalid character in Guild name."); + Message(Chat::Red, "Invalid character in Guild name."); return; } } @@ -7251,13 +7251,13 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) if (GuildCount >= RuleI(Guild, PlayerCreationLimit)) { - Message(clientMessageError, "You cannot create this guild because this account may only be leader of %i guilds.", RuleI(Guild, PlayerCreationLimit)); + Message(Chat::Red, "You cannot create this guild because this account may only be leader of %i guilds.", RuleI(Guild, PlayerCreationLimit)); return; } if (guild_mgr.GetGuildIDByName(GuildName) != GUILD_NONE) { - Message_StringID(clientMessageError, GUILD_NAME_IN_USE); + Message_StringID(Chat::Red, GUILD_NAME_IN_USE); return; } @@ -7267,14 +7267,14 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) GuildName, CharacterID(), (unsigned long)NewGuildID); if (NewGuildID == GUILD_NONE) - Message(clientMessageError, "Guild creation failed."); + Message(Chat::Red, "Guild creation failed."); else { if (!guild_mgr.SetGuild(CharacterID(), NewGuildID, GUILD_LEADER)) - Message(clientMessageError, "Unable to set guild leader's guild in the database. Contact a GM."); + Message(Chat::Red, "Unable to set guild leader's guild in the database. Contact a GM."); else { - Message(clientMessageYellow, "You are now the leader of %s", GuildName); + Message(Chat::Yellow, "You are now the leader of %s", GuildName); if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) GuildBanks->SendGuildBank(this); @@ -7341,7 +7341,7 @@ void Client::Handle_OP_GuildDemote(const EQApplicationPacket *app) guild_mgr.GetGuildName(GuildID()), GuildID()); if (!guild_mgr.SetGuildRank(gci.char_id, rank)) { - Message(13, "Error while setting rank %d on '%s'.", rank, demote->target); + Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, demote->target); return; } Message(0, "Successfully demoted %s to rank %d", demote->target, rank); @@ -7364,7 +7364,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) if (!IsInAGuild()) Message(0, "Error: You are not in a guild!"); else if (gc->officer > GUILD_MAX_RANK) - Message(13, "Invalid rank."); + Message(Chat::Red, "Invalid rank."); else if (!worldserver.Connected()) Message(0, "Error: World server disconnected"); else { @@ -7373,7 +7373,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) Mob* invitee = entity_list.GetMob(gc->othername); if (!invitee) { - Message(13, "Prospective guild member %s must be in zone to preform guild operations on them.", gc->othername); + Message(Chat::Red, "Prospective guild member %s must be in zone to preform guild operations on them.", gc->othername); return; } @@ -7386,7 +7386,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) if (gc->officer < client->GuildRank()) { //demotion if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_DEMOTE)) { - Message(13, "You dont have permission to demote."); + Message(Chat::Red, "You dont have permission to demote."); return; } @@ -7400,7 +7400,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) guild_mgr.GetGuildName(GuildID()), GuildID()); if (!guild_mgr.SetGuildRank(client->CharacterID(), gc->officer)) { - Message(13, "There was an error during the demotion, DB may now be inconsistent."); + Message(Chat::Red, "There was an error during the demotion, DB may now be inconsistent."); return; } @@ -7408,7 +7408,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) else if (gc->officer > client->GuildRank()) { //promotion if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_PROMOTE)) { - Message(13, "You dont have permission to demote."); + Message(Chat::Red, "You dont have permission to demote."); return; } @@ -7429,7 +7429,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) } else { - Message(13, "That member is already that rank."); + Message(Chat::Red, "That member is already that rank."); return; } } @@ -7438,12 +7438,12 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) // if (client->GetPendingGuildInvitation()) { - Message(13, "That person is already considering a guild invitation."); + Message(Chat::Red, "That person is already considering a guild invitation."); return; } if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_INVITE)) { - Message(13, "You dont have permission to invite."); + Message(Chat::Red, "You dont have permission to invite."); return; } @@ -7474,7 +7474,7 @@ void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app) } else { //they are in some other guild - Message(13, "Player is in a guild."); + Message(Chat::Red, "Player is in a guild."); return; } } @@ -7551,7 +7551,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) //it has been authorized with the guild manager if (!guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, guildrank)) { worldserver.SendEmoteMessage(gj->inviter, 0, 0, "%s has sent an invalid response to your invite!", GetName()); - Message(13, "Invalid invite response packet!"); + Message(Chat::Red, "Invalid invite response packet!"); return; } @@ -7564,7 +7564,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) guild_mgr.GetGuildName(GuildID()), GuildID()); if (!guild_mgr.SetGuildRank(CharacterID(), gj->response)) { - Message(13, "There was an error during the rank change, DB may now be inconsistent."); + Message(Chat::Red, "There was an error during the rank change, DB may now be inconsistent."); return; } } @@ -7588,7 +7588,7 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app) } if (!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, guildrank)) { - Message(13, "There was an error during the invite, DB may now be inconsistent."); + Message(Chat::Red, "There was an error during the invite, DB may now be inconsistent."); return; } if (zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks) @@ -7627,7 +7627,7 @@ void Client::Handle_OP_GuildLeader(const EQApplicationPacket *app) if (guild_mgr.SetGuildLeader(GuildID(), newleader->CharacterID())) { Message(0, "Successfully Transfered Leadership to %s.", gml->target); - newleader->Message(15, "%s has transfered the guild leadership into your hands.", GetName()); + newleader->Message(Chat::Yellow, "%s has transfered the guild leadership into your hands.", GetName()); } else Message(0, "Could not change leadership at this time."); @@ -7650,7 +7650,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app) GuildManageBanker_Struct* gmb = (GuildManageBanker_Struct*)app->pBuffer; if (!IsInAGuild()) { - Message(13, "Your not in a guild!"); + Message(Chat::Red, "Your not in a guild!"); return; } @@ -7671,7 +7671,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app) if ((IsCurrentlyABanker != NewBankerStatus) && !guild_mgr.IsGuildLeader(GuildID(), CharacterID())) { - Message(13, "Only the guild leader can assign guild bankers!"); + Message(Chat::Red, "Only the guild leader can assign guild bankers!"); return; } @@ -7681,7 +7681,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app) if (!IsAllowed) { - Message(13, "You are not allowed to change the alt status of %s", gmb->member); + Message(Chat::Red, "You are not allowed to change the alt status of %s", gmb->member); return; } } @@ -7694,7 +7694,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app) if (IsCurrentlyABanker != NewBankerStatus) { if (!guild_mgr.SetBankerFlag(gci.char_id, NewBankerStatus)) { - Message(13, "Error setting guild banker flag."); + Message(Chat::Red, "Error setting guild banker flag."); return; } @@ -7706,7 +7706,7 @@ void Client::Handle_OP_GuildManageBanker(const EQApplicationPacket *app) if (IsCurrentlyAnAlt != NewAltStatus) { if (!guild_mgr.SetAltFlag(gci.char_id, NewAltStatus)) { - Message(13, "Error setting guild alt flag."); + Message(Chat::Red, "Error setting guild alt flag."); return; } @@ -7767,7 +7767,7 @@ void Client::Handle_OP_GuildPromote(const EQApplicationPacket *app) guild_mgr.GetGuildName(GuildID()), GuildID()); if (!guild_mgr.SetGuildRank(gci.char_id, rank)) { - Message(13, "Error while setting rank %d on '%s'.", rank, promote->target); + Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, promote->target); return; } Message(0, "Successfully promoted %s to rank %d", promote->target, rank); @@ -7802,7 +7802,7 @@ void Client::Handle_OP_GuildPublicNote(const EQApplicationPacket *app) gpn->note); if (!guild_mgr.SetPublicNote(gci.char_id, gpn->note)) { - Message(13, "Failed to set public note on %s", gpn->target); + Message(Chat::Red, "Failed to set public note on %s", gpn->target); } else { Message(0, "Successfully changed public note on %s", gpn->target); @@ -7897,7 +7897,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if (!c) { - Message_StringID(clientMessageWhite, TARGET_PLAYER_FOR_GUILD_STATUS); + Message_StringID(Chat::LightGray, TARGET_PLAYER_FOR_GUILD_STATUS); return; } @@ -7905,7 +7905,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if (TargetGuildID == GUILD_NONE) { - Message_StringID(clientMessageWhite, NOT_IN_A_GUILD, c->GetName()); + Message_StringID(Chat::LightGray, NOT_IN_A_GUILD, c->GetName()); return; } @@ -7920,21 +7920,21 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if ((TargetGuildID == GuildID()) && (c != this)) { if (IsLeader) - Message_StringID(clientMessageWhite, LEADER_OF_YOUR_GUILD, c->GetName()); + Message_StringID(Chat::LightGray, LEADER_OF_YOUR_GUILD, c->GetName()); else if (IsOfficer) - Message_StringID(clientMessageWhite, OFFICER_OF_YOUR_GUILD, c->GetName()); + Message_StringID(Chat::LightGray, OFFICER_OF_YOUR_GUILD, c->GetName()); else - Message_StringID(clientMessageWhite, MEMBER_OF_YOUR_GUILD, c->GetName()); + Message_StringID(Chat::LightGray, MEMBER_OF_YOUR_GUILD, c->GetName()); return; } if (IsLeader) - Message_StringID(clientMessageWhite, LEADER_OF_X_GUILD, c->GetName(), GuildName); + Message_StringID(Chat::LightGray, LEADER_OF_X_GUILD, c->GetName(), GuildName); else if (IsOfficer) - Message_StringID(clientMessageWhite, OFFICER_OF_X_GUILD, c->GetName(), GuildName); + Message_StringID(Chat::LightGray, OFFICER_OF_X_GUILD, c->GetName(), GuildName); else - Message_StringID(clientMessageWhite, MEMBER_OF_X_GUILD, c->GetName(), GuildName); + Message_StringID(Chat::LightGray, MEMBER_OF_X_GUILD, c->GetName(), GuildName); } void Client::Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app) @@ -7956,7 +7956,7 @@ void Client::Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app) if (!guild_mgr.IsGuildLeader(GuildID(), CharacterID())) { - Message(13, "Only the guild leader can change the Channel or URL.!"); + Message(Chat::Red, "Only the guild leader can change the Channel or URL.!"); return; } @@ -7995,7 +7995,7 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app) } if (!p_timers.Expired(&database, pTimerHide, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } int reuse = HideReuseTime - GetSkillReuseTime(EQEmu::skills::SkillHide); @@ -8201,7 +8201,7 @@ void Client::Handle_OP_InstillDoubt(const EQApplicationPacket *app) //packet is empty as of 12/14/04 if (!p_timers.Expired(&database, pTimerInstillDoubt, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } p_timers.Start(pTimerInstillDoubt, InstillDoubtReuseTime - 1); @@ -8227,7 +8227,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) const EQEmu::ItemData *item = database.GetItem(ivrs->item_id); if (!item) { if (ivrs->item_id != SAYLINK_ITEM_ID) { - Message(13, "Error: The item for the link you have clicked on does not exist!"); + Message(Chat::Red, "Error: The item for the link you have clicked on does not exist!"); return; } // This new scheme will shuttle the ID in the first augment for non-silent links @@ -8240,12 +8240,12 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) std::string query = StringFormat("SELECT `phrase` FROM saylink WHERE `id` = '%i'", sayid); auto results = database.QueryDatabase(query); if (!results.Success()) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + Message(Chat::Red, "Error: The saylink (%s) was not found in the database.", response.c_str()); return; } if (results.RowCount() != 1) { - Message(13, "Error: The saylink (%s) was not found in the database.", response.c_str()); + Message(Chat::Red, "Error: The saylink (%s) was not found in the database.", response.c_str()); return; } @@ -8264,7 +8264,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); } else { - Message(7, "You say, '%s'", response.c_str()); + Message(Chat::LightGray, "You say, '%s'", response.c_str()); ChannelMessageReceived(8, 0, 100, response.c_str()); } return; @@ -8274,14 +8274,14 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); } else { - Message(7, "You say, '%s'", response.c_str()); + Message(Chat::LightGray, "You say, '%s'", response.c_str()); ChannelMessageReceived(8, 0, 100, response.c_str()); } return; } } else { - Message(13, "Error: Say Link not found or is too long."); + Message(Chat::Red, "Error: Say Link not found or is too long."); return; } } @@ -8537,7 +8537,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (IsAIControlled()) { - this->Message_StringID(13, NOT_IN_CONTROL); + this->Message_StringID(Chat::Red, NOT_IN_CONTROL); return; } @@ -8646,7 +8646,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (inst->GetCharges() == 0) { //Message(0, "This item is out of charges."); - Message_StringID(13, ITEM_OUT_OF_CHARGES); + Message_StringID(Chat::Red, ITEM_OUT_OF_CHARGES); return; } if (GetLevel() >= item->Click.Level2) @@ -8666,7 +8666,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else { - Message_StringID(13, ITEMS_INSUFFICIENT_LEVEL); + Message_StringID(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); return; } } @@ -8675,7 +8675,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (clickaug->GetCharges() == 0) { //Message(0, "This item is out of charges."); - Message_StringID(13, ITEM_OUT_OF_CHARGES); + Message_StringID(Chat::Red, ITEM_OUT_OF_CHARGES); return; } if (GetLevel() >= augitem->Click.Level2) @@ -8695,7 +8695,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else { - Message_StringID(13, ITEMS_INSUFFICIENT_LEVEL); + Message_StringID(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); return; } } @@ -8829,13 +8829,13 @@ void Client::Handle_OP_LDoNDisarmTraps(const EQApplicationPacket *app) { if (DistanceSquaredNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - Message(13, "%s is too far away.", target->GetCleanName()); + Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } HandleLDoNDisarm(target->CastToNPC(), GetSkill(EQEmu::skills::SkillDisarmTraps), LDoNTypeMechanical); } else - Message(13, "You do not have the disarm trap skill."); + Message(Chat::Red, "You do not have the disarm trap skill."); } } @@ -8843,7 +8843,7 @@ void Client::Handle_OP_LDoNInspect(const EQApplicationPacket *app) { Mob * target = GetTarget(); if (target && target->GetClass() == LDON_TREASURE) - Message(15, "%s", target->GetCleanName()); + Message(Chat::Yellow, "%s", target->GetCleanName()); } void Client::Handle_OP_LDoNOpen(const EQApplicationPacket *app) @@ -8862,13 +8862,13 @@ void Client::Handle_OP_LDoNPickLock(const EQApplicationPacket *app) { if (DistanceSquaredNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - Message(13, "%s is too far away.", target->GetCleanName()); + Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } HandleLDoNPickLock(target->CastToNPC(), GetSkill(EQEmu::skills::SkillPickLock), LDoNTypeMechanical); } else - Message(13, "You do not have the pick locks skill."); + Message(Chat::Red, "You do not have the pick locks skill."); } } @@ -8881,13 +8881,13 @@ void Client::Handle_OP_LDoNSenseTraps(const EQApplicationPacket *app) { if (DistanceSquaredNoZ(m_Position, target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - Message(13, "%s is too far away.", target->GetCleanName()); + Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } HandleLDoNSenseTraps(target->CastToNPC(), GetSkill(EQEmu::skills::SkillSenseTraps), LDoNTypeMechanical); } else - Message(13, "You do not have the sense traps skill."); + Message(Chat::Red, "You do not have the sense traps skill."); } } @@ -8902,12 +8902,12 @@ void Client::Handle_OP_LeadershipExpToggle(const EQApplicationPacket *app) if (*mode) { m_pp.leadAAActive = 1; Save(); - Message_StringID(clientMessageYellow, LEADERSHIP_EXP_ON); + Message_StringID(Chat::Yellow, LEADERSHIP_EXP_ON); } else { m_pp.leadAAActive = 0; Save(); - Message_StringID(clientMessageYellow, LEADERSHIP_EXP_OFF); + Message_StringID(Chat::Yellow, LEADERSHIP_EXP_OFF); } } @@ -9266,7 +9266,7 @@ void Client::Handle_OP_LootItem(const EQApplicationPacket *app) EQApplicationPacket* outapp = nullptr; Entity* entity = entity_list.GetID(*((uint16*)app->pBuffer)); if (entity == 0) { - Message(13, "Error: OP_LootItem: Corpse not found (ent = 0)"); + Message(Chat::Red, "Error: OP_LootItem: Corpse not found (ent = 0)"); outapp = new EQApplicationPacket(OP_LootComplete, 0); QueuePacket(outapp); safe_delete(outapp); @@ -9278,7 +9278,7 @@ void Client::Handle_OP_LootItem(const EQApplicationPacket *app) return; } else { - Message(13, "Error: Corpse not found! (!ent->IsCorpse())"); + Message(Chat::Red, "Error: Corpse not found! (!ent->IsCorpse())"); Corpse::SendEndLootErrorPacket(this); } @@ -9294,7 +9294,7 @@ void Client::Handle_OP_LootRequest(const EQApplicationPacket *app) Entity* ent = entity_list.GetID(*((uint32*)app->pBuffer)); if (ent == 0) { - Message(13, "Error: OP_LootRequest: Corpse not found (ent = 0)"); + Message(Chat::Red, "Error: OP_LootRequest: Corpse not found (ent = 0)"); Corpse::SendLootReqErrorPacket(this); return; } @@ -9307,7 +9307,7 @@ void Client::Handle_OP_LootRequest(const EQApplicationPacket *app) } else { std::cout << "npc == 0 LOOTING FOOKED3" << std::endl; - Message(13, "Error: OP_LootRequest: Corpse not a corpse?"); + Message(Chat::Red, "Error: OP_LootRequest: Corpse not a corpse?"); Corpse::SendLootReqErrorPacket(this); } return; @@ -9359,7 +9359,7 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) return; if (!p_timers.Expired(&database, pTimerMend, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } p_timers.Start(pTimerMend, MendReuseTime - 1); @@ -9372,11 +9372,11 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) if (zone->random.Int(0, 99) < criticalchance) { mendhp *= 2; - Message_StringID(4, MEND_CRITICAL); + Message_StringID(Chat::LightBlue, MEND_CRITICAL); } SetHP(GetHP() + mendhp); SendHPUpdate(); - Message_StringID(4, MEND_SUCCESS); + Message_StringID(Chat::LightBlue, MEND_SUCCESS); } else { /* the purpose of the following is to make the chance to worsen wounds much less common, @@ -9389,10 +9389,10 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) { SetHP(currenthp > mendhp ? (GetHP() - mendhp) : 1); SendHPUpdate(); - Message_StringID(4, MEND_WORSEN); + Message_StringID(Chat::LightBlue, MEND_WORSEN); } else - Message_StringID(4, MEND_FAIL); + Message_StringID(Chat::LightBlue, MEND_FAIL); } CheckIncreaseSkill(EQEmu::skills::SkillMend, nullptr, 10); @@ -9403,7 +9403,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app) { if (app->size != sizeof(MercenaryCommand_Struct)) { - Message(13, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); + Message(Chat::Red, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); Log(Logs::General, Logs::None, "Size mismatch in OP_MercenaryCommand expected %i got %i", sizeof(MercenaryCommand_Struct), app->size); DumpPacket(app); return; @@ -9590,7 +9590,7 @@ void Client::Handle_OP_MercenaryDataUpdateRequest(const EQApplicationPacket *app // The payload is 0 bytes. if (app->size != 0) { - Message(13, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); + Message(Chat::Red, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); Log(Logs::General, Logs::None, "Size mismatch in OP_MercenaryDataUpdateRequest expected 0 got %i", app->size); DumpPacket(app); return; @@ -9609,7 +9609,7 @@ void Client::Handle_OP_MercenaryDismiss(const EQApplicationPacket *app) // The payload is 0 or 1 bytes. if (app->size > 1) { - Message(13, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); + Message(Chat::Red, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); Log(Logs::General, Logs::None, "Size mismatch in OP_MercenaryDismiss expected 0 got %i", app->size); DumpPacket(app); return; @@ -9704,7 +9704,7 @@ void Client::Handle_OP_MercenarySuspendRequest(const EQApplicationPacket *app) { if (app->size != sizeof(SuspendMercenary_Struct)) { - Message(13, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); + Message(Chat::Red, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); Log(Logs::General, Logs::None, "Size mismatch in OP_MercenarySuspendRequest expected %i got %i", sizeof(SuspendMercenary_Struct), app->size); DumpPacket(app); return; @@ -9727,7 +9727,7 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app) // The payload is 0 bytes. if (app->size > 1) { - Message(13, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); + Message(Chat::Red, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); Log(Logs::General, Logs::None, "Size mismatch in OP_MercenaryTimerRequest expected 0 got %i", app->size); DumpPacket(app); return; @@ -9829,7 +9829,7 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app) } } - if (mi_hack) { Message(15, "Caution: Illegal use of inaccessible bag slots!"); } + if (mi_hack) { Message(Chat::Yellow, "Caution: Illegal use of inaccessible bag slots!"); } if (!SwapItem(mi) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot)) { SwapItemResync(mi); @@ -9930,9 +9930,9 @@ void Client::Handle_OP_PDeletePetition(const EQApplicationPacket *app) return; } if (petition_list.DeletePetitionByCharName((char*)app->pBuffer)) - Message_StringID(0, PETITION_DELETED); + Message_StringID(Chat::White, PETITION_DELETED); else - Message_StringID(0, PETITION_NO_DELETE); + Message_StringID(Chat::White, PETITION_NO_DELETE); return; } @@ -9989,7 +9989,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (!target) break; if (target->IsMezzed()) { - Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName()); + Message_StringID(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName()); break; } if (mypet->IsFeared()) @@ -10027,7 +10027,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) hate += mypet->GetHateAmount(top) - mypet->GetHateAmount(target) + 100; // should be enough to cause target change } mypet->AddToHateList(target, hate, 0, true, false, false, SPELL_UNKNOWN, true); - Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName()); + Message_StringID(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName()); SetTarget(target); } } @@ -10040,7 +10040,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (!GetTarget()) break; if (GetTarget()->IsMezzed()) { - Message_StringID(10, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName()); + Message_StringID(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName()); break; } @@ -10061,7 +10061,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } zone->AddAggroMob(); mypet->AddToHateList(GetTarget(), 1, 0, true, false, false, SPELL_UNKNOWN, true); - Message_StringID(MT_PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); + Message_StringID(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); } } break; @@ -10070,7 +10070,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //keeps pet running while feared if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_CALMING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_CALMING); mypet->WipeHateList(); mypet->SetTarget(nullptr); if (mypet->IsPetStop()) { @@ -10082,7 +10082,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } case PET_HEALTHREPORT: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(MT_PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); + Message_StringID(Chat::PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); mypet->ShowBuffList(this); } break; @@ -10101,7 +10101,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) SetPet(nullptr); } - mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); mypet->CastToNPC()->Depop(); //Oddly, the client (Titanium) will still allow "/pet get lost" command despite me adding the code below. If someone can figure that out, you can uncomment this code and use it. @@ -10119,7 +10119,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->IsNPC()) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_GUARDINGLIFE); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GUARDINGLIFE); mypet->SetPetOrder(SPO_Guard); mypet->CastToNPC()->SaveGuardSpot(mypet->GetPosition()); if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down @@ -10136,7 +10136,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_FOLLOWING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_FOLLOWING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); if (mypet->IsPetStop()) { @@ -10150,12 +10150,12 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->CastToNPC()->IsTaunting()) { - Message_StringID(MT_PetResponse, PET_NO_TAUNT); + Message_StringID(Chat::PetResponse, PET_NO_TAUNT); mypet->CastToNPC()->SetTaunting(false); } else { - Message_StringID(MT_PetResponse, PET_DO_TAUNT); + Message_StringID(Chat::PetResponse, PET_DO_TAUNT); mypet->CastToNPC()->SetTaunting(true); } } @@ -10163,14 +10163,14 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } case PET_TAUNT_ON: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(MT_PetResponse, PET_DO_TAUNT); + Message_StringID(Chat::PetResponse, PET_DO_TAUNT); mypet->CastToNPC()->SetTaunting(true); } break; } case PET_TAUNT_OFF: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(MT_PetResponse, PET_NO_TAUNT); + Message_StringID(Chat::PetResponse, PET_NO_TAUNT); mypet->CastToNPC()->SetTaunting(false); } break; @@ -10179,7 +10179,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_GUARDME_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GUARDME_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); if (mypet->IsPetStop()) { @@ -10195,13 +10195,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->GetPetOrder() == SPO_Sit) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); } else { - mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Sit); mypet->SetRunAnimSpeed(0); if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet @@ -10215,7 +10215,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); } @@ -10225,7 +10225,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, MT_PetResponse, PET_SIT_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Sit); mypet->SetRunAnimSpeed(0); if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet @@ -10239,18 +10239,18 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF); + Message_StringID(Chat::PetResponse, PET_HOLD_SET_OFF); mypet->SetHeld(false); } else { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_HOLD_SET_ON); + Message_StringID(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); else - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); mypet->SetHeld(true); } @@ -10262,12 +10262,12 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_HOLD_ON: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && !mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_HOLD_SET_ON); + Message_StringID(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - mypet->SayTo_StringID(this, MT_PetResponse, PET_NOW_HOLDING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); else - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); mypet->SetHeld(true); mypet->SetGHeld(false); SetPetCommandState(PET_BUTTON_GHOLD, 0); @@ -10277,7 +10277,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_HOLD_OFF: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_HOLD_SET_OFF); + Message_StringID(Chat::PetResponse, PET_HOLD_SET_OFF); mypet->SetHeld(false); } break; @@ -10287,16 +10287,16 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsGHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - Message_StringID(MT_PetResponse, PET_OFF_GHOLD); + Message_StringID(Chat::PetResponse, PET_OFF_GHOLD); mypet->SetGHeld(false); } else { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { - Message_StringID(MT_PetResponse, PET_ON_GHOLD); - mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG); + Message_StringID(Chat::PetResponse, PET_ON_GHOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); } mypet->SetGHeld(true); } @@ -10308,10 +10308,10 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_GHOLD_ON: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { - Message_StringID(MT_PetResponse, PET_ON_GHOLD); - mypet->SayTo_StringID(this, MT_PetResponse, PET_GHOLD_ON_MSG); + Message_StringID(Chat::PetResponse, PET_ON_GHOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_HOLD); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); } mypet->SetGHeld(true); mypet->SetHeld(false); @@ -10322,7 +10322,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_GHOLD_OFF: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsGHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - Message_StringID(MT_PetResponse, PET_OFF_GHOLD); + Message_StringID(Chat::PetResponse, PET_OFF_GHOLD); mypet->SetGHeld(false); } break; @@ -10332,15 +10332,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsNoCast()) { - Message_StringID(MT_PetResponse, PET_CASTING); + Message_StringID(Chat::PetResponse, PET_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF); + Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); mypet->SetNoCast(false); } else { - Message_StringID(MT_PetResponse, PET_NOT_CASTING); + Message_StringID(Chat::PetResponse, PET_NOT_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON); + Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_ON); mypet->SetNoCast(true); } } @@ -10351,9 +10351,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (!mypet->IsNoCast()) { - Message_StringID(MT_PetResponse, PET_NOT_CASTING); + Message_StringID(Chat::PetResponse, PET_NOT_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_ON); + Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_ON); mypet->SetNoCast(true); } } @@ -10364,9 +10364,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsNoCast()) { - Message_StringID(MT_PetResponse, PET_CASTING); + Message_StringID(Chat::PetResponse, PET_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_SPELLHOLD_SET_OFF); + Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); mypet->SetNoCast(false); } } @@ -10377,15 +10377,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsFocused()) { - Message_StringID(MT_PetResponse, PET_NOT_FOCUSING); + Message_StringID(Chat::PetResponse, PET_NOT_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF); + Message_StringID(Chat::PetResponse, PET_FOCUS_SET_OFF); mypet->SetFocused(false); } else { - Message_StringID(MT_PetResponse, PET_NOW_FOCUSING); + Message_StringID(Chat::PetResponse, PET_NOW_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON); + Message_StringID(Chat::PetResponse, PET_FOCUS_SET_ON); mypet->SetFocused(true); } } @@ -10396,9 +10396,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (!mypet->IsFocused()) { - Message_StringID(MT_PetResponse, PET_NOW_FOCUSING); + Message_StringID(Chat::PetResponse, PET_NOW_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_FOCUS_SET_ON); + Message_StringID(Chat::PetResponse, PET_FOCUS_SET_ON); mypet->SetFocused(true); } } @@ -10409,9 +10409,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsFocused()) { - Message_StringID(MT_PetResponse, PET_NOT_FOCUSING); + Message_StringID(Chat::PetResponse, PET_NOT_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(MT_PetResponse, PET_FOCUS_SET_OFF); + Message_StringID(Chat::PetResponse, PET_FOCUS_SET_OFF); mypet->SetFocused(false); } } @@ -10432,7 +10432,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) SetPetCommandState(PET_BUTTON_REGROUP, 0); } } - mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); } break; } @@ -10443,7 +10443,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetStop(true); mypet->StopNavigation(); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); if (mypet->IsPetRegroup()) { mypet->SetPetRegroup(false); SetPetCommandState(PET_BUTTON_REGROUP, 0); @@ -10456,7 +10456,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SetPetStop(false); - mypet->SayTo_StringID(this, MT_PetResponse, PET_GETLOST_STRING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); } break; } @@ -10466,11 +10466,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { if (mypet->IsPetRegroup()) { mypet->SetPetRegroup(false); - mypet->SayTo_StringID(this, MT_PetResponse, PET_OFF_REGROUPING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_OFF_REGROUPING); } else { mypet->SetPetRegroup(true); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_REGROUPING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_REGROUPING); if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10485,7 +10485,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { mypet->SetPetRegroup(true); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, MT_PetResponse, PET_ON_REGROUPING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_REGROUPING); if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10498,7 +10498,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { mypet->SetPetRegroup(false); - mypet->SayTo_StringID(this, MT_PetResponse, PET_OFF_REGROUPING); + mypet->SayTo_StringID(this, Chat::PetResponse, PET_OFF_REGROUPING); } break; } @@ -10706,7 +10706,7 @@ void Client::Handle_OP_PickPocket(const EQApplicationPacket *app) if (!p_timers.Expired(&database, pTimerBeggingPickPocket, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); database.SetMQDetectionFlag(this->AccountName(), this->GetName(), "OP_PickPocket was sent again too quickly.", zone->GetShortName()); return; } @@ -10793,7 +10793,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) case EQEmu::popupresponse::MOB_INFO_DISMISS: this->SetDisplayMobInfoWindow(false); - this->Message(15, "[DevTools] Window snoozed in this zone..."); + this->Message(Chat::Yellow, "[DevTools] Window snoozed in this zone..."); break; default: break; @@ -10855,13 +10855,13 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app) uint32 current_rank = m_pp.leader_abilities.ranks[aaid]; if (current_rank >= MAX_LEADERSHIP_TIERS) { - Message(13, "This ability can be trained no further."); + Message(Chat::Red, "This ability can be trained no further."); return; } uint8 cost = LeadershipAACosts[aaid][current_rank]; if (cost == 0) { - Message(13, "This ability can be trained no further."); + Message(Chat::Red, "This ability can be trained no further."); return; } @@ -10870,7 +10870,7 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app) if (aaid >= raidAAMarkNPC) { //it is a raid ability. if (cost > m_pp.raid_leadership_points) { - Message(13, "You do not have enough points to purchase this ability."); + Message(Chat::Red, "You do not have enough points to purchase this ability."); return; } @@ -10883,7 +10883,7 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app) else { //it is a group ability. if (cost > m_pp.group_leadership_points) { - Message(13, "You do not have enough points to purchase this ability."); + Message(Chat::Red, "You do not have enough points to purchase this ability."); return; } @@ -11082,12 +11082,12 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) Group *player_to_invite_group = player_to_invite->GetGroup(); if (player_to_invite->HasRaid()) { - Message(13, "%s is already in a raid.", player_to_invite->GetName()); + Message(Chat::Red, "%s is already in a raid.", player_to_invite->GetName()); break; } if (player_to_invite_group && !player_to_invite_group->IsLeader(player_to_invite)) { - Message(13, "You can only invite an ungrouped player or group leader to join your raid."); + Message(Chat::Red, "You can only invite an ungrouped player or group leader to join your raid."); break; } @@ -11111,7 +11111,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) Client *player_accepting_invite = entity_list.GetClientByName(raid_command_packet->player_name); if (player_accepting_invite) { if (IsRaidGrouped()) { - player_accepting_invite->Message_StringID(0, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid... + player_accepting_invite->Message_StringID(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid... return; } Raid *raid = entity_list.GetRaidByClient(player_accepting_invite); @@ -11120,13 +11120,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) Group *group = GetGroup(); if (group) { if (group->GroupCount() + raid->RaidCount() > MAX_RAID_MEMBERS) { - player_accepting_invite->Message(13, "Invite failed, group invite would create a raid larger than the maximum number of members allowed."); + player_accepting_invite->Message(Chat::Red, "Invite failed, group invite would create a raid larger than the maximum number of members allowed."); return; } } else { if (1 + raid->RaidCount() > MAX_RAID_MEMBERS) { - player_accepting_invite->Message(13, "Invite failed, member invite would create a raid larger than the maximum number of members allowed."); + player_accepting_invite->Message(Chat::Red, "Invite failed, member invite would create a raid larger than the maximum number of members allowed."); return; } } @@ -11618,7 +11618,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) { Raid *raid = entity_list.GetRaidByClient(this); if (raid) { - Message(15, "Loot type changed to: %d.", raid_command_packet->parameter); + Message(Chat::Yellow, "Loot type changed to: %d.", raid_command_packet->parameter); raid->ChangeLootType(raid_command_packet->parameter); } break; @@ -11629,7 +11629,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) { Raid *raid = entity_list.GetRaidByClient(this); if (raid) { - Message(15, "Adding %s as a raid looter.", raid_command_packet->leader_name); + Message(Chat::Yellow, "Adding %s as a raid looter.", raid_command_packet->leader_name); raid->AddRaidLooter(raid_command_packet->leader_name); } break; @@ -11640,7 +11640,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) { Raid *raid = entity_list.GetRaidByClient(this); if (raid) { - Message(15, "Removing %s as a raid looter.", raid_command_packet->leader_name); + Message(Chat::Yellow, "Removing %s as a raid looter.", raid_command_packet->leader_name); raid->RemoveRaidLooter(raid_command_packet->leader_name); } break; @@ -11673,7 +11673,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) } default: { - Message(13, "Raid command (%d) NYI", raid_command_packet->action); + Message(Chat::Red, "Raid command (%d) NYI", raid_command_packet->action); break; } } @@ -11983,14 +11983,14 @@ void Client::Handle_OP_RemoveTrap(const EQApplicationPacket *app) if (good) RemoveAura(id); else - Message_StringID(MT_SpellFailure, NOT_YOUR_TRAP); // pretty sure this was red + Message_StringID(Chat::SpellFailure, NOT_YOUR_TRAP); // pretty sure this was red } void Client::Handle_OP_Report(const EQApplicationPacket *app) { if (!CanUseReport) { - Message_StringID(MT_System, REPORT_ONCE); + Message_StringID(Chat::System, REPORT_ONCE); return; } @@ -12057,11 +12057,11 @@ void Client::Handle_OP_RequestDuel(const EQApplicationPacket *app) ds->duel_target = duel; Entity* entity = entity_list.GetID(ds->duel_target); if (GetID() != ds->duel_target && entity->IsClient() && (entity->CastToClient()->IsDueling() && entity->CastToClient()->GetDuelTarget() != 0)) { - Message_StringID(10, DUEL_CONSIDERING, entity->GetName()); + Message_StringID(Chat::NPCQuestSay, DUEL_CONSIDERING, entity->GetName()); return; } if (IsDueling()) { - Message_StringID(10, DUEL_INPROGRESS); + Message_StringID(Chat::NPCQuestSay, DUEL_INPROGRESS); return; } @@ -12108,7 +12108,7 @@ void Client::Handle_OP_RespawnWindow(const EQApplicationPacket *app) void Client::Handle_OP_Rewind(const EQApplicationPacket *app) { if ((rewind_timer.GetRemainingTime() > 1 && rewind_timer.Enabled())) { - Message_StringID(MT_System, REWIND_WAIT); + Message_StringID(Chat::System, REWIND_WAIT); } else { CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_RewindLocation.x, m_RewindLocation.y, m_RewindLocation.z, 0, 2, Rewind); @@ -12220,7 +12220,7 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app) return; if (!p_timers.Expired(&database, pTimerSenseTraps, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -12243,23 +12243,23 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app) auto diff = trap->m_Position - glm::vec3(GetPosition()); if (diff.x == 0 && diff.y == 0) - Message(MT_Skills, "You sense a trap right under your feet!"); + Message(Chat::Skills, "You sense a trap right under your feet!"); else if (diff.x > 10 && diff.y > 10) - Message(MT_Skills, "You sense a trap to the NorthWest."); + Message(Chat::Skills, "You sense a trap to the NorthWest."); else if (diff.x < -10 && diff.y > 10) - Message(MT_Skills, "You sense a trap to the NorthEast."); + Message(Chat::Skills, "You sense a trap to the NorthEast."); else if (diff.y > 10) - Message(MT_Skills, "You sense a trap to the North."); + Message(Chat::Skills, "You sense a trap to the North."); else if (diff.x > 10 && diff.y < -10) - Message(MT_Skills, "You sense a trap to the SouthWest."); + Message(Chat::Skills, "You sense a trap to the SouthWest."); else if (diff.x < -10 && diff.y < -10) - Message(MT_Skills, "You sense a trap to the SouthEast."); + Message(Chat::Skills, "You sense a trap to the SouthEast."); else if (diff.y < -10) - Message(MT_Skills, "You sense a trap to the South."); + Message(Chat::Skills, "You sense a trap to the South."); else if (diff.x > 10) - Message(MT_Skills, "You sense a trap to the West."); + Message(Chat::Skills, "You sense a trap to the West."); else - Message(MT_Skills, "You sense a trap to the East."); + Message(Chat::Skills, "You sense a trap to the East."); trap->detected = true; float angle = CalculateHeadingToTarget(trap->m_Position.x, trap->m_Position.y); @@ -12272,7 +12272,7 @@ void Client::Handle_OP_SenseTraps(const EQApplicationPacket *app) return; } } - Message(MT_Skills, "You did not find any traps nearby."); + Message(Chat::Skills, "You did not find any traps nearby."); return; } @@ -12286,11 +12286,11 @@ void Client::Handle_OP_SetGuildMOTD(const EQApplicationPacket *app) return; } if (!IsInAGuild()) { - Message(13, "You are not in a guild!"); + Message(Chat::Red, "You are not in a guild!"); return; } if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_MOTD)) { - Message(13, "You do not have permissions to edit your guild's MOTD."); + Message(Chat::Red, "You do not have permissions to edit your guild's MOTD."); return; } @@ -12341,7 +12341,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) { // if the character has a start city, don't let them use the command if (m_pp.binds[4].zoneId != 0 && m_pp.binds[4].zoneId != 189) { - Message(15, "Your home city has already been set.", m_pp.binds[4].zoneId, database.GetZoneName(m_pp.binds[4].zoneId)); + Message(Chat::Yellow, "Your home city has already been set.", m_pp.binds[4].zoneId, database.GetZoneName(m_pp.binds[4].zoneId)); return; } @@ -12381,7 +12381,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) } if (validCity) { - Message(15, "Your home city has been set"); + Message(Chat::Yellow, "Your home city has been set"); SetStartZone(startCity, x, y, z); return; } @@ -12393,7 +12393,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) if (!results.Success()) return; - Message(15, "Use \"/setstartcity #\" to choose a home city from the following list:"); + Message(Chat::Yellow, "Use \"/setstartcity #\" to choose a home city from the following list:"); for (auto row = results.begin(); row != results.end(); ++row) { if (atoi(row[1]) != 0) @@ -12403,7 +12403,7 @@ void Client::Handle_OP_SetStartCity(const EQApplicationPacket *app) char* name = nullptr; database.GetZoneLongName(database.GetZoneName(zoneid), &name); - Message(15, "%d - %s", zoneid, name); + Message(Chat::Yellow, "%d - %s", zoneid, name); } } @@ -12509,7 +12509,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) } if (!ack) { - Message_StringID(0, ALREADY_SHIELDED); + Message_StringID(Chat::White, ALREADY_SHIELDED); shield_target = 0; return; } @@ -12586,7 +12586,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) item = database.GetItem(item_id); if (!item) { //error finding item, client didnt get the update packet for whatever reason, roleplay a tad - Message(15, "%s tells you 'Sorry, that item is for display purposes only.' as they take the item off the shelf.", tmp->GetCleanName()); + Message(Chat::Yellow, "%s tells you 'Sorry, that item is for display purposes only.' as they take the item off the shelf.", tmp->GetCleanName()); auto delitempacket = new EQApplicationPacket(OP_ShopDelItem, sizeof(Merchant_DelItem_Struct)); Merchant_DelItem_Struct* delitem = (Merchant_DelItem_Struct*)delitempacket->pBuffer; delitem->itemslot = mp->itemslot; @@ -12599,7 +12599,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) } if (CheckLoreConflict(item)) { - Message(15, "You can only have one of a lore item."); + Message(Chat::Yellow, "You can only have one of a lore item."); return; } if (tmpmer_used && (mp->quantity > prevcharges || item->MaxCharges > 1)) @@ -12673,7 +12673,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) //make sure we are not completely full... if (freeslotid == EQEmu::invslot::slotCursor) { if (m_inv.GetItem(EQEmu::invslot::slotCursor) != nullptr) { - Message(13, "You do not have room for any more items."); + Message(Chat::Red, "You do not have room for any more items."); safe_delete(outapp); safe_delete(inst); return; @@ -12682,7 +12682,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app) if (!stacked && freeslotid == INVALID_INDEX) { - Message(13, "You do not have room for any more items."); + Message(Chat::Red, "You do not have room for any more items."); safe_delete(outapp); safe_delete(inst); return; @@ -12817,7 +12817,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) const EQEmu::ItemData* item = database.GetItem(itemid); EQEmu::ItemInstance* inst = GetInv().GetItem(mp->itemslot); if (!item || !inst) { - Message(13, "You seemed to have misplaced that item.."); + Message(Chat::Red, "You seemed to have misplaced that item.."); return; } if (mp->quantity > 1) @@ -12827,7 +12827,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app) } if (!item->NoDrop) { - //Message(13,"%s tells you, 'LOL NOPE'", vendor->GetName()); + //Message(Chat::Red,"%s tells you, 'LOL NOPE'", vendor->GetName()); return; } @@ -13021,7 +13021,7 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) return; } if (tmp->IsEngaged()) { - this->Message_StringID(0, MERCHANT_BUSY); + this->Message_StringID(Chat::White, MERCHANT_BUSY); action = 0; } if (GetFeigned() || IsInvisible()) @@ -13074,7 +13074,7 @@ void Client::Handle_OP_Sneak(const EQApplicationPacket *app) } if (!p_timers.Expired(&database, pTimerSneak, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } p_timers.Start(pTimerSneak, SneakReuseTime - 1); @@ -13295,13 +13295,13 @@ void Client::Handle_OP_Split(const EQApplicationPacket *app) //Per the note above, Im not exactly sure what to do on error //to notify the client of the error... if (!isgrouped) { - Message(13, "You can not split money if you're not in a group."); + Message(Chat::Red, "You can not split money if you're not in a group."); return; } Group *cgroup = GetGroup(); if (cgroup == nullptr) { //invalid group, not sure if we should say more... - Message(13, "You can not split money if you're not in a group."); + Message(Chat::Red, "You can not split money if you're not in a group."); return; } @@ -13309,7 +13309,7 @@ void Client::Handle_OP_Split(const EQApplicationPacket *app) 10 * static_cast(split->silver) + 100 * static_cast(split->gold) + 1000 * static_cast(split->platinum))) { - Message(13, "You do not have enough money to do that split."); + Message(Chat::Red, "You do not have enough money to do that split."); return; } cgroup->SplitMoney(split->copper, split->silver, split->gold, split->platinum); @@ -13328,13 +13328,13 @@ void Client::Handle_OP_Surname(const EQApplicationPacket *app) if (!p_timers.Expired(&database, pTimerSurnameChange, false) && !GetGM()) { - Message(15, "You may only change surnames once every 7 days, your /surname is currently on cooldown."); + Message(Chat::Yellow, "You may only change surnames once every 7 days, your /surname is currently on cooldown."); return; } if (GetLevel() < 20) { - Message_StringID(15, SURNAME_LEVEL); + Message_StringID(Chat::Yellow, SURNAME_LEVEL); return; } @@ -13356,13 +13356,13 @@ void Client::Handle_OP_Surname(const EQApplicationPacket *app) } if (strlen(surname->lastname) >= 20) { - Message_StringID(15, SURNAME_TOO_LONG); + Message_StringID(Chat::Yellow, SURNAME_TOO_LONG); return; } if (!database.CheckNameFilter(surname->lastname, true)) { - Message_StringID(15, SURNAME_REJECTED); + Message_StringID(Chat::Yellow, SURNAME_REJECTED); return; } @@ -13657,7 +13657,7 @@ void Client::Handle_OP_Taunt(const EQApplicationPacket *app) } if (!p_timers.Expired(&database, pTimerTaunt, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } p_timers.Start(pTimerTaunt, TauntReuseTime - 1); @@ -13666,7 +13666,7 @@ void Client::Handle_OP_Taunt(const EQApplicationPacket *app) return; if (!zone->CanDoCombat()) { - Message(13, "You cannot taunt in a no combat zone."); + Message(Chat::Red, "You cannot taunt in a no combat zone."); return; } @@ -13742,31 +13742,31 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) trade->state = TradeCompleting; if (CheckTradeLoreConflict(other) || other->CheckTradeLoreConflict(this)) { - Message_StringID(13, TRADE_CANCEL_LORE); - other->Message_StringID(13, TRADE_CANCEL_LORE); + Message_StringID(Chat::Red, TRADE_CANCEL_LORE); + other->Message_StringID(Chat::Red, TRADE_CANCEL_LORE); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); trade->Reset(); } else if (CheckTradeNonDroppable()) { - Message_StringID(13, TRADE_HAS_BEEN_CANCELLED); - other->Message_StringID(13, TRADE_HAS_BEEN_CANCELLED); + Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + other->Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); trade->Reset(); - Message(15, "Hacking activity detected in trade transaction."); + Message(Chat::Yellow, "Hacking activity detected in trade transaction."); // TODO: query (this) as a hacker } else if (other->CheckTradeNonDroppable()) { - Message_StringID(13, TRADE_HAS_BEEN_CANCELLED); - other->Message_StringID(13, TRADE_HAS_BEEN_CANCELLED); + Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + other->Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); trade->Reset(); - other->Message(15, "Hacking activity detected in trade transaction."); + other->Message(Chat::Yellow, "Hacking activity detected in trade transaction."); // TODO: query (other) as a hacker } else { @@ -13955,7 +13955,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) { if (Buyer) { Trader_EndTrader(); - Message(13, "You cannot be a Trader and Buyer at the same time."); + Message(Chat::Red, "You cannot be a Trader and Buyer at the same time."); return; } @@ -13974,20 +13974,20 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app) if (gis->Items[i] == 0) break; if (ints->ItemCost[i] == 0) { - Message(13, "Item in Trader Satchel with no price. Unable to start trader mode"); + Message(Chat::Red, "Item in Trader Satchel with no price. Unable to start trader mode"); TradeItemsValid = false; break; } const EQEmu::ItemData *Item = database.GetItem(gis->Items[i]); if (!Item) { - Message(13, "Unexpected error. Unable to start trader mode"); + Message(Chat::Red, "Unexpected error. Unable to start trader mode"); TradeItemsValid = false; break; } if (Item->NoDrop == 0) { - Message(13, "NODROP Item in Trader Satchel. Unable to start trader mode"); + Message(Chat::Red, "NODROP Item in Trader Satchel. Unable to start trader mode"); TradeItemsValid = false; break; } @@ -14209,7 +14209,7 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app) } else { - Message_StringID(clientMessageYellow, TRADER_BUSY); + Message_StringID(Chat::Yellow, TRADER_BUSY); Log(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy"); } @@ -14287,7 +14287,7 @@ void Client::Handle_OP_TradeSkillCombine(const EQApplicationPacket *app) return; } /*if (m_tradeskill_object == nullptr) { - Message(13, "Error: Server is not aware of the tradeskill container you are attempting to use"); + Message(Chat::Red, "Error: Server is not aware of the tradeskill container you are attempting to use"); return; }*/ @@ -14313,7 +14313,7 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app) return; if ((RuleI(Spells, TranslocateTimeLimit) > 0) && (time(nullptr) > (TranslocateTime + RuleI(Spells, TranslocateTimeLimit)))) { - Message(13, "You did not accept the Translocate within the required time limit."); + Message(Chat::Red, "You did not accept the Translocate within the required time limit."); PendingTranslocate = false; return; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 244f36580..ecbf90d1e 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -378,10 +378,10 @@ bool Client::Process() { } if (!CombatRange(auto_attack_target)) { - Message_StringID(MT_TooFarAway, TARGET_TOO_FAR); + Message_StringID(Chat::TooFarAway, TARGET_TOO_FAR); } else if (auto_attack_target == this) { - Message_StringID(MT_TooFarAway, TRY_ATTACKING_SOMEONE); + Message_StringID(Chat::TooFarAway, TRY_ATTACKING_SOMEONE); } else if (!los_status || !los_status_facing) { //you can't see your target @@ -416,11 +416,11 @@ bool Client::Process() { // Range check if (!CombatRange(auto_attack_target)) { // this is a duplicate message don't use it. - //Message_StringID(MT_TooFarAway,TARGET_TOO_FAR); + //Message_StringID(Chat::TooFarAway,TARGET_TOO_FAR); } // Don't attack yourself else if (auto_attack_target == this) { - //Message_StringID(MT_TooFarAway,TRY_ATTACKING_SOMEONE); + //Message_StringID(Chat::TooFarAway,TRY_ATTACKING_SOMEONE); } else if (!los_status || !los_status_facing) { @@ -951,9 +951,9 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { sprintf(handy_id, "%i", greet_id); if (greet_id != MERCHANT_GREETING) - Message_StringID(10, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName(), handyitem->Name); + Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName(), handyitem->Name); else - Message_StringID(10, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName()); + Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName()); } // safe_delete_array(cpi); @@ -989,7 +989,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I if(PendingRezzXP < 0) { // pendingrezexp is set to -1 if we are not expecting an OP_RezzAnswer Log(Logs::Detail, Logs::Spells, "Unexpected OP_RezzAnswer. Ignoring it."); - Message(13, "You have already been resurrected.\n"); + Message(Chat::Red, "You have already been resurrected.\n"); return; } @@ -1043,7 +1043,7 @@ void Client::OPTGB(const EQApplicationPacket *app) uint32 tgb_flag = *(uint32 *)app->pBuffer; if(tgb_flag == 2) - Message_StringID(0, TGB() ? TGB_ON : TGB_OFF); + Message_StringID(Chat::White, TGB() ? TGB_ON : TGB_OFF); else tgb = tgb_flag; } @@ -1061,7 +1061,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) if(!IsValidSpell(memspell->spell_id)) { - Message(13, "Unexpected error: spell id out of range"); + Message(Chat::Red, "Unexpected error: spell id out of range"); return; } @@ -1072,8 +1072,8 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) ) { char val1[20]={0}; - Message_StringID(13,SPELL_LEVEL_TO_LOW,ConvertArray(spells[memspell->spell_id].classes[GetClass()-1],val1),spells[memspell->spell_id].name); - //Message(13, "Unexpected error: Class cant use this spell at your level!"); + Message_StringID(Chat::Red,SPELL_LEVEL_TO_LOW,ConvertArray(spells[memspell->spell_id].classes[GetClass()-1],val1),spells[memspell->spell_id].name); + //Message(Chat::Red, "Unexpected error: Class cant use this spell at your level!"); return; } @@ -1087,7 +1087,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) const EQEmu::ItemData* item = inst->GetItem(); if (RuleB(Character, RestrictSpellScribing) && !item->IsEquipable(GetRace(), GetClass())) { - Message_StringID(13, CANNOT_USE_ITEM); + Message_StringID(Chat::Red, CANNOT_USE_ITEM); break; } @@ -1439,7 +1439,7 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) } else{ if (to_bucket == &m_pp.platinum_shared || from_bucket == &m_pp.platinum_shared){ - this->Message(13, "::: WARNING! ::: SHARED BANK IS DISABLED AND YOUR PLATINUM WILL BE DESTROYED IF YOU PUT IT HERE"); + this->Message(Chat::Red, "::: WARNING! ::: SHARED BANK IS DISABLED AND YOUR PLATINUM WILL BE DESTROYED IF YOU PUT IT HERE"); } } } @@ -1455,8 +1455,8 @@ void Client::OPMoveCoin(const EQApplicationPacket* app) with->trade->state = Trading; Client* recipient = trader->CastToClient(); - recipient->Message(15, "%s adds some coins to the trade.", GetName()); - recipient->Message(15, "The total trade is: %i PP, %i GP, %i SP, %i CP", + recipient->Message(Chat::Yellow, "%s adds some coins to the trade.", GetName()); + recipient->Message(Chat::Yellow, "The total trade is: %i PP, %i GP, %i SP, %i CP", trade->pp, trade->gp, trade->sp, trade->cp ); @@ -1645,7 +1645,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) case EQEmu::skills::SkillJewelryMaking: case EQEmu::skills::SkillPottery: if(skilllevel >= RuleI(Skills, MaxTrainTradeskills)) { - Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } break; @@ -1655,7 +1655,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) case EQEmu::skills::SkillSpecializeDivination: case EQEmu::skills::SkillSpecializeEvocation: if(skilllevel >= RuleI(Skills, MaxTrainSpecializations)) { - Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } default: @@ -1666,7 +1666,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) if (skilllevel >= MaxSkillValue) { // Don't allow training over max skill level - Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } @@ -1676,7 +1676,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) if (skilllevel >= MaxSpecSkill) { // Restrict specialization training to follow the rules - Message_StringID(13, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } } @@ -1919,7 +1919,7 @@ void Client::DoTracking() Mob *m = entity_list.GetMob(TrackingID); if (!m || m->IsCorpse()) { - Message_StringID(MT_Skills, TRACK_LOST_TARGET); + Message_StringID(Chat::Skills, TRACK_LOST_TARGET); TrackingID = 0; return; } @@ -1930,23 +1930,23 @@ void Client::DoTracking() RelativeHeading += 512; if (RelativeHeading > 480) - Message_StringID(MT_Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); + Message_StringID(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); else if (RelativeHeading > 416) - Message_StringID(MT_Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left"); + Message_StringID(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left"); else if (RelativeHeading > 352) - Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "left"); + Message_StringID(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "left"); else if (RelativeHeading > 288) - Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); + Message_StringID(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); else if (RelativeHeading > 224) - Message_StringID(MT_Skills, TRACK_BEHIND_YOU, m->GetCleanName()); + Message_StringID(Chat::Skills, TRACK_BEHIND_YOU, m->GetCleanName()); else if (RelativeHeading > 160) - Message_StringID(MT_Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); + Message_StringID(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); else if (RelativeHeading > 96) - Message_StringID(MT_Skills, TRACK_TO_THE, m->GetCleanName(), "right"); + Message_StringID(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "right"); else if (RelativeHeading > 32) - Message_StringID(MT_Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); + Message_StringID(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); else if (RelativeHeading >= 0) - Message_StringID(MT_Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); + Message_StringID(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); } void Client::HandleRespawnFromHover(uint32 Option) diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 1465064f3..942c3374b 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -889,14 +889,14 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a if(IsPlayerCorpse() && !corpse_db_id) { // really should try to resave in this case // SendLootReqErrorPacket(client, 0); - client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); + client->Message(Chat::Red, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl; // return; } if(is_locked && client->Admin() < 100) { SendLootReqErrorPacket(client, LootResponse::SomeoneElse); - client->Message(13, "Error: Corpse locked by GM."); + client->Message(Chat::Red, "Error: Corpse locked by GM."); return; } @@ -960,7 +960,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a loot_coin = (tmp[0] == 1 && tmp[1] == '\0'); if (loot_request_type == LootRequestType::GMPeek || loot_request_type == LootRequestType::GMAllowed) { - client->Message(15, "This corpse contains %u platinum, %u gold, %u silver and %u copper.", + client->Message(Chat::Yellow, "This corpse contains %u platinum, %u gold, %u silver and %u copper.", GetPlatinum(), GetGold(), GetSilver(), GetCopper()); auto outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct)); @@ -1035,7 +1035,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a else { Log(Logs::General, Logs::Inventory, "MakeLootRequestPackets() PlayerKillItem %i not found", pkitemid); - client->Message(CC_Red, "PlayerKillItem (id: %i) could not be found!", pkitemid); + client->Message(Chat::Red, "PlayerKillItem (id: %i) could not be found!", pkitemid); } client->QueuePacket(app); @@ -1129,7 +1129,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) /* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */ if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) { - client->Message(13, "You may not loot an item while you have an item on your cursor."); + client->Message(Chat::Red, "You may not loot an item while you have an item on your cursor."); client->QueuePacket(app); SendEndLootErrorPacket(client); /* Unlock corpse for others */ @@ -1146,7 +1146,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) { - client->Message(13, "Error: This is a player corpse and you dont own it."); + client->Message(Chat::Red, "Error: This is a player corpse and you dont own it."); client->QueuePacket(app); SendEndLootErrorPacket(client); return; @@ -1155,13 +1155,13 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) if (is_locked && client->Admin() < 100) { client->QueuePacket(app); SendLootReqErrorPacket(client, LootResponse::SomeoneElse); - client->Message(13, "Error: Corpse locked by GM."); + client->Message(Chat::Red, "Error: Corpse locked by GM."); return; } if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPlayerKillItem() == 0) { - client->Message(13, "Error: You cannot loot any more items from this corpse."); + client->Message(Chat::Red, "Error: You cannot loot any more items from this corpse."); client->QueuePacket(app); SendEndLootErrorPacket(client); ResetLooter(); @@ -1201,7 +1201,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) if (client && inst) { if (client->CheckLoreConflict(item)) { - client->Message_StringID(0, LOOT_LORE_ERROR); + client->Message_StringID(Chat::White, LOOT_LORE_ERROR); client->QueuePacket(app); SendEndLootErrorPacket(client); ResetLooter(); @@ -1214,7 +1214,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) EQEmu::ItemInstance *itm = inst->GetAugment(i); if (itm) { if (client->CheckLoreConflict(itm->GetItem())) { - client->Message_StringID(0, LOOT_LORE_ERROR); + client->Message_StringID(Chat::White, LOOT_LORE_ERROR); client->QueuePacket(app); SendEndLootErrorPacket(client); ResetLooter(); @@ -1236,7 +1236,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) args.push_back(this); if (parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args) != 0) { lootitem->auto_loot = -1; - client->Message_StringID(CC_Red, LOOT_NOT_ALLOWED, inst->GetItem()->Name); + client->Message_StringID(Chat::Red, LOOT_NOT_ALLOWED, inst->GetItem()->Name); client->QueuePacket(app); delete inst; return; @@ -1312,18 +1312,18 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) linker.GenerateLink(); - client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, linker.Link().c_str()); + client->Message_StringID(Chat::Loot, LOOTED_MESSAGE, linker.Link().c_str()); if (!IsPlayerCorpse()) { Group *g = client->GetGroup(); if (g != nullptr) { - g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, + g->GroupMessage_StringID(client, Chat::Loot, OTHER_LOOTED_MESSAGE, client->GetName(), linker.Link().c_str()); } else { Raid *r = client->GetRaid(); if (r != nullptr) { - r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, + r->RaidMessage_StringID(client, Chat::Loot, OTHER_LOOTED_MESSAGE, client->GetName(), linker.Link().c_str()); } } @@ -1426,7 +1426,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) { if (!spell) { if (this->GetCharID() == client->CharacterID()) { if (IsLocked() && client->Admin() < 100) { - client->Message(13, "That corpse is locked by a GM."); + client->Message(Chat::Red, "That corpse is locked by a GM."); return false; } if (!CheckDistance || (DistanceSquaredNoZ(m_Position, client->GetPosition()) <= dist2)) { diff --git a/zone/doors.cpp b/zone/doors.cpp index 899e3f6b5..15f61ba47 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -171,7 +171,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { if (RuleI(Adventure, ItemIDToEnablePorts) != 0) { if (!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) { if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) { - sender->Message_StringID(13, DUNGEON_SEALED); + sender->Message_StringID(Chat::Red, DUNGEON_SEALED); safe_delete(outapp); return; } else { @@ -267,7 +267,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { strcpy(door_message, "Door is locked by an unknown guild"); } - sender->Message(4, door_message); + sender->Message(Chat::LightBlue, door_message); safe_delete(outapp); return; } @@ -275,13 +275,13 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { /** * Key required */ - sender->Message(4, "This is locked..."); + sender->Message(Chat::LightBlue, "This is locked..."); /** * GM can always open locks */ if (sender->GetGM()) { - sender->Message_StringID(4, DOORS_GM); + sender->Message_StringID(Chat::LightBlue, DOORS_GM); if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); @@ -306,7 +306,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { sender->KeyRingAdd(player_key); } - sender->Message(4, "You got it open!"); + sender->Message(Chat::LightBlue, "You got it open!"); if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); @@ -333,19 +333,19 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { } else { move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } - sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK); + sender->Message_StringID(Chat::LightBlue, DOORS_SUCCESSFUL_PICK); } else { - sender->Message_StringID(4, DOORS_INSUFFICIENT_SKILL); + sender->Message_StringID(Chat::LightBlue, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } } else { - sender->Message_StringID(4, DOORS_NO_PICK); + sender->Message_StringID(Chat::LightBlue, DOORS_NO_PICK); safe_delete(outapp); return; } } else { - sender->Message_StringID(4, DOORS_CANT_PICK); + sender->Message_StringID(Chat::LightBlue, DOORS_CANT_PICK); safe_delete(outapp); return; } @@ -361,14 +361,14 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { */ if (sender->KeyRingCheck(required_key_item)) { player_key = required_key_item; - sender->Message(4, "You got it open!"); // more debug spam + sender->Message(Chat::LightBlue, "You got it open!"); // more debug spam if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); } else { move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } else { - sender->Message_StringID(4, DOORS_LOCKED); + sender->Message_StringID(Chat::LightBlue, DOORS_LOCKED); safe_delete(outapp); return; } diff --git a/zone/effects.cpp b/zone/effects.cpp index 7887eb652..e51d540ad 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -122,11 +122,11 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { else if (IsNPC() && CastToNPC()->GetSpellScale()) value = int(static_cast(value) * CastToNPC()->GetSpellScale() / 100.0f); - entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, + entity_list.MessageClose_StringID(this, true, 100, Chat::SpellCrit, OTHER_CRIT_BLAST, GetName(), itoa(-value)); if (IsClient()) - Message_StringID(MT_SpellCrits, YOU_CRIT_BLAST, itoa(-value)); + Message_StringID(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value)); return value; } @@ -306,11 +306,11 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { value = int(static_cast(value) * CastToNPC()->GetHealScale() / 100.0f); if (Critical) { - entity_list.MessageClose_StringID(this, true, 100, MT_SpellCrits, + entity_list.MessageClose_StringID(this, true, 100, Chat::SpellCrit, OTHER_CRIT_HEAL, GetName(), itoa(value)); if (IsClient()) - Message_StringID(MT_SpellCrits, YOU_CRIT_HEAL, itoa(value)); + Message_StringID(Chat::SpellCrit, YOU_CRIT_HEAL, itoa(value)); } return value; @@ -432,13 +432,13 @@ bool Client::TrainDiscipline(uint32 itemid) { //get the item info const EQEmu::ItemData *item = database.GetItem(itemid); if(item == nullptr) { - Message(13, "Unable to find the tome you turned in!"); + Message(Chat::Red, "Unable to find the tome you turned in!"); Log(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid); return(false); } if (!item->IsClassCommon() || item->ItemType != EQEmu::item::ItemTypeSpell) { - Message(13, "Invalid item type, you cannot learn from this item."); + Message(Chat::Red, "Invalid item type, you cannot learn from this item."); //summon them the item back... SummonItem(itemid); return(false); @@ -462,7 +462,7 @@ bool Client::TrainDiscipline(uint32 itemid) { item->Name[5] == ':' && item->Name[6] == ' ' )) { - Message(13, "This item is not a tome."); + Message(Chat::Red, "This item is not a tome."); //summon them the item back... SummonItem(itemid); return(false); @@ -470,7 +470,7 @@ bool Client::TrainDiscipline(uint32 itemid) { int myclass = GetClass(); if(myclass == WIZARD || myclass == ENCHANTER || myclass == MAGICIAN || myclass == NECROMANCER) { - Message(13, "Your class cannot learn from this tome."); + Message(Chat::Red, "Your class cannot learn from this tome."); //summon them the item back... SummonItem(itemid); return(false); @@ -480,7 +480,7 @@ bool Client::TrainDiscipline(uint32 itemid) { //can we use the item? uint32 cbit = 1 << (myclass-1); if(!(item->Classes & cbit)) { - Message(13, "Your class cannot learn from this tome."); + Message(Chat::Red, "Your class cannot learn from this tome."); //summon them the item back... SummonItem(itemid); return(false); @@ -488,7 +488,7 @@ bool Client::TrainDiscipline(uint32 itemid) { uint32 spell_id = item->Scroll.Effect; if(!IsValidSpell(spell_id)) { - Message(13, "This tome contains invalid knowledge."); + Message(Chat::Red, "This tome contains invalid knowledge."); return(false); } @@ -496,14 +496,14 @@ bool Client::TrainDiscipline(uint32 itemid) { const SPDat_Spell_Struct &spell = spells[spell_id]; uint8 level_to_use = spell.classes[myclass - 1]; if(level_to_use == 255) { - Message(13, "Your class cannot learn from this tome."); + Message(Chat::Red, "Your class cannot learn from this tome."); //summon them the item back... SummonItem(itemid); return(false); } if(level_to_use > GetLevel()) { - Message(13, "You must be at least level %d to learn this discipline.", level_to_use); + Message(Chat::Red, "You must be at least level %d to learn this discipline.", level_to_use); //summon them the item back... SummonItem(itemid); return(false); @@ -513,7 +513,7 @@ bool Client::TrainDiscipline(uint32 itemid) { int r; for(r = 0; r < MAX_PP_DISCIPLINES; r++) { if(m_pp.disciplines.values[r] == spell_id) { - Message(13, "You already know this discipline."); + Message(Chat::Red, "You already know this discipline."); //summon them the item back... SummonItem(itemid); return(false); @@ -525,7 +525,7 @@ bool Client::TrainDiscipline(uint32 itemid) { return(true); } } - Message(13, "You have learned too many disciplines and can learn no more."); + Message(Chat::Red, "You have learned too many disciplines and can learn no more."); return(false); } @@ -537,7 +537,7 @@ void Client::TrainDiscBySpellID(int32 spell_id) m_pp.disciplines.values[i] = spell_id; database.SaveCharacterDisc(this->CharacterID(), i, spell_id); SendDisciplineUpdate(); - Message(15, "You have learned a new combat ability!"); + Message(Chat::Yellow, "You have learned a new combat ability!"); return; } } @@ -581,7 +581,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { //make sure we can use it.. if(!IsValidSpell(spell_id)) { - Message(13, "This tome contains invalid knowledge."); + Message(Chat::Red, "This tome contains invalid knowledge."); return(false); } @@ -589,13 +589,13 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { const SPDat_Spell_Struct &spell = spells[spell_id]; uint8 level_to_use = spell.classes[GetClass() - 1]; if(level_to_use == 255) { - Message(13, "Your class cannot learn from this tome."); + Message(Chat::Red, "Your class cannot learn from this tome."); //should summon them a new one... return(false); } if(level_to_use > GetLevel()) { - Message_StringID(13, DISC_LEVEL_USE_ERROR); + Message_StringID(Chat::Red, DISC_LEVEL_USE_ERROR); //should summon them a new one... return(false); } @@ -607,7 +607,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { // sneak attack discs require you to be hidden for 4 seconds before use if (spell.sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) { - Message_StringID(MT_SpellFailure, SNEAK_RESTRICT); + Message_StringID(Chat::SpellFailure, SNEAK_RESTRICT); return false; } @@ -621,7 +621,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { /*char val1[20]={0};*/ //unused /*char val2[20]={0};*/ //unused uint32 remain = p_timers.GetRemainingTime(DiscTimer); - //Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); + //Message_StringID(Chat::WhiteSmoke, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60)); return(false); } diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index bdb190e9c..5cb17ca50 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -160,7 +160,7 @@ XS(XS__say) { opts.speak_mode = Journal::SpeakMode::Say; opts.journal_mode = Journal::Mode::Log2; opts.language = 0; - opts.message_type = MT_NPCQuestSay; + opts.message_type = Chat::NPCQuestSay; if (items == 0 || items > 5) { Perl_croak(aTHX_ "Usage: quest::say(string message, [int language_id], [int message_type], [int speak_mode], [int journal_mode])"); } else if (items == 2) { diff --git a/zone/entity.cpp b/zone/entity.cpp index 1c8de0780..97678b2d0 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1671,9 +1671,9 @@ void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee) //might want some sort of distance check in here? if (cur != winner && cur != loser) { if (flee) - cur->Message_StringID(15, DUEL_FLED, winner->GetName(),loser->GetName(),loser->GetName()); + cur->Message_StringID(Chat::Yellow, DUEL_FLED, winner->GetName(),loser->GetName(),loser->GetName()); else - cur->Message_StringID(15, DUEL_FINISHED, winner->GetName(),loser->GetName()); + cur->Message_StringID(Chat::Yellow, DUEL_FINISHED, winner->GetName(),loser->GetName()); } ++it; } @@ -2099,6 +2099,23 @@ void EntityList::MessageClose_StringID(Mob *sender, bool skipsender, float dist, } } +/** + * @param sender + * @param skipsender + * @param dist + * @param type + * @param filter + * @param string_id + * @param message1 + * @param message2 + * @param message3 + * @param message4 + * @param message5 + * @param message6 + * @param message7 + * @param message8 + * @param message9 + */ void EntityList::FilteredMessageClose_StringID(Mob *sender, bool skipsender, float dist, uint32 type, eqFilterType filter, uint32 string_id, const char *message1, const char *message2, const char *message3, @@ -2774,7 +2791,7 @@ void EntityList::CorpseFix(Client* c) Corpse* corpse = it->second; if (corpse->IsNPCCorpse()) { if (DistanceNoZ(c->GetPosition(), corpse->GetPosition()) < 100) { - c->Message(15, "Attempting to fix %s", it->second->GetCleanName()); + c->Message(Chat::Yellow, "Attempting to fix %s", it->second->GetCleanName()); corpse->GMMove(corpse->GetX(), corpse->GetY(), c->GetZ() + 2, 0); } } @@ -4632,7 +4649,7 @@ void EntityList::ExpeditionWarning(uint32 minutes_left) auto it = client_list.begin(); while (it != client_list.end()) { - it->second->Message_StringID(15, EXPEDITION_MIN_REMAIN, itoa((int)minutes_left)); + it->second->Message_StringID(Chat::Yellow, EXPEDITION_MIN_REMAIN, itoa((int)minutes_left)); it->second->QueuePacket(outapp); ++it; } diff --git a/zone/exp.cpp b/zone/exp.cpp index 63fbff79a..2fe87997b 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -333,18 +333,18 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f); exp -= mentor_exp; mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down - mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP); + mentoree->Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } if (exp > 0) { // possible if you mentor 100% to the other client AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it - Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP); + Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } } else { - Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS); + Message_StringID(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); } } else @@ -357,11 +357,11 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) && RuleI(Character, KillsPerRaidLeadershipAA) > 0) { AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA)); - Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_EXP); + Message_StringID(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_EXP); } else { - Message_StringID(MT_Leadership, MAX_RAID_LEADERSHIP_POINTS); + Message_StringID(Chat::LeaderShip, MAX_RAID_LEADERSHIP_POINTS); } } else @@ -378,17 +378,17 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f); exp -= mentor_exp; mentoree->AddLeadershipEXP(mentor_exp, 0); - mentoree->Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP); + mentoree->Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } if (exp > 0) { AddLeadershipEXP(exp, 0); - Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_EXP); + Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } } else { - Message_StringID(MT_Leadership, MAX_GROUP_LEADERSHIP_POINTS); + Message_StringID(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); } } } @@ -514,7 +514,7 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) { // AA Sanity Checking for players who set aa exp and deleveled below allowed aa level. if (GetLevel() <= 50 && m_epp.perAA > 0) { - Message(15, "You are below the level allowed to gain AA Experience. AA Experience set to 0%"); + Message(Chat::Yellow, "You are below the level allowed to gain AA Experience. AA Experience set to 0%"); aaexp = 0; m_epp.perAA = 0; } @@ -528,7 +528,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { auto max_AAXP = GetRequiredAAExperience(); if (max_AAXP == 0 || GetEXPForLevel(GetLevel()) == 0xFFFFFFFF) { - Message(13, "Error in Client::SetEXP. EXP not set."); + Message(Chat::Red, "Error in Client::SetEXP. EXP not set."); return; // Must be invalid class/race } uint32 i = 0; @@ -564,23 +564,23 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { if (isrezzexp) { if (RuleI(Character, ShowExpValues) > 0) - Message(MT_Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(MT_Experience, REZ_REGAIN); + Message(Chat::Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str()); + else Message_StringID(Chat::Experience, REZ_REGAIN); } else { if (membercount > 1) { if (RuleI(Character, ShowExpValues) > 0) - Message(MT_Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(MT_Experience, GAIN_GROUPXP); + Message(Chat::Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); + else Message_StringID(Chat::Experience, GAIN_GROUPXP); } else if (IsRaidGrouped()) { if (RuleI(Character, ShowExpValues) > 0) - Message(MT_Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(MT_Experience, GAIN_RAIDEXP); + Message(Chat::Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); + else Message_StringID(Chat::Experience, GAIN_RAIDEXP); } else { if (RuleI(Character, ShowExpValues) > 0) - Message(MT_Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(MT_Experience, GAIN_XP); + Message(Chat::Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); + else Message_StringID(Chat::Experience, GAIN_XP); } } } @@ -588,9 +588,9 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { uint32 exp_lost = m_pp.exp - set_exp; float exp_percent = (float)((float)exp_lost / (float)(GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())))*(float)100; - if (RuleI(Character, ShowExpValues) == 1 && exp_lost > 0) Message(15, "You have lost %i experience.", exp_lost); - else if (RuleI(Character, ShowExpValues) == 2 && exp_lost > 0) Message(15, "You have lost %i experience. (%.3f%%)", exp_lost, exp_percent); - else Message(15, "You have lost experience."); + if (RuleI(Character, ShowExpValues) == 1 && exp_lost > 0) Message(Chat::Yellow, "You have lost %i experience.", exp_lost); + else if (RuleI(Character, ShowExpValues) == 2 && exp_lost > 0) Message(Chat::Yellow, "You have lost %i experience. (%.3f%%)", exp_lost, exp_percent); + else Message(Chat::Yellow, "You have lost experience."); } //check_level represents the level we should be when we have @@ -654,9 +654,9 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { //figure out how many points were actually gained /*uint32 gained = m_pp.aapoints - last_unspentAA;*/ //unused - //Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA); + //Message(Chat::Yellow, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA); char val1[20]={0}; - Message_StringID(MT_Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2. + Message_StringID(Chat::Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2. /* QS: PlayerLogAARate */ if (RuleB(QueryServ, PlayerLogAARate)){ @@ -665,7 +665,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { QServ->SendQuery(query.c_str()); } - //Message(15, "You now have %d skill points available to spend.", m_pp.aapoints); + //Message(Chat::Yellow, "You now have %d skill points available to spend.", m_pp.aapoints); } uint8 maxlevel = RuleI(Character, MaxExpLevel) + 1; @@ -699,18 +699,18 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { if (level_increase) { if (level_count == 1) - Message_StringID(MT_Experience, GAIN_LEVEL, ConvertArray(check_level, val1)); + Message_StringID(Chat::Experience, GAIN_LEVEL, ConvertArray(check_level, val1)); else - Message(15, "Welcome to level %i!", check_level); + Message(Chat::Yellow, "Welcome to level %i!", check_level); if (check_level == RuleI(Character, DeathItemLossLevel)) - Message_StringID(15, CORPSE_ITEM_LOST); + Message_StringID(Chat::Yellow, CORPSE_ITEM_LOST); if (check_level == RuleI(Character, DeathExpLossLevel)) - Message_StringID(15, CORPSE_EXP_LOST); + Message_StringID(Chat::Yellow, CORPSE_EXP_LOST); } else - Message_StringID(MT_Experience, LOSE_LEVEL, ConvertArray(check_level, val1)); + Message_StringID(Chat::Experience, LOSE_LEVEL, ConvertArray(check_level, val1)); #ifdef BOTS uint8 myoldlevel = GetLevel(); @@ -758,7 +758,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { char val1[20]={0}; char val2[20]={0}; char val3[20]={0}; - Message_StringID(MT_Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3). + Message_StringID(Chat::Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3). } } @@ -812,7 +812,7 @@ void Client::SetLevel(uint8 set_level, bool command) m_pp.level = set_level; if (command){ m_pp.exp = GetEXPForLevel(set_level); - Message(15, "Welcome to level %i!", set_level); + Message(Chat::Yellow, "Welcome to level %i!", set_level); lu->exp = 0; } else { @@ -1077,12 +1077,12 @@ void Client::SetLeadershipEXP(uint32 group_exp, uint32 raid_exp) { while(group_exp >= GROUP_EXP_PER_POINT) { group_exp -= GROUP_EXP_PER_POINT; m_pp.group_leadership_points++; - Message_StringID(MT_Leadership, GAIN_GROUP_LEADERSHIP_POINT); + Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_POINT); } while(raid_exp >= RAID_EXP_PER_POINT) { raid_exp -= RAID_EXP_PER_POINT; m_pp.raid_leadership_points++; - Message_StringID(MT_Leadership, GAIN_RAID_LEADERSHIP_POINT); + Message_StringID(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_POINT); } m_pp.group_leadership_exp = group_exp; diff --git a/zone/forage.cpp b/zone/forage.cpp index 3bdb87d7a..df3cce2a0 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -161,14 +161,14 @@ bool Client::CanFish() { if (!Pole || !Pole->IsClassCommon() || Pole->GetItem()->ItemType != EQEmu::item::ItemTypeFishingPole) { if (m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingPole, 1, invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor)) //We have a fishing pole somewhere, just not equipped - Message_StringID(MT_Skills, FISHING_EQUIP_POLE); //You need to put your fishing pole in your primary hand. + Message_StringID(Chat::Skills, FISHING_EQUIP_POLE); //You need to put your fishing pole in your primary hand. else //We don't have a fishing pole anywhere - Message_StringID(MT_Skills, FISHING_NO_POLE); //You can't fish without a fishing pole, go buy one. + Message_StringID(Chat::Skills, FISHING_NO_POLE); //You can't fish without a fishing pole, go buy one. return false; } if (!Bait || !Bait->IsClassCommon() || Bait->GetItem()->ItemType != EQEmu::item::ItemTypeFishingBait) { - Message_StringID(MT_Skills, FISHING_NO_BAIT); //You can't fish without fishing bait, go buy some. + Message_StringID(Chat::Skills, FISHING_NO_BAIT); //You can't fish without fishing bait, go buy some. return false; } @@ -190,7 +190,7 @@ bool Client::CanFish() { float bestz = zone->zonemap->FindBestZ(rodPosition, nullptr); float len = m_Position.z - bestz; if(len > LineLength || len < 0.0f) { - Message_StringID(MT_Skills, FISHING_LAND); + Message_StringID(Chat::Skills, FISHING_LAND); return false; } @@ -203,7 +203,7 @@ bool Client::CanFish() { bool in_water = zone->watermap->InWater(dest) || zone->watermap->InVWater(dest); if (in_lava) { - Message_StringID(MT_Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? + Message_StringID(Chat::Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? return false; } @@ -212,7 +212,7 @@ bool Client::CanFish() { } } - Message_StringID(MT_Skills, FISHING_LAND); + Message_StringID(Chat::Skills, FISHING_LAND); return false; } return true; @@ -223,7 +223,7 @@ void Client::GoFish() //TODO: generate a message if we're already fishing /*if (!fishing_timer.Check()) { //this isn't the right check, may need to add something to the Client class like 'bool is_fishing' - Message_StringID(0, ALREADY_FISHING); //You are already fishing! + Message_StringID(Chat::WhiteSmoke, ALREADY_FISHING); //You are already fishing! return; }*/ @@ -293,12 +293,12 @@ void Client::GoFish() entity_list.AddNPC(npc); - Message(MT_Emote, + Message(Chat::Emote, "You fish up a little more than you bargained for..."); } } else { - Message(MT_Emote, "You notice something lurking just below the water's surface..."); + Message(Chat::Emote, "You notice something lurking just below the water's surface..."); } } } @@ -315,17 +315,17 @@ void Client::GoFish() const EQEmu::ItemData* food_item = database.GetItem(food_id); if (food_item->ItemType != EQEmu::item::ItemTypeFood) { - Message_StringID(MT_Skills, FISHING_SUCCESS); + Message_StringID(Chat::Skills, FISHING_SUCCESS); } else { - Message_StringID(MT_Skills, FISHING_SUCCESS_FISH_NAME, food_item->Name); + Message_StringID(Chat::Skills, FISHING_SUCCESS_FISH_NAME, food_item->Name); } EQEmu::ItemInstance* inst = database.CreateItem(food_item, 1); if(inst != nullptr) { if(CheckLoreConflict(inst->GetItem())) { - Message_StringID(0, DUP_LORE); + Message_StringID(Chat::White, DUP_LORE); safe_delete(inst); } else @@ -351,13 +351,13 @@ void Client::GoFish() //chance to use bait when you dont catch anything... if (zone->random.Int(0, 4) == 1) { DeleteItemInInventory(bslot, 1, true); //do we need client update? - Message_StringID(MT_Skills, FISHING_LOST_BAIT); //You lost your bait! + Message_StringID(Chat::Skills, FISHING_LOST_BAIT); //You lost your bait! } else { if (zone->random.Int(0, 15) == 1) //give about a 1 in 15 chance to spill your beer. we could make this a rule, but it doesn't really seem worth it //TODO: check for & consume an alcoholic beverage from inventory when this triggers, and set it as a rule that's disabled by default - Message_StringID(MT_Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. + Message_StringID(Chat::Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. else - Message_StringID(MT_Skills, FISHING_FAILED); //You didn't catch anything. + Message_StringID(Chat::Skills, FISHING_FAILED); //You didn't catch anything. } parse->EventPlayer(EVENT_FISH_FAILURE, this, "", 0); @@ -367,7 +367,7 @@ void Client::GoFish() //this is potentially exploitable in that they can fish //and then swap out items in primary slot... too lazy to fix right now if (zone->random.Int(0, 49) == 1) { - Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke! + Message_StringID(Chat::Skills, FISHING_POLE_BROKE); //Your fishing pole broke! DeleteItemInInventory(EQEmu::invslot::slotPrimary, 0, true); } @@ -434,13 +434,13 @@ void Client::ForageItem(bool guarantee) { break; } - Message_StringID(MT_Skills, stringid); + Message_StringID(Chat::Skills, stringid); EQEmu::ItemInstance* inst = database.CreateItem(food_item, 1); if(inst != nullptr) { // check to make sure it isn't a foraged lore item if(CheckLoreConflict(inst->GetItem())) { - Message_StringID(0, DUP_LORE); + Message_StringID(Chat::White, DUP_LORE); safe_delete(inst); } else { @@ -462,12 +462,12 @@ void Client::ForageItem(bool guarantee) { int ChanceSecondForage = aabonuses.ForageAdditionalItems + itembonuses.ForageAdditionalItems + spellbonuses.ForageAdditionalItems; if(!guarantee && zone->random.Roll(ChanceSecondForage)) { - Message_StringID(MT_Skills, FORAGE_MASTERY); + Message_StringID(Chat::Skills, FORAGE_MASTERY); ForageItem(true); } } else { - Message_StringID(MT_Skills, FORAGE_FAILED); + Message_StringID(Chat::Skills, FORAGE_FAILED); parse->EventPlayer(EVENT_FORAGE_FAILURE, this, "", 0); } diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index eafe4b9f5..43157ed2d 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -1391,7 +1391,7 @@ bool GuildApproval::ProcessApproval() { if(owner && owner->GuildID() != 0) { - owner->Message(10,"You are already in a guild! Guild request deleted."); + owner->Message(Chat::NPCQuestSay,"You are already in a guild! Guild request deleted."); return false; } if(deletion_timer->Check() || !owner) diff --git a/zone/horse.cpp b/zone/horse.cpp index 6c81b3d21..3871b355d 100644 --- a/zone/horse.cpp +++ b/zone/horse.cpp @@ -118,7 +118,7 @@ const NPCType *Horse::BuildHorseType(uint16 spell_id) { void Client::SummonHorse(uint16 spell_id) { if (GetHorseId() != 0) { - Message(13,"You already have a Horse. Get off, Fatbutt!"); + Message(Chat::Red,"You already have a Horse. Get off, Fatbutt!"); return; } if(!Horse::IsHorseSpell(spell_id)) { diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 96f0fe15b..b24d03795 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -185,7 +185,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // make sure the item exists if(item == nullptr) { - Message(13, "Item %u does not exist.", item_id); + Message(Chat::Red, "Item %u does not exist.", item_id); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create an item with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item_id, aug1, aug2, aug3, aug4, aug5, aug6); @@ -194,13 +194,13 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check that there is not a lore conflict between base item and existing inventory else if(CheckLoreConflict(item)) { // DuplicateLoreMessage(item_id); - Message(13, "You already have a lore %s (%i) in your inventory.", item->Name, item_id); + Message(Chat::Red, "You already have a lore %s (%i) in your inventory.", item->Name, item_id); return false; } // check to make sure we are augmenting an augmentable item else if (((!item->IsClassCommon()) || (item->AugType > 0)) && (aug1 | aug2 | aug3 | aug4 | aug5 | aug6)) { - Message(13, "You can not augment an augment or a non-common class item."); + Message(Chat::Red, "You can not augment an augment or a non-common class item."); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to augment an augment or a non-common class item.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug5: %u)\n", GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -214,7 +214,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check to make sure we are a GM if the item is GM-only /* else if(item->MinStatus && ((this->Admin() < item->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) { - Message(13, "You are not a GM or do not have the status to summon this item."); + Message(Chat::Red, "You are not a GM or do not have the status to summon this item."); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create a GM-only item with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u, MinStatus: %u)\n", GetName(), account_name, this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, aug6, item->MinStatus); @@ -237,7 +237,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, if(augtest == nullptr) { if(augments[iter]) { - Message(13, "Augment %u (Aug%i) does not exist.", augments[iter], iter + 1); + Message(Chat::Red, "Augment %u (Aug%i) does not exist.", augments[iter], iter + 1); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create an augment (Aug%i) with an invalid id.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -248,13 +248,13 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check that there is not a lore conflict between augment and existing inventory if(CheckLoreConflict(augtest)) { // DuplicateLoreMessage(augtest->ID); - Message(13, "You already have a lore %s (%u) in your inventory.", augtest->Name, augtest->ID); + Message(Chat::Red, "You already have a lore %s (%u) in your inventory.", augtest->Name, augtest->ID); return false; } // check that augment is an actual augment else if(augtest->AugType == 0) { - Message(13, "%s (%u) (Aug%i) is not an actual augment.", augtest->Name, augtest->ID, iter + 1); + Message(Chat::Red, "%s (%u) (Aug%i) is not an actual augment.", augtest->Name, augtest->ID, iter + 1); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to use a non-augment item (Aug%i) as an augment.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item->ID, (iter + 1), aug1, aug2, aug3, aug4, aug5, aug6); @@ -266,7 +266,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check to make sure we are a GM if the augment is GM-only /* else if(augtest->MinStatus && ((this->Admin() < augtest->MinStatus) || (this->Admin() < RuleI(GM, MinStatusToSummonItem)))) { - Message(13, "You are not a GM or do not have the status to summon this augment."); + Message(Chat::Red, "You are not a GM or do not have the status to summon this augment."); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create a GM-only augment (Aug%i) with a status of %i.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, MinStatus: %u)\n", GetName(), account_name, (iter + 1), this->Admin(), item->ID, aug1, aug2, aug3, aug4, aug5, aug6, item->MinStatus); @@ -277,7 +277,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check for augment type allowance if(enforcewear) { if ((item->AugSlotType[iter] == EQEmu::item::AugTypeNone) || !(((uint32)1 << (item->AugSlotType[iter] - 1)) & augtest->AugType)) { - Message(13, "Augment %u (Aug%i) is not acceptable wear on Item %u.", augments[iter], iter + 1, item->ID); + Message(Chat::Red, "Augment %u (Aug%i) is not acceptable wear on Item %u.", augments[iter], iter + 1, item->ID); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to augment an item with an unacceptable augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -285,7 +285,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, } if(item->AugSlotVisible[iter] == 0) { - Message(13, "Item %u has not evolved enough to accept Augment %u (Aug%i).", item->ID, augments[iter], iter + 1); + Message(Chat::Red, "Item %u has not evolved enough to accept Augment %u (Aug%i).", item->ID, augments[iter], iter + 1); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to augment an unevolved item with augment type (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -462,7 +462,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, } if(restrictfail) { - Message(13, "Augment %u (Aug%i) is restricted from wear on Item %u.", augments[iter], (iter + 1), item->ID); + Message(Chat::Red, "Augment %u (Aug%i) is restricted from wear on Item %u.", augments[iter], (iter + 1), item->ID); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to augment an item with a restricted augment (Aug%i).\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, (iter + 1), item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -473,7 +473,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, if(enforceusable) { // check for class usability if(item->Classes && !(classes &= augtest->Classes)) { - Message(13, "Augment %u (Aug%i) will result in an item not usable by any class.", augments[iter], (iter + 1)); + Message(Chat::Red, "Augment %u (Aug%i) will result in an item not usable by any class.", augments[iter], (iter + 1)); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create an item unusable by any class.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -482,7 +482,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check for race usability if(item->Races && !(races &= augtest->Races)) { - Message(13, "Augment %u (Aug%i) will result in an item not usable by any race.", augments[iter], (iter + 1)); + Message(Chat::Red, "Augment %u (Aug%i) will result in an item not usable by any race.", augments[iter], (iter + 1)); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create an item unusable by any race.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -491,7 +491,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, // check for slot usability if(item->Slots && !(slots &= augtest->Slots)) { - Message(13, "Augment %u (Aug%i) will result in an item not usable in any slot.", augments[iter], (iter + 1)); + Message(Chat::Red, "Augment %u (Aug%i) will result in an item not usable in any slot.", augments[iter], (iter + 1)); Log(Logs::Detail, Logs::Inventory, "Player %s on account %s attempted to create an item unusable in any slot.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -517,7 +517,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, EQEmu::ItemInstance* inst = database.CreateItem(item, charges); if(inst == nullptr) { - Message(13, "An unknown server error has occurred and your item was not created."); + Message(Chat::Red, "An unknown server error has occurred and your item was not created."); // this goes to logfile since this is a major error Log(Logs::General, Logs::Error, "Player %s on account %s encountered an unknown item creation error.\n(Item: %u, Aug1: %u, Aug2: %u, Aug3: %u, Aug4: %u, Aug5: %u, Aug6: %u)\n", GetName(), account_name, item->ID, aug1, aug2, aug3, aug4, aug5, aug6); @@ -652,7 +652,7 @@ void Client::DropItem(int16 slot_id, bool recurse) } else { // Item doesn't exist in inventory! Log(Logs::General, Logs::Inventory, "DropItem() - No item found in slot %i", slot_id); - Message(13, "Error: Item not found in slot %i", slot_id); + Message(Chat::Red, "Error: Item not found in slot %i", slot_id); return; } @@ -752,14 +752,14 @@ void Client::DropInst(const EQEmu::ItemInstance* inst) { if (!inst) { // Item doesn't exist in inventory! - Message(13, "Error: Item not found"); + Message(Chat::Red, "Error: Item not found"); return; } if (inst->GetItem()->NoDrop == 0) { - Message(13, "This item is NODROP. Deleting."); + Message(Chat::Red, "This item is NODROP. Deleting."); return; } @@ -853,7 +853,7 @@ void Client::SendCursorBuffer() if (!lore_pass) { Log(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", GetName(), test_item->Name, test_item->ID); - Message_StringID(MT_LootMessages, 290); + Message_StringID(Chat::Loot, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); DeleteItemInInventory(EQEmu::invslot::slotCursor); SendCursorBuffer(); @@ -1520,7 +1520,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(!IsValidSlot(src_slot_check)){ // SoF+ sends a Unix timestamp (should be int32) for src and dst slots every 10 minutes for some reason. if(src_slot_check < 2147483647) - Message(13, "Warning: Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); + Message(Chat::Red, "Warning: Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); Log(Logs::Detail, Logs::Inventory, "Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); return false; } @@ -1528,7 +1528,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if(!IsValidSlot(dst_slot_check)) { // SoF+ sends a Unix timestamp (should be int32) for src and dst slots every 10 minutes for some reason. if(src_slot_check < 2147483647) - Message(13, "Warning: Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); + Message(Chat::Red, "Warning: Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); Log(Logs::Detail, Logs::Inventory, "Invalid slot move from slot %u to slot %u with %u charges!", src_slot_check, dst_slot_check, stack_count_check); return false; } @@ -1555,7 +1555,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if (!lore_pass) { Log(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", GetName(), test_item->Name, test_item->ID); - Message_StringID(MT_LootMessages, 290); + Message_StringID(Chat::Loot, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); DeleteItemInInventory(EQEmu::invslot::slotCursor, 0, true); } @@ -1624,7 +1624,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { //SetTint(dst_slot_id,src_inst->GetColor()); if (src_inst->GetCharges() > 0 && (src_inst->GetCharges() < (int16)move_in->number_in_stack || move_in->number_in_stack > src_inst->GetItem()->StackSize)) { - Message(13,"Error: Insufficient number in stack."); + Message(Chat::Red,"Error: Insufficient number in stack."); return false; } } @@ -1650,7 +1650,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { } if (srcitemid==17899 || srcbagid==17899 || dstitemid==17899 || dstbagid==17899){ this->Trader_EndTrader(); - this->Message(13,"You cannot move your Trader Satchels, or items inside them, while Trading."); + this->Message(Chat::Red,"You cannot move your Trader Satchels, or items inside them, while Trading."); } } @@ -1829,7 +1829,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { Log(Logs::Detail, Logs::Inventory, "Trade item move from slot %d to slot %d (trade with %s)", src_slot_id, dst_slot_id, with->GetName()); // Fill Trade list with items from cursor if (!m_inv[EQEmu::invslot::slotCursor]) { - Message(13, "Error: Cursor item not located on server!"); + Message(Chat::Red, "Error: Cursor item not located on server!"); return false; } @@ -1939,7 +1939,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { fail_message = "You are not sufficient level to use this item."; if (fail_message) - Message(CC_Red, "%s", fail_message); + Message(Chat::Red, "%s", fail_message); return false; } @@ -2008,7 +2008,7 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { // resync the 'from' and 'to' slots on an as-needed basis // Not as effective as the full process, but less intrusive to gameplay Log(Logs::Detail, Logs::Inventory, "Inventory desyncronization. (charname: %s, source: %i, destination: %i)", GetName(), move_slots->from_slot, move_slots->to_slot); - Message(15, "Inventory Desyncronization detected: Resending slot data..."); + Message(Chat::Yellow, "Inventory Desyncronization detected: Resending slot data..."); if (move_slots->from_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->from_slot <= EQEmu::invbag::CURSOR_BAG_END) { int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot); @@ -2031,9 +2031,9 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { safe_delete(outapp); } safe_delete(token_inst); - Message(14, "Source slot %i resyncronized.", move_slots->from_slot); + Message(Chat::Lime, "Source slot %i resyncronized.", move_slots->from_slot); } - else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); } + else { Message(Chat::Red, "Could not resyncronize source slot %i.", move_slots->from_slot); } } else { int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot) == INVALID_INDEX) ? move_slots->from_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->from_slot); @@ -2046,11 +2046,11 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade); safe_delete(token_inst); - Message(14, "Source slot %i resyncronized.", move_slots->from_slot); + Message(Chat::Lime, "Source slot %i resyncronized.", move_slots->from_slot); } - else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); } + else { Message(Chat::Red, "Could not resyncronize source slot %i.", move_slots->from_slot); } } - else { Message(13, "Could not resyncronize source slot %i.", move_slots->from_slot); } + else { Message(Chat::Red, "Could not resyncronize source slot %i.", move_slots->from_slot); } } if (move_slots->to_slot >= EQEmu::invslot::EQUIPMENT_BEGIN && move_slots->to_slot <= EQEmu::invbag::CURSOR_BAG_END) { @@ -2073,9 +2073,9 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { safe_delete(outapp); } safe_delete(token_inst); - Message(14, "Destination slot %i resyncronized.", move_slots->to_slot); + Message(Chat::Lime, "Destination slot %i resyncronized.", move_slots->to_slot); } - else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); } + else { Message(Chat::Red, "Could not resyncronize destination slot %i.", move_slots->to_slot); } } else { int16 resync_slot = (EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot) == INVALID_INDEX) ? move_slots->to_slot : EQEmu::InventoryProfile::CalcSlotId(move_slots->to_slot); @@ -2088,11 +2088,11 @@ void Client::SwapItemResync(MoveItem_Struct* move_slots) { SendItemPacket(resync_slot, m_inv[resync_slot], ItemPacketTrade); safe_delete(token_inst); - Message(14, "Destination slot %i resyncronized.", move_slots->to_slot); + Message(Chat::Lime, "Destination slot %i resyncronized.", move_slots->to_slot); } - else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); } + else { Message(Chat::Red, "Could not resyncronize destination slot %i.", move_slots->to_slot); } } - else { Message(13, "Could not resyncronize destination slot %i.", move_slots->to_slot); } + else { Message(Chat::Red, "Could not resyncronize destination slot %i.", move_slots->to_slot); } } } @@ -2219,7 +2219,7 @@ void Client::DyeArmor(EQEmu::TintProfile* dye){ SendWearChange(i); } else{ - Message(13,"Could not locate A Vial of Prismatic Dye."); + Message(Chat::Red,"Could not locate A Vial of Prismatic Dye."); return; } } @@ -3406,9 +3406,9 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool } if (error) { - Message(13, "An error has been discovered in your inventory!"); - Message(13, "Do not log out, zone or re-arrange items until this"); - Message(13, "issue has been resolved or item loss may occur!"); + Message(Chat::Red, "An error has been discovered in your inventory!"); + Message(Chat::Red, "Do not log out, zone or re-arrange items until this"); + Message(Chat::Red, "issue has been resolved or item loss may occur!"); if (allowtrip) TripInterrogateInvState(); @@ -3466,7 +3466,7 @@ void Client::InterrogateInventory_(bool errorcheck, Client* requester, int16 hea head, depth, i.c_str(), p.c_str(), e.c_str()); } if (!silent) { - requester->Message(6, "%i:%i - inst: %s - parent: %s%s", + requester->Message(Chat::Gray, "%i:%i - inst: %s - parent: %s%s", head, depth, i.c_str(), p.c_str(), e.c_str()); } diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index ef9180b68..4dddd887d 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -2234,92 +2234,92 @@ luabind::scope lua_register_message_types() { return luabind::class_("MT") .enum_("constants") [ - luabind::value("NPCQuestSay", MT_NPCQuestSay), - luabind::value("Say", MT_Say), - luabind::value("Tell", MT_Tell), - luabind::value("Group", MT_Group), - luabind::value("Guild", MT_Guild), - luabind::value("OOC", MT_OOC), - luabind::value("Auction", MT_Auction), - luabind::value("Shout", MT_Shout), - luabind::value("Emote", MT_Emote), - luabind::value("Spells", MT_Spells), - luabind::value("YouHitOther", MT_YouHitOther), - luabind::value("OtherHitsYou", MT_OtherHitsYou), - luabind::value("YouMissOther", MT_YouMissOther), - luabind::value("OtherMissesYou", MT_OtherMissesYou), - luabind::value("Broadcasts", MT_Broadcasts), - luabind::value("Skills", MT_Skills), - luabind::value("Disciplines", MT_Disciplines), - luabind::value("Unused1", MT_Unused1), - luabind::value("DefaultText", MT_DefaultText), - luabind::value("Unused2", MT_Unused2), - luabind::value("MerchantOffer", MT_MerchantOffer), - luabind::value("MerchantBuySell", MT_MerchantBuySell), - luabind::value("YourDeath", MT_YourDeath), - luabind::value("OtherDeath", MT_OtherDeath), - luabind::value("OtherHits", MT_OtherHits), - luabind::value("OtherMisses", MT_OtherMisses), - luabind::value("Who", MT_Who), - luabind::value("YellForHelp", MT_YellForHelp), - luabind::value("NonMelee", MT_NonMelee), - luabind::value("WornOff", MT_WornOff), - luabind::value("MoneySplit", MT_MoneySplit), - luabind::value("LootMessages", MT_LootMessages), - luabind::value("DiceRoll", MT_DiceRoll), - luabind::value("OtherSpells", MT_OtherSpells), - luabind::value("SpellFailure", MT_SpellFailure), - luabind::value("Chat", MT_Chat), - luabind::value("Channel1", MT_Channel1), - luabind::value("Channel2", MT_Channel2), - luabind::value("Channel3", MT_Channel3), - luabind::value("Channel4", MT_Channel4), - luabind::value("Channel5", MT_Channel5), - luabind::value("Channel6", MT_Channel6), - luabind::value("Channel7", MT_Channel7), - luabind::value("Channel8", MT_Channel8), - luabind::value("Channel9", MT_Channel9), - luabind::value("Channel10", MT_Channel10), - luabind::value("CritMelee", MT_CritMelee), - luabind::value("SpellCrits", MT_SpellCrits), - luabind::value("TooFarAway", MT_TooFarAway), - luabind::value("NPCRampage", MT_NPCRampage), - luabind::value("NPCFlurry", MT_NPCFlurry), - luabind::value("NPCEnrage", MT_NPCEnrage), - luabind::value("SayEcho", MT_SayEcho), - luabind::value("TellEcho", MT_TellEcho), - luabind::value("GroupEcho", MT_GroupEcho), - luabind::value("GuildEcho", MT_GuildEcho), - luabind::value("OOCEcho", MT_OOCEcho), - luabind::value("AuctionEcho", MT_AuctionEcho), - luabind::value("ShoutECho", MT_ShoutECho), - luabind::value("EmoteEcho", MT_EmoteEcho), - luabind::value("Chat1Echo", MT_Chat1Echo), - luabind::value("Chat2Echo", MT_Chat2Echo), - luabind::value("Chat3Echo", MT_Chat3Echo), - luabind::value("Chat4Echo", MT_Chat4Echo), - luabind::value("Chat5Echo", MT_Chat5Echo), - luabind::value("Chat6Echo", MT_Chat6Echo), - luabind::value("Chat7Echo", MT_Chat7Echo), - luabind::value("Chat8Echo", MT_Chat8Echo), - luabind::value("Chat9Echo", MT_Chat9Echo), - luabind::value("Chat10Echo", MT_Chat10Echo), - luabind::value("DoTDamage", MT_DoTDamage), - luabind::value("ItemLink", MT_ItemLink), - luabind::value("RaidSay", MT_RaidSay), - luabind::value("MyPet", MT_MyPet), - luabind::value("DS", MT_DS), - luabind::value("Leadership", MT_Leadership), - luabind::value("PetFlurry", MT_PetFlurry), - luabind::value("PetCrit", MT_PetCrit), - luabind::value("FocusEffect", MT_FocusEffect), - luabind::value("Experience", MT_Experience), - luabind::value("System", MT_System), - luabind::value("PetSpell", MT_PetSpell), - luabind::value("PetResponse", MT_PetResponse), - luabind::value("ItemSpeech", MT_ItemSpeech), - luabind::value("StrikeThrough", MT_StrikeThrough), - luabind::value("Stun", MT_Stun) + luabind::value("NPCQuestSay", Chat::NPCQuestSay), + luabind::value("Say", Chat::Say), + luabind::value("Tell", Chat::Tell), + luabind::value("Group", Chat::Group), + luabind::value("Guild", Chat::Guild), + luabind::value("OOC", Chat::OOC), + luabind::value("Auction", Chat::Auction), + luabind::value("Shout", Chat::Shout), + luabind::value("Emote", Chat::Emote), + luabind::value("Spells", Chat::Spells), + luabind::value("YouHitOther", Chat::YouHitOther), + luabind::value("OtherHitsYou", Chat::OtherHitYou), + luabind::value("YouMissOther", Chat::YouMissOther), + luabind::value("OtherMissesYou", Chat::OtherMissYou), + luabind::value("Broadcasts", Chat::Broadcasts), + luabind::value("Skills", Chat::Skills), + luabind::value("Disciplines", Chat::Disciplines), + luabind::value("Unused1", Chat::Unused1), + luabind::value("DefaultText", Chat::DefaultText), + luabind::value("Unused2", Chat::Unused2), + luabind::value("MerchantOffer", Chat::MerchantOffer), + luabind::value("MerchantBuySell", Chat::MerchantExchange), + luabind::value("YourDeath", Chat::YourDeath), + luabind::value("OtherDeath", Chat::OtherDeath), + luabind::value("OtherHits", Chat::OtherHitOther), + luabind::value("OtherMisses", Chat::OtherMissOther), + luabind::value("Who", Chat::Who), + luabind::value("YellForHelp", Chat::YellForHelp), + luabind::value("NonMelee", Chat::NonMelee), + luabind::value("WornOff", Chat::SpellWornOff), + luabind::value("MoneySplit", Chat::MoneySplit), + luabind::value("LootMessages", Chat::Loot), + luabind::value("DiceRoll", Chat::DiceRoll), + luabind::value("OtherSpells", Chat::OtherSpells), + luabind::value("SpellFailure", Chat::SpellFailure), + luabind::value("Chat", Chat::ChatChannel), + luabind::value("Channel1", Chat::Chat1), + luabind::value("Channel2", Chat::Chat2), + luabind::value("Channel3", Chat::Chat3), + luabind::value("Channel4", Chat::Chat4), + luabind::value("Channel5", Chat::Chat5), + luabind::value("Channel6", Chat::Chat6), + luabind::value("Channel7", Chat::Chat7), + luabind::value("Channel8", Chat::Chat8), + luabind::value("Channel9", Chat::Chat9), + luabind::value("Channel10", Chat::Chat10), + luabind::value("CritMelee", Chat::MeleeCrit), + luabind::value("SpellCrits", Chat::SpellCrit), + luabind::value("TooFarAway", Chat::TooFarAway), + luabind::value("NPCRampage", Chat::NPCRampage), + luabind::value("NPCFlurry", Chat::NPCFlurry), + luabind::value("NPCEnrage", Chat::NPCEnrage), + luabind::value("SayEcho", Chat::EchoSay), + luabind::value("TellEcho", Chat::EchoTell), + luabind::value("GroupEcho", Chat::EchoGroup), + luabind::value("GuildEcho", Chat::EchoGuild), + luabind::value("OOCEcho", Chat::EchoOOC), + luabind::value("AuctionEcho", Chat::EchoAuction), + luabind::value("ShoutECho", Chat::EchoShout), + luabind::value("EmoteEcho", Chat::EchoEmote), + luabind::value("Chat1Echo", Chat::EchoChat1), + luabind::value("Chat2Echo", Chat::EchoChat2), + luabind::value("Chat3Echo", Chat::EchoChat3), + luabind::value("Chat4Echo", Chat::EchoChat4), + luabind::value("Chat5Echo", Chat::EchoChat5), + luabind::value("Chat6Echo", Chat::EchoChat6), + luabind::value("Chat7Echo", Chat::EchoChat7), + luabind::value("Chat8Echo", Chat::EchoChat8), + luabind::value("Chat9Echo", Chat::EchoChat9), + luabind::value("Chat10Echo", Chat::EchoChat10), + luabind::value("DoTDamage", Chat::DotDamage), + luabind::value("ItemLink", Chat::ItemLink), + luabind::value("RaidSay", Chat::RaidSay), + luabind::value("MyPet", Chat::MyPet), + luabind::value("DS", Chat::DamageShield), + luabind::value("Leadership", Chat::LeaderShip), + luabind::value("PetFlurry", Chat::PetFlurry), + luabind::value("PetCrit", Chat::PetCritical), + luabind::value("FocusEffect", Chat::FocusEffect), + luabind::value("Experience", Chat::Experience), + luabind::value("System", Chat::System), + luabind::value("PetSpell", Chat::PetSpell), + luabind::value("PetResponse", Chat::PetResponse), + luabind::value("ItemSpeech", Chat::ItemSpeech), + luabind::value("StrikeThrough", Chat::StrikeThrough), + luabind::value("Stun", Chat::Stun) ]; } diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index 6f7e435f3..df0cd7b70 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -764,7 +764,7 @@ void Lua_Mob::QuestSay(Lua_Client client, const char *message) { journal_opts.speak_mode = Journal::SpeakMode::Say; journal_opts.journal_mode = RuleB(NPC, EnableNPCQuestJournal) ? Journal::Mode::Log2 : Journal::Mode::None; journal_opts.language = 0; - journal_opts.message_type = MT_NPCQuestSay; + journal_opts.message_type = Chat::NPCQuestSay; journal_opts.target_spawn_id = 0; self->QuestJournalledSay(client, message, journal_opts); } @@ -777,7 +777,7 @@ void Lua_Mob::QuestSay(Lua_Client client, const char *message, luabind::adl::obj journal_opts.speak_mode = Journal::SpeakMode::Say; journal_opts.journal_mode = Journal::Mode::Log2; journal_opts.language = 0; - journal_opts.message_type = MT_NPCQuestSay; + journal_opts.message_type = Chat::NPCQuestSay; journal_opts.target_spawn_id = 0; if (luabind::type(opts) == LUA_TTABLE) { diff --git a/zone/merc.cpp b/zone/merc.cpp index 7c15fbd65..7ae4a4d9f 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1618,7 +1618,7 @@ void Merc::AI_Process() { { if(zone->random.Roll(flurrychance)) { - Message_StringID(MT_NPCFlurry, YOU_FLURRY); + Message_StringID(Chat::NPCFlurry, YOU_FLURRY); Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); } @@ -2623,7 +2623,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { realTotal = CalcFocusEffect(type, UsedFocusID, spell_id); if (realTotal != 0 && UsedItem) - Message_StringID(MT_Spells, BEGINS_TO_GLOW, UsedItem->Name); + Message_StringID(Chat::Spells, BEGINS_TO_GLOW, UsedItem->Name); } //Check if spell focus effect exists for the client. @@ -5321,10 +5321,10 @@ void Client::UpdateMercTimer() Log(Logs::General, Logs::Mercenaries, "UpdateMercTimer Complete for %s.", GetName()); // Normal upkeep charge message - //Message(7, "You have been charged a mercenary upkeep cost of %i plat, and %i gold and your mercenary upkeep cost timer has been reset to 15 minutes.", upkeep_plat, upkeep_gold, (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); + //Message(Chat::LightGray, "You have been charged a mercenary upkeep cost of %i plat, and %i gold and your mercenary upkeep cost timer has been reset to 15 minutes.", upkeep_plat, upkeep_gold, (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); // Message below given when too low level to be charged - //Message(7, "Your mercenary waived an upkeep cost of %i plat, and %i gold or %i %s and your mercenary upkeep cost timer has been reset to %i minutes", upkeep_plat, upkeep_gold, 1, "Bayle Marks", (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); + //Message(Chat::LightGray, "Your mercenary waived an upkeep cost of %i plat, and %i gold or %i %s and your mercenary upkeep cost timer has been reset to %i minutes", upkeep_plat, upkeep_gold, 1, "Bayle Marks", (int)(RuleI(Mercs, UpkeepIntervalMS) / 1000 / 60)); } } } diff --git a/zone/mob.cpp b/zone/mob.cpp index 3a307bf3f..6067f206e 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2709,7 +2709,7 @@ bool Mob::HateSummon() { if(target) { if(summon_level == 1) { - entity_list.MessageClose(this, true, 500, MT_Say, "%s says,'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); + entity_list.MessageClose(this, true, 500, Chat::Say, "%s says 'You will not evade me, %s!' ", GetCleanName(), target->GetCleanName() ); if (target->IsClient()) target->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Position.x, m_Position.y, m_Position.z, target->GetHeading(), 0, SummonPC); @@ -2718,7 +2718,7 @@ bool Mob::HateSummon() { return true; } else if(summon_level == 2) { - entity_list.MessageClose(this, true, 500, MT_Say, "%s says,'You will not evade me, %s!'", GetCleanName(), target->GetCleanName()); + entity_list.MessageClose(this, true, 500, Chat::Say, "%s says 'You will not evade me, %s!'", GetCleanName(), target->GetCleanName()); GMMove(target->GetX(), target->GetY(), target->GetZ()); } } @@ -2875,7 +2875,7 @@ void Mob::SayTo_StringID(Client *to, uint32 string_id, const char *message3, con auto string_id_str = std::to_string(string_id); - to->Message_StringID(10, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); + to->Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); } void Mob::SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) @@ -2897,7 +2897,7 @@ void Mob::Shout(const char *format, ...) vsnprintf(buf, 1000, format, ap); va_end(ap); - entity_list.Message_StringID(this, false, MT_Shout, + entity_list.Message_StringID(this, false, Chat::Shout, GENERIC_SHOUT, GetCleanName(), buf); } @@ -3569,7 +3569,7 @@ void Mob::TryTwincast(Mob *caster, Mob *target, uint32 spell_id) { if(zone->random.Roll(focus)) { - Message(MT_Spells,"You twincast %s!",spells[spell_id].name); + Message(Chat::Spells,"You twincast %s!", spells[spell_id].name); SpellFinished(spell_id, target, EQEmu::spells::CastingSlot::Item, 0, -1, spells[spell_id].ResistDiff); } } @@ -4887,16 +4887,16 @@ void Mob::SlowMitigation(Mob* caster) if (GetSlowMitigation() && caster && caster->IsClient()) { if ((GetSlowMitigation() > 0) && (GetSlowMitigation() < 26)) - caster->Message_StringID(MT_SpellFailure, SLOW_MOSTLY_SUCCESSFUL); + caster->Message_StringID(Chat::SpellFailure, SLOW_MOSTLY_SUCCESSFUL); else if ((GetSlowMitigation() >= 26) && (GetSlowMitigation() < 74)) - caster->Message_StringID(MT_SpellFailure, SLOW_PARTIALLY_SUCCESSFUL); + caster->Message_StringID(Chat::SpellFailure, SLOW_PARTIALLY_SUCCESSFUL); else if ((GetSlowMitigation() >= 74) && (GetSlowMitigation() < 101)) - caster->Message_StringID(MT_SpellFailure, SLOW_SLIGHTLY_SUCCESSFUL); + caster->Message_StringID(Chat::SpellFailure, SLOW_SLIGHTLY_SUCCESSFUL); else if (GetSlowMitigation() > 100) - caster->Message_StringID(MT_SpellFailure, SPELL_OPPOSITE_EFFECT); + caster->Message_StringID(Chat::SpellFailure, SPELL_OPPOSITE_EFFECT); } } diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 0df05254e..e71a28a05 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -578,7 +578,7 @@ void NPC::AI_Stop() { void Client::AI_Stop() { Mob::AI_Stop(); - this->Message_StringID(13,PLAYER_REGAIN); + this->Message_StringID(Chat::Red,PLAYER_REGAIN); auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct)); Charm_Struct *ps = (Charm_Struct*)app->pBuffer; @@ -1667,9 +1667,9 @@ void NPC::AI_DoMovement() { pause_timer_complete = true; AI_walking_timer->Disable(); } - + int32 gridno = CastToNPC()->GetGrid(); - + if (gridno > 0 || cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) { if (pause_timer_complete == true) { // time to pause at wp is over AI_SetupNextWaypoint(); @@ -1685,7 +1685,7 @@ void NPC::AI_DoMovement() { GetY(), GetZ(), GetGrid()); - + SetWaypointPause(); SetAppearance(eaStanding, false); if (cur_wp_pause > 0) { @@ -2029,14 +2029,14 @@ void Mob::StartEnrage() // start the timer. need to call IsEnraged frequently since we dont have callback timers :-/ bEnraged = true; - entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_START, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_START, GetCleanName()); } void Mob::ProcessEnrage(){ if(IsEnraged()){ Timer *timer = GetSpecialAbilityTimer(SPECATK_ENRAGE); if(timer && timer->Check()){ - entity_list.MessageClose_StringID(this, true, 200, MT_NPCEnrage, NPC_ENRAGE_END, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_END, GetCleanName()); int enraged_cooldown = GetSpecialAbilityParam(SPECATK_ENRAGE, 2); enraged_cooldown = enraged_cooldown > 0 ? enraged_cooldown : EnragedTimer; @@ -2057,9 +2057,9 @@ bool Mob::Flurry(ExtraAttackOptions *opts) Mob *target = GetTarget(); if (target) { if (!IsPet()) { - entity_list.MessageClose_StringID(this, true, 200, MT_NPCFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::NPCFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); } else { - entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); } int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1); @@ -2096,9 +2096,9 @@ bool Mob::Rampage(ExtraAttackOptions *opts) { int index_hit = 0; if (!IsPet()) - entity_list.MessageClose_StringID(this, true, 200, MT_NPCRampage, NPC_RAMPAGE, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::NPCRampage, NPC_RAMPAGE, GetCleanName()); else - entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, NPC_RAMPAGE, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, NPC_RAMPAGE, GetCleanName()); int rampage_targets = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1); if (rampage_targets == 0) // if set to 0 or not set in the DB @@ -2153,9 +2153,9 @@ void Mob::AreaRampage(ExtraAttackOptions *opts) { int index_hit = 0; if (!IsPet()) { // do not know every pet AA so thought it safer to add this - entity_list.MessageClose_StringID(this, true, 200, MT_NPCRampage, AE_RAMPAGE, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::NPCRampage, AE_RAMPAGE, GetCleanName()); } else { - entity_list.MessageClose_StringID(this, true, 200, MT_PetFlurry, AE_RAMPAGE, GetCleanName()); + entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, AE_RAMPAGE, GetCleanName()); } int rampage_targets = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1); diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 4bf1663d3..2f87a1912 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -835,27 +835,27 @@ void MobMovementManager::DumpStats(Client *client) auto current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; auto total_time = current_time - _impl->Stats.LastResetTime; - client->Message(MT_System, "Dumping Movement Stats:"); + client->Message(Chat::System, "Dumping Movement Stats:"); client->Message( - MT_System, + Chat::System, "Total Sent: %u (%.2f / sec)", _impl->Stats.TotalSent, static_cast(_impl->Stats.TotalSent) / total_time ); client->Message( - MT_System, + Chat::System, "Total Heading: %u (%.2f / sec)", _impl->Stats.TotalSentHeading, static_cast(_impl->Stats.TotalSentHeading) / total_time ); client->Message( - MT_System, + Chat::System, "Total Movement: %u (%.2f / sec)", _impl->Stats.TotalSentMovement, static_cast(_impl->Stats.TotalSentMovement) / total_time ); client->Message( - MT_System, + Chat::System, "Total Position: %u (%.2f / sec)", _impl->Stats.TotalSentPosition, static_cast(_impl->Stats.TotalSentPosition) / total_time diff --git a/zone/npc.cpp b/zone/npc.cpp index 60e6f73c4..3f31d57da 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1577,7 +1577,7 @@ void NPC::PickPocket(Client* thief) //make sure were allowed to target them: int over_level = GetLevel(); if(over_level > (thief->GetLevel() + THIEF_PICKPOCKET_OVER)) { - thief->Message(13, "You are too inexperienced to pick pocket this target"); + thief->Message(Chat::Red, "You are too inexperienced to pick pocket this target"); thief->SendPickPocketResponse(this, 0, PickPocketFailed); //should we check aggro return; @@ -1587,7 +1587,7 @@ void NPC::PickPocket(Client* thief) if (zone->CanDoCombat()) AddToHateList(thief, 50); Say("Stop thief!"); - thief->Message(13, "You are noticed trying to steal!"); + thief->Message(Chat::Red, "You are noticed trying to steal!"); thief->SendPickPocketResponse(this, 0, PickPocketFailed); return; } @@ -1744,17 +1744,17 @@ void NPC::Disarm(Client* client, int chance) { SendWearChange(matslot); if ((CastToMob()->GetBodyType() == BT_Humanoid || CastToMob()->GetBodyType() == BT_Summoned) && eslot == EQEmu::invslot::slotPrimary) Say("Ahh! My weapon!"); - client->Message_StringID(MT_Skills, DISARM_SUCCESS, this->GetCleanName()); + client->Message_StringID(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); if (chance != 1000) client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); return; } - client->Message_StringID(MT_Skills, DISARM_FAILED); + client->Message_StringID(Chat::Skills, DISARM_FAILED); if (chance != 1000) client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); return; } - client->Message_StringID(MT_Skills, DISARM_FAILED); + client->Message_StringID(Chat::Skills, DISARM_FAILED); } void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool remove) { diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp index 600e8ad5c..7da290439 100644 --- a/zone/oldcode.cpp +++ b/zone/oldcode.cpp @@ -1198,7 +1198,7 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0] char val1[20]={0}; char val2[20]={0}; uint32 remain = p_timers.GetRemainingTime(pTimerDisciplineReuse); - Message_StringID(0,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); + Message_StringID(Chat::WhiteSmoke,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); //Message(0,"You can use a new discipline in %i minutes %i seconds.", (disc_timer.GetRemainingTime()/1000)/60, disc_timer.GetRemainingTime()/1000%60); return; } diff --git a/zone/pathing.cpp b/zone/pathing.cpp index 79b7900d2..e579bd0fe 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -50,7 +50,7 @@ void Client::SendPathPacket(const std::vector &points) { auto points = EQEmu::any_cast>(result); if (points.size() < 2) { if (Admin() > 10) { - Message(MT_System, "Too few points"); + Message(Chat::System, "Too few points"); } EQApplicationPacket outapp(OP_FindPersonReply, 0); @@ -60,7 +60,7 @@ void Client::SendPathPacket(const std::vector &points) { if (points.size() > 36) { if (Admin() > 10) { - Message(MT_System, "Too many points %u", points.size()); + Message(Chat::System, "Too many points %u", points.size()); } EQApplicationPacket outapp(OP_FindPersonReply, 0); @@ -69,7 +69,7 @@ void Client::SendPathPacket(const std::vector &points) { } if (Admin() > 10) { - Message(MT_System, "Total points %u", points.size()); + Message(Chat::System, "Total points %u", points.size()); } int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point); diff --git a/zone/pets.cpp b/zone/pets.cpp index ab1f13bce..6f8c5d44e 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -212,7 +212,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, //lookup our pets table record for this type PetRecord record; if(!database.GetPoweredPetEntry(pettype, act_power, &record)) { - Message(13, "Unable to find data for pet %s", pettype); + Message(Chat::Red, "Unable to find data for pet %s", pettype); Log(Logs::General, Logs::Error, "Unable to find data for pet %s, check pets table.", pettype); return; } @@ -220,7 +220,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower, //find the NPC data for the specified NPC type const NPCType *base = database.LoadNPCTypesData(record.npc_type); if(base == nullptr) { - Message(13, "Unable to load NPC data for pet %s", pettype); + Message(Chat::Red, "Unable to load NPC data for pet %s", pettype); Log(Logs::General, Logs::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type); return; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index dafc3f1e6..cc19c59fd 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -807,13 +807,13 @@ void QuestManager::changedeity(int diety_id) { if(initiator->IsClient()) { initiator->SetDeity(diety_id); - initiator->Message(15,"Your Deity has been changed/set to: %i", diety_id); + initiator->Message(Chat::Yellow,"Your Deity has been changed/set to: %i", diety_id); initiator->Save(1); initiator->Kick("Deity change by QuestManager"); } else { - initiator->Message(15,"Error changing Deity"); + initiator->Message(Chat::Yellow,"Error changing Deity"); } } } @@ -929,11 +929,11 @@ void QuestManager::surname(const char *name) { if(initiator->IsClient()) { initiator->ChangeLastName(name); - initiator->Message(15,"Your surname has been changed/set to: %s", name); + initiator->Message(Chat::Yellow,"Your surname has been changed/set to: %s", name); } else { - initiator->Message(15,"Error changing/setting surname"); + initiator->Message(Chat::Yellow,"Error changing/setting surname"); } } } @@ -986,11 +986,11 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { break; } if (spell_id < 0 || spell_id >= SPDAT_RECORDS) { - initiator->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); + initiator->Message(Chat::Red, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); return count; } if (book_slot < 0 || book_slot >= EQEmu::spells::SPELLBOOK_SIZE) { - initiator->Message(13, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE); + initiator->Message(Chat::Red, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE); return count; } @@ -1008,7 +1008,7 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) { uint16 spell_id_ = (uint16)spell_id; if ((spell_id_ != spell_id) || (spell_id != spell_id_)) { - initiator->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); + initiator->Message(Chat::Red, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); return count; } @@ -1059,7 +1059,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { for( ; spell_id < SPDAT_RECORDS; ++spell_id) { if (spell_id < 0 || spell_id >= SPDAT_RECORDS) { - initiator->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); + initiator->Message(Chat::Red, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); return count; } @@ -1077,7 +1077,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { uint16 spell_id_ = (uint16)spell_id; if ((spell_id_ != spell_id) || (spell_id != spell_id_)) { - initiator->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); + initiator->Message(Chat::Red, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); return count; } @@ -1086,7 +1086,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { for (uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) { if (initiator->GetPP().disciplines.values[r] == spell_id_) { - initiator->Message(13, "You already know this discipline."); + initiator->Message(Chat::Red, "You already know this discipline."); break; // continue the 1st loop } else if (initiator->GetPP().disciplines.values[r] == 0) { @@ -1190,7 +1190,7 @@ void QuestManager::givecash(int copper, int silver, int gold, int platinum) { } tmp += " pieces."; if (initiator) - initiator->Message(MT_OOC, tmp.c_str()); + initiator->Message(Chat::OOC, tmp.c_str()); } } @@ -2164,7 +2164,7 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level { if(Bot::SpawnedBotCount(initiator->CharacterID()) >= MaxBotCreate) { - initiator->Message(15,"You have the maximum number of bots allowed."); + initiator->Message(Chat::Yellow,"You have the maximum number of bots allowed."); return false; } @@ -2657,13 +2657,13 @@ uint16 QuestManager::CreateInstance(const char *zone, int16 version, uint32 dura uint16 id = 0; if(!database.GetUnusedInstanceID(id)) { - initiator->Message(13, "Server was unable to find a free instance id."); + initiator->Message(Chat::Red, "Server was unable to find a free instance id."); return 0; } if(!database.CreateInstance(id, zone_id, version, duration)) { - initiator->Message(13, "Server was unable to create a new instance."); + initiator->Message(Chat::Red, "Server was unable to create a new instance."); return 0; } return id; @@ -2776,9 +2776,9 @@ void QuestManager::RemoveFromInstance(uint16 instance_id) if (initiator) { if (database.RemoveClientFromInstance(instance_id, initiator->CharacterID())) - initiator->Message(MT_Say, "Removed client from instance."); + initiator->Message(Chat::Say, "Removed client from instance."); else - initiator->Message(MT_Say, "Failed to remove client from instance."); + initiator->Message(Chat::Say, "Failed to remove client from instance."); } } @@ -2794,11 +2794,11 @@ void QuestManager::RemoveAllFromInstance(uint16 instance_id) std::list charid_list; if (database.RemoveClientsFromInstance(instance_id)) - initiator->Message(MT_Say, "Removed all players from instance."); + initiator->Message(Chat::Say, "Removed all players from instance."); else { database.GetCharactersInInstance(instance_id, charid_list); - initiator->Message(MT_Say, "Failed to remove %i player(s) from instance.", charid_list.size()); // once the expedition system is in, this message it not relevant + initiator->Message(Chat::Say, "Failed to remove %i player(s) from instance.", charid_list.size()); // once the expedition system is in, this message it not relevant } } } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index bcffa4077..35b865610 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -177,7 +177,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 auto fbash = GetFuriousBash(itm->Focus.Effect); hate = hate * (100 + fbash) / 100; if (fbash) - Message_StringID(MT_Spells, GLOWS_RED, itm->Name); + Message_StringID(Chat::Spells, GLOWS_RED, itm->Name); } } } @@ -283,7 +283,7 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk) return; if (!p_timers.Expired(&database, timer, false)) { - Message(13, "Ability recovery time not yet met."); + Message(Chat::Red, "Ability recovery time not yet met."); return; } @@ -530,7 +530,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { if(IsClient()) { const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if (!wpn || (wpn->GetItem()->ItemType != EQEmu::item::ItemType1HPiercing)){ - Message_StringID(13, BACKSTAB_WEAPON); + Message_StringID(Chat::Red, BACKSTAB_WEAPON); return; } } @@ -720,11 +720,11 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { float dist = DistanceSquared(m_Position, other->GetPosition()); if(dist > range) { Log(Logs::Detail, Logs::Combat, "Ranged attack out of range... client should catch this. (%f > %f).\n", dist, range); - Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. + Message_StringID(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. return; } else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ - Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. + Message_StringID(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. return; } @@ -1273,11 +1273,11 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 float dist = DistanceSquared(m_Position, other->GetPosition()); if(dist > range) { Log(Logs::Detail, Logs::Combat, "Throwing attack out of range... client should catch this. (%f > %f).\n", dist, range); - Message_StringID(13,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. + Message_StringID(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. return; } else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ - Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. + Message_StringID(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. return; } @@ -1566,7 +1566,7 @@ void NPC::DoClassAttacks(Mob *target) { //general stuff, for all classes.... //only gets used when their primary ability get used too if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) { - this->GetOwner()->Message_StringID(MT_PetResponse, PET_TAUNTING); + this->GetOwner()->Message_StringID(Chat::PetResponse, PET_TAUNTING); Taunt(target->CastToNPC(), false); } @@ -1898,7 +1898,7 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, // Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level. if ((RuleB(Combat, TauntOverLevel) == false) && (level_difference < 0) || who->GetSpecialAbility(IMMUNE_TAUNT)) { - Message_StringID(MT_SpellFailure, FAILED_TAUNT); + Message_StringID(Chat::SpellFailure, FAILED_TAUNT); return; } @@ -1955,10 +1955,10 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, if (who->CanTalk()) who->Say_StringID(SUCCESSFUL_TAUNT, GetCleanName()); } else { - Message_StringID(MT_SpellFailure, FAILED_TAUNT); + Message_StringID(Chat::SpellFailure, FAILED_TAUNT); } } else { - Message_StringID(MT_SpellFailure, FAILED_TAUNT); + Message_StringID(Chat::SpellFailure, FAILED_TAUNT); } if (HasSkillProcs()) @@ -2003,10 +2003,10 @@ void Mob::InstillDoubt(Mob *who) { SpellOnTarget(229, who, false, true, -2000); //is there a success message? } else { - Message_StringID(4,NOT_SCARING); + Message_StringID(Chat::LightBlue,NOT_SCARING); //Idea from WR: /* if (target->IsNPC() && zone->random.Int(0,99) < 10 ) { - entity_list.MessageClose(target, false, 50, MT_NPCRampage, "%s lashes out in anger!",target->GetName()); + entity_list.MessageClose(target, false, 50, Chat::NPCRampage, "%s lashes out in anger!",target->GetName()); //should we actually do this? and the range is completely made up, unconfirmed entity_list.AEAttack(target, 50); }*/ @@ -2033,7 +2033,7 @@ int Mob::TryHeadShot(Mob *defender, EQEmu::skills::SkillType skillInUse) chance = chance * norm / 100; chance += aabonuses.HeadShot[0] + spellbonuses.HeadShot[0] + itembonuses.HeadShot[0]; if (zone->random.Int(1, 1000) <= chance) { - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, FATAL_BOW_SHOT, + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, FATAL_BOW_SHOT, GetName()); return HeadShot_Dmg; } @@ -2078,7 +2078,7 @@ int Mob::TryAssassinate(Mob *defender, EQEmu::skills::SkillType skillInUse) if (Assassinate_Dmg && Assassinate_Level && (defender->GetLevel() <= Assassinate_Level)) { if (zone->random.Int(1, 1000) <= chance) { - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, ASSASSINATES, + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, ASSASSINATES, GetName()); return Assassinate_Dmg; } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index e4c0badd5..af5a63ffc 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -471,7 +471,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(zone->random.Roll(RuleI(Spells, SuccorFailChance))) { //2% Fail chance by default if(IsClient()) { - CastToClient()->Message_StringID(MT_SpellFailure,SUCCOR_FAIL); + CastToClient()->Message_StringID(Chat::SpellFailure,SUCCOR_FAIL); } break; } @@ -638,11 +638,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove CastToClient()->SummonItem(13073, fcharges); } else{ - Message(13, "You can only transmute flesh to bone."); + Message(Chat::Red, "You can only transmute flesh to bone."); } } else{ - Message(13, "You can only transmute flesh to bone."); + Message(Chat::Red, "You can only transmute flesh to bone."); } } break; @@ -703,7 +703,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))))) { if (caster) - caster->Message_StringID(MT_SpellFailure, IMMUNE_STUN); + caster->Message_StringID(Chat::SpellFailure, IMMUNE_STUN); } else { int stun_resist = itembonuses.StunResist+spellbonuses.StunResist; if (IsClient()) @@ -718,7 +718,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Stun(effect_value); } else { if (IsClient()) - Message_StringID(MT_Stun, SHAKE_OFF_STUN); + Message_StringID(Chat::Stun, SHAKE_OFF_STUN); Log(Logs::Detail, Logs::Combat, "Stun Resisted. We had %d percent resist chance.", stun_resist); } @@ -847,14 +847,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(ClosestMob) { - Message_StringID(MT_Spells, MessageID); + Message_StringID(Chat::Spells, MessageID); SetHeading(CalculateHeadingToTarget(ClosestMob->GetX(), ClosestMob->GetY())); SetTarget(ClosestMob); CastToClient()->SendTargetCommand(ClosestMob->GetID()); SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else - Message_StringID(clientMessageError, SENSE_NOTHING); + Message_StringID(Chat::Red, SENSE_NOTHING); } } break; @@ -939,14 +939,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { if(!zone->CanBind()) { - Message_StringID(MT_SpellFailure, CANNOT_BIND); + Message_StringID(Chat::SpellFailure, CANNOT_BIND); break; } if(!zone->IsCity()) { if(caster != this) { - Message_StringID(MT_SpellFailure, CANNOT_BIND); + Message_StringID(Chat::SpellFailure, CANNOT_BIND); break; } else @@ -1039,7 +1039,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(zone->random.Roll(effect_value)) Gate(spells[spell_id].base2[i] - 1); else if (caster) - caster->Message_StringID(MT_SpellFailure,GATE_FAIL); + caster->Message_StringID(Chat::SpellFailure,GATE_FAIL); } break; } @@ -1051,7 +1051,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1077,7 +1077,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1103,7 +1103,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(MT_SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1155,7 +1155,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove snprintf(effect_desc, _EDLEN, "Summon Item: %s (id %d)", itemname, spell.base[i]); #endif if (!item) { - Message(13, "Unable to summon item %d. Item not found.", spell.base[i]); + Message(Chat::Red, "Unable to summon item %d. Item not found.", spell.base[i]); } else if (IsClient()) { Client *c = CastToClient(); if (c->CheckLoreConflict(item)) { @@ -1194,10 +1194,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (!SummonedItem || !SummonedItem->IsClassBag()) { if (caster) - caster->Message(13, "SE_SummonItemIntoBag but no bag has been summoned!"); + caster->Message(Chat::Red, "SE_SummonItemIntoBag but no bag has been summoned!"); } else if ((slot = SummonedItem->FirstOpenSlot()) == 0xff) { if (caster) - caster->Message(13, "SE_SummonItemIntoBag but no room in summoned bag!"); + caster->Message(Chat::Red, "SE_SummonItemIntoBag but no room in summoned bag!"); } else if (IsClient()) { if (CastToClient()->CheckLoreConflict(item)) { CastToClient()->DuplicateLoreMessage(spell.base[i]); @@ -1235,7 +1235,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetPet()) { - Message_StringID(MT_Shout, ONLY_ONE_PET); + Message_StringID(Chat::Shout, ONLY_ONE_PET); } else { @@ -1516,7 +1516,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { WipeHateList(); } - Message(13, "Your mind fogs. Who are my friends? Who are my enemies?... it was all so clear a moment ago..."); + Message(Chat::Red, "Your mind fogs. Who are my friends? Who are my enemies?... it was all so clear a moment ago..."); } break; } @@ -1537,7 +1537,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove && caster && (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))) { if (caster) - caster->Message_StringID(MT_Shout, IMMUNE_STUN); + caster->Message_StringID(Chat::Shout, IMMUNE_STUN); } else { @@ -1644,12 +1644,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { if(caster == this) { - Message_StringID(MT_Spells, + Message_StringID(Chat::Spells, SENTINEL_TRIG_YOU); } else { - caster->Message_StringID(MT_Spells, + caster->Message_StringID(Chat::Spells, SENTINEL_TRIG_OTHER, GetCleanName()); } } @@ -1757,7 +1757,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Group* group = entity_list.GetGroupByClient(TargetClient); if(group) { if(!group->IsGroupMember(TargetClient)) { - Message(13, "Your target must be a group member for this spell."); + Message(Chat::Red, "Your target must be a group member for this spell."); break; } } @@ -1770,13 +1770,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(gid < 11) { if(r->GetGroup(TargetClient->GetName()) != gid) { - Message(13, "Your target must be a group member for this spell."); + Message(Chat::Red, "Your target must be a group member for this spell."); break; } } } else { if(TargetClient != this->CastToClient()) { - Message(13, "Your target must be a group member for this spell."); + Message(Chat::Red, "Your target must be a group member for this spell."); break; } } @@ -1790,26 +1790,26 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Corpse *corpse = entity_list.GetCorpseByOwner(TargetClient); if(corpse) { if(TargetClient == this->CastToClient()) - Message_StringID(4, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName()); + Message_StringID(Chat::LightBlue, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName()); else - Message_StringID(4, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName()); + Message_StringID(Chat::LightBlue, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName()); corpse->Summon(CastToClient(), true, true); } else { // No corpse found in the zone - Message_StringID(4, CORPSE_CANT_SENSE); + Message_StringID(Chat::LightBlue, CORPSE_CANT_SENSE); } } else if (caster) { char level[4]; ConvertArray(effect_value, level); - caster->Message_StringID(MT_SpellFailure, + caster->Message_StringID(Chat::SpellFailure, SPELL_LEVEL_REQ, level); } } else { - Message_StringID(4, TARGET_NOT_FOUND); + Message_StringID(Chat::LightBlue, TARGET_NOT_FOUND); Log(Logs::General, Logs::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id); } } @@ -1937,7 +1937,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove continue; if (effect_value >= static_cast(buffs[j].counters)) { if (caster) { - caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); + caster->Message(Chat::Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); } @@ -1971,7 +1971,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (effect_value >= static_cast(buffs[j].counters)) { if (caster) { - caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); + caster->Message(Chat::Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); } @@ -2007,7 +2007,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (effect_value >= static_cast(buffs[j].counters)) { if (caster) { - caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); + caster->Message(Chat::Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); } @@ -2042,7 +2042,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove continue; if (effect_value >= static_cast(buffs[j].counters)) { if (caster) { - caster->Message(MT_Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); + caster->Message(Chat::Spells,"You have cured your target of %s!",spells[buffs[j].spellid].name); caster->CastOnCurer(buffs[j].spellid); CastOnCure(buffs[j].spellid); } @@ -2068,7 +2068,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(GetLevel() <= 52) CastToNPC()->Depop(true); else - Message(13, "Your target is too high level to be affected by this spell."); + Message(Chat::Red, "Your target is too high level to be affected by this spell."); } break; } @@ -2115,10 +2115,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), caster->GetX(), caster->GetY(), caster->GetZ(), caster->GetHeading(), 2, SummonPC); - Message(15, "You have been summoned!"); + Message(Chat::Yellow, "You have been summoned!"); entity_list.ClearAggro(this); } else - caster->Message(13, "This spell can only be cast on players."); + caster->Message(Chat::Red, "This spell can only be cast on players."); break; } @@ -2725,13 +2725,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove case SE_MassGroupBuff:{ SetMGB(true); - Message_StringID(MT_Disciplines, MGB_STRING); + Message_StringID(Chat::Disciplines, MGB_STRING); break; } case SE_IllusionOther: { SetProjectIllusion(true); - Message(10, "The power of your next illusion spell will flow to your grouped target in your place."); + Message(Chat::NPCQuestSay, "The power of your next illusion spell will flow to your grouped target in your place."); break; } @@ -3572,7 +3572,7 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster) if (IsAIControlled()) { WipeHateList(); } - Message(13, "Your mind fogs. Who are my friends? Who are my enemies?... it was all so " + Message(Chat::Red, "Your mind fogs. Who are my friends? Who are my enemies?... it was all so " "clear a moment ago..."); } break; @@ -3643,7 +3643,7 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster) case SE_Invisibility2: case SE_InvisVsUndead2: { if (buff.ticsremaining <= 3 && buff.ticsremaining > 1) { - Message_StringID(MT_Spells, INVIS_BEGIN_BREAK); + Message_StringID(Chat::Spells, INVIS_BEGIN_BREAK); } break; } @@ -4047,7 +4047,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) if(p->IsPet()) notify = p->GetOwner(); if(p) { - notify->Message_StringID(MT_WornOff, SPELL_WORN_OFF_OF, + notify->Message_StringID(Chat::SpellWornOff, SPELL_WORN_OFF_OF, spells[buffs[slot].spellid].name, GetCleanName()); } } @@ -5406,7 +5406,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) default: break; } - Message_StringID(MT_Spells, string_id, UsedItem->Name); + Message_StringID(Chat::Spells, string_id, UsedItem->Name); } } @@ -5814,9 +5814,9 @@ bool Mob::TryDeathSave() { Message(263, "The gods have healed you for %i points of damage.", HealAmt); if(spellbonuses.DeathSave[0] == 2) - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, DIVINE_INTERVENTION, GetCleanName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); else - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, DEATH_PACT, GetCleanName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); SendHPUpdate(); BuffFadeBySlot(buffSlot); @@ -5847,9 +5847,9 @@ bool Mob::TryDeathSave() { Message(263, "The gods have healed you for %i points of damage.", HealAmt); if(spellbonuses.DeathSave[0] == 2) - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, DIVINE_INTERVENTION, GetCleanName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); else - entity_list.MessageClose_StringID(this, false, 200, MT_CritMelee, DEATH_PACT, GetCleanName()); + entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); SendHPUpdate(); BuffFadeBySlot(buffSlot); @@ -6802,11 +6802,11 @@ void Client::BreakFeignDeathWhenCastOn(bool IsResisted) chance *= 2; if(chance && (zone->random.Roll(chance))){ - Message_StringID(MT_SpellFailure,FD_CAST_ON_NO_BREAK); + Message_StringID(Chat::SpellFailure,FD_CAST_ON_NO_BREAK); return; } SetFeigned(false); - Message_StringID(MT_SpellFailure,FD_CAST_ON); + Message_StringID(Chat::SpellFailure,FD_CAST_ON); } } diff --git a/zone/spells.cpp b/zone/spells.cpp index fa09727a2..2b4056434 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -180,9 +180,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d, amnesiad? %d", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced(), IsAmnesiad() ); if(IsSilenced() && !IsDiscipline(spell_id)) - Message_StringID(13, SILENCED_STRING); + Message_StringID(Chat::Red, SILENCED_STRING); if(IsAmnesiad() && IsDiscipline(spell_id)) - Message_StringID(13, MELEE_SILENCE); + Message_StringID(Chat::Red, MELEE_SILENCE); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); if(casting_spell_id && IsNPC()) @@ -197,7 +197,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);//Client only if (zone->random.Roll(chance)) { - Message_StringID(13, SILENCED_STRING); + Message_StringID(Chat::Red, SILENCED_STRING); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); return(false); @@ -205,7 +205,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, } if(IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()){ - Message_StringID(13, SPELL_WOULDNT_HOLD); + Message_StringID(Chat::Red, SPELL_WOULDNT_HOLD); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); if(casting_spell_id && IsNPC()) @@ -257,7 +257,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class"); } else { - Message_StringID(13, MUST_EQUIP_ITEM); + Message_StringID(Chat::Red, MUST_EQUIP_ITEM); } return(false); } @@ -272,11 +272,11 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, if (CastToClient()->ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { // Line 181 in eqstr_us.txt was changed in RoF+ - Message(15, "Your race, class, or deity cannot use this item."); + Message(Chat::Yellow, "Your race, class, or deity cannot use this item."); } else { - Message_StringID(13, CANNOT_USE_ITEM); + Message_StringID(Chat::Red, CANNOT_USE_ITEM); } } return(false); @@ -289,7 +289,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it"); } else { - Message_StringID(13, MUST_EQUIP_ITEM); + Message_StringID(Chat::Red, MUST_EQUIP_ITEM); } return(false); } @@ -370,22 +370,24 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Mob::SetMana(GetMana() - use_mana); // We send StopCasting which will update mana StopCasting(); - Message_StringID(MT_SpellFailure, fizzle_msg); + Message_StringID(Chat::SpellFailure, fizzle_msg); - /* Song Failure Messages */ + /** + * Song Failure message + */ entity_list.FilteredMessageClose_StringID( - this, /* Sender */ - true, /* Skip Sender */ + this, + true, RuleI(Range, SpellMessages), - MT_SpellFailure, /* Type: 289 */ - (IsClient() ? FilterPCSpells : FilterNPCSpells), /* FilterType: 8 or 9 depending on client/npc */ + Chat::SpellFailure, + (IsClient() ? FilterPCSpells : FilterNPCSpells), (fizzle_msg == MISS_NOTE ? MISSED_NOTE_OTHER : SPELL_FIZZLE_OTHER), /* MessageFormat: You miss a note, bringing your song to a close! (if missed note) MessageFormat: A missed note brings %1's song to a close! MessageFormat: %1's spell fizzles! */ - GetName() /* Message1 */ + GetName() ); TryTriggerOnValueAmount(false, true); @@ -426,7 +428,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell Error: no target. spell=%d", spell_id); if(IsClient()) { //clients produce messages... npcs should not for this case - Message_StringID(13, SPELL_NEED_TAR); + Message_StringID(Chat::Red, SPELL_NEED_TAR); InterruptSpell(); } else { InterruptSpell(0, 0, 0); //the 0 args should cause no messages @@ -459,7 +461,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", spell_id, my_curmana, mana_cost); if(IsClient()) { //clients produce messages... npcs should not for this case - Message_StringID(13, INSUFFICIENT_MANA); + Message_StringID(Chat::Red, INSUFFICIENT_MANA); InterruptSpell(); } else { InterruptSpell(0, 0, 0); //the 0 args should cause no messages @@ -516,7 +518,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, if (IsClient() && slot == CastingSlot::Item && item_slot != 0xFFFFFFFF) { auto item = CastToClient()->GetInv().GetItem(item_slot); if (item && item->GetItem()) - Message_StringID(MT_Spells, BEGINS_TO_GLOW, item->GetItem()->Name); + Message_StringID(Chat::Spells, BEGINS_TO_GLOW, item->GetItem()->Name); } if (!DoCastingChecks()) { @@ -573,28 +575,28 @@ bool Mob::DoCastingChecks() if (spell_target && spells[spell_id].targettype != ST_Self && !spell_target->CheckSpellLevelRestriction(spell_id)) { Log(Logs::Detail, Logs::Spells, "Spell %d failed: recipient did not meet the level restrictions", spell_id); if (!IsBardSong(spell_id)) - Message_StringID(MT_SpellFailure, SPELL_TOO_POWERFUL); + Message_StringID(Chat::SpellFailure, SPELL_TOO_POWERFUL); return false; } } if (spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()) { - Message_StringID(13, CAST_OUTDOORS); + Message_StringID(Chat::Red, CAST_OUTDOORS); return false; } if (IsEffectInSpell(spell_id, SE_Levitate) && !zone->CanLevitate()) { - Message(13, "You can't levitate in this zone."); + Message(Chat::Red, "You can't levitate in this zone."); return false; } if(zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) { const char *msg = zone->GetSpellBlockedMessage(spell_id, glm::vec3(GetPosition())); if (msg) { - Message(13, msg); + Message(Chat::Red, msg); return false; } else { - Message(13, "You can't cast this spell here."); + Message(Chat::Red, "You can't cast this spell here."); return false; } } @@ -678,7 +680,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillPercussionInstruments) > 0) // no skill increases if not trained in the instrument CheckIncreaseSkill(EQEmu::skills::SkillPercussionInstruments, nullptr, -15); else - Message_StringID(13,NO_INSTRUMENT_SKILL); // tell the client that they need instrument training + Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); // tell the client that they need instrument training } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -688,7 +690,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillStringedInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillStringedInstruments, nullptr, -15); else - Message_StringID(13,NO_INSTRUMENT_SKILL); + Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -698,7 +700,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillWindInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillWindInstruments, nullptr, -15); else - Message_StringID(13,NO_INSTRUMENT_SKILL); + Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -708,7 +710,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillBrassInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillBrassInstruments, nullptr, -15); else - Message_StringID(13,NO_INSTRUMENT_SKILL); + Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -859,7 +861,7 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid) } if(casting_spell_aa_id && IsClient()) { //Rest AA Timer on failed cast - CastToClient()->Message_StringID(MT_SpellFailure, ABILITY_FAILED); + CastToClient()->Message_StringID(Chat::SpellFailure, ABILITY_FAILED); CastToClient()->ResetAlternateAdvancementTimer(casting_spell_aa_id); } @@ -938,7 +940,7 @@ void Mob::StopCasting() if (IsClient()) { auto c = CastToClient(); if (casting_spell_aa_id) { //Rest AA Timer on failed cast - c->Message_StringID(MT_SpellFailure, ABILITY_FAILED); + c->Message_StringID(Chat::SpellFailure, ABILITY_FAILED); c->ResetAlternateAdvancementTimer(casting_spell_aa_id); } @@ -967,7 +969,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(IsClient() && slot != CastingSlot::Item && slot != CastingSlot::PotionBelt && spells[spell_id].recast_time > 1000) { // 10 is item if(!CastToClient()->GetPTimers().Expired(&database, pTimerSpellStart + spell_id, false)) { //should we issue a message or send them a spell gem packet? - Message_StringID(13, SPELL_RECAST); + Message_StringID(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: spell reuse timer not expired", spell_id); StopCasting(); return; @@ -981,7 +983,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(itm && itm->GetItem()->RecastDelay > 0) { if(!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + itm->GetItem()->RecastType), false)) { - Message_StringID(13, SPELL_RECAST); + Message_StringID(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: item spell reuse timer not expired", spell_id); StopCasting(); return; @@ -1003,7 +1005,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(delaytimer) { Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: recast too quickly", spell_id); - Message(13, "You are unable to focus."); + Message(Chat::Red, "You are unable to focus."); InterruptSpell(); return; } @@ -1013,7 +1015,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if (casting_spell_id != spell_id) { Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: already casting", spell_id); - Message_StringID(13,ALREADY_CASTING); + Message_StringID(Chat::Red,ALREADY_CASTING); InterruptSpell(); return; } @@ -1131,8 +1133,8 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo } // if we got here, we regained concentration regain_conc = true; - Message_StringID(MT_Spells,REGAIN_AND_CONTINUE); - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), MT_Spells, OTHER_REGAIN_CAST, this->GetCleanName()); + Message_StringID(Chat::Spells, REGAIN_AND_CONTINUE); + entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), Chat::Spells, OTHER_REGAIN_CAST, this->GetCleanName()); } } @@ -1168,7 +1170,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13000: if(itembonuses.percussionMod == 0) { // check for the appropriate instrument type HasInstrument = false; - c->Message_StringID(13, SONG_NEEDS_DRUM); // send an error message if missing + c->Message_StringID(Chat::Red, SONG_NEEDS_DRUM); // send an error message if missing } break; @@ -1176,7 +1178,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13001: if(itembonuses.windMod == 0) { HasInstrument = false; - c->Message_StringID(13, SONG_NEEDS_WIND); + c->Message_StringID(Chat::Red, SONG_NEEDS_WIND); } break; @@ -1184,7 +1186,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13011: if(itembonuses.stringedMod == 0) { HasInstrument = false; - c->Message_StringID(13, SONG_NEEDS_STRINGS); + c->Message_StringID(Chat::Red, SONG_NEEDS_STRINGS); } break; @@ -1192,7 +1194,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13012: if(itembonuses.brassMod == 0) { HasInstrument = false; - c->Message_StringID(13, SONG_NEEDS_BRASS); + c->Message_StringID(Chat::Red, SONG_NEEDS_BRASS); } break; @@ -1220,13 +1222,13 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo { if (!missingreags) { - c->Message_StringID(13, MISSING_SPELL_COMP); + c->Message_StringID(Chat::Red, MISSING_SPELL_COMP); missingreags=true; } const EQEmu::ItemData *item = database.GetItem(component); if(item) { - c->Message_StringID(13, MISSING_SPELL_COMP_ITEM, item->Name); + c->Message_StringID(Chat::Red, MISSING_SPELL_COMP_ITEM, item->Name); Log(Logs::Detail, Logs::Spells, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, item->Name, component); } else { @@ -1270,7 +1272,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo } else { // some kind of error in the code if this happens - c->Message(13, "ERROR: reagent item disappeared while processing?"); + c->Message(Chat::Red, "ERROR: reagent item disappeared while processing?"); } } } @@ -1322,7 +1324,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(IsClient() && fromaug && recastdelay > 0) { if(!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + recasttype), false)) { - Message_StringID(13, SPELL_RECAST); + Message_StringID(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: item spell reuse timer not expired", spell_id); StopCasting(); return; @@ -1353,7 +1355,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo else { Log(Logs::Detail, Logs::Spells, "Item used to cast spell %d was missing from inventory slot %d after casting!", spell_id, inventory_slot); - Message(13, "Casting Error: Active casting item not found in inventory slot %i", inventory_slot); + Message(Chat::Red, "Casting Error: Active casting item not found in inventory slot %i", inventory_slot); InterruptSpell(); return; } @@ -1500,7 +1502,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce targetType = ST_Target; if (spell_target && !spell_target->PassCastRestriction(true, spells[spell_id].CastRestriction)){ - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } @@ -1510,7 +1512,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if (spell_target && ((spell_target->IsNPC() && spell_target->IsEngaged()) || (spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount()))) { - Message_StringID(13, SPELL_NO_EFFECT); // Unsure correct string + Message_StringID(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string return false; } } @@ -1518,9 +1520,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce else if (IsBeneficialSpell(spell_id)) { if ((IsNPC() && IsEngaged()) || (IsClient() && CastToClient()->GetAggroCount())) { if (IsDiscipline(spell_id)) - Message_StringID(13, NO_ABILITY_IN_COMBAT); + Message_StringID(Chat::Red, NO_ABILITY_IN_COMBAT); else - Message_StringID(13, NO_CAST_IN_COMBAT); + Message_StringID(Chat::Red, NO_CAST_IN_COMBAT); return false; } @@ -1533,7 +1535,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if (spell_target && ((spell_target->IsNPC() && !spell_target->IsEngaged()) || (spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount()))) { - Message_StringID(13, SPELL_NO_EFFECT); // Unsure correct string + Message_StringID(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string return false; } } @@ -1541,9 +1543,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce else if (IsBeneficialSpell(spell_id)) { if ((IsNPC() && !IsEngaged()) || (IsClient() && !CastToClient()->GetAggroCount())) { if (IsDiscipline(spell_id)) - Message_StringID(13, NO_ABILITY_OUT_OF_COMBAT); + Message_StringID(Chat::Red, NO_ABILITY_OUT_OF_COMBAT); else - Message_StringID(13, NO_CAST_OUT_OF_COMBAT); + Message_StringID(Chat::Red, NO_CAST_OUT_OF_COMBAT); return false; } @@ -1580,9 +1582,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (undead)", spell_id, mob_body); if(!spell_target) - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); else - Message_StringID(13,CANNOT_AFFECT_NPC); + Message_StringID(Chat::Red,CANNOT_AFFECT_NPC); return false; } CastAction = SingleTarget; @@ -1594,7 +1596,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (summoned)", spell_id, mob_body); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } CastAction = SingleTarget; @@ -1609,7 +1611,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (summoned pet)", spell_id, mob_body); - Message_StringID(13, SPELL_NEED_TAR); + Message_StringID(Chat::Red, SPELL_NEED_TAR); return false; } @@ -1633,9 +1635,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (want body Type %d)", spell_id, mob_body, target_bt); if(!spell_target) - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); else - Message_StringID(13,CANNOT_AFFECT_NPC); + Message_StringID(Chat::Red,CANNOT_AFFECT_NPC); return false; } CastAction = SingleTarget; @@ -1650,7 +1652,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (ldon object)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } else @@ -1658,14 +1660,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target->IsNPC()) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } if(spell_target->GetClass() != LDON_TREASURE) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } } @@ -1674,7 +1676,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; // can't cast these unless we have a target } CastAction = SingleTarget; @@ -1690,7 +1692,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) message = SPELL_NEED_TAR; else if(!spell_target->IsCorpse()) message = ONLY_ON_CORPSES; else if(!spell_target->IsPlayerCorpse()) message = CORPSE_NOT_VALID; - Message_StringID(13, message); + Message_StringID(Chat::Red, message); return false; } CastAction = SingleTarget; @@ -1702,7 +1704,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (no pet)", spell_id); - Message_StringID(13,NO_PET); + Message_StringID(Chat::Red,NO_PET); return false; // can't cast these unless we have a target } CastAction = SingleTarget; @@ -1773,7 +1775,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (AOE)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } ae_center = spell_target; @@ -1798,7 +1800,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } if (spell_target && spell_target->IsPet() && spells[spell_id].targettype == ST_GroupNoPets){ - Message_StringID(13,NO_CAST_ON_PET); + Message_StringID(Chat::Red,NO_CAST_ON_PET); return false; } @@ -1810,7 +1812,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (Group Required: Single Target)", spell_id); - Message_StringID(13,SPELL_NEED_TAR); + Message_StringID(Chat::Red,SPELL_NEED_TAR); return false; } @@ -1927,14 +1929,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(group_id_caster == 0 || group_id_target == 0) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: Attempted to cast a Single Target Group spell on a ungrouped member.", spell_id); - Message_StringID(13, TARGET_GROUP_MEMBER); + Message_StringID(Chat::Red, TARGET_GROUP_MEMBER); return false; } if(group_id_caster != group_id_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: Attempted to cast a Single Target Group spell on a ungrouped member.", spell_id); - Message_StringID(13, TARGET_GROUP_MEMBER); + Message_StringID(Chat::Red, TARGET_GROUP_MEMBER); return false; } @@ -2028,7 +2030,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if( spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()){ if(IsClient()){ if(!CastToClient()->GetGM()){ - Message_StringID(13, CAST_OUTDOORS); + Message_StringID(Chat::Red, CAST_OUTDOORS); return false; } } @@ -2037,7 +2039,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(IsEffectInSpell(spell_id, SE_Levitate) && !zone->CanLevitate()){ if(IsClient()){ if(!CastToClient()->GetGM()){ - Message(13, "You can't levitate in this zone."); + Message(Chat::Red, "You can't levitate in this zone."); return false; } } @@ -2048,11 +2050,11 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))){ const char *msg = zone->GetSpellBlockedMessage(spell_id, glm::vec3(GetPosition())); if(msg){ - Message(13, msg); + Message(Chat::Red, msg); return false; } else{ - Message(13, "You can't cast this spell here."); + Message(Chat::Red, "You can't cast this spell here."); return false; } @@ -2110,14 +2112,14 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(!spells[spell_id].npc_no_los && spell_target && IsDetrimentalSpell(spell_id) && !CheckLosFN(spell_target) && !IsHarmonySpell(spell_id) && spells[spell_id].targettype != ST_TargetOptional) { Log(Logs::Detail, Logs::Spells, "Spell %d: cannot see target %s", spell_id, spell_target->GetName()); - Message_StringID(13,CANT_SEE_TARGET); + Message_StringID(Chat::Red,CANT_SEE_TARGET); return false; } // check to see if target is a caster mob before performing a mana tap if(spell_target && IsManaTapSpell(spell_id)) { if(spell_target->GetCasterClass() == 'N') { - Message_StringID(13, TARGET_NO_MANA); + Message_StringID(Chat::Red, TARGET_NO_MANA); return false; } } @@ -2141,13 +2143,13 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(13, TARGET_OUT_OF_RANGE); + Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } else if (dist2 < min_range2){ //target is too close range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2); - Message_StringID(13, TARGET_TOO_CLOSE); + Message_StringID(Chat::Red, TARGET_TOO_CLOSE); return(false); } @@ -2162,13 +2164,13 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(13, TARGET_OUT_OF_RANGE); + Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } else if (dist2 < min_range2){ //target is too close range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2); - Message_StringID(13, TARGET_TOO_CLOSE); + Message_StringID(Chat::Red, TARGET_TOO_CLOSE); return(false); } @@ -2518,7 +2520,7 @@ bool Mob::ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, CastingSlot slo if(spell_target && IsDetrimentalSpell(spell_id) && !CheckLosFN(spell_target)) { Log(Logs::Detail, Logs::Spells, "Bard Song Pulse %d: cannot see target %s", spell_target->GetName()); - Message_StringID(13, CANT_SEE_TARGET); + Message_StringID(Chat::Red, CANT_SEE_TARGET); return(false); } @@ -2533,7 +2535,7 @@ bool Mob::ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, CastingSlot slo if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Bard Song Pulse %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(13, TARGET_OUT_OF_RANGE); + Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } } @@ -2892,7 +2894,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, if (spellbonuses.Screech == 1) { if (effect2 == SE_Screech && sp2.base[i] == -1) { - Message_StringID(MT_SpellFailure, SCREECH_BUFF_BLOCK, sp2.name); + Message_StringID(Chat::SpellFailure, SCREECH_BUFF_BLOCK, sp2.name); return -1; } } @@ -3213,7 +3215,7 @@ int Mob::AddBuff(Mob *caster, uint16 spell_id, int duration, int32 level_overrid Log(Logs::Detail, Logs::Spells, "Adding buff %d failed: stacking prevented by spell %d in slot %d with caster level %d", spell_id, curbuf.spellid, buffslot, curbuf.casterlevel); if (caster && caster->IsClient() && RuleB(Client, UseLiveBlockedMessage)) { - caster->Message(13, "Your %s did not take hold on %s. (Blocked by %s.)", spells[spell_id].name, this->GetName(), spells[curbuf.spellid].name); + caster->Message(Chat::Red, "Your %s did not take hold on %s. (Blocked by %s.)", spells[spell_id].name, this->GetName(), spells[curbuf.spellid].name); } return -1; } @@ -3414,7 +3416,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r if(!spelltar) { Log(Logs::Detail, Logs::Spells, "Unable to apply spell %d without a target", spell_id); - Message(13, "SOT: You must have a target for this spell."); + Message(Chat::Red, "SOT: You must have a target for this spell."); return false; } @@ -3423,7 +3425,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id)) { if(!IsClient() || !CastToClient()->GetGM()) { - Message_StringID(MT_SpellFailure, SPELL_NO_HOLD); + Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); return false; } } @@ -3588,7 +3590,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible) { - spelltar->Message_StringID(MT_SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3598,7 +3600,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible_undead) { - spelltar->Message_StringID(MT_SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3608,7 +3610,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible_animals) { - spelltar->Message_StringID(MT_SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3688,7 +3690,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r Log(Logs::Detail, Logs::Spells, "Beneficial ae bard song %d can't take hold %s -> %s, IBA? %d", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); } else { Log(Logs::Detail, Logs::Spells, "Beneficial spell %d can't take hold %s -> %s, IBA? %d", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); - Message_StringID(MT_SpellFailure, SPELL_NO_HOLD); + Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); } safe_delete(action_packet); return false; @@ -3698,7 +3700,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r else if ( !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id)) // Detrimental spells - PVP check { Log(Logs::Detail, Logs::Spells, "Detrimental spell %d can't take hold %s -> %s", spell_id, GetName(), spelltar->GetName()); - spelltar->Message_StringID(MT_SpellFailure, YOU_ARE_PROTECTED, GetCleanName()); + spelltar->Message_StringID(Chat::SpellFailure, YOU_ARE_PROTECTED, GetCleanName()); safe_delete(action_packet); return false; } @@ -3735,7 +3737,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r focus = CalcFocusEffect(focusBlockNextSpell, buffs[b].spellid, spell_id); if(focus) { CheckNumHitsRemaining(NumHit::MatchingSpells, b); - Message_StringID(MT_SpellFailure, SPELL_WOULDNT_HOLD); + Message_StringID(Chat::SpellFailure, SPELL_WOULDNT_HOLD); safe_delete(action_packet); return false; } @@ -3788,14 +3790,14 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r this, /* Sender */ false, /* Skip Sender */ RuleI(Range, SpellMessages), /* Range */ - MT_Spells, /* Type */ + Chat::Spells, /* Type */ SPELL_REFLECT, /* String ID */ GetCleanName(), /* Message 1 */ spelltar->GetCleanName() /* Message 2 */ ); } else { - Message_StringID(MT_Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); + Message_StringID(Chat::Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); } CheckNumHitsRemaining(NumHit::ReflectSpell); @@ -3827,12 +3829,12 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r Log(Logs::Detail, Logs::Spells, "Spell %d was completely resisted by %s", spell_id, spelltar->GetName()); if (spells[spell_id].resisttype == RESIST_PHYSICAL){ - Message_StringID(MT_SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); - spelltar->Message_StringID(MT_SpellFailure, YOU_RESIST, spells[spell_id].name); + Message_StringID(Chat::SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); + spelltar->Message_StringID(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); } else { - Message_StringID(MT_SpellFailure, TARGET_RESISTED, spells[spell_id].name); - spelltar->Message_StringID(MT_SpellFailure, YOU_RESIST, spells[spell_id].name); + Message_StringID(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name); + spelltar->Message_StringID(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); } if (spelltar->IsAIControlled()) { @@ -3897,7 +3899,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { Log(Logs::Detail, Logs::Spells, "Spell %d failed: recipient did not meet the level restrictions", spell_id); if(!IsBardSong(spell_id)) - Message_StringID(MT_SpellFailure, SPELL_TOO_POWERFUL); + Message_StringID(Chat::SpellFailure, SPELL_TOO_POWERFUL); safe_delete(action_packet); return false; } @@ -3909,7 +3911,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r // spell. It's most likely a buff that can't stack. Log(Logs::Detail, Logs::Spells, "Spell %d could not apply its effects %s -> %s\n", spell_id, GetName(), spelltar->GetName()); if(casting_spell_aa_id) - Message_StringID(MT_SpellFailure, SPELL_NO_HOLD); + Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); safe_delete(action_packet); return false; } @@ -3989,14 +3991,14 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) if(IsRezzed()){ if(Caster && Caster->IsClient()) - Caster->Message(13,"This character has already been resurrected."); + Caster->Message(Chat::Red,"This character has already been resurrected."); return; } /* if(!can_rez) { if(Caster && Caster->IsClient()) - Caster->Message_StringID(0, CORPSE_TOO_OLD); + Caster->Message_StringID(Chat::WhiteSmoke, CORPSE_TOO_OLD); return; } */ @@ -4224,7 +4226,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNMEZABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Mez spells."); - caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ); + caster->Message_StringID(Chat::SpellFailure, CANNOT_MEZ); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4242,7 +4244,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Mez spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ_WITH_SPELL); + caster->Message_StringID(Chat::SpellFailure, CANNOT_MEZ_WITH_SPELL); AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } @@ -4252,7 +4254,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNSLOWABLE) && IsEffectInSpell(spell_id, SE_AttackSpeed)) { Log(Logs::Detail, Logs::Spells, "We are immune to Slow spells."); - caster->Message_StringID(CC_Red, IMMUNE_ATKSPEED); + caster->Message_StringID(Chat::Red, IMMUNE_ATKSPEED); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4268,7 +4270,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) effect_index = GetSpellEffectIndex(spell_id, SE_Fear); if(GetSpecialAbility(UNFEARABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Fear spells."); - caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4279,13 +4281,13 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) } else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) { Log(Logs::Detail, Logs::Spells, "Clients cannot fear eachother!"); - caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } else if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) { Log(Logs::Detail, Logs::Spells, "Level is %d, cannot be feared by this spell.", GetLevel()); - caster->Message_StringID(MT_Shout, FEAR_TOO_HIGH); + caster->Message_StringID(Chat::Shout, FEAR_TOO_HIGH); int32 aggro = caster->CheckAggroAmount(spell_id, this); if (aggro > 0) { AddToHateList(caster, aggro); @@ -4296,9 +4298,9 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) } else if (CheckAATimer(aaTimerWarcry)) { - Message(13, "Your are immune to fear."); + Message(Chat::Red, "Your are immune to fear."); Log(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!"); - caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } } @@ -4308,7 +4310,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNCHARMABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Charm spells."); - caster->Message_StringID(CC_Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up + caster->Message_StringID(Chat::Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4321,7 +4323,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You are immune to your own charms."); - caster->Message(CC_Red, "You cannot charm yourself."); // need to look up message? + caster->Message(Chat::Red, "You cannot charm yourself."); // need to look up message? return true; } @@ -4334,7 +4336,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Charm spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(CC_Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up + caster->Message_StringID(Chat::Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } @@ -4349,7 +4351,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNSNAREABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Snare spells."); - caster->Message_StringID(CC_Red, IMMUNE_MOVEMENT); + caster->Message_StringID(Chat::Red, IMMUNE_MOVEMENT); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4365,7 +4367,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot lifetap yourself."); - caster->Message_StringID(MT_SpellFailure, CANT_DRAIN_SELF); + caster->Message_StringID(Chat::SpellFailure, CANT_DRAIN_SELF); return true; } } @@ -4375,7 +4377,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot sacrifice yourself."); - caster->Message_StringID(MT_SpellFailure, CANNOT_SAC_SELF); + caster->Message_StringID(Chat::SpellFailure, CANNOT_SAC_SELF); return true; } } @@ -4993,7 +4995,7 @@ void Client::MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message) const char *fadetext = spells[spell_id].spell_fades; outapp = new EQApplicationPacket(OP_ColoredText, sizeof(ColoredText_Struct) + strlen(fadetext)); ColoredText_Struct *bfm = (ColoredText_Struct *) outapp->pBuffer; - bfm->color = MT_Spells; + bfm->color = Chat::Spells; memcpy(bfm->msg, fadetext, strlen(fadetext)); QueuePacket(outapp); safe_delete(outapp); diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 7761747f9..40d301e7d 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -678,7 +678,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) if (taskID == TASKSLOTEMPTY) continue; if (!Tasks[taskID]) { - c->Message(13, + c->Message(Chat::Red, "Active Task Slot %i, references a task (%i), that does not exist. " "Removing from memory. Contact a GM to resolve this.", i, taskID); @@ -691,7 +691,7 @@ bool TaskManager::LoadClientState(Client *c, ClientTaskState *state) for (int j = 0; j < Tasks[taskID]->ActivityCount; j++) { if (state->ActiveTasks[i].Activity[j].ActivityID != j) { - c->Message(13, + c->Message(Chat::Red, "Active Task %i, %s. Activity count does not match expected value." "Removing from memory. Contact a GM to resolve this.", taskID, Tasks[taskID]->Title.c_str()); @@ -1001,7 +1001,7 @@ void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, i return; if (TaskSets[TaskSetID].empty()) { - mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // I think this is suppose to be yellow + mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // I think this is suppose to be yellow return; } @@ -1033,7 +1033,7 @@ void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, i if (TaskListIndex > 0) { SendTaskSelector(c, mob, TaskListIndex, TaskList); } else { - mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow } return; @@ -1065,7 +1065,7 @@ void TaskManager::TaskQuestSetSelector(Client *c, ClientTaskState *state, Mob *m if (TaskListIndex > 0) { SendTaskSelector(c, mob, TaskListIndex, TaskList); } else { - mob->SayTo_StringID(c, CC_Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow } return; @@ -2001,7 +2001,7 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { c->SummonItem(Task->RewardID); Item = database.GetItem(Task->RewardID); if(Item) - c->Message(15, "You receive %s as a reward.", Item->Name); + c->Message(Chat::Yellow, "You receive %s as a reward.", Item->Name); } break; } @@ -2012,7 +2012,7 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { c->SummonItem(RewardList[i]); Item = database.GetItem(RewardList[i]); if(Item) - c->Message(15, "You receive %s as a reward.", Item->Name); + c->Message(Chat::Yellow, "You receive %s as a reward.", Item->Name); } break; } @@ -2024,7 +2024,7 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { } if (!Task->completion_emote.empty()) - c->SendColoredText(CC_Yellow, Task->completion_emote); // unsure if they use this packet or color, should work + c->SendColoredText(Chat::Yellow, Task->completion_emote); // unsure if they use this packet or color, should work // just use normal NPC faction ID stuff if (Task->faction_reward) @@ -2081,7 +2081,7 @@ void ClientTaskState::RewardTask(Client *c, TaskInformation *Task) { CashMessage += " copper"; } CashMessage += " pieces."; - c->Message(15,CashMessage.c_str()); + c->Message(Chat::Yellow,CashMessage.c_str()); } int32 EXPReward = Task->XPReward; if(EXPReward > 0) { @@ -3204,14 +3204,14 @@ void ClientTaskState::RemoveTask(Client *c, int sequenceNumber, TaskType type) void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enforce_level_requirement) { if (!taskmanager || TaskID < 0 || TaskID >= MAXTASKS) { - c->Message(13, "Task system not functioning, or TaskID %i out of range.", TaskID); + c->Message(Chat::Red, "Task system not functioning, or TaskID %i out of range.", TaskID); return; } auto task = taskmanager->Tasks[TaskID]; if (task == nullptr) { - c->Message(13, "Invalid TaskID %i", TaskID); + c->Message(Chat::Red, "Invalid TaskID %i", TaskID); return; } @@ -3235,7 +3235,7 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor } if (max_tasks) { - c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); + c->Message(Chat::Red, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); return; } @@ -3243,14 +3243,14 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor if (task->type == TaskType::Quest) { for (int i = 0; i < MAXACTIVEQUESTS; i++) { if (ActiveQuests[i].TaskID == TaskID) { - c->Message(13, "You have already been assigned this task."); + c->Message(Chat::Red, "You have already been assigned this task."); return; } } } if (enforce_level_requirement && !taskmanager->AppropriateLevel(TaskID, c->GetLevel())) { - c->Message(13, "You are outside the level range of this task."); + c->Message(Chat::Red, "You are outside the level range of this task."); return; } @@ -3287,7 +3287,7 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor // This shouldn't happen unless there is a bug in the handling of ActiveTaskCount somewhere if (active_slot == nullptr) { - c->Message(13, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); + c->Message(Chat::Red, "You already have the maximum allowable number of active tasks (%i)", MAXACTIVEQUESTS); return; } @@ -3315,8 +3315,8 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor NPC *npc = entity_list.GetID(NPCID)->CastToNPC(); if(!npc) { - c->Message(clientMessageYellow, "Task Giver ID is %i", NPCID); - c->Message(clientMessageError, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug."); + c->Message(Chat::Yellow, "Task Giver ID is %i", NPCID); + c->Message(Chat::Red, "Unable to find NPC to send EVENT_TASKACCEPTED to. Report this bug."); return; } diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 72cb51795..07e6da7fb 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -80,7 +80,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if (itemsFound != 2) { - user->Message(13, "Error: Too many/few items in augmentation container."); + user->Message(Chat::Red, "Error: Too many/few items in augmentation container."); return; } } @@ -90,7 +90,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if(!container) { Log(Logs::General, Logs::Error, "Player tried to augment an item without a container set."); - user->Message(13, "Error: This item is not a container!"); + user->Message(Chat::Red, "Error: This item is not a container!"); return; } @@ -115,7 +115,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme { // Either 2 augmentable items found or none found // This should never occur due to client restrictions, but prevent in case of a hack - user->Message(13, "Error: Must be 1 augmentable item in the sealer"); + user->Message(Chat::Red, "Error: Must be 1 augmentable item in the sealer"); return; } } @@ -124,11 +124,11 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme // This happens if the augment button is clicked more than once quickly while augmenting if (!container->GetItem(0)) { - user->Message(13, "Error: No item in slot 0 of sealer"); + user->Message(Chat::Red, "Error: No item in slot 0 of sealer"); } if (!container->GetItem(1)) { - user->Message(13, "Error: No item in slot 1 of sealer"); + user->Message(Chat::Red, "Error: No item in slot 1 of sealer"); } return; } @@ -160,7 +160,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme } else { - user->Message(13, "Error: No available slot for augment"); + user->Message(Chat::Red, "Error: No available slot for augment"); } } else @@ -170,7 +170,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if (!isSolvent && auged_with->GetItem()->ItemType != EQEmu::item::ItemTypeAugmentationDistiller) { Log(Logs::General, Logs::Error, "Player tried to remove an augment without a solvent or distiller."); - user->Message(13, "Error: Missing an augmentation solvent or distiller for removing this augment."); + user->Message(Chat::Red, "Error: Missing an augmentation solvent or distiller for removing this augment."); return; } @@ -180,7 +180,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme if (!isSolvent && auged_with->GetItem()->ID != aug->GetItem()->AugDistiller) { Log(Logs::General, Logs::Error, "Player tried to safely remove an augment with the wrong distiller (item %u vs expected %u).", auged_with->GetItem()->ID, aug->GetItem()->AugDistiller); - user->Message(13, "Error: Wrong augmentation distiller for safely removing this augment."); + user->Message(Chat::Red, "Error: Wrong augmentation distiller for safely removing this augment."); return; } std::vector args; @@ -266,7 +266,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob if (in_combine->container_slot == EQEmu::invslot::SLOT_TRADESKILL_EXPERIMENT_COMBINE) { if(!worldo) { - user->Message(13, "Error: Server is not aware of the tradeskill container you are attempting to use"); + user->Message(Chat::Red, "Error: Server is not aware of the tradeskill container you are attempting to use"); return; } c_type = worldo->m_type; @@ -291,7 +291,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob } if (!inst || !inst->IsType(EQEmu::item::ItemClassBag)) { - user->Message(13, "Error: Server does not recognize specified tradeskill container"); + user->Message(Chat::Red, "Error: Server does not recognize specified tradeskill container"); return; } @@ -304,12 +304,12 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); - user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); + user->Message_StringID(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); if (RuleB(Inventory, DeleteTransformationMold)) user->DeleteItemInInventory(in_combine->container_slot, 0, true); } else if (inst) { - user->Message_StringID(4, TRANSFORM_FAILED, inst->GetItem()->Name); + user->Message_StringID(Chat::LightBlue, TRANSFORM_FAILED, inst->GetItem()->Name); } auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); @@ -324,10 +324,10 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, 0, 0); - user->Message_StringID(4, TRANSFORM_COMPLETE, inst->GetItem()->Name); + user->Message_StringID(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); } else if (inst) { - user->Message_StringID(4, DETRANSFORM_FAILED, inst->GetItem()->Name); + user->Message_StringID(Chat::LightBlue, DETRANSFORM_FAILED, inst->GetItem()->Name); } auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); @@ -337,7 +337,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob DBTradeskillRecipe_Struct spec; if (!database.GetTradeRecipe(container, c_type, some_id, user->CharacterID(), &spec)) { - user->Message_StringID(MT_Emote,TRADESKILL_NOCOMBINE); + user->Message_StringID(Chat::Emote,TRADESKILL_NOCOMBINE); auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); safe_delete(outapp); @@ -352,7 +352,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob // bit 6 (0x20): unlisted recipe flag if ((spec.must_learn&0xF) == 1 && !spec.has_learnt) { // Made up message for the client. Just giving a DNC is the other option. - user->Message(4, "You need to learn how to combine these first."); + user->Message(Chat::LightBlue, "You need to learn how to combine these first."); auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); safe_delete(outapp); @@ -361,7 +361,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob // Character does not have the required skill. if(spec.skill_needed > 0 && user->GetSkill(spec.tradeskill) < spec.skill_needed ) { // Notify client. - user->Message(4, "You are not skilled enough."); + user->Message(Chat::LightBlue, "You are not skilled enough."); auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); safe_delete(outapp); @@ -371,23 +371,23 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob //changing from a switch to string of if's since we don't need to iterate through all of the skills in the SkillType enum if (spec.tradeskill == EQEmu::skills::SkillAlchemy) { if (user_pp.class_ != SHAMAN) { - user->Message(13, "This tradeskill can only be performed by a shaman."); + user->Message(Chat::Red, "This tradeskill can only be performed by a shaman."); return; } else if (user_pp.level < MIN_LEVEL_ALCHEMY) { - user->Message(13, "You cannot perform alchemy until you reach level %i.", MIN_LEVEL_ALCHEMY); + user->Message(Chat::Red, "You cannot perform alchemy until you reach level %i.", MIN_LEVEL_ALCHEMY); return; } } else if (spec.tradeskill == EQEmu::skills::SkillTinkering) { if (user_pp.race != GNOME) { - user->Message(13, "Only gnomes can tinker."); + user->Message(Chat::Red, "Only gnomes can tinker."); return; } } else if (spec.tradeskill == EQEmu::skills::SkillMakePoison) { if (user_pp.class_ != ROGUE) { - user->Message(13, "Only rogues can mix poisons."); + user->Message(Chat::Red, "Only rogues can mix poisons."); return; } } @@ -422,7 +422,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob // Update Made count if (success) { if (!spec.has_learnt && ((spec.must_learn&0x10) != 0x10)) { - user->Message_StringID(4, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); + user->Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); } database.UpdateRecipeMadecount(spec.recipe_id, user->CharacterID(), spec.madecount+1); } @@ -469,7 +469,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac // This shouldn't happen. if ((spec.must_learn&0xf) && !spec.has_learnt) { // Made up message for the client. Just giving a DNC is the other option. - user->Message(4, "You need to learn how to combine these first."); + user->Message(Chat::LightBlue, "You need to learn how to combine these first."); user->QueuePacket(outapp); safe_delete(outapp); return; @@ -540,13 +540,13 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac safe_delete(outapp); - user->Message_StringID(MT_Skills, TRADESKILL_MISSING_COMPONENTS); + user->Message_StringID(Chat::Skills, TRADESKILL_MISSING_COMPONENTS); for (auto it = MissingItems.begin(); it != MissingItems.end(); ++it) { const EQEmu::ItemData* item = database.GetItem(*it); if(item) - user->Message_StringID(MT_Skills, TRADESKILL_MISSING_ITEM, item->Name); + user->Message_StringID(Chat::Skills, TRADESKILL_MISSING_ITEM, item->Name); } return; @@ -593,7 +593,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac if (success) { if (!spec.has_learnt && ((spec.must_learn & 0x10) != 0x10)) { - user->Message_StringID(4, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); + user->Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); } database.UpdateRecipeMadecount(spec.recipe_id, user->CharacterID(), spec.madecount+1); } @@ -951,7 +951,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { // above critical still stands. // Mastery modifier is: 10%/25%/50% for rank one/two/three chance = 95.0f + (float(user_skill - spec->trivial) / 40.0f); - Message_StringID(MT_Emote, TRADESKILL_TRIVIAL); + Message_StringID(Chat::Emote, TRADESKILL_TRIVIAL); } else if(chance < 5) { // Minimum chance is always 5 chance = 5; @@ -978,7 +978,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { if(over_trivial < 0) CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill); - Message_StringID(4, TRADESKILL_SUCCEED, spec->name.c_str()); + Message_StringID(Chat::LightBlue, TRADESKILL_SUCCEED, spec->name.c_str()); Log(Logs::Detail, Logs::Tradeskills, "Tradeskill success"); @@ -988,7 +988,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { SummonItem(itr->first, itr->second); item = database.GetItem(itr->first); if (this->GetGroup()) { - entity_list.MessageGroup(this, true, MT_Skills, "%s has successfully fashioned %s!", GetName(), item->Name); + entity_list.MessageGroup(this, true, Chat::Skills, "%s has successfully fashioned %s!", GetName(), item->Name); } /* QS: Player_Log_Trade_Skill_Events */ @@ -1010,12 +1010,12 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { if(over_trivial < 0) CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill); - Message_StringID(MT_Emote,TRADESKILL_FAILED); + Message_StringID(Chat::Emote,TRADESKILL_FAILED); Log(Logs::Detail, Logs::Tradeskills, "Tradeskill failed"); if (this->GetGroup()) { - entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its"); + entity_list.MessageGroup(this, true, Chat::Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its"); } @@ -1404,7 +1404,7 @@ void Client::LearnRecipe(uint32 recipeID) if (row[1] != nullptr) return; - Message_StringID(4, TRADESKILL_LEARN_RECIPE, row[0]); + Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, row[0]); // Actually learn the recipe now query = StringFormat("INSERT INTO char_recipe_list " "SET recipe_id = %u, char_id = %u, madecount = 0 " diff --git a/zone/trading.cpp b/zone/trading.cpp index fe9a72daa..80e5dc851 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -102,7 +102,7 @@ void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) { EQEmu::ItemInstance* inst = client->GetInv().GetItem(EQEmu::invslot::slotCursor); if (!inst) { - client->Message(13, "Error: Could not find item on your cursor!"); + client->Message(Chat::Red, "Error: Could not find item on your cursor!"); return; } @@ -1110,7 +1110,7 @@ void Client::Trader_EndTrader() { tdis->Unknown000 = 0; tdis->TraderID = Customer->GetID(); tdis->Unknown012 = 0; - Customer->Message(13, "The Trader is no longer open for business"); + Customer->Message(Chat::Red, "The Trader is no longer open for business"); for(int i = 0; i < 80; i++) { if(gis->Items[i] != 0) { @@ -1628,8 +1628,8 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic Log(Logs::Detail, Logs::Trading, "Actual quantity that will be traded is %i", outtbs->Quantity); if((tbs->Price * outtbs->Quantity) <= 0) { - Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); - Trader->Message(13, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); + Message(Chat::Red, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); + Trader->Message(Chat::Red, "Internal error. Aborting trade. Please report this to the ServerOP. Error code is 1"); Log(Logs::General, Logs::Error, "Bazaar: Zero price transaction between %s and %s aborted." "Item: %s, Charges: %i, TBS: Qty %i, Price: %i", GetName(), Trader->GetName(), @@ -1642,7 +1642,7 @@ void Client::BuyTraderItem(TraderBuy_Struct* tbs, Client* Trader, const EQApplic uint64 TotalTransactionValue = static_cast(tbs->Price) * static_cast(outtbs->Quantity); if(TotalTransactionValue > MAX_TRANSACTION_VALUE) { - Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); + Message(Chat::Red, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); TradeRequestFailed(app); safe_delete(outapp); return; @@ -1754,7 +1754,7 @@ void Client::SendBazaarWelcome() return; auto row = results.begin(); - Message(10, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them, " + Message(Chat::NPCQuestSay, "There are %i Buyers waiting to purchase your loot. Type /barter to search for them, " "or use /buyer to set up your own Buy Lines.", atoi(row[0])); } @@ -1945,7 +1945,7 @@ void Client::SendBazaarResults(uint32 TraderID, uint32 Class_, uint32 Race, uint uint32 ID = 0; if (results.RowCount() == static_cast(RuleI(Bazaar, MaxSearchResults))) - Message(15, "Your search reached the limit of %i results. Please narrow your search down by selecting more options.", + Message(Chat::Yellow, "Your search reached the limit of %i results. Please narrow your search down by selecting more options.", RuleI(Bazaar, MaxSearchResults)); if(results.RowCount() == 0) { @@ -2057,7 +2057,7 @@ static void UpdateTraderCustomerItemsAdded(uint32 CustomerID, TraderCharges_Stru if(!inst) return; - Customer->Message(13, "The Trader has put up %s for sale.", item->Name); + Customer->Message(Chat::Red, "The Trader has put up %s for sale.", item->Name); for(int i = 0; i < 80; i++) { @@ -2105,7 +2105,7 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St tdis->Unknown000 = 0; tdis->TraderID = Customer->GetID(); tdis->Unknown012 = 0; - Customer->Message(13, "The Trader has withdrawn the %s from sale.", item->Name); + Customer->Message(Chat::Red, "The Trader has withdrawn the %s from sale.", item->Name); for(int i = 0; i < 80; i++) { @@ -2147,7 +2147,7 @@ static void UpdateTraderCustomerPriceChanged(uint32 CustomerID, TraderCharges_St inst->SetMerchantCount(Charges); // Let the customer know the price in the window has suddenly just changed on them. - Customer->Message(13, "The Trader has changed the price of %s.", item->Name); + Customer->Message(Chat::Red, "The Trader has changed the price of %s.", item->Name); for(int i = 0; i < 80; i++) { if((gis->ItemID[i] != ItemID) || @@ -2286,7 +2286,7 @@ void Client::HandleTraderPriceUpdate(const EQApplicationPacket *app) { } if(SameItemWithDifferingCharges) - Message(13, "Warning: You have more than one %s with different charges. They have all been added for sale " + Message(Chat::Red, "Warning: You have more than one %s with different charges. They have all been added for sale " "at the same price.", item->Name); } @@ -2333,8 +2333,8 @@ void Client::HandleTraderPriceUpdate(const EQApplicationPacket *app) { tpus->SubAction = BazaarPriceChange_Fail; QueuePacket(app); Trader_EndTrader(); - Message(13, "You must remove the item from sale before you can increase the price while a customer is browsing."); - Message(13, "Click 'Begin Trader' to restart Trader mode with the increased price for this item."); + Message(Chat::Red, "You must remove the item from sale before you can increase the price while a customer is browsing."); + Message(Chat::Red, "Click 'Begin Trader' to restart Trader mode with the increased price for this item."); safe_delete(gis); return; } @@ -2387,11 +2387,11 @@ void Client::SendBuyerResults(char* searchString, uint32 searchID) { int numberOfRows = results.RowCount(); if(numberOfRows == RuleI(Bazaar, MaxBarterSearchResults)) - Message(15, "Your search found too many results; some are not displayed."); + Message(Chat::Yellow, "Your search found too many results; some are not displayed."); else if(strlen(searchString) == 0) - Message(10, "There are %i Buy Lines.", numberOfRows); + Message(Chat::NPCQuestSay, "There are %i Buy Lines.", numberOfRows); else - Message(10, "There are %i Buy Lines that match the search string '%s'.", numberOfRows, searchString); + Message(Chat::NPCQuestSay, "There are %i Buy Lines that match the search string '%s'.", numberOfRows, searchString); if(numberOfRows == 0) return; @@ -2466,7 +2466,7 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) { if(!Buyer) { bir->Approval = 0; // Tell the client that the Buyer is unavailable QueuePacket(app); - Message(13, "The Buyer has gone away."); + Message(Chat::Red, "The Buyer has gone away."); return; } @@ -2475,14 +2475,14 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) { QueuePacket(app); if(bir->Approval == 0) { - Message_StringID(clientMessageYellow, TRADER_BUSY); + Message_StringID(Chat::Yellow, TRADER_BUSY); return; } const char *WelcomeMessagePointer = Buyer->GetBuyerWelcomeMessage(); if(strlen(WelcomeMessagePointer) > 0) - Message(10, "%s greets you, '%s'.", Buyer->GetName(), WelcomeMessagePointer); + Message(Chat::NPCQuestSay, "%s greets you, '%s'.", Buyer->GetName(), WelcomeMessagePointer); auto outapp = new EQApplicationPacket(OP_Barter, sizeof(BuyerBrowsing_Struct)); @@ -2563,7 +2563,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if(!item || !Quantity || !Price || !QtyBuyerWants) return; if (m_inv.HasItem(ItemID, Quantity, invWhereWorn | invWherePersonal | invWhereCursor) == INVALID_INDEX) { - Message(13, "You do not have %i %s on you.", Quantity, item->Name); + Message(Chat::Red, "You do not have %i %s on you.", Quantity, item->Name); return; } @@ -2571,37 +2571,37 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { Client *Buyer = entity_list.GetClientByID(BuyerID); if(!Buyer || !Buyer->IsBuyer()) { - Message(13, "The Buyer has gone away."); + Message(Chat::Red, "The Buyer has gone away."); return; } // For Stackable items, HasSpaceForItem will try check if there is space to stack with existing stacks in // the buyer inventory. if(!(Buyer->GetInv().HasSpaceForItem(item, Quantity))) { - Message(13, "The Buyer does not have space for %i %s", Quantity, item->Name); + Message(Chat::Red, "The Buyer does not have space for %i %s", Quantity, item->Name); return; } if((static_cast(Quantity) * static_cast(Price)) > MAX_TRANSACTION_VALUE) { - Message(13, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); + Message(Chat::Red, "That would exceed the single transaction limit of %u platinum.", MAX_TRANSACTION_VALUE / 1000); return; } if(!Buyer->HasMoney(Quantity * Price)) { - Message(13, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name); - Buyer->Message(13, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name); + Message(Chat::Red, "The Buyer does not have sufficient money to purchase that quantity of %s.", item->Name); + Buyer->Message(Chat::Red, "%s tried to sell you %i %s, but you have insufficient funds.", GetName(), Quantity, item->Name); return; } if(Buyer->CheckLoreConflict(item)) { - Message(13, "That item is LORE and the Buyer already has one."); - Buyer->Message(13, "%s tried to sell you %s but this item is LORE and you already have one.", + Message(Chat::Red, "That item is LORE and the Buyer already has one."); + Buyer->Message(Chat::Red, "%s tried to sell you %s but this item is LORE and you already have one.", GetName(), item->Name); return; } if(item->NoDrop == 0) { - Message(13, "That item is NODROP."); + Message(Chat::Red, "That item is NODROP."); return; } @@ -2620,7 +2620,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { break; } Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); return; } @@ -2628,7 +2628,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if(!ItemToTransfer || !Buyer->MoveItemToInventory(ItemToTransfer, true)) { Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); if(ItemToTransfer) safe_delete(ItemToTransfer); @@ -2666,7 +2666,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if (SellerSlot == INVALID_INDEX) { Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); return; } @@ -2674,7 +2674,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if(!ItemToTransfer) { Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); return; } @@ -2686,7 +2686,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); safe_delete(ItemToTransfer); return; } @@ -2721,7 +2721,7 @@ void Client::SellToBuyer(const EQApplicationPacket *app) { if(!Buyer->MoveItemToInventory(ItemToTransfer, true)) { Log(Logs::General, Logs::Error, "Unexpected error while moving item from seller to buyer."); - Message(13, "Internal error while processing transaction."); + Message(Chat::Red, "Internal error while processing transaction."); safe_delete(ItemToTransfer); return; } @@ -2965,19 +2965,19 @@ void Client::UpdateBuyLine(const EQApplicationPacket *app) { } else { if(ItemCount > 0) - Message(13, "Buy line %s disabled as Item Compensation is not currently supported.", ItemName); + Message(Chat::Red, "Buy line %s disabled as Item Compensation is not currently supported.", ItemName); else if(Quantity <= 0) - Message(13, "Buy line %s disabled as the quantity is invalid.", ItemName); + Message(Chat::Red, "Buy line %s disabled as the quantity is invalid.", ItemName); else if(LoreConflict) - Message(13, "Buy line %s disabled as the item is LORE and you have one already.", ItemName); + Message(Chat::Red, "Buy line %s disabled as the item is LORE and you have one already.", ItemName); else if(item->NoDrop == 0) - Message(13, "Buy line %s disabled as the item is NODROP.", ItemName); + Message(Chat::Red, "Buy line %s disabled as the item is NODROP.", ItemName); else if(ToggleOnOff) - Message(13, "Buy line %s disabled due to insufficient funds.", ItemName); + Message(Chat::Red, "Buy line %s disabled due to insufficient funds.", ItemName); else database.RemoveBuyLine(CharacterID(), BuySlot); @@ -3047,7 +3047,7 @@ void Client::BuyerItemSearch(const EQApplicationPacket *app) { break; } if (Count == MAX_BUYER_ITEMSEARCH_RESULTS) - Message(15, "Your search returned more than %i results. Only the first %i are displayed.", + Message(Chat::Yellow, "Your search returned more than %i results. Only the first %i are displayed.", MAX_BUYER_ITEMSEARCH_RESULTS, MAX_BUYER_ITEMSEARCH_RESULTS); bisr->Action = Barter_BuyerSearch; diff --git a/zone/trap.cpp b/zone/trap.cpp index 29314f568..7027f3e28 100644 --- a/zone/trap.cpp +++ b/zone/trap.cpp @@ -373,13 +373,13 @@ void EntityList::GetTrapInfo(Client* client) if (cur->IsTrap()) { bool isset = (cur->chkarea_timer.Enabled() && !cur->reset_timer.Enabled()); - client->Message(CC_Default, " Trap: (%d) found at %0.2f,%0.2f,%0.2f. Times Triggered: %d Is Active: %d Group: %d Message: %s", cur->trap_id, cur->m_Position.x, cur->m_Position.y, cur->m_Position.z, cur->times_triggered, isset, cur->group, cur->message.c_str()); + client->Message(Chat::Default, " Trap: (%d) found at %0.2f,%0.2f,%0.2f. Times Triggered: %d Is Active: %d Group: %d Message: %s", cur->trap_id, cur->m_Position.x, cur->m_Position.y, cur->m_Position.z, cur->times_triggered, isset, cur->group, cur->message.c_str()); ++count; } ++it; } - client->Message(CC_Default, "%d traps found.", count); + client->Message(Chat::Default, "%d traps found.", count); } void EntityList::ClearTrapPointers() diff --git a/zone/tribute.cpp b/zone/tribute.cpp index ce1eb5f6d..a52d5d1d6 100644 --- a/zone/tribute.cpp +++ b/zone/tribute.cpp @@ -93,7 +93,7 @@ void Client::ToggleTribute(bool enabled) { } if(cost > m_pp.tribute_points) { - Message(13, "You do not have enough tribute points to activate your tribute!"); + Message(Chat::Red, "You do not have enough tribute points to activate your tribute!"); ToggleTribute(false); return; } @@ -250,7 +250,7 @@ int32 Client::TributeItem(uint32 slot, uint32 quantity) { pts = mod_tribute_item_value(pts, m_inv[slot]); if(pts < 1) { - Message(13, "This item is worthless for favor."); + Message(Chat::Red, "This item is worthless for favor."); return(0); } @@ -277,7 +277,7 @@ int32 Client::TributeItem(uint32 slot, uint32 quantity) { //returns the number of points received from the tribute int32 Client::TributeMoney(uint32 platinum) { if(!TakeMoneyFromPP(platinum * 1000)) { - Message(13, "You do not have that much money!"); + Message(Chat::Red, "You do not have that much money!"); return(0); } diff --git a/zone/tune.cpp b/zone/tune.cpp index c0510f94a..e4d730abc 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -203,11 +203,11 @@ void Mob::Tune_FindACByPctMitigation(Mob* defender, Mob *attacker, float pct_mit Message(0, "#Tune - [WARNING] Mitigation can not be further decreased due to minium hit value (%i).",minhit); if (defender->IsNPC()){ - Message(7, "#Tune - Recommended NPC AC ADJUSTMENT ( %i ) on ' %s ' for an average mitigation of (+ %.0f) pct from attacker ' %s '.",add_ac,defender->GetCleanName(), pct_mitigation, attacker->GetCleanName()); + Message(Chat::LightGray, "#Tune - Recommended NPC AC ADJUSTMENT ( %i ) on ' %s ' for an average mitigation of (+ %.0f) pct from attacker ' %s '.",add_ac,defender->GetCleanName(), pct_mitigation, attacker->GetCleanName()); Message(0, "#SET: [NPC Attack STAT] = [%i]",add_ac + defender->CastToNPC()->GetRawAC()); } if (defender->IsClient()){ - Message(7, "#Tune - Recommended CLIENT AC ADJUSTMENT ( %i ) on ' %s ' for an average mitigation of (+ %.0f) pct from attacker ' %s '.",add_ac,defender->GetCleanName(), pct_mitigation, attacker->GetCleanName()); + Message(Chat::LightGray, "#Tune - Recommended CLIENT AC ADJUSTMENT ( %i ) on ' %s ' for an average mitigation of (+ %.0f) pct from attacker ' %s '.",add_ac,defender->GetCleanName(), pct_mitigation, attacker->GetCleanName()); Message(0, "#Modify (+/-): [Client AC STAT/SE_AC(1)] [%i]",add_ac); } @@ -693,7 +693,7 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch tmp_hit_chance = Tune_CheckHitChance(defender, attacker, skillinuse, EQEmu::invslot::slotPrimary, 0, false, 0, avoid_override, add_acc); if (Msg >= 3) - Message(15, "#Tune - Processing... [%i] [ACCURACY %i] Hit Chance %.2f ",j,add_acc,tmp_hit_chance); + Message(Chat::Yellow, "#Tune - Processing... [%i] [ACCURACY %i] Hit Chance %.2f ",j,add_acc,tmp_hit_chance); if (interval > 0 && tmp_hit_chance >= hit_chance){ end = true; @@ -727,8 +727,8 @@ void Mob::Tune_FindAccuaryByHitChance(Mob* defender, Mob *attacker, float hit_ch add_acc = add_acc + interval; } - Message(7, "#Tune - Error: Unable to find desired result for (%.0f) pct - Increase interval (%i) AND/OR max loop value (%i) and run again.", hit_chance, interval, max_loop); - Message(7, "#Tune - Parse ended at ACCURACY ADJUSTMENTT ( %i ) at hit chance of (%.0f) / (%.0f) pct.",add_acc,tmp_hit_chance / hit_chance); + Message(Chat::LightGray, "#Tune - Error: Unable to find desired result for (%.0f) pct - Increase interval (%i) AND/OR max loop value (%i) and run again.", hit_chance, interval, max_loop); + Message(Chat::LightGray, "#Tune - Parse ended at ACCURACY ADJUSTMENTT ( %i ) at hit chance of (%.0f) / (%.0f) pct.",add_acc,tmp_hit_chance / hit_chance); } void Mob::Tune_FindAvoidanceByHitChance(Mob* defender, Mob *attacker, float hit_chance, int interval, int max_loop, int acc_override, int Msg) diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index ffe777808..6493188bf 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -211,7 +211,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) else if (scm->queued == 2) // tell queue was full client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message); else if (scm->queued == 3) // person was offline - client->Message_StringID(MT_TellEcho, TOLD_NOT_ONLINE, scm->to); + client->Message_StringID(Chat::EchoTell, TOLD_NOT_ONLINE, scm->to); else // normal tell echo "You told Soanso, 'something'" // tell echo doesn't use language, so it looks normal to you even if nobody can understand your tells client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, 0, 100, scm->message); @@ -374,15 +374,15 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) switch (ztz->response) { case -2: { - entity->CastToClient()->Message(13, "You do not own the required locations to enter this zone."); + entity->CastToClient()->Message(Chat::Red, "You do not own the required locations to enter this zone."); break; } case -1: { - entity->CastToClient()->Message(13, "The zone is currently full, please try again later."); + entity->CastToClient()->Message(Chat::Red, "The zone is currently full, please try again later."); break; } case 0: { - entity->CastToClient()->Message(13, "All zone servers are taken at this time, please try again later."); + entity->CastToClient()->Message(Chat::Red, "All zone servers are taken at this time, please try again later."); break; } } @@ -414,7 +414,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Client* client = entity_list.GetClientByID(wars->id); if (client) { if (pack->size == 64)//no results - client->Message_StringID(0, WHOALL_NO_RESULTS); + client->Message_StringID(Chat::White, WHOALL_NO_RESULTS); else { auto outapp = new EQApplicationPacket(OP_WhoAllResponse, pack->size); memcpy(outapp->pBuffer, pack->pBuffer, pack->size); @@ -783,7 +783,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Client* c = entity_list.GetClientByName(Rezzer); if (c) - c->Message_StringID(MT_WornOff, REZZ_ALREADY_PENDING); + c->Message_StringID(Chat::SpellWornOff, REZZ_ALREADY_PENDING); break; } @@ -910,7 +910,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) entity_list.AddGroup(group); if (group->GetID() == 0) { - Inviter->Message(13, "Unable to get new group id. Cannot create group."); + Inviter->Message(Chat::Red, "Unable to get new group id. Cannot create group."); break; } @@ -1485,7 +1485,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; Client* client = entity_list.GetClientByName(s->ownername); if (client) { - client->Message_StringID(0, s->message_string_id); + client->Message_StringID(Chat::White, s->message_string_id); } break; } @@ -1729,7 +1729,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (c) { c->ClearPendingAdventureDoorClick(); - c->Message_StringID(13, 5141); + c->Message_StringID(Chat::Red, 5141); } break; } @@ -1751,7 +1751,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (c) { c->ClearPendingAdventureLeave(); - c->Message(13, "You cannot leave this adventure at this time."); + c->Message(Chat::Red, "You cannot leave this adventure at this time."); } break; } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index e2825da5a..7c90bcc11 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3061,10 +3061,10 @@ bool ZoneDatabase::SaveMerc(Merc *merc) { auto results = database.QueryDatabase(query); if(!results.Success()) { - owner->Message(13, results.ErrorMessage().c_str()); + owner->Message(Chat::Red, results.ErrorMessage().c_str()); return false; } else if (results.RowsAffected() != 1) { - owner->Message(13, "Unable to save merc to the database."); + owner->Message(Chat::Red, "Unable to save merc to the database."); return false; } @@ -3095,10 +3095,10 @@ bool ZoneDatabase::SaveMerc(Merc *merc) { auto results = database.QueryDatabase(query); if (!results.Success()) { - owner->Message(13, results.ErrorMessage().c_str()); + owner->Message(Chat::Red, results.ErrorMessage().c_str()); return false; } else if (results.RowsAffected() != 1) { - owner->Message(13, "Unable to save merc to the database."); + owner->Message(Chat::Red, "Unable to save merc to the database."); return false; } diff --git a/zone/zoning.cpp b/zone/zoning.cpp index dbe9346b7..869ef4eb4 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -96,7 +96,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //that can be a valid un-zolicited zone request? //Todo cheat detection - Message(13, "Invalid unsolicited zone request."); + Message(Chat::Red, "Invalid unsolicited zone request."); Log(Logs::General, Logs::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; @@ -142,14 +142,14 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //make sure we are in it and it's unexpired. if(!database.VerifyInstanceAlive(target_instance_id, CharacterID())) { - Message(13, "Instance ID was expired or you were not in it."); + Message(Chat::Red, "Instance ID was expired or you were not in it."); SendZoneCancel(zc); return; } if(!database.VerifyZoneInstance(target_zone_id, target_instance_id)) { - Message(13, "Instance ID was %u does not go with zone id %u", target_instance_id, target_zone_id); + Message(Chat::Red, "Instance ID was %u does not go with zone id %u", target_instance_id, target_zone_id); SendZoneCancel(zc); return; } @@ -159,7 +159,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { const char *target_zone_name = database.GetZoneName(target_zone_id); if(target_zone_name == nullptr) { //invalid zone... - Message(13, "Invalid target zone ID."); + Message(Chat::Red, "Invalid target zone ID."); Log(Logs::General, Logs::Error, "Zoning %s: Unable to get zone name for zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); return; @@ -172,7 +172,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { char flag_needed[128]; if(!database.GetSafePoints(target_zone_name, database.GetInstanceVersion(target_instance_id), &safe_x, &safe_y, &safe_z, &minstatus, &minlevel, flag_needed)) { //invalid zone... - Message(13, "Invalid target zone while getting safe points."); + Message(Chat::Red, "Invalid target zone while getting safe points."); Log(Logs::General, Logs::Error, "Zoning %s: Unable to get safe coordinates for zone '%s'.", GetName(), target_zone_name); SendZoneCancel(zc); return; @@ -277,7 +277,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //the flag needed string is not empty, meaning a flag is required. if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(target_zone_id)) { - Message(13, "You do not have the flag to enter %s.", target_zone_name); + Message(Chat::Red, "You do not have the flag to enter %s.", target_zone_name); myerror = ZONE_ERROR_NOEXPERIENCE; } } @@ -453,7 +453,7 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; case GMSummon: - Message(15, "You have been summoned by a GM!"); + Message(Chat::Yellow, "You have been summoned by a GM!"); ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; case ZoneToBindPoint: @@ -463,11 +463,11 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y, ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; case SummonPC: - Message(15, "You have been summoned!"); + Message(Chat::Yellow, "You have been summoned!"); ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; case Rewind: - Message(15, "Rewinding to previous location."); + Message(Chat::Yellow, "Rewinding to previous location."); ZonePC(zoneID, instance_id, x, y, z, heading, ignorerestrictions, zm); break; default: @@ -486,7 +486,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z database.GetZoneLongName(pShortZoneName, &pZoneName); if(!pZoneName) { - Message(13, "Invalid zone number specified"); + Message(Chat::Red, "Invalid zone number specified"); safe_delete_array(pZoneName); return; } @@ -560,7 +560,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z Entity* entity = entity_list.GetID(entity_id_being_looted); if (entity == 0) { - Message(13, "Error: OP_EndLootRequest: Corpse not found (ent = 0)"); + Message(Chat::Red, "Error: OP_EndLootRequest: Corpse not found (ent = 0)"); if (ClientVersion() >= EQEmu::versions::ClientVersion::SoD) Corpse::SendEndLootErrorPacket(this); else @@ -568,7 +568,7 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z } else if (!entity->IsCorpse()) { - Message(13, "Error: OP_EndLootRequest: Corpse not found (!entity->IsCorpse())"); + Message(Chat::Red, "Error: OP_EndLootRequest: Corpse not found (!entity->IsCorpse())"); Corpse::SendLootReqErrorPacket(this); } else @@ -723,7 +723,7 @@ void Client::Gate(uint8 bindnum) { } void NPC::Gate(uint8 bindnum) { - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), MT_Spells, GATES, GetCleanName()); + entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), Chat::Spells, GATES, GetCleanName()); Mob::Gate(bindnum); } From 9f25c9070c1aec1b197099f73b6e1b0ed1094371 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 00:14:02 -0500 Subject: [PATCH 147/491] Refactor message functions --- utils/deprecated/perlxs/mob.h | 2 +- zone/aa.cpp | 8 +- zone/attack.cpp | 98 ++++++------- zone/aura.cpp | 4 +- zone/bot.cpp | 8 +- zone/bot_command.cpp | 6 +- zone/client.cpp | 108 +++++++------- zone/client.h | 8 +- zone/client_packet.cpp | 230 +++++++++++++++--------------- zone/client_process.cpp | 53 +++---- zone/corpse.cpp | 12 +- zone/doors.cpp | 14 +- zone/effects.cpp | 20 +-- zone/entity.cpp | 256 +++++++++++++++++++++++++++------- zone/entity.h | 37 ++++- zone/exp.cpp | 40 +++--- zone/forage.cpp | 36 ++--- zone/groups.cpp | 4 +- zone/groups.h | 2 +- zone/inventory.cpp | 4 +- zone/lua_mob.cpp | 7 +- zone/lua_mob.h | 2 +- zone/merc.cpp | 4 +- zone/mob.cpp | 28 ++-- zone/mob.h | 8 +- zone/mob_ai.cpp | 32 +++-- zone/npc.cpp | 8 +- zone/oldcode.cpp | 2 +- zone/perl_mob.cpp | 2 +- zone/raids.cpp | 4 +- zone/raids.h | 2 +- zone/special_attacks.cpp | 32 +++-- zone/spell_effects.cpp | 74 ++++++---- zone/spells.cpp | 198 +++++++++++++------------- zone/tradeskills.cpp | 26 ++-- zone/trading.cpp | 2 +- zone/worldserver.cpp | 10 +- zone/zoning.cpp | 2 +- 38 files changed, 814 insertions(+), 579 deletions(-) diff --git a/utils/deprecated/perlxs/mob.h b/utils/deprecated/perlxs/mob.h index 0485e299d..7dc85b2a3 100644 --- a/utils/deprecated/perlxs/mob.h +++ b/utils/deprecated/perlxs/mob.h @@ -130,7 +130,7 @@ int32 GetFollowID(); virtual void Message(int32 type, const char* message, ...); - virtual void Message_StringID(int32 type, int32 string_id, int32 distance = 0); + virtual void MessageString(int32 type, int32 string_id, int32 distance = 0); void Say(const char *format, ...); void Shout(const char *format, ...); void Emote(const char *format, ...); diff --git a/zone/aa.cpp b/zone/aa.cpp index 5696bd445..1712dd7a0 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -1091,7 +1091,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost SendAlternateAdvancementStats(); if(rank->prev) { - Message_StringID(Chat::Yellow, AA_IMPROVE, + MessageString(Chat::Yellow, AA_IMPROVE, std::to_string(rank->title_sid).c_str(), std::to_string(rank->prev->current_value).c_str(), std::to_string(cost).c_str(), @@ -1104,7 +1104,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost } } else { - Message_StringID(Chat::Yellow, AA_GAIN_ABILITY, + MessageString(Chat::Yellow, AA_GAIN_ABILITY, std::to_string(rank->title_sid).c_str(), std::to_string(cost).c_str(), cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()); @@ -1200,7 +1200,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { CommonBreakInvisible(); if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) { - Message_StringID(Chat::SpellFailure, SNEAK_RESTRICT); + MessageString(Chat::SpellFailure, SNEAK_RESTRICT); return; } // @@ -1214,7 +1214,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) { SetAppearance(eaStanding, false); if (GetAppearance() != eaStanding) { - Message_StringID(Chat::SpellFailure, STAND_TO_CAST); + MessageString(Chat::SpellFailure, STAND_TO_CAST); return; } } diff --git a/zone/attack.cpp b/zone/attack.cpp index d555e4458..58a661969 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1319,7 +1319,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) if (other->AvoidDamage(this, hit)) { int strike_through = itembonuses.StrikeThrough + spellbonuses.StrikeThrough + aabonuses.StrikeThrough; if (strike_through && zone->random.Roll(strike_through)) { - Message_StringID(Chat::StrikeThrough, + MessageString(Chat::StrikeThrough, STRIKETHROUGH_STRING); // You strike through your opponents defenses! hit.damage_done = 1; // set to one, we will check this to continue } @@ -1340,9 +1340,9 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts) int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist; int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist; if (zone->random.Roll(stun_resist2)) { - other->Message_StringID(Chat::Stun, AVOID_STUNNING_BLOW); + other->MessageString(Chat::Stun, AVOID_STUNNING_BLOW); } else if (zone->random.Roll(stun_resist)) { - other->Message_StringID(Chat::Stun, SHAKE_OFF_STUN); + other->MessageString(Chat::Stun, SHAKE_OFF_STUN); } else { other->Stun(3000); // yuck -- 3 seconds } @@ -1392,7 +1392,7 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b if (DivineAura() && !GetGM()) {//cant attack while invulnerable unless your a gm Log(Logs::Detail, Logs::Combat, "Attack canceled, Divine Aura is in effect."); - Message_StringID(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable! + MessageString(Chat::DefaultText, DIVINE_AURA_NO_ATK); //You can't attack while invulnerable! return false; } @@ -1615,7 +1615,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk if (killerMob && killerMob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { char val1[20] = { 0 }; - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, DamageMessages), @@ -1624,7 +1624,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, EQEmu::skills::Sk killerMob->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ ConvertArray(damage, val1)/* Message3 */ - ); + ); } int exploss = 0; @@ -2129,7 +2129,7 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, EQEmu::skills::Skill { if (IsLDoNTrapped()) { - Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); + MessageString(Chat::Red, LDON_ACCIDENT_SETOFF2); SpellFinished(GetLDoNTrapSpellID(), other, EQEmu::spells::CastingSlot::Item, 0, -1, spells[GetLDoNTrapSpellID()].ResistDiff, false); SetLDoNTrapSpellID(0); SetLDoNTrapped(false); @@ -2169,7 +2169,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil if (killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) { char val1[20] = { 0 }; - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, DamageMessages), @@ -2178,7 +2178,7 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil killer_mob->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ ConvertArray(damage, val1) /* Message3 */ - ); + ); } } else { @@ -3439,7 +3439,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const Log(Logs::Detail, Logs::Aggro, "Sending pet %s into battle due to attack.", pet->GetName()); pet->AddToHateList(attacker, 1, 0, true, false, false, spell_id); pet->SetTarget(attacker); - Message_StringID(Chat::NPCQuestSay, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); + MessageString(Chat::NPCQuestSay, PET_ATTACKING, pet->GetCleanName(), attacker->GetCleanName()); } } @@ -3507,7 +3507,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const //fade mez if we are mezzed if (IsMezzed() && attacker) { Log(Logs::Detail, Logs::Combat, "Breaking mez due to attack."); - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( this, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), @@ -3515,7 +3515,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const HAS_BEEN_AWAKENED, // %1 has been awakened by %2. GetCleanName(), /* Message1 */ attacker->GetCleanName() /* Message2 */ - ); + ); BuffFadeByEffect(SE_Mez); } @@ -3564,13 +3564,13 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const else { // stun resist passed! if (IsClient()) - Message_StringID(Chat::Stun, SHAKE_OFF_STUN); + MessageString(Chat::Stun, SHAKE_OFF_STUN); } } else { // stun resist 2 passed! if (IsClient()) - Message_StringID(Chat::Stun, AVOID_STUNNING_BLOW); + MessageString(Chat::Stun, AVOID_STUNNING_BLOW); } } else { @@ -3650,7 +3650,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const if (((spell_id != SPELL_UNKNOWN) || (FromDamageShield)) && damage>0) { //special crap for spell damage, looks hackish to me char val1[20] = { 0 }; - owner->Message_StringID(Chat::NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); + owner->MessageString(Chat::NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); } else { if (damage > 0) { @@ -3680,10 +3680,10 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const char val1[20] = { 0 }; if (FromDamageShield) { if (attacker->CastToClient()->GetFilter(FilterDamageShields) != FilterHide) - attacker->Message_StringID(Chat::DamageShield, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); + attacker->MessageString(Chat::DamageShield, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1)); } else { - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( this, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), @@ -3692,7 +3692,7 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const attacker->GetCleanName(), /* Message1 */ GetCleanName(), /* Message2 */ ConvertArray(damage, val1) /* Message3 */ - ); + ); } } else { @@ -3754,11 +3754,11 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const // So we can see our dot dmg like live shows it. if (spell_id != SPELL_UNKNOWN && damage > 0 && attacker && attacker != this && attacker->IsClient()) { //might filter on (attack_skill>200 && attack_skill<250), but I dont think we need it - attacker->FilteredMessage_StringID(attacker, Chat::DotDamage, FilterDOT, + attacker->FilteredMessageString(attacker, Chat::DotDamage, FilterDOT, YOUR_HIT_DOT, GetCleanName(), itoa(damage), spells[spell_id].name); /* older clients don't have the below String ID, but it will be filtered */ - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( attacker, /* Sender */ true, /* Skip Sender */ RuleI(Range, SpellMessages), @@ -3792,37 +3792,37 @@ void Mob::HealDamage(uint32 amount, Mob *caster, uint16 spell_id) // message to caster if (caster->IsClient() && caster == this) { if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, + FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime, HOT_HEAL_SELF, itoa(acthealed), spells[spell_id].name); else - FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, + FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime, YOU_HEALED, GetCleanName(), itoa(acthealed)); } else if (caster->IsClient() && caster != this) { if (caster->CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, + caster->FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime, HOT_HEAL_OTHER, GetCleanName(), itoa(acthealed), spells[spell_id].name); else - caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterHealOverTime, + caster->FilteredMessageString(caster, Chat::NonMelee, FilterHealOverTime, YOU_HEAL, GetCleanName(), itoa(acthealed)); } // message to target if (IsClient() && caster != this) { if (CastToClient()->ClientVersionBit() & EQEmu::versions::maskSoFAndLater) - FilteredMessage_StringID(this, Chat::NonMelee, FilterHealOverTime, + FilteredMessageString(this, Chat::NonMelee, FilterHealOverTime, HOT_HEALED_OTHER, caster->GetCleanName(), itoa(acthealed), spells[spell_id].name); else - FilteredMessage_StringID(this, Chat::NonMelee, FilterHealOverTime, + FilteredMessageString(this, Chat::NonMelee, FilterHealOverTime, YOU_HEALED, caster->GetCleanName(), itoa(acthealed)); } } else { // normal heals - FilteredMessage_StringID(caster, Chat::NonMelee, FilterSpellDamage, + FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage, YOU_HEALED, caster->GetCleanName(), itoa(acthealed)); if (caster != this) - caster->FilteredMessage_StringID(caster, Chat::NonMelee, FilterSpellDamage, + caster->FilteredMessageString(caster, Chat::NonMelee, FilterSpellDamage, YOU_HEAL, GetCleanName(), itoa(acthealed)); } } @@ -3993,10 +3993,10 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * if (IsPet()) { Mob *own = GetOwner(); if (own) - own->Message_StringID(Chat::Red, PROC_PETTOOLOW); + own->MessageString(Chat::Red, PROC_PETTOOLOW); } else { - Message_StringID(Chat::Red, PROC_TOOLOW); + MessageString(Chat::Red, PROC_TOOLOW); } } else { @@ -4030,10 +4030,10 @@ void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData * if (IsPet()) { Mob *own = GetOwner(); if (own) - own->Message_StringID(Chat::Red, PROC_PETTOOLOW); + own->MessageString(Chat::Red, PROC_PETTOOLOW); } else { - Message_StringID(Chat::Red, PROC_TOOLOW); + MessageString(Chat::Red, PROC_TOOLOW); } } else { @@ -4183,7 +4183,7 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit) hit.damage_done += 5; hit.damage_done = (hit.damage_done * critMod) / 100; - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4192,7 +4192,7 @@ void Mob::TryPetCriticalHit(Mob *defender, DamageHitInfo &hit) CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); } } @@ -4243,7 +4243,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * /* Female */ if (GetGender() == 1) { - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4252,11 +4252,11 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * FEMALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses her target!(%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); } /* Males and Neuter */ else { - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4265,7 +4265,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * MALE_SLAYUNDEAD, /* MessageFormat: %1's holy blade cleanses his target!(%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); } return; } @@ -4340,7 +4340,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * } hit.damage_done = hit.damage_done * 200 / 100; - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4349,7 +4349,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * DEADLY_STRIKE, /* MessageFormat: %1 scores a Deadly Strike!(%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); return; } } @@ -4368,7 +4368,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * hit.damage_done += og_damage * 119 / 100; Log(Logs::Detail, Logs::Combat, "Crip damage %d", hit.damage_done); - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4377,7 +4377,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * CRIPPLING_BLOW, /* MessageFormat: %1 lands a Crippling Blow!(%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); // Crippling blows also have a chance to stun // Kayen: Crippling Blow would cause a chance to interrupt for npcs < 55, with a @@ -4390,7 +4390,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * } /* Normal Critical hit message */ - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4399,7 +4399,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions * CRITICAL_HIT, /* MessageFormat: %1 scores a critical hit! (%2) */ GetCleanName(), /* Message1 */ itoa(hit.damage_done + hit.min_damage) /* Message2 */ - ); + ); } } } @@ -4427,7 +4427,7 @@ bool Mob::TryFinishingBlow(Mob *defender, int &damage) (ProcChance >= zone->random.Int(1, 1000))) { /* Finishing Blow Critical Message */ - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, CriticalDamage), @@ -4435,7 +4435,7 @@ bool Mob::TryFinishingBlow(Mob *defender, int &damage) FilterMeleeCrits, /* FilterType: 12 */ FINISHING_BLOW, /* MessageFormat: %1 scores a Finishing Blow!!) */ GetCleanName() /* Message1 */ - ); + ); damage = FB_Dmg; return true; @@ -4453,7 +4453,7 @@ void Mob::DoRiposte(Mob *defender) // so ahhh the angle you can riposte is larger than the angle you can hit :P if (!defender->IsFacingMob(this)) { - defender->Message_StringID(Chat::TooFarAway, CANT_SEE_TARGET); + defender->MessageString(Chat::TooFarAway, CANT_SEE_TARGET); return; } @@ -5042,7 +5042,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac else if (GetClass() == RANGER && GetLevel() > 50) { // no double dmg on headshot if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) { hit.damage_done *= 2; - Message_StringID(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE); + MessageString(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE); } } } @@ -5347,7 +5347,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell) Attack(target, hand, false, false, IsFromSpell); if (zone->random.Roll(flurrychance)) Attack(target, hand, false, false, IsFromSpell); - Message_StringID(Chat::NPCFlurry, YOU_FLURRY); + MessageString(Chat::NPCFlurry, YOU_FLURRY); } } } diff --git a/zone/aura.cpp b/zone/aura.cpp index 223b5dcb4..adedb3f56 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -841,10 +841,10 @@ void Mob::AddTrap(Aura *aura, AuraRecord &record) bool Mob::CanSpawnAura(bool trap) { if (trap && !HasFreeTrapSlots()) { - Message_StringID(Chat::SpellFailure, NO_MORE_TRAPS); + MessageString(Chat::SpellFailure, NO_MORE_TRAPS); return false; } else if (!trap && !HasFreeAuraSlots()) { - Message_StringID(Chat::SpellFailure, NO_MORE_AURAS); + MessageString(Chat::SpellFailure, NO_MORE_AURAS); return false; } diff --git a/zone/bot.cpp b/zone/bot.cpp index 7265492aa..daef58a9a 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2808,7 +2808,7 @@ void Bot::AI_Process() { int32 flurrychance = (aabonuses.FlurryChance + spellbonuses.FlurryChance + itembonuses.FlurryChance); if (flurrychance) { if (zone->random.Int(0, 100) < flurrychance) { - Message_StringID(Chat::NPCFlurry, YOU_FLURRY); + MessageString(Chat::NPCFlurry, YOU_FLURRY); Attack(tar, EQEmu::invslot::slotPrimary, false); TEST_TARGET(); @@ -6444,11 +6444,11 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlo if(!IsValidSpell(spell_id) || casting_spell_id || delaytimer || spellend_timer.Enabled() || IsStunned() || IsFeared() || IsMezzed() || (IsSilenced() && !IsDiscipline(spell_id)) || (IsAmnesiad() && IsDiscipline(spell_id))) { Log(Logs::Detail, Logs::Spells, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced() ); if(IsSilenced() && !IsDiscipline(spell_id)) - Message_StringID(Chat::Red, SILENCED_STRING); + MessageString(Chat::Red, SILENCED_STRING); if(IsAmnesiad() && IsDiscipline(spell_id)) - Message_StringID(Chat::Red, MELEE_SILENCE); + MessageString(Chat::Red, MELEE_SILENCE); if(casting_spell_id) AI_Event_SpellCastFinished(false, static_cast(casting_spell_slot)); @@ -6458,7 +6458,7 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQEmu::spells::CastingSlo } if(IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()){ - Message_StringID(Chat::Red, SPELL_WOULDNT_HOLD); + MessageString(Chat::Red, SPELL_WOULDNT_HOLD); if(casting_spell_id) AI_Event_SpellCastFinished(false, static_cast(casting_spell_slot)); diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index da17b78d8..90d694004 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -7284,7 +7284,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName); if (c->GetTradeskillObject() || (c->trade->state == Trading)) { - c->Message_StringID(Chat::Tell, MERCHANT_BUSY); + c->MessageString(Chat::Tell, MERCHANT_BUSY); return; } @@ -7310,7 +7310,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) itm = itminst->GetItem(); if (itminst && itm && c->CheckLoreConflict(itm)) { - c->Message_StringID(Chat::WhiteSmoke, PICK_LORE); + c->MessageString(Chat::WhiteSmoke, PICK_LORE); return; } @@ -7324,7 +7324,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) if (!c->CheckLoreConflict(itma->GetItem())) continue; - c->Message_StringID(Chat::WhiteSmoke, PICK_LORE); + c->MessageString(Chat::WhiteSmoke, PICK_LORE); return; } diff --git a/zone/client.cpp b/zone/client.cpp index 18385fe30..dfee9a340 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -914,7 +914,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s { case ChatChannel_Guild: { /* Guild Chat */ if (!IsInAGuild()) - Message_StringID(Chat::DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild. + MessageString(Chat::DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild. else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK)) Message(0, "Error: You dont have permission to speak to the guild."); else if (!worldserver.SendChannelMessage(this, targetname, chan_num, GuildID(), language, lang_skill, message)) @@ -1509,7 +1509,7 @@ void Client::IncreaseLanguageSkill(int skill_id, int value) { QueuePacket(outapp); safe_delete(outapp); - Message_StringID( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify client + MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify client } void Client::AddSkill(EQEmu::skills::SkillType skillid, uint16 value) { @@ -2578,7 +2578,7 @@ void Client::SetPVP(bool toggle, bool message) { if (message) { if(GetPVP()) - this->Message_StringID(Chat::Shout,PVP_ON); + this->MessageString(Chat::Shout,PVP_ON); else Message(Chat::Red, "You no longer follow the ways of discord."); } @@ -2714,22 +2714,22 @@ void Client::Disarm(Client* disarmer, int chance) { if (matslot != EQEmu::textures::materialInvalid) SendWearChange(matslot); } - Message_StringID(Chat::Skills, DISARMED); + MessageString(Chat::Skills, DISARMED); if (disarmer != this) - disarmer->Message_StringID(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); + disarmer->MessageString(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); if (chance != 1000) disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); CalcBonuses(); // CalcEnduranceWeightFactor(); return; } - disarmer->Message_StringID(Chat::Skills, DISARM_FAILED); + disarmer->MessageString(Chat::Skills, DISARM_FAILED); if (chance != 1000) disarmer->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); return; } } - disarmer->Message_StringID(Chat::Skills, DISARM_FAILED); + disarmer->MessageString(Chat::Skills, DISARM_FAILED); } bool Client::BindWound(Mob *bindmob, bool start, bool fail) @@ -2771,7 +2771,7 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail) } else { // send bindmob "stand still" if (!bindmob->IsAIControlled() && bindmob != this) { - bindmob->CastToClient()->Message_StringID(Chat::Yellow, + bindmob->CastToClient()->MessageString(Chat::Yellow, YOU_ARE_BEING_BANDAGED); } else if (bindmob->IsAIControlled() && bindmob != this) { ; // Tell IPC to stand still? @@ -3075,7 +3075,7 @@ void Client::ServerFilter(SetServerFilter_Struct* filter){ } // this version is for messages with no parameters -void Client::Message_StringID(uint32 type, uint32 string_id, uint32 distance) +void Client::MessageString(uint32 type, uint32 string_id, uint32 distance) { if (GetFilter(FilterSpellDamage) == FilterHide && type == Chat::NonMelee) return; @@ -3103,7 +3103,7 @@ void Client::Message_StringID(uint32 type, uint32 string_id, uint32 distance) // to load the eqstr file and count them in the string. // This hack sucks but it's gonna work for now. // -void Client::Message_StringID(uint32 type, uint32 string_id, const char* message1, +void Client::MessageString(uint32 type, uint32 string_id, const char* message1, const char* message2,const char* message3,const char* message4, const char* message5,const char* message6,const char* message7, const char* message8,const char* message9, uint32 distance) @@ -3126,7 +3126,7 @@ void Client::Message_StringID(uint32 type, uint32 string_id, const char* message if(!message1) { - Message_StringID(type, string_id); // use the simple message instead + MessageString(type, string_id); // use the simple message instead return; } @@ -3205,7 +3205,7 @@ bool Client::FilteredMessageCheck(Mob *sender, eqFilterType filter) return true; } -void Client::FilteredMessage_StringID(Mob *sender, uint32 type, +void Client::FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id) { if (!FilteredMessageCheck(sender, filter)) @@ -3224,7 +3224,7 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, return; } -void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id, +void Client::FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id, const char *message1, const char *message2, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) @@ -3240,7 +3240,7 @@ void Client::FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType fil type = 4; if (!message1) { - FilteredMessage_StringID(sender, type, filter, string_id); // use the simple message instead + FilteredMessageString(sender, type, filter, string_id); // use the simple message instead return; } @@ -3281,7 +3281,7 @@ void Client::Tell_StringID(uint32 string_id, const char *who, const char *messag char string_id_str[10]; snprintf(string_id_str, 10, "%d", string_id); - Message_StringID(Chat::EchoTell, TELL_QUEUED_MESSAGE, who, string_id_str, message); + MessageString(Chat::EchoTell, TELL_QUEUED_MESSAGE, who, string_id_str, message); } void Client::SetTint(int16 in_slot, uint32 color) { @@ -3344,7 +3344,7 @@ void Client::SetLanguageSkill(int langid, int value) QueuePacket(outapp); safe_delete(outapp); - Message_StringID( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify the client + MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify the client } void Client::LinkDead() @@ -3432,7 +3432,7 @@ void Client::Escape() entity_list.RemoveFromTargets(this, true); SetInvisible(1); - Message_StringID(Chat::Skills, ESCAPE); + MessageString(Chat::Skills, ESCAPE); } float Client::CalcPriceMod(Mob* other, bool reverse) @@ -3872,13 +3872,13 @@ void Client::SacrificeConfirm(Client *caster) } if (GetLevel() < RuleI(Spells, SacrificeMinLevel)) { - caster->Message_StringID(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. + caster->MessageString(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. safe_delete(outapp); return; } if (GetLevel() > RuleI(Spells, SacrificeMaxLevel)) { - caster->Message_StringID(Chat::Red, SAC_TOO_HIGH); + caster->MessageString(Chat::Red, SAC_TOO_HIGH); safe_delete(outapp); return; } @@ -3947,7 +3947,7 @@ void Client::Sacrifice(Client *caster) caster->SummonItem(RuleI(Spells, SacrificeItemID)); } } else { - caster->Message_StringID(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. + caster->MessageString(Chat::Red, SAC_TOO_LOW); // This being is not a worthy sacrifice. } } @@ -4932,7 +4932,7 @@ void Client::HandleLDoNOpen(NPC *target) { if(target->GetLDoNTrapSpellID() != 0) { - Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); + MessageString(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -4948,7 +4948,7 @@ void Client::HandleLDoNOpen(NPC *target) if(target->IsLDoNLocked()) { - Message_StringID(Chat::Skills, LDON_STILL_LOCKED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_STILL_LOCKED, target->GetCleanName()); return; } else @@ -4982,13 +4982,13 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) { if((target->GetLDoNTrapType() == LDoNTypeCursed || target->GetLDoNTrapType() == LDoNTypeMagical) && type != target->GetLDoNTrapType()) { - Message_StringID(Chat::Skills, LDON_CANT_DETERMINE_TRAP, target->GetCleanName()); + MessageString(Chat::Skills, LDON_CANT_DETERMINE_TRAP, target->GetCleanName()); return; } if(target->IsLDoNTrapDetected()) { - Message_StringID(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); + MessageString(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); } else { @@ -4997,10 +4997,10 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) { case -1: case 0: - Message_StringID(Chat::Skills, LDON_DONT_KNOW_TRAPPED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_DONT_KNOW_TRAPPED, target->GetCleanName()); break; case 1: - Message_StringID(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); + MessageString(Chat::Skills, LDON_CERTAIN_TRAP, target->GetCleanName()); target->SetLDoNTrapDetected(true); break; default: @@ -5010,7 +5010,7 @@ void Client::HandleLDoNSenseTraps(NPC *target, uint16 skill, uint8 type) } else { - Message_StringID(Chat::Skills, LDON_CERTAIN_NOT_TRAP, target->GetCleanName()); + MessageString(Chat::Skills, LDON_CERTAIN_NOT_TRAP, target->GetCleanName()); } } } @@ -5023,13 +5023,13 @@ void Client::HandleLDoNDisarm(NPC *target, uint16 skill, uint8 type) { if(!target->IsLDoNTrapped()) { - Message_StringID(Chat::Skills, LDON_WAS_NOT_TRAPPED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_WAS_NOT_TRAPPED, target->GetCleanName()); return; } if((target->GetLDoNTrapType() == LDoNTypeCursed || target->GetLDoNTrapType() == LDoNTypeMagical) && type != target->GetLDoNTrapType()) { - Message_StringID(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); return; } @@ -5048,13 +5048,13 @@ void Client::HandleLDoNDisarm(NPC *target, uint16 skill, uint8 type) target->SetLDoNTrapDetected(false); target->SetLDoNTrapped(false); target->SetLDoNTrapSpellID(0); - Message_StringID(Chat::Skills, LDON_HAVE_DISARMED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_HAVE_DISARMED, target->GetCleanName()); break; case 0: - Message_StringID(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_HAVE_NOT_DISARMED, target->GetCleanName()); break; case -1: - Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); + MessageString(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -5073,7 +5073,7 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) { if(target->IsLDoNTrapped()) { - Message_StringID(Chat::Red, LDON_ACCIDENT_SETOFF2); + MessageString(Chat::Red, LDON_ACCIDENT_SETOFF2); target->SpellFinished(target->GetLDoNTrapSpellID(), this, EQEmu::spells::CastingSlot::Item, 0, -1, spells[target->GetLDoNTrapSpellID()].ResistDiff); target->SetLDoNTrapSpellID(0); target->SetLDoNTrapped(false); @@ -5082,7 +5082,7 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) if(!target->IsLDoNLocked()) { - Message_StringID(Chat::Skills, LDON_WAS_NOT_LOCKED, target->GetCleanName()); + MessageString(Chat::Skills, LDON_WAS_NOT_LOCKED, target->GetCleanName()); return; } @@ -5098,11 +5098,11 @@ void Client::HandleLDoNPickLock(NPC *target, uint16 skill, uint8 type) { case 0: case -1: - Message_StringID(Chat::Skills, LDON_PICKLOCK_FAILURE, target->GetCleanName()); + MessageString(Chat::Skills, LDON_PICKLOCK_FAILURE, target->GetCleanName()); break; case 1: target->SetLDoNLocked(false); - Message_StringID(Chat::Skills, LDON_PICKLOCK_SUCCESS, target->GetCleanName()); + MessageString(Chat::Skills, LDON_PICKLOCK_SUCCESS, target->GetCleanName()); break; } } @@ -5607,7 +5607,7 @@ void Client::SuspendMinion() CurrentPet->SetMana(m_suspendedminion.Mana); - Message_StringID(Chat::Magenta, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName()); + MessageString(Chat::Magenta, SUSPEND_MINION_UNSUSPEND, CurrentPet->GetCleanName()); memset(&m_suspendedminion, 0, sizeof(struct PetInfo)); // TODO: These pet command states need to be synced ... @@ -5637,19 +5637,19 @@ void Client::SuspendMinion() { if(m_suspendedminion.SpellID > 0) { - Message_StringID(Chat::Red,ONLY_ONE_PET); + MessageString(Chat::Red,ONLY_ONE_PET); return; } else if(CurrentPet->IsEngaged()) { - Message_StringID(Chat::Red,SUSPEND_MINION_FIGHTING); + MessageString(Chat::Red,SUSPEND_MINION_FIGHTING); return; } else if(entity_list.Fighting(CurrentPet)) { - Message_StringID(Chat::Blue,SUSPEND_MINION_HAS_AGGRO); + MessageString(Chat::Blue,SUSPEND_MINION_HAS_AGGRO); } else { @@ -5666,7 +5666,7 @@ void Client::SuspendMinion() else strn0cpy(m_suspendedminion.Name, CurrentPet->GetName(), 64); // Name stays even at rank 1 - Message_StringID(Chat::Magenta, SUSPEND_MINION_SUSPEND, CurrentPet->GetCleanName()); + MessageString(Chat::Magenta, SUSPEND_MINION_SUSPEND, CurrentPet->GetCleanName()); CurrentPet->Depop(false); @@ -5675,7 +5675,7 @@ void Client::SuspendMinion() } else { - Message_StringID(Chat::Red, ONLY_SUMMONED_PETS); + MessageString(Chat::Red, ONLY_SUMMONED_PETS); return; } @@ -6149,16 +6149,16 @@ void Client::LocateCorpse() if(ClosestCorpse) { - Message_StringID(Chat::Spells, SENSE_CORPSE_DIRECTION); + MessageString(Chat::Spells, SENSE_CORPSE_DIRECTION); SetHeading(CalculateHeadingToTarget(ClosestCorpse->GetX(), ClosestCorpse->GetY())); SetTarget(ClosestCorpse); SendTargetCommand(ClosestCorpse->GetID()); SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else if(!GetTarget()) - Message_StringID(Chat::Red, SENSE_CORPSE_NONE); + MessageString(Chat::Red, SENSE_CORPSE_NONE); else - Message_StringID(Chat::Red, SENSE_CORPSE_NOT_NAME); + MessageString(Chat::Red, SENSE_CORPSE_NOT_NAME); } void Client::NPCSpawn(NPC *target_npc, const char *identifier, uint32 extra) @@ -6218,7 +6218,7 @@ void Client::DragCorpses() if (!corpse || !corpse->IsPlayerCorpse() || corpse->CastToCorpse()->IsBeingLooted() || !corpse->CastToCorpse()->Summon(this, false, false)) { - Message_StringID(Chat::DefaultText, CORPSEDRAG_STOP); + MessageString(Chat::DefaultText, CORPSEDRAG_STOP); It = DraggedCorpses.erase(It); if (It == DraggedCorpses.end()) break; @@ -7623,7 +7623,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID) { if (!(m_ClientVersionBit & EQEmu::versions::maskRoFAndLater)) { - Message_StringID(Chat::White, PICK_LORE); + MessageString(Chat::White, PICK_LORE); return; } @@ -7632,7 +7632,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID) if(!item) return; - Message_StringID(Chat::White, PICK_LORE, item->Name); + MessageString(Chat::White, PICK_LORE, item->Name); } void Client::GarbleMessage(char *message, uint8 variance) @@ -8031,13 +8031,13 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 faction_ if (tmpvalue == 0 || temp == 1 || temp == 2) return; else if (faction_value >= this_faction_max) - Message_StringID(Chat::Yellow, FACTION_BEST, name); + MessageString(Chat::Yellow, FACTION_BEST, name); else if (faction_value <= this_faction_min) - Message_StringID(Chat::Yellow, FACTION_WORST, name); + MessageString(Chat::Yellow, FACTION_WORST, name); else if (tmpvalue > 0 && faction_value < this_faction_max && !RuleB(Client, UseLiveFactionMessage)) - Message_StringID(Chat::Yellow, FACTION_BETTER, name); + MessageString(Chat::Yellow, FACTION_BETTER, name); else if (tmpvalue < 0 && faction_value > this_faction_min && !RuleB(Client, UseLiveFactionMessage)) - Message_StringID(Chat::Yellow, FACTION_WORSE, name); + MessageString(Chat::Yellow, FACTION_WORSE, name); else if (RuleB(Client, UseLiveFactionMessage)) Message(Chat::Yellow, "Your faction standing with %s has been adjusted by %i.", name, tmpvalue); //New Live faction message (14261) @@ -8365,7 +8365,7 @@ void Client::Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool a DeleteItemInInventory(slot, 1, false); if (!auto_consume) // no message if the client consumed for us - entity_list.MessageClose_StringID(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name); + entity_list.MessageCloseString(this, true, 50, 0, EATING_MESSAGE, GetName(), item->Name); Log(Logs::General, Logs::Food, "Eating from slot: %i", (int)slot); @@ -8383,7 +8383,7 @@ void Client::Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool a increase, m_pp.thirst_level); if (!auto_consume) // no message if the client consumed for us - entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name); + entity_list.MessageCloseString(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name); Log(Logs::General, Logs::Food, "Drinking from slot: %i", (int)slot); } diff --git a/zone/client.h b/zone/client.h index c22f18419..bb80e7ffc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -278,11 +278,11 @@ public: void SendBazaarWelcome(); void DyeArmor(EQEmu::TintProfile* dye); uint8 SlotConvert(uint8 slot,bool bracer=false); - void Message_StringID(uint32 type, uint32 string_id, uint32 distance = 0); - void Message_StringID(uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); + void MessageString(uint32 type, uint32 string_id, uint32 distance = 0); + void MessageString(uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); bool FilteredMessageCheck(Mob *sender, eqFilterType filter); - void FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id); - void FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType filter, + void FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id); + void FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id, const char *message1, const char *message2 = nullptr, const char *message3 = nullptr, const char *message4 = nullptr, const char *message5 = nullptr, const char *message6 = nullptr, diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index cf0633033..67c766597 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1752,14 +1752,14 @@ void Client::Handle_OP_AAAction(const EQApplicationPacket *app) } else if (action->action == aaActionDisableEXP) { //Turn Off AA Exp if (m_epp.perAA > 0) - Message_StringID(Chat::White, AA_OFF); + MessageString(Chat::White, AA_OFF); m_epp.perAA = 0; SendAlternateAdvancementStats(); } else if (action->action == aaActionSetEXP) { if (m_epp.perAA == 0) - Message_StringID(Chat::White, AA_ON); + MessageString(Chat::White, AA_ON); m_epp.perAA = action->exp_value; if (m_epp.perAA < 0 || m_epp.perAA > 100) m_epp.perAA = 0; // stop exploit with sanity check @@ -2834,7 +2834,7 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app) if (poison->Proc.Level2 > GetLevel()) { // Poison is too high to apply. - Message_StringID(Chat::LightBlue, POISON_TOO_HIGH); + MessageString(Chat::LightBlue, POISON_TOO_HIGH); } else if ((primary && primary->ItemType == EQEmu::item::ItemType1HPiercing) || @@ -4023,7 +4023,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app) return; } if (IsAIControlled()) { - this->Message_StringID(Chat::Red, NOT_IN_CONTROL); + this->MessageString(Chat::Red, NOT_IN_CONTROL); //Message(Chat::Red, "You cant cast right now, you arent in control of yourself!"); return; } @@ -4625,7 +4625,7 @@ void Client::Handle_OP_Consent(const EQApplicationPacket *app) safe_delete(pack); } else { - Message_StringID(Chat::White, CONSENT_YOURSELF); + MessageString(Chat::White, CONSENT_YOURSELF); } } return; @@ -4765,10 +4765,10 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app) // this could be done better, but this is only called when you con so w/e // Shroud of Stealth has a special message if (improved_hidden && (!tmob->see_improved_hide && (tmob->see_invis || tmob->see_hide))) - Message_StringID(Chat::NPCQuestSay, SOS_KEEPS_HIDDEN); + MessageString(Chat::NPCQuestSay, SOS_KEEPS_HIDDEN); // we are trying to hide but they can see us else if ((invisible || invisible_undead || hidden || invisible_animals) && !IsInvisible(tmob)) - Message_StringID(Chat::NPCQuestSay, SUSPECT_SEES_YOU); + MessageString(Chat::NPCQuestSay, SUSPECT_SEES_YOU); safe_delete(outapp); @@ -4791,10 +4791,10 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) min = (ttime / 60000) % 60; // Total seconds / 60 drop .00 char val1[20] = { 0 }; char val2[20] = { 0 }; - Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY1, ConvertArray(min, val1), ConvertArray(sec, val2)); + MessageString(Chat::NPCQuestSay, CORPSE_DECAY1, ConvertArray(min, val1), ConvertArray(sec, val2)); } else { - Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY_NOW); + MessageString(Chat::NPCQuestSay, CORPSE_DECAY_NOW); } } else if (tcorpse && tcorpse->IsPlayerCorpse()) { @@ -4825,12 +4825,12 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) Message(0, "This corpse can be resurrected for %i minutes and %i seconds.", min, sec); } else { - Message_StringID(Chat::WhiteSmoke, CORPSE_TOO_OLD); + MessageString(Chat::WhiteSmoke, CORPSE_TOO_OLD); } */ } else { - Message_StringID(Chat::NPCQuestSay, CORPSE_DECAY_NOW); + MessageString(Chat::NPCQuestSay, CORPSE_DECAY_NOW); } } } @@ -4932,7 +4932,7 @@ void Client::Handle_OP_ControlBoat(const EQApplicationPacket *app) boat->SetTarget(this); } else { - this->Message_StringID(Chat::Red, IN_USE); + this->MessageString(Chat::Red, IN_USE); return; } } @@ -4950,7 +4950,7 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) { if (DraggedCorpses.size() >= (unsigned int)RuleI(Character, MaxDraggedCorpses)) { - Message_StringID(Chat::Red, CORPSEDRAG_LIMIT); + MessageString(Chat::Red, CORPSEDRAG_LIMIT); return; } @@ -4968,9 +4968,9 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) if (c) { if (c == this) - Message_StringID(Chat::DefaultText, CORPSEDRAG_ALREADY, corpse->GetCleanName()); + MessageString(Chat::DefaultText, CORPSEDRAG_ALREADY, corpse->GetCleanName()); else - Message_StringID(Chat::DefaultText, CORPSEDRAG_SOMEONE_ELSE, corpse->GetCleanName()); + MessageString(Chat::DefaultText, CORPSEDRAG_SOMEONE_ELSE, corpse->GetCleanName()); return; } @@ -4980,14 +4980,14 @@ void Client::Handle_OP_CorpseDrag(const EQApplicationPacket *app) DraggedCorpses.push_back(std::pair(cds->CorpseName, corpse->GetID())); - Message_StringID(Chat::DefaultText, CORPSEDRAG_BEGIN, cds->CorpseName); + MessageString(Chat::DefaultText, CORPSEDRAG_BEGIN, cds->CorpseName); } void Client::Handle_OP_CorpseDrop(const EQApplicationPacket *app) { if (app->size == 1) { - Message_StringID(Chat::DefaultText, CORPSEDRAG_STOPALL); + MessageString(Chat::DefaultText, CORPSEDRAG_STOPALL); ClearDraggedCorpses(); return; } @@ -4996,7 +4996,7 @@ void Client::Handle_OP_CorpseDrop(const EQApplicationPacket *app) { if (!strcasecmp(Iterator->first.c_str(), (const char *)app->pBuffer)) { - Message_StringID(Chat::DefaultText, CORPSEDRAG_STOP); + MessageString(Chat::DefaultText, CORPSEDRAG_STOP); Iterator = DraggedCorpses.erase(Iterator); return; } @@ -5168,7 +5168,7 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app) DeleteItem_Struct* alc = (DeleteItem_Struct*)app->pBuffer; const EQEmu::ItemInstance *inst = GetInv().GetItem(alc->from_slot); if (inst && inst->GetItem()->ItemType == EQEmu::item::ItemTypeAlcohol) { - entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), inst->GetItem()->Name); + entity_list.MessageCloseString(this, true, 50, 0, DRINKING_MESSAGE, GetName(), inst->GetItem()->Name); CheckIncreaseSkill(EQEmu::skills::SkillAlcoholTolerance, nullptr, 25); int16 AlcoholTolerance = GetSkill(EQEmu::skills::SkillAlcoholTolerance); @@ -5300,7 +5300,7 @@ void Client::Handle_OP_Disarm(const EQApplicationPacket *app) { return; } // Trying to disarm something we can't disarm - Message_StringID(Chat::Skills, DISARM_NO_TARGET); + MessageString(Chat::Skills, DISARM_NO_TARGET); return; } @@ -5358,14 +5358,14 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app) if ((zone->random.Int(0, 49) + uskill) >= (zone->random.Int(0, 49) + trap->skill)) { success = SKILLUP_SUCCESS; - Message_StringID(Chat::Skills, DISARMED_TRAP); + MessageString(Chat::Skills, DISARMED_TRAP); trap->disarmed = true; Log(Logs::General, Logs::Traps, "Trap %d is disarmed.", trap->trap_id); trap->UpdateTrap(); } else { - Message_StringID(Chat::Skills, FAIL_DISARM_DETECTED_TRAP); + MessageString(Chat::Skills, FAIL_DISARM_DETECTED_TRAP); if (zone->random.Int(0, 99) < 25) { trap->Trigger(this); } @@ -5375,12 +5375,12 @@ void Client::Handle_OP_DisarmTraps(const EQApplicationPacket *app) } else { - Message_StringID(Chat::Skills, TRAP_TOO_FAR); + MessageString(Chat::Skills, TRAP_TOO_FAR); } } else { - Message_StringID(Chat::Skills, LDON_SENSE_TRAP2); + MessageString(Chat::Skills, LDON_SENSE_TRAP2); } return; @@ -5464,9 +5464,9 @@ void Client::Handle_OP_DuelResponse(const EQApplicationPacket *app) initiator->CastToClient()->SetDuelTarget(0); initiator->CastToClient()->SetDueling(false); if (GetID() == initiator->GetID()) - entity->CastToClient()->Message_StringID(Chat::NPCQuestSay, DUEL_DECLINE, initiator->GetName()); + entity->CastToClient()->MessageString(Chat::NPCQuestSay, DUEL_DECLINE, initiator->GetName()); else - initiator->CastToClient()->Message_StringID(Chat::NPCQuestSay, DUEL_DECLINE, entity->GetName()); + initiator->CastToClient()->MessageString(Chat::NPCQuestSay, DUEL_DECLINE, entity->GetName()); return; } @@ -5690,7 +5690,7 @@ void Client::Handle_OP_FaceChange(const EQApplicationPacket *app) m_pp.drakkin_tattoo = fc->drakkin_tattoo; m_pp.drakkin_details = fc->drakkin_details; Save(); - Message_StringID(Chat::Red, FACE_ACCEPTED); + MessageString(Chat::Red, FACE_ACCEPTED); //Message(Chat::Red, "Facial features updated."); return; } @@ -5727,7 +5727,7 @@ void Client::Handle_OP_FeignDeath(const EQApplicationPacket *app) uint16 totalfeign = primfeign + secfeign; if (zone->random.Real(0, 160) > totalfeign) { SetFeigned(false); - entity_list.MessageClose_StringID(this, false, 200, 10, STRING_FEIGNFAILED, GetName()); + entity_list.MessageCloseString(this, false, 200, 10, STRING_FEIGNFAILED, GetName()); } else { SetFeigned(true); @@ -5929,7 +5929,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app) cli->SendAppearancePacket(AT_NPCName, 1, true); cli->CastToClient()->SetBecomeNPC(true); cli->CastToClient()->SetBecomeNPCLevel(bnpc->maxlevel); - cli->Message_StringID(Chat::White, TOGGLE_OFF); + cli->MessageString(Chat::White, TOGGLE_OFF); cli->CastToClient()->tellsoff = true; //TODO: Make this toggle a BecomeNPC flag so that it gets updated when people zone in as well; Make combat work with this. return; @@ -6336,13 +6336,13 @@ void Client::Handle_OP_GMToggle(const EQApplicationPacket *app) } GMToggle_Struct *ts = (GMToggle_Struct *)app->pBuffer; if (ts->toggle == 0) { - this->Message_StringID(Chat::White, TOGGLE_OFF); + this->MessageString(Chat::White, TOGGLE_OFF); //Message(0, "Turning tells OFF"); tellsoff = true; } else if (ts->toggle == 1) { //Message(0, "Turning tells ON"); - this->Message_StringID(Chat::White, TOGGLE_ON); + this->MessageString(Chat::White, TOGGLE_ON); tellsoff = false; } else { @@ -6736,7 +6736,7 @@ void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app) if (Invitee == this) { - Message_StringID(Chat::LightGray, GROUP_INVITEE_SELF); + MessageString(Chat::LightGray, GROUP_INVITEE_SELF); return; } @@ -6974,7 +6974,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GuildBanks->IsAreaFull(GuildID(), GuildBankMainArea)) { - Message_StringID(Chat::Red, GUILD_BANK_FULL); + MessageString(Chat::Red, GUILD_BANK_FULL); GuildBankDepositAck(true, sentAction); @@ -6991,7 +6991,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (inst) { - Message_StringID(Chat::LightGray, GUILD_BANK_TRANSFERRED, inst->GetItem()->Name); + MessageString(Chat::LightGray, GUILD_BANK_TRANSFERRED, inst->GetItem()->Name); safe_delete(inst); } } @@ -7023,7 +7023,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GuildBanks->IsAreaFull(GuildID(), GuildBankDepositArea)) { - Message_StringID(Chat::Red, GUILD_BANK_FULL); + MessageString(Chat::Red, GUILD_BANK_FULL); GuildBankDepositAck(true, sentAction); @@ -7068,7 +7068,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (!Allowed) { - Message_StringID(Chat::Red, GUILD_BANK_CANNOT_DEPOSIT); + MessageString(Chat::Red, GUILD_BANK_CANNOT_DEPOSIT); GuildBankDepositAck(true, sentAction); return; @@ -7101,7 +7101,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) { if (GetInv()[EQEmu::invslot::slotCursor]) { - Message_StringID(Chat::Red, GUILD_BANK_EMPTY_HANDS); + MessageString(Chat::Red, GUILD_BANK_EMPTY_HANDS); GuildBankAck(); @@ -7132,7 +7132,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) if (CheckLoreConflict(inst->GetItem())) { - Message_StringID(Chat::Red, DUP_LORE); + MessageString(Chat::Red, DUP_LORE); GuildBankAck(); @@ -7164,7 +7164,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app) case GuildBankSplitStacks: { if (GuildBanks->IsAreaFull(GuildID(), GuildBankMainArea)) - Message_StringID(Chat::Red, GUILD_BANK_FULL); + MessageString(Chat::Red, GUILD_BANK_FULL); else { GuildBankWithdrawItem_Struct *gbwis = (GuildBankWithdrawItem_Struct*)app->pBuffer; @@ -7257,7 +7257,7 @@ void Client::Handle_OP_GuildCreate(const EQApplicationPacket *app) if (guild_mgr.GetGuildIDByName(GuildName) != GUILD_NONE) { - Message_StringID(Chat::Red, GUILD_NAME_IN_USE); + MessageString(Chat::Red, GUILD_NAME_IN_USE); return; } @@ -7897,7 +7897,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if (!c) { - Message_StringID(Chat::LightGray, TARGET_PLAYER_FOR_GUILD_STATUS); + MessageString(Chat::LightGray, TARGET_PLAYER_FOR_GUILD_STATUS); return; } @@ -7905,7 +7905,7 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if (TargetGuildID == GUILD_NONE) { - Message_StringID(Chat::LightGray, NOT_IN_A_GUILD, c->GetName()); + MessageString(Chat::LightGray, NOT_IN_A_GUILD, c->GetName()); return; } @@ -7920,21 +7920,21 @@ void Client::Handle_OP_GuildStatus(const EQApplicationPacket *app) if ((TargetGuildID == GuildID()) && (c != this)) { if (IsLeader) - Message_StringID(Chat::LightGray, LEADER_OF_YOUR_GUILD, c->GetName()); + MessageString(Chat::LightGray, LEADER_OF_YOUR_GUILD, c->GetName()); else if (IsOfficer) - Message_StringID(Chat::LightGray, OFFICER_OF_YOUR_GUILD, c->GetName()); + MessageString(Chat::LightGray, OFFICER_OF_YOUR_GUILD, c->GetName()); else - Message_StringID(Chat::LightGray, MEMBER_OF_YOUR_GUILD, c->GetName()); + MessageString(Chat::LightGray, MEMBER_OF_YOUR_GUILD, c->GetName()); return; } if (IsLeader) - Message_StringID(Chat::LightGray, LEADER_OF_X_GUILD, c->GetName(), GuildName); + MessageString(Chat::LightGray, LEADER_OF_X_GUILD, c->GetName(), GuildName); else if (IsOfficer) - Message_StringID(Chat::LightGray, OFFICER_OF_X_GUILD, c->GetName(), GuildName); + MessageString(Chat::LightGray, OFFICER_OF_X_GUILD, c->GetName(), GuildName); else - Message_StringID(Chat::LightGray, MEMBER_OF_X_GUILD, c->GetName(), GuildName); + MessageString(Chat::LightGray, MEMBER_OF_X_GUILD, c->GetName(), GuildName); } void Client::Handle_OP_GuildUpdateURLAndChannel(const EQApplicationPacket *app) @@ -8537,7 +8537,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (IsAIControlled()) { - this->Message_StringID(Chat::Red, NOT_IN_CONTROL); + this->MessageString(Chat::Red, NOT_IN_CONTROL); return; } @@ -8646,7 +8646,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (inst->GetCharges() == 0) { //Message(0, "This item is out of charges."); - Message_StringID(Chat::Red, ITEM_OUT_OF_CHARGES); + MessageString(Chat::Red, ITEM_OUT_OF_CHARGES); return; } if (GetLevel() >= item->Click.Level2) @@ -8666,7 +8666,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else { - Message_StringID(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); + MessageString(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); return; } } @@ -8675,7 +8675,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) if (clickaug->GetCharges() == 0) { //Message(0, "This item is out of charges."); - Message_StringID(Chat::Red, ITEM_OUT_OF_CHARGES); + MessageString(Chat::Red, ITEM_OUT_OF_CHARGES); return; } if (GetLevel() >= augitem->Click.Level2) @@ -8695,7 +8695,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) } else { - Message_StringID(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); + MessageString(Chat::Red, ITEMS_INSUFFICIENT_LEVEL); return; } } @@ -8902,12 +8902,12 @@ void Client::Handle_OP_LeadershipExpToggle(const EQApplicationPacket *app) if (*mode) { m_pp.leadAAActive = 1; Save(); - Message_StringID(Chat::Yellow, LEADERSHIP_EXP_ON); + MessageString(Chat::Yellow, LEADERSHIP_EXP_ON); } else { m_pp.leadAAActive = 0; Save(); - Message_StringID(Chat::Yellow, LEADERSHIP_EXP_OFF); + MessageString(Chat::Yellow, LEADERSHIP_EXP_OFF); } } @@ -9372,11 +9372,11 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) if (zone->random.Int(0, 99) < criticalchance) { mendhp *= 2; - Message_StringID(Chat::LightBlue, MEND_CRITICAL); + MessageString(Chat::LightBlue, MEND_CRITICAL); } SetHP(GetHP() + mendhp); SendHPUpdate(); - Message_StringID(Chat::LightBlue, MEND_SUCCESS); + MessageString(Chat::LightBlue, MEND_SUCCESS); } else { /* the purpose of the following is to make the chance to worsen wounds much less common, @@ -9389,10 +9389,10 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app) { SetHP(currenthp > mendhp ? (GetHP() - mendhp) : 1); SendHPUpdate(); - Message_StringID(Chat::LightBlue, MEND_WORSEN); + MessageString(Chat::LightBlue, MEND_WORSEN); } else - Message_StringID(Chat::LightBlue, MEND_FAIL); + MessageString(Chat::LightBlue, MEND_FAIL); } CheckIncreaseSkill(EQEmu::skills::SkillMend, nullptr, 10); @@ -9930,9 +9930,9 @@ void Client::Handle_OP_PDeletePetition(const EQApplicationPacket *app) return; } if (petition_list.DeletePetitionByCharName((char*)app->pBuffer)) - Message_StringID(Chat::White, PETITION_DELETED); + MessageString(Chat::White, PETITION_DELETED); else - Message_StringID(Chat::White, PETITION_NO_DELETE); + MessageString(Chat::White, PETITION_NO_DELETE); return; } @@ -9989,7 +9989,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (!target) break; if (target->IsMezzed()) { - Message_StringID(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName()); + MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), target->GetCleanName()); break; } if (mypet->IsFeared()) @@ -10027,7 +10027,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) hate += mypet->GetHateAmount(top) - mypet->GetHateAmount(target) + 100; // should be enough to cause target change } mypet->AddToHateList(target, hate, 0, true, false, false, SPELL_UNKNOWN, true); - Message_StringID(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName()); + MessageString(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), target->GetCleanName()); SetTarget(target); } } @@ -10040,7 +10040,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (!GetTarget()) break; if (GetTarget()->IsMezzed()) { - Message_StringID(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName()); + MessageString(Chat::NPCQuestSay, CANNOT_WAKE, mypet->GetCleanName(), GetTarget()->GetCleanName()); break; } @@ -10061,7 +10061,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } zone->AddAggroMob(); mypet->AddToHateList(GetTarget(), 1, 0, true, false, false, SPELL_UNKNOWN, true); - Message_StringID(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); + MessageString(Chat::PetResponse, PET_ATTACKING, mypet->GetCleanName(), GetTarget()->GetCleanName()); } } break; @@ -10082,7 +10082,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } case PET_HEALTHREPORT: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(Chat::PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); + MessageString(Chat::PetResponse, PET_REPORT_HP, ConvertArrayF(mypet->GetHPRatio(), val1)); mypet->ShowBuffList(this); } break; @@ -10150,12 +10150,12 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->CastToNPC()->IsTaunting()) { - Message_StringID(Chat::PetResponse, PET_NO_TAUNT); + MessageString(Chat::PetResponse, PET_NO_TAUNT); mypet->CastToNPC()->SetTaunting(false); } else { - Message_StringID(Chat::PetResponse, PET_DO_TAUNT); + MessageString(Chat::PetResponse, PET_DO_TAUNT); mypet->CastToNPC()->SetTaunting(true); } } @@ -10163,14 +10163,14 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } case PET_TAUNT_ON: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(Chat::PetResponse, PET_DO_TAUNT); + MessageString(Chat::PetResponse, PET_DO_TAUNT); mypet->CastToNPC()->SetTaunting(true); } break; } case PET_TAUNT_OFF: { if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - Message_StringID(Chat::PetResponse, PET_NO_TAUNT); + MessageString(Chat::PetResponse, PET_NO_TAUNT); mypet->CastToNPC()->SetTaunting(false); } break; @@ -10239,13 +10239,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_HOLD_SET_OFF); + MessageString(Chat::PetResponse, PET_HOLD_SET_OFF); mypet->SetHeld(false); } else { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_HOLD_SET_ON); + MessageString(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); @@ -10262,7 +10262,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_HOLD_ON: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && !mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_HOLD_SET_ON); + MessageString(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); @@ -10277,7 +10277,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_HOLD_OFF: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_HOLD_SET_OFF); + MessageString(Chat::PetResponse, PET_HOLD_SET_OFF); mypet->SetHeld(false); } break; @@ -10287,13 +10287,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsGHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - Message_StringID(Chat::PetResponse, PET_OFF_GHOLD); + MessageString(Chat::PetResponse, PET_OFF_GHOLD); mypet->SetGHeld(false); } else { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { - Message_StringID(Chat::PetResponse, PET_ON_GHOLD); + MessageString(Chat::PetResponse, PET_ON_GHOLD); mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); @@ -10308,7 +10308,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_GHOLD_ON: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { - Message_StringID(Chat::PetResponse, PET_ON_GHOLD); + MessageString(Chat::PetResponse, PET_ON_GHOLD); mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); @@ -10322,7 +10322,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) case PET_GHOLD_OFF: { if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC() && mypet->IsGHeld()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - Message_StringID(Chat::PetResponse, PET_OFF_GHOLD); + MessageString(Chat::PetResponse, PET_OFF_GHOLD); mypet->SetGHeld(false); } break; @@ -10332,15 +10332,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsNoCast()) { - Message_StringID(Chat::PetResponse, PET_CASTING); + MessageString(Chat::PetResponse, PET_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); + MessageString(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); mypet->SetNoCast(false); } else { - Message_StringID(Chat::PetResponse, PET_NOT_CASTING); + MessageString(Chat::PetResponse, PET_NOT_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_ON); + MessageString(Chat::PetResponse, PET_SPELLHOLD_SET_ON); mypet->SetNoCast(true); } } @@ -10351,9 +10351,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (!mypet->IsNoCast()) { - Message_StringID(Chat::PetResponse, PET_NOT_CASTING); + MessageString(Chat::PetResponse, PET_NOT_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_ON); + MessageString(Chat::PetResponse, PET_SPELLHOLD_SET_ON); mypet->SetNoCast(true); } } @@ -10364,9 +10364,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsNoCast()) { - Message_StringID(Chat::PetResponse, PET_CASTING); + MessageString(Chat::PetResponse, PET_CASTING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); + MessageString(Chat::PetResponse, PET_SPELLHOLD_SET_OFF); mypet->SetNoCast(false); } } @@ -10377,15 +10377,15 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsFocused()) { - Message_StringID(Chat::PetResponse, PET_NOT_FOCUSING); + MessageString(Chat::PetResponse, PET_NOT_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_FOCUS_SET_OFF); + MessageString(Chat::PetResponse, PET_FOCUS_SET_OFF); mypet->SetFocused(false); } else { - Message_StringID(Chat::PetResponse, PET_NOW_FOCUSING); + MessageString(Chat::PetResponse, PET_NOW_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_FOCUS_SET_ON); + MessageString(Chat::PetResponse, PET_FOCUS_SET_ON); mypet->SetFocused(true); } } @@ -10396,9 +10396,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (!mypet->IsFocused()) { - Message_StringID(Chat::PetResponse, PET_NOW_FOCUSING); + MessageString(Chat::PetResponse, PET_NOW_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_FOCUS_SET_ON); + MessageString(Chat::PetResponse, PET_FOCUS_SET_ON); mypet->SetFocused(true); } } @@ -10409,9 +10409,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; if (mypet->IsFocused()) { - Message_StringID(Chat::PetResponse, PET_NOT_FOCUSING); + MessageString(Chat::PetResponse, PET_NOT_FOCUSING); if (m_ClientVersionBit & EQEmu::versions::maskSoDAndLater) - Message_StringID(Chat::PetResponse, PET_FOCUS_SET_OFF); + MessageString(Chat::PetResponse, PET_FOCUS_SET_OFF); mypet->SetFocused(false); } } @@ -11111,7 +11111,7 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app) Client *player_accepting_invite = entity_list.GetClientByName(raid_command_packet->player_name); if (player_accepting_invite) { if (IsRaidGrouped()) { - player_accepting_invite->Message_StringID(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid... + player_accepting_invite->MessageString(Chat::White, ALREADY_IN_RAID, GetName()); //group failed, must invite members not in raid... return; } Raid *raid = entity_list.GetRaidByClient(player_accepting_invite); @@ -11983,14 +11983,14 @@ void Client::Handle_OP_RemoveTrap(const EQApplicationPacket *app) if (good) RemoveAura(id); else - Message_StringID(Chat::SpellFailure, NOT_YOUR_TRAP); // pretty sure this was red + MessageString(Chat::SpellFailure, NOT_YOUR_TRAP); // pretty sure this was red } void Client::Handle_OP_Report(const EQApplicationPacket *app) { if (!CanUseReport) { - Message_StringID(Chat::System, REPORT_ONCE); + MessageString(Chat::System, REPORT_ONCE); return; } @@ -12057,11 +12057,11 @@ void Client::Handle_OP_RequestDuel(const EQApplicationPacket *app) ds->duel_target = duel; Entity* entity = entity_list.GetID(ds->duel_target); if (GetID() != ds->duel_target && entity->IsClient() && (entity->CastToClient()->IsDueling() && entity->CastToClient()->GetDuelTarget() != 0)) { - Message_StringID(Chat::NPCQuestSay, DUEL_CONSIDERING, entity->GetName()); + MessageString(Chat::NPCQuestSay, DUEL_CONSIDERING, entity->GetName()); return; } if (IsDueling()) { - Message_StringID(Chat::NPCQuestSay, DUEL_INPROGRESS); + MessageString(Chat::NPCQuestSay, DUEL_INPROGRESS); return; } @@ -12108,7 +12108,7 @@ void Client::Handle_OP_RespawnWindow(const EQApplicationPacket *app) void Client::Handle_OP_Rewind(const EQApplicationPacket *app) { if ((rewind_timer.GetRemainingTime() > 1 && rewind_timer.Enabled())) { - Message_StringID(Chat::System, REWIND_WAIT); + MessageString(Chat::System, REWIND_WAIT); } else { CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_RewindLocation.x, m_RewindLocation.y, m_RewindLocation.z, 0, 2, Rewind); @@ -12445,7 +12445,8 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) if (shield_target) { - entity_list.MessageClose_StringID(this, false, 100, 0, + entity_list.MessageCloseString( + this, false, 100, 0, END_SHIELDING, GetName(), shield_target->GetName()); for (int y = 0; y < 2; y++) { @@ -12471,7 +12472,8 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) { if (shield_target->shielder[x].shielder_id == 0) { - entity_list.MessageClose_StringID(this, false, 100, 0, + entity_list.MessageCloseString( + this, false, 100, 0, START_SHIELDING, GetName(), shield_target->GetName()); shield_target->shielder[x].shielder_id = GetID(); int shieldbonus = shield->AC * 2; @@ -12509,7 +12511,7 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app) } if (!ack) { - Message_StringID(Chat::White, ALREADY_SHIELDED); + MessageString(Chat::White, ALREADY_SHIELDED); shield_target = 0; return; } @@ -13021,7 +13023,7 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) return; } if (tmp->IsEngaged()) { - this->Message_StringID(Chat::White, MERCHANT_BUSY); + this->MessageString(Chat::White, MERCHANT_BUSY); action = 0; } if (GetFeigned() || IsInvisible()) @@ -13334,7 +13336,7 @@ void Client::Handle_OP_Surname(const EQApplicationPacket *app) if (GetLevel() < 20) { - Message_StringID(Chat::Yellow, SURNAME_LEVEL); + MessageString(Chat::Yellow, SURNAME_LEVEL); return; } @@ -13356,13 +13358,13 @@ void Client::Handle_OP_Surname(const EQApplicationPacket *app) } if (strlen(surname->lastname) >= 20) { - Message_StringID(Chat::Yellow, SURNAME_TOO_LONG); + MessageString(Chat::Yellow, SURNAME_TOO_LONG); return; } if (!database.CheckNameFilter(surname->lastname, true)) { - Message_StringID(Chat::Yellow, SURNAME_REJECTED); + MessageString(Chat::Yellow, SURNAME_REJECTED); return; } @@ -13742,16 +13744,16 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) trade->state = TradeCompleting; if (CheckTradeLoreConflict(other) || other->CheckTradeLoreConflict(this)) { - Message_StringID(Chat::Red, TRADE_CANCEL_LORE); - other->Message_StringID(Chat::Red, TRADE_CANCEL_LORE); + MessageString(Chat::Red, TRADE_CANCEL_LORE); + other->MessageString(Chat::Red, TRADE_CANCEL_LORE); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); trade->Reset(); } else if (CheckTradeNonDroppable()) { - Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); - other->Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + MessageString(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + other->MessageString(Chat::Red, TRADE_HAS_BEEN_CANCELLED); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); @@ -13760,8 +13762,8 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app) // TODO: query (this) as a hacker } else if (other->CheckTradeNonDroppable()) { - Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); - other->Message_StringID(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + MessageString(Chat::Red, TRADE_HAS_BEEN_CANCELLED); + other->MessageString(Chat::Red, TRADE_HAS_BEEN_CANCELLED); this->FinishTrade(this); other->FinishTrade(other); other->trade->Reset(); @@ -14209,7 +14211,7 @@ void Client::Handle_OP_TraderShop(const EQApplicationPacket *app) } else { - Message_StringID(Chat::Yellow, TRADER_BUSY); + MessageString(Chat::Yellow, TRADER_BUSY); Log(Logs::Detail, Logs::Trading, "Client::Handle_OP_TraderShop: Trader Busy"); } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index ecbf90d1e..7e08054d8 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -378,10 +378,10 @@ bool Client::Process() { } if (!CombatRange(auto_attack_target)) { - Message_StringID(Chat::TooFarAway, TARGET_TOO_FAR); + MessageString(Chat::TooFarAway, TARGET_TOO_FAR); } else if (auto_attack_target == this) { - Message_StringID(Chat::TooFarAway, TRY_ATTACKING_SOMEONE); + MessageString(Chat::TooFarAway, TRY_ATTACKING_SOMEONE); } else if (!los_status || !los_status_facing) { //you can't see your target @@ -401,11 +401,11 @@ bool Client::Process() { if (GetClass() == WARRIOR || GetClass() == BERSERKER) { if (!dead && !IsBerserk() && GetHPRatio() < RuleI(Combat, BerserkerFrenzyStart)) { - entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName()); + entity_list.MessageCloseString(this, false, 200, 0, BERSERK_START, GetName()); berserk = true; } if (IsBerserk() && GetHPRatio() > RuleI(Combat, BerserkerFrenzyEnd)) { - entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName()); + entity_list.MessageCloseString(this, false, 200, 0, BERSERK_END, GetName()); berserk = false; } } @@ -416,11 +416,11 @@ bool Client::Process() { // Range check if (!CombatRange(auto_attack_target)) { // this is a duplicate message don't use it. - //Message_StringID(Chat::TooFarAway,TARGET_TOO_FAR); + //MessageString(Chat::TooFarAway,TARGET_TOO_FAR); } // Don't attack yourself else if (auto_attack_target == this) { - //Message_StringID(Chat::TooFarAway,TRY_ATTACKING_SOMEONE); + //MessageString(Chat::TooFarAway,TRY_ATTACKING_SOMEONE); } else if (!los_status || !los_status_facing) { @@ -465,7 +465,8 @@ bool Client::Process() { { if (!CombatRange(shield_target)) { - entity_list.MessageClose_StringID(this, false, 100, 0, + entity_list.MessageCloseString( + this, false, 100, 0, END_SHIELDING, GetCleanName(), shield_target->GetCleanName()); for (int y = 0; y < 2; y++) { @@ -951,9 +952,9 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) { sprintf(handy_id, "%i", greet_id); if (greet_id != MERCHANT_GREETING) - Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName(), handyitem->Name); + MessageString(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName(), handyitem->Name); else - Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName()); + MessageString(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, merch->GetCleanName(), handy_id, this->GetName()); } // safe_delete_array(cpi); @@ -1043,7 +1044,7 @@ void Client::OPTGB(const EQApplicationPacket *app) uint32 tgb_flag = *(uint32 *)app->pBuffer; if(tgb_flag == 2) - Message_StringID(Chat::White, TGB() ? TGB_ON : TGB_OFF); + MessageString(Chat::White, TGB() ? TGB_ON : TGB_OFF); else tgb = tgb_flag; } @@ -1072,7 +1073,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) ) { char val1[20]={0}; - Message_StringID(Chat::Red,SPELL_LEVEL_TO_LOW,ConvertArray(spells[memspell->spell_id].classes[GetClass()-1],val1),spells[memspell->spell_id].name); + MessageString(Chat::Red,SPELL_LEVEL_TO_LOW,ConvertArray(spells[memspell->spell_id].classes[GetClass()-1],val1),spells[memspell->spell_id].name); //Message(Chat::Red, "Unexpected error: Class cant use this spell at your level!"); return; } @@ -1087,7 +1088,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) const EQEmu::ItemData* item = inst->GetItem(); if (RuleB(Character, RestrictSpellScribing) && !item->IsEquipable(GetRace(), GetClass())) { - Message_StringID(Chat::Red, CANNOT_USE_ITEM); + MessageString(Chat::Red, CANNOT_USE_ITEM); break; } @@ -1645,7 +1646,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) case EQEmu::skills::SkillJewelryMaking: case EQEmu::skills::SkillPottery: if(skilllevel >= RuleI(Skills, MaxTrainTradeskills)) { - Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } break; @@ -1655,7 +1656,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) case EQEmu::skills::SkillSpecializeDivination: case EQEmu::skills::SkillSpecializeEvocation: if(skilllevel >= RuleI(Skills, MaxTrainSpecializations)) { - Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } default: @@ -1666,7 +1667,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) if (skilllevel >= MaxSkillValue) { // Don't allow training over max skill level - Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } @@ -1676,7 +1677,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app) if (skilllevel >= MaxSpecSkill) { // Restrict specialization training to follow the rules - Message_StringID(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); + MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName()); return; } } @@ -1919,7 +1920,7 @@ void Client::DoTracking() Mob *m = entity_list.GetMob(TrackingID); if (!m || m->IsCorpse()) { - Message_StringID(Chat::Skills, TRACK_LOST_TARGET); + MessageString(Chat::Skills, TRACK_LOST_TARGET); TrackingID = 0; return; } @@ -1930,23 +1931,23 @@ void Client::DoTracking() RelativeHeading += 512; if (RelativeHeading > 480) - Message_StringID(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); + MessageString(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); else if (RelativeHeading > 416) - Message_StringID(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left"); + MessageString(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "left"); else if (RelativeHeading > 352) - Message_StringID(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "left"); + MessageString(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "left"); else if (RelativeHeading > 288) - Message_StringID(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); + MessageString(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "left"); else if (RelativeHeading > 224) - Message_StringID(Chat::Skills, TRACK_BEHIND_YOU, m->GetCleanName()); + MessageString(Chat::Skills, TRACK_BEHIND_YOU, m->GetCleanName()); else if (RelativeHeading > 160) - Message_StringID(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); + MessageString(Chat::Skills, TRACK_BEHIND_AND_TO, m->GetCleanName(), "right"); else if (RelativeHeading > 96) - Message_StringID(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "right"); + MessageString(Chat::Skills, TRACK_TO_THE, m->GetCleanName(), "right"); else if (RelativeHeading > 32) - Message_StringID(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); + MessageString(Chat::Skills, TRACK_AHEAD_AND_TO, m->GetCleanName(), "right"); else if (RelativeHeading >= 0) - Message_StringID(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); + MessageString(Chat::Skills, TRACK_STRAIGHT_AHEAD, m->GetCleanName()); } void Client::HandleRespawnFromHover(uint32 Option) diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 942c3374b..2dc2872ec 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1201,7 +1201,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) if (client && inst) { if (client->CheckLoreConflict(item)) { - client->Message_StringID(Chat::White, LOOT_LORE_ERROR); + client->MessageString(Chat::White, LOOT_LORE_ERROR); client->QueuePacket(app); SendEndLootErrorPacket(client); ResetLooter(); @@ -1214,7 +1214,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) EQEmu::ItemInstance *itm = inst->GetAugment(i); if (itm) { if (client->CheckLoreConflict(itm->GetItem())) { - client->Message_StringID(Chat::White, LOOT_LORE_ERROR); + client->MessageString(Chat::White, LOOT_LORE_ERROR); client->QueuePacket(app); SendEndLootErrorPacket(client); ResetLooter(); @@ -1236,7 +1236,7 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) args.push_back(this); if (parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args) != 0) { lootitem->auto_loot = -1; - client->Message_StringID(Chat::Red, LOOT_NOT_ALLOWED, inst->GetItem()->Name); + client->MessageString(Chat::Red, LOOT_NOT_ALLOWED, inst->GetItem()->Name); client->QueuePacket(app); delete inst; return; @@ -1312,18 +1312,18 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app) linker.GenerateLink(); - client->Message_StringID(Chat::Loot, LOOTED_MESSAGE, linker.Link().c_str()); + client->MessageString(Chat::Loot, LOOTED_MESSAGE, linker.Link().c_str()); if (!IsPlayerCorpse()) { Group *g = client->GetGroup(); if (g != nullptr) { - g->GroupMessage_StringID(client, Chat::Loot, OTHER_LOOTED_MESSAGE, + g->GroupMessageString(client, Chat::Loot, OTHER_LOOTED_MESSAGE, client->GetName(), linker.Link().c_str()); } else { Raid *r = client->GetRaid(); if (r != nullptr) { - r->RaidMessage_StringID(client, Chat::Loot, OTHER_LOOTED_MESSAGE, + r->RaidMessageString(client, Chat::Loot, OTHER_LOOTED_MESSAGE, client->GetName(), linker.Link().c_str()); } } diff --git a/zone/doors.cpp b/zone/doors.cpp index 15f61ba47..d81eb72f8 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -171,7 +171,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { if (RuleI(Adventure, ItemIDToEnablePorts) != 0) { if (!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts))) { if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX) { - sender->Message_StringID(Chat::Red, DUNGEON_SEALED); + sender->MessageString(Chat::Red, DUNGEON_SEALED); safe_delete(outapp); return; } else { @@ -281,7 +281,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { * GM can always open locks */ if (sender->GetGM()) { - sender->Message_StringID(Chat::LightBlue, DOORS_GM); + sender->MessageString(Chat::LightBlue, DOORS_GM); if (!IsDoorOpen() || (open_type == 58)) { move_door_packet->action = static_cast(invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR); @@ -333,19 +333,19 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { } else { move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } - sender->Message_StringID(Chat::LightBlue, DOORS_SUCCESSFUL_PICK); + sender->MessageString(Chat::LightBlue, DOORS_SUCCESSFUL_PICK); } else { - sender->Message_StringID(Chat::LightBlue, DOORS_INSUFFICIENT_SKILL); + sender->MessageString(Chat::LightBlue, DOORS_INSUFFICIENT_SKILL); safe_delete(outapp); return; } } else { - sender->Message_StringID(Chat::LightBlue, DOORS_NO_PICK); + sender->MessageString(Chat::LightBlue, DOORS_NO_PICK); safe_delete(outapp); return; } } else { - sender->Message_StringID(Chat::LightBlue, DOORS_CANT_PICK); + sender->MessageString(Chat::LightBlue, DOORS_CANT_PICK); safe_delete(outapp); return; } @@ -368,7 +368,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger) { move_door_packet->action = static_cast(invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR); } } else { - sender->Message_StringID(Chat::LightBlue, DOORS_LOCKED); + sender->MessageString(Chat::LightBlue, DOORS_LOCKED); safe_delete(outapp); return; } diff --git a/zone/effects.cpp b/zone/effects.cpp index e51d540ad..f6996c030 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -122,11 +122,12 @@ int32 Mob::GetActSpellDamage(uint16 spell_id, int32 value, Mob* target) { else if (IsNPC() && CastToNPC()->GetSpellScale()) value = int(static_cast(value) * CastToNPC()->GetSpellScale() / 100.0f); - entity_list.MessageClose_StringID(this, true, 100, Chat::SpellCrit, - OTHER_CRIT_BLAST, GetName(), itoa(-value)); + entity_list.MessageCloseString( + this, true, 100, Chat::SpellCrit, + OTHER_CRIT_BLAST, GetName(), itoa(-value)); if (IsClient()) - Message_StringID(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value)); + MessageString(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value)); return value; } @@ -306,11 +307,12 @@ int32 Mob::GetActSpellHealing(uint16 spell_id, int32 value, Mob* target) { value = int(static_cast(value) * CastToNPC()->GetHealScale() / 100.0f); if (Critical) { - entity_list.MessageClose_StringID(this, true, 100, Chat::SpellCrit, - OTHER_CRIT_HEAL, GetName(), itoa(value)); + entity_list.MessageCloseString( + this, true, 100, Chat::SpellCrit, + OTHER_CRIT_HEAL, GetName(), itoa(value)); if (IsClient()) - Message_StringID(Chat::SpellCrit, YOU_CRIT_HEAL, itoa(value)); + MessageString(Chat::SpellCrit, YOU_CRIT_HEAL, itoa(value)); } return value; @@ -595,7 +597,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { } if(level_to_use > GetLevel()) { - Message_StringID(Chat::Red, DISC_LEVEL_USE_ERROR); + MessageString(Chat::Red, DISC_LEVEL_USE_ERROR); //should summon them a new one... return(false); } @@ -607,7 +609,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { // sneak attack discs require you to be hidden for 4 seconds before use if (spell.sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) { - Message_StringID(Chat::SpellFailure, SNEAK_RESTRICT); + MessageString(Chat::SpellFailure, SNEAK_RESTRICT); return false; } @@ -621,7 +623,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { /*char val1[20]={0};*/ //unused /*char val2[20]={0};*/ //unused uint32 remain = p_timers.GetRemainingTime(DiscTimer); - //Message_StringID(Chat::WhiteSmoke, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); + //MessageString(Chat::WhiteSmoke, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60)); return(false); } diff --git a/zone/entity.cpp b/zone/entity.cpp index 97678b2d0..e52935ded 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1671,9 +1671,9 @@ void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee) //might want some sort of distance check in here? if (cur != winner && cur != loser) { if (flee) - cur->Message_StringID(Chat::Yellow, DUEL_FLED, winner->GetName(),loser->GetName(),loser->GetName()); + cur->MessageString(Chat::Yellow, DUEL_FLED, winner->GetName(),loser->GetName(),loser->GetName()); else - cur->Message_StringID(Chat::Yellow, DUEL_FINISHED, winner->GetName(),loser->GetName()); + cur->MessageString(Chat::Yellow, DUEL_FINISHED, winner->GetName(),loser->GetName()); } ++it; } @@ -2071,7 +2071,7 @@ void EntityList::QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struc void EntityList::MessageStatus(uint32 to_guild_id, int to_minstatus, uint32 type, const char *message, ...) { va_list argptr; - char buffer[4096]; + char buffer[4096]; va_start(argptr, message); vsnprintf(buffer, 4096, message, argptr); @@ -2080,22 +2080,66 @@ void EntityList::MessageStatus(uint32 to_guild_id, int to_minstatus, uint32 type auto it = client_list.begin(); while (it != client_list.end()) { Client *client = it->second; - if ((to_guild_id == 0 || client->IsInGuild(to_guild_id)) && client->Admin() >= to_minstatus) + if ((to_guild_id == 0 || client->IsInGuild(to_guild_id)) && client->Admin() >= to_minstatus) { client->Message(type, buffer); + } ++it; } } -// works much like MessageClose, but with formatted strings -void EntityList::MessageClose_StringID(Mob *sender, bool skipsender, float dist, uint32 type, uint32 string_id, const char* message1,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9) +/** + * @param sender + * @param skipsender + * @param dist + * @param type + * @param string_id + * @param message1 + * @param message2 + * @param message3 + * @param message4 + * @param message5 + * @param message6 + * @param message7 + * @param message8 + * @param message9 + */ +void EntityList::MessageCloseString( + Mob *sender, + bool skipsender, + float dist, + uint32 type, + uint32 string_id, + const char *message1, + const char *message2, + const char *message3, + const char *message4, + const char *message5, + const char *message6, + const char *message7, + const char *message8, + const char *message9 +) { Client *c; - float dist2 = dist * dist; + float dist2 = dist * dist; - for (auto it = client_list.begin(); it != client_list.end(); ++it) { - c = it->second; - if(c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender)) - c->Message_StringID(type, string_id, message1, message2, message3, message4, message5, message6, message7, message8, message9); + for (auto & it : client_list) { + c = it.second; + if (c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender)) { + c->MessageString( + type, + string_id, + message1, + message2, + message3, + message4, + message5, + message6, + message7, + message8, + message9 + ); + } } } @@ -2116,56 +2160,162 @@ void EntityList::MessageClose_StringID(Mob *sender, bool skipsender, float dist, * @param message8 * @param message9 */ -void EntityList::FilteredMessageClose_StringID(Mob *sender, bool skipsender, - float dist, uint32 type, eqFilterType filter, uint32 string_id, - const char *message1, const char *message2, const char *message3, - const char *message4, const char *message5, const char *message6, - const char *message7, const char *message8, const char *message9) +void EntityList::FilteredMessageCloseString( + Mob *sender, bool skipsender, + float dist, + uint32 type, + eqFilterType filter, + uint32 string_id, + const char *message1, + const char *message2, + const char *message3, + const char *message4, + const char *message5, + const char *message6, + const char *message7, + const char *message8, + const char *message9 +) { Client *c; - float dist2 = dist * dist; + float dist2 = dist * dist; - for (auto it = client_list.begin(); it != client_list.end(); ++it) { - c = it->second; - if (c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender)) - c->FilteredMessage_StringID(sender, type, filter, string_id, - message1, message2, message3, message4, message5, - message6, message7, message8, message9); + for (auto & it : client_list) { + c = it.second; + if (c && DistanceSquared(c->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || c != sender)) { + c->FilteredMessageString( + sender, type, filter, string_id, + message1, message2, message3, message4, message5, + message6, message7, message8, message9 + ); + } } } -void EntityList::Message_StringID(Mob *sender, bool skipsender, uint32 type, uint32 string_id, const char* message1,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9) +/** + * + * @param sender + * @param skipsender + * @param type + * @param string_id + * @param message1 + * @param message2 + * @param message3 + * @param message4 + * @param message5 + * @param message6 + * @param message7 + * @param message8 + * @param message9 + */ +void EntityList::MessageString( + Mob *sender, + bool skipsender, + uint32 type, + uint32 string_id, + const char *message1, + const char *message2, + const char *message3, + const char *message4, + const char *message5, + const char *message6, + const char *message7, + const char *message8, + const char *message9 +) { Client *c; - for (auto it = client_list.begin(); it != client_list.end(); ++it) { - c = it->second; - if(c && (!skipsender || c != sender)) - c->Message_StringID(type, string_id, message1, message2, message3, message4, message5, message6, message7, message8, message9); + for (auto & it : client_list) { + c = it.second; + if (c && (!skipsender || c != sender)) { + c->MessageString( + type, + string_id, + message1, + message2, + message3, + message4, + message5, + message6, + message7, + message8, + message9 + ); + } } } -void EntityList::FilteredMessage_StringID(Mob *sender, bool skipsender, - uint32 type, eqFilterType filter, uint32 string_id, - const char *message1, const char *message2, const char *message3, - const char *message4, const char *message5, const char *message6, - const char *message7, const char *message8, const char *message9) +/** + * + * @param sender + * @param skipsender + * @param type + * @param filter + * @param string_id + * @param message1 + * @param message2 + * @param message3 + * @param message4 + * @param message5 + * @param message6 + * @param message7 + * @param message8 + * @param message9 + */ +void EntityList::FilteredMessageString( + Mob *sender, + bool skipsender, + uint32 type, + eqFilterType filter, + uint32 string_id, + const char *message1, + const char *message2, + const char *message3, + const char *message4, + const char *message5, + const char *message6, + const char *message7, + const char *message8, + const char *message9 +) { Client *c; - for (auto it = client_list.begin(); it != client_list.end(); ++it) { - c = it->second; - if (c && (!skipsender || c != sender)) - c->FilteredMessage_StringID(sender, type, filter, string_id, - message1, message2, message3, message4, message5, message6, - message7, message8, message9); + for (auto & it : client_list) { + c = it.second; + if (c && (!skipsender || c != sender)) { + c->FilteredMessageString( + sender, + type, + filter, + string_id, + message1, + message2, + message3, + message4, + message5, + message6, + message7, + message8, + message9 + ); + } } } -void EntityList::MessageClose(Mob* sender, bool skipsender, float dist, uint32 type, const char* message, ...) +/** + * @param sender + * @param skipsender + * @param dist + * @param type + * @param message + * @param ... + */ +void EntityList::MessageClose(Mob *sender, bool skipsender, float dist, uint32 type, const char *message, ...) { va_list argptr; - char buffer[4096]; + char buffer[4096]; va_start(argptr, message); vsnprintf(buffer, 4095, message, argptr); @@ -2175,16 +2325,26 @@ void EntityList::MessageClose(Mob* sender, bool skipsender, float dist, uint32 t auto it = client_list.begin(); while (it != client_list.end()) { - if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || it->second != sender)) + if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && + (!skipsender || it->second != sender)) { it->second->Message(type, buffer); + } ++it; } } -void EntityList::FilteredMessageClose(Mob *sender, bool skipsender, float dist, uint32 type, eqFilterType filter, const char *message, ...) +void EntityList::FilteredMessageClose( + Mob *sender, + bool skipsender, + float dist, + uint32 type, + eqFilterType filter, + const char *message, + ... +) { va_list argptr; - char buffer[4096]; + char buffer[4096]; va_start(argptr, message); vsnprintf(buffer, 4095, message, argptr); @@ -2194,8 +2354,10 @@ void EntityList::FilteredMessageClose(Mob *sender, bool skipsender, float dist, auto it = client_list.begin(); while (it != client_list.end()) { - if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && (!skipsender || it->second != sender)) - it->second->FilteredMessage(sender, type, filter, buffer); + if (DistanceSquared(it->second->GetPosition(), sender->GetPosition()) <= dist2 && + (!skipsender || it->second != sender)) { + it->second->FilteredMessage(sender, type, filter, buffer); + } ++it; } } @@ -4649,7 +4811,7 @@ void EntityList::ExpeditionWarning(uint32 minutes_left) auto it = client_list.begin(); while (it != client_list.end()) { - it->second->Message_StringID(Chat::Yellow, EXPEDITION_MIN_REMAIN, itoa((int)minutes_left)); + it->second->MessageString(Chat::Yellow, EXPEDITION_MIN_REMAIN, itoa((int)minutes_left)); it->second->QueuePacket(outapp); ++it; } diff --git a/zone/entity.h b/zone/entity.h index a02a8be2e..3f6581ca6 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -321,10 +321,39 @@ public: void MessageStatus(uint32 to_guilddbid, int to_minstatus, uint32 type, const char* message, ...); void MessageClose(Mob* sender, bool skipsender, float dist, uint32 type, const char* message, ...); void FilteredMessageClose(Mob* sender, bool skipsender, float dist, uint32 type, eqFilterType filter, const char* message, ...); - void Message_StringID(Mob *sender, bool skipsender, uint32 type, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); - void FilteredMessage_StringID(Mob *sender, bool skipsender, uint32 type, eqFilterType filter, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); - void MessageClose_StringID(Mob *sender, bool skipsender, float dist, uint32 type, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); - void FilteredMessageClose_StringID(Mob *sender, bool skipsender, float dist, uint32 type, eqFilterType filter, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); + void MessageString(Mob *sender, bool skipsender, uint32 type, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); + void FilteredMessageString(Mob *sender, bool skipsender, uint32 type, eqFilterType filter, uint32 string_id, const char* message1=0,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0); + void MessageCloseString( + Mob *sender, + bool skipsender, + float dist, + uint32 type, + uint32 string_id, + const char *message1 = 0, + const char *message2 = 0, + const char *message3 = 0, + const char *message4 = 0, + const char *message5 = 0, + const char *message6 = 0, + const char *message7 = 0, + const char *message8 = 0, + const char *message9 = 0); + void FilteredMessageCloseString( + Mob *sender, + bool skipsender, + float dist, + uint32 type, + eqFilterType filter, + uint32 string_id, + const char *message1 = 0, + const char *message2 = 0, + const char *message3 = 0, + const char *message4 = 0, + const char *message5 = 0, + const char *message6 = 0, + const char *message7 = 0, + const char *message8 = 0, + const char *message9 = 0); void ChannelMessageFromWorld(const char* from, const char* to, uint8 chan_num, uint32 guilddbid, uint8 language, uint8 lang_skill, const char* message); void ChannelMessage(Mob* from, uint8 chan_num, uint8 language, const char* message, ...); void ChannelMessage(Mob* from, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...); diff --git a/zone/exp.cpp b/zone/exp.cpp index 2fe87997b..23593f644 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -333,18 +333,18 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) uint32 mentor_exp = exp * (GetGroup()->GetMentorPercent() / 100.0f); exp -= mentor_exp; mentoree->AddLeadershipEXP(mentor_exp, 0); // ends up rounded down - mentoree->Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); + mentoree->MessageString(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } if (exp > 0) { // possible if you mentor 100% to the other client AddLeadershipEXP(exp, 0); // ends up rounded up if mentored, no idea how live actually does it - Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); + MessageString(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } } else { - Message_StringID(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); + MessageString(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); } } else @@ -357,11 +357,11 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) && RuleI(Character, KillsPerRaidLeadershipAA) > 0) { AddLeadershipEXP(0, RAID_EXP_PER_POINT / RuleI(Character, KillsPerRaidLeadershipAA)); - Message_StringID(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_EXP); + MessageString(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_EXP); } else { - Message_StringID(Chat::LeaderShip, MAX_RAID_LEADERSHIP_POINTS); + MessageString(Chat::LeaderShip, MAX_RAID_LEADERSHIP_POINTS); } } else @@ -378,17 +378,17 @@ void Client::CalculateLeadershipExp(uint32 &add_exp, uint8 conlevel) uint32 mentor_exp = exp * (raid->GetMentorPercent(group_id) / 100.0f); exp -= mentor_exp; mentoree->AddLeadershipEXP(mentor_exp, 0); - mentoree->Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); + mentoree->MessageString(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } if (exp > 0) { AddLeadershipEXP(exp, 0); - Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); + MessageString(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_EXP); } } else { - Message_StringID(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); + MessageString(Chat::LeaderShip, MAX_GROUP_LEADERSHIP_POINTS); } } } @@ -565,22 +565,22 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { if (isrezzexp) { if (RuleI(Character, ShowExpValues) > 0) Message(Chat::Experience, "You regain %s experience from resurrection. %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(Chat::Experience, REZ_REGAIN); + else MessageString(Chat::Experience, REZ_REGAIN); } else { if (membercount > 1) { if (RuleI(Character, ShowExpValues) > 0) Message(Chat::Experience, "You have gained %s party experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(Chat::Experience, GAIN_GROUPXP); + else MessageString(Chat::Experience, GAIN_GROUPXP); } else if (IsRaidGrouped()) { if (RuleI(Character, ShowExpValues) > 0) Message(Chat::Experience, "You have gained %s raid experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(Chat::Experience, GAIN_RAIDEXP); + else MessageString(Chat::Experience, GAIN_RAIDEXP); } else { if (RuleI(Character, ShowExpValues) > 0) Message(Chat::Experience, "You have gained %s experience! %s", exp_amount_message.c_str(), exp_percent_message.c_str()); - else Message_StringID(Chat::Experience, GAIN_XP); + else MessageString(Chat::Experience, GAIN_XP); } } } @@ -656,7 +656,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { //Message(Chat::Yellow, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA); char val1[20]={0}; - Message_StringID(Chat::Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2. + MessageString(Chat::Experience, GAIN_ABILITY_POINT, ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2. /* QS: PlayerLogAARate */ if (RuleB(QueryServ, PlayerLogAARate)){ @@ -699,18 +699,18 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { if (level_increase) { if (level_count == 1) - Message_StringID(Chat::Experience, GAIN_LEVEL, ConvertArray(check_level, val1)); + MessageString(Chat::Experience, GAIN_LEVEL, ConvertArray(check_level, val1)); else Message(Chat::Yellow, "Welcome to level %i!", check_level); if (check_level == RuleI(Character, DeathItemLossLevel)) - Message_StringID(Chat::Yellow, CORPSE_ITEM_LOST); + MessageString(Chat::Yellow, CORPSE_ITEM_LOST); if (check_level == RuleI(Character, DeathExpLossLevel)) - Message_StringID(Chat::Yellow, CORPSE_EXP_LOST); + MessageString(Chat::Yellow, CORPSE_EXP_LOST); } else - Message_StringID(Chat::Experience, LOSE_LEVEL, ConvertArray(check_level, val1)); + MessageString(Chat::Experience, LOSE_LEVEL, ConvertArray(check_level, val1)); #ifdef BOTS uint8 myoldlevel = GetLevel(); @@ -758,7 +758,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) { char val1[20]={0}; char val2[20]={0}; char val3[20]={0}; - Message_StringID(Chat::Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3). + MessageString(Chat::Experience, GM_GAINXP, ConvertArray(set_aaxp,val1),ConvertArray(set_exp,val2),ConvertArray(GetEXPForLevel(GetLevel()+1),val3)); //[GM] You have gained %1 AXP and %2 EXP (%3). } } @@ -1077,12 +1077,12 @@ void Client::SetLeadershipEXP(uint32 group_exp, uint32 raid_exp) { while(group_exp >= GROUP_EXP_PER_POINT) { group_exp -= GROUP_EXP_PER_POINT; m_pp.group_leadership_points++; - Message_StringID(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_POINT); + MessageString(Chat::LeaderShip, GAIN_GROUP_LEADERSHIP_POINT); } while(raid_exp >= RAID_EXP_PER_POINT) { raid_exp -= RAID_EXP_PER_POINT; m_pp.raid_leadership_points++; - Message_StringID(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_POINT); + MessageString(Chat::LeaderShip, GAIN_RAID_LEADERSHIP_POINT); } m_pp.group_leadership_exp = group_exp; diff --git a/zone/forage.cpp b/zone/forage.cpp index df3cce2a0..c3310a0d3 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -161,14 +161,14 @@ bool Client::CanFish() { if (!Pole || !Pole->IsClassCommon() || Pole->GetItem()->ItemType != EQEmu::item::ItemTypeFishingPole) { if (m_inv.HasItemByUse(EQEmu::item::ItemTypeFishingPole, 1, invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor)) //We have a fishing pole somewhere, just not equipped - Message_StringID(Chat::Skills, FISHING_EQUIP_POLE); //You need to put your fishing pole in your primary hand. + MessageString(Chat::Skills, FISHING_EQUIP_POLE); //You need to put your fishing pole in your primary hand. else //We don't have a fishing pole anywhere - Message_StringID(Chat::Skills, FISHING_NO_POLE); //You can't fish without a fishing pole, go buy one. + MessageString(Chat::Skills, FISHING_NO_POLE); //You can't fish without a fishing pole, go buy one. return false; } if (!Bait || !Bait->IsClassCommon() || Bait->GetItem()->ItemType != EQEmu::item::ItemTypeFishingBait) { - Message_StringID(Chat::Skills, FISHING_NO_BAIT); //You can't fish without fishing bait, go buy some. + MessageString(Chat::Skills, FISHING_NO_BAIT); //You can't fish without fishing bait, go buy some. return false; } @@ -190,7 +190,7 @@ bool Client::CanFish() { float bestz = zone->zonemap->FindBestZ(rodPosition, nullptr); float len = m_Position.z - bestz; if(len > LineLength || len < 0.0f) { - Message_StringID(Chat::Skills, FISHING_LAND); + MessageString(Chat::Skills, FISHING_LAND); return false; } @@ -203,7 +203,7 @@ bool Client::CanFish() { bool in_water = zone->watermap->InWater(dest) || zone->watermap->InVWater(dest); if (in_lava) { - Message_StringID(Chat::Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? + MessageString(Chat::Skills, FISHING_LAVA); //Trying to catch a fire elemental or something? return false; } @@ -212,7 +212,7 @@ bool Client::CanFish() { } } - Message_StringID(Chat::Skills, FISHING_LAND); + MessageString(Chat::Skills, FISHING_LAND); return false; } return true; @@ -223,7 +223,7 @@ void Client::GoFish() //TODO: generate a message if we're already fishing /*if (!fishing_timer.Check()) { //this isn't the right check, may need to add something to the Client class like 'bool is_fishing' - Message_StringID(Chat::WhiteSmoke, ALREADY_FISHING); //You are already fishing! + MessageString(Chat::WhiteSmoke, ALREADY_FISHING); //You are already fishing! return; }*/ @@ -315,17 +315,17 @@ void Client::GoFish() const EQEmu::ItemData* food_item = database.GetItem(food_id); if (food_item->ItemType != EQEmu::item::ItemTypeFood) { - Message_StringID(Chat::Skills, FISHING_SUCCESS); + MessageString(Chat::Skills, FISHING_SUCCESS); } else { - Message_StringID(Chat::Skills, FISHING_SUCCESS_FISH_NAME, food_item->Name); + MessageString(Chat::Skills, FISHING_SUCCESS_FISH_NAME, food_item->Name); } EQEmu::ItemInstance* inst = database.CreateItem(food_item, 1); if(inst != nullptr) { if(CheckLoreConflict(inst->GetItem())) { - Message_StringID(Chat::White, DUP_LORE); + MessageString(Chat::White, DUP_LORE); safe_delete(inst); } else @@ -351,13 +351,13 @@ void Client::GoFish() //chance to use bait when you dont catch anything... if (zone->random.Int(0, 4) == 1) { DeleteItemInInventory(bslot, 1, true); //do we need client update? - Message_StringID(Chat::Skills, FISHING_LOST_BAIT); //You lost your bait! + MessageString(Chat::Skills, FISHING_LOST_BAIT); //You lost your bait! } else { if (zone->random.Int(0, 15) == 1) //give about a 1 in 15 chance to spill your beer. we could make this a rule, but it doesn't really seem worth it //TODO: check for & consume an alcoholic beverage from inventory when this triggers, and set it as a rule that's disabled by default - Message_StringID(Chat::Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. + MessageString(Chat::Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. else - Message_StringID(Chat::Skills, FISHING_FAILED); //You didn't catch anything. + MessageString(Chat::Skills, FISHING_FAILED); //You didn't catch anything. } parse->EventPlayer(EVENT_FISH_FAILURE, this, "", 0); @@ -367,7 +367,7 @@ void Client::GoFish() //this is potentially exploitable in that they can fish //and then swap out items in primary slot... too lazy to fix right now if (zone->random.Int(0, 49) == 1) { - Message_StringID(Chat::Skills, FISHING_POLE_BROKE); //Your fishing pole broke! + MessageString(Chat::Skills, FISHING_POLE_BROKE); //Your fishing pole broke! DeleteItemInInventory(EQEmu::invslot::slotPrimary, 0, true); } @@ -434,13 +434,13 @@ void Client::ForageItem(bool guarantee) { break; } - Message_StringID(Chat::Skills, stringid); + MessageString(Chat::Skills, stringid); EQEmu::ItemInstance* inst = database.CreateItem(food_item, 1); if(inst != nullptr) { // check to make sure it isn't a foraged lore item if(CheckLoreConflict(inst->GetItem())) { - Message_StringID(Chat::White, DUP_LORE); + MessageString(Chat::White, DUP_LORE); safe_delete(inst); } else { @@ -462,12 +462,12 @@ void Client::ForageItem(bool guarantee) { int ChanceSecondForage = aabonuses.ForageAdditionalItems + itembonuses.ForageAdditionalItems + spellbonuses.ForageAdditionalItems; if(!guarantee && zone->random.Roll(ChanceSecondForage)) { - Message_StringID(Chat::Skills, FORAGE_MASTERY); + MessageString(Chat::Skills, FORAGE_MASTERY); ForageItem(true); } } else { - Message_StringID(Chat::Skills, FORAGE_FAILED); + MessageString(Chat::Skills, FORAGE_FAILED); parse->EventPlayer(EVENT_FORAGE_FAILURE, this, "", 0); } diff --git a/zone/groups.cpp b/zone/groups.cpp index 2f0c5e854..a4104b26a 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -1236,7 +1236,7 @@ void Group::VerifyGroup() { } } -void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { +void Group::GroupMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { uint32 i; for (i = 0; i < MAX_GROUP_MEMBERS; i++) { if(members[i] == nullptr) @@ -1248,7 +1248,7 @@ void Group::GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, co if(!members[i]->IsClient()) continue; - members[i]->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0); + members[i]->MessageString(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, 0); } } diff --git a/zone/groups.h b/zone/groups.h index 913a6c169..0d39409e0 100644 --- a/zone/groups.h +++ b/zone/groups.h @@ -74,7 +74,7 @@ public: void GroupBardPulse(Mob* caster,uint16 spellid); void SplitExp(uint32 exp, Mob* other); void GroupMessage(Mob* sender,uint8 language,uint8 lang_skill,const char* message); - void GroupMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); + void GroupMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); uint32 GetTotalGroupDamage(Mob* other); void SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter = nullptr); inline void SetLeader(Mob* newleader){ leader=newleader; }; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index b24d03795..94ca78007 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -853,7 +853,7 @@ void Client::SendCursorBuffer() if (!lore_pass) { Log(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", GetName(), test_item->Name, test_item->ID); - Message_StringID(Chat::Loot, 290); + MessageString(Chat::Loot, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); DeleteItemInInventory(EQEmu::invslot::slotCursor); SendCursorBuffer(); @@ -1555,7 +1555,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) { if (!lore_pass) { Log(Logs::General, Logs::Inventory, "(%s) Duplicate lore items are not allowed - destroying item %s(id:%u) on cursor", GetName(), test_item->Name, test_item->ID); - Message_StringID(Chat::Loot, 290); + MessageString(Chat::Loot, 290); parse->EventItem(EVENT_DESTROY_ITEM, this, test_inst, nullptr, "", 0); DeleteItemInInventory(EQEmu::invslot::slotCursor, 0, true); } diff --git a/zone/lua_mob.cpp b/zone/lua_mob.cpp index df0cd7b70..7d769b8dd 100644 --- a/zone/lua_mob.cpp +++ b/zone/lua_mob.cpp @@ -743,9 +743,9 @@ void Lua_Mob::Message(int type, const char *message) { self->Message(type, message); } -void Lua_Mob::Message_StringID(int type, int string_id, uint32 distance) { +void Lua_Mob::MessageString(int type, int string_id, uint32 distance) { Lua_Safe_Call_Void(); - self->Message_StringID(type, string_id, distance); + self->MessageString(type, string_id, distance); } void Lua_Mob::Say(const char *message) { @@ -2386,7 +2386,8 @@ luabind::scope lua_register_mob() { .def("SetCurrentWP", &Lua_Mob::SetCurrentWP) .def("GetSize", &Lua_Mob::GetSize) .def("Message", &Lua_Mob::Message) - .def("Message_StringID", &Lua_Mob::Message_StringID) + .def("MessageString", &Lua_Mob::MessageString) + .def("Message_StringID", &Lua_Mob::MessageString) .def("Say", (void(Lua_Mob::*)(const char*))& Lua_Mob::Say) .def("Say", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Say) .def("QuestSay", (void(Lua_Mob::*)(Lua_Client,const char *))&Lua_Mob::QuestSay) diff --git a/zone/lua_mob.h b/zone/lua_mob.h index 1270f2121..592ac6243 100644 --- a/zone/lua_mob.h +++ b/zone/lua_mob.h @@ -166,7 +166,7 @@ public: void SetCurrentWP(int wp); double GetSize(); void Message(int type, const char *message); - void Message_StringID(int type, int string_id, uint32 distance); + void MessageString(int type, int string_id, uint32 distance); void Say(const char *message); void Say(const char* message, int language); void QuestSay(Lua_Client client, const char *message); diff --git a/zone/merc.cpp b/zone/merc.cpp index 7ae4a4d9f..c2b433d52 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1618,7 +1618,7 @@ void Merc::AI_Process() { { if(zone->random.Roll(flurrychance)) { - Message_StringID(Chat::NPCFlurry, YOU_FLURRY); + MessageString(Chat::NPCFlurry, YOU_FLURRY); Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); Attack(GetTarget(), EQEmu::invslot::slotPrimary, false); } @@ -2623,7 +2623,7 @@ int16 Merc::GetFocusEffect(focusType type, uint16 spell_id) { realTotal = CalcFocusEffect(type, UsedFocusID, spell_id); if (realTotal != 0 && UsedItem) - Message_StringID(Chat::Spells, BEGINS_TO_GLOW, UsedItem->Name); + MessageString(Chat::Spells, BEGINS_TO_GLOW, UsedItem->Name); } //Check if spell focus effect exists for the client. diff --git a/zone/mob.cpp b/zone/mob.cpp index 6067f206e..a5d7ae261 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2835,7 +2835,7 @@ void Mob::Say(const char *format, ...) talker = this; } - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( talker, false, 200, 10, GENERIC_SAY, GetCleanName(), buf ); @@ -2850,7 +2850,8 @@ void Mob::Say_StringID(uint32 string_id, const char *message3, const char *messa snprintf(string_id_str, 10, "%d", string_id); - entity_list.MessageClose_StringID(this, false, 200, 10, + entity_list.MessageCloseString( + this, false, 200, 10, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str, message3, message4, message5, message6, message7, message8, message9 ); @@ -2862,7 +2863,8 @@ void Mob::Say_StringID(uint32 type, uint32 string_id, const char *message3, cons snprintf(string_id_str, 10, "%d", string_id); - entity_list.MessageClose_StringID(this, false, 200, type, + entity_list.MessageCloseString( + this, false, 200, type, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str, message3, message4, message5, message6, message7, message8, message9 ); @@ -2875,7 +2877,7 @@ void Mob::SayTo_StringID(Client *to, uint32 string_id, const char *message3, con auto string_id_str = std::to_string(string_id); - to->Message_StringID(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); + to->MessageString(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); } void Mob::SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) @@ -2885,7 +2887,7 @@ void Mob::SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char * auto string_id_str = std::to_string(string_id); - to->Message_StringID(type, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); + to->MessageString(type, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); } void Mob::Shout(const char *format, ...) @@ -2897,7 +2899,7 @@ void Mob::Shout(const char *format, ...) vsnprintf(buf, 1000, format, ap); va_end(ap); - entity_list.Message_StringID(this, false, Chat::Shout, + entity_list.MessageString(this, false, Chat::Shout, GENERIC_SHOUT, GetCleanName(), buf); } @@ -2910,8 +2912,10 @@ void Mob::Emote(const char *format, ...) vsnprintf(buf, 1000, format, ap); va_end(ap); - entity_list.MessageClose_StringID(this, false, 200, 10, - GENERIC_EMOTE, GetCleanName(), buf); + entity_list.MessageCloseString( + this, false, 200, 10, + GENERIC_EMOTE, GetCleanName(), buf + ); } void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::Options &opts) @@ -4887,16 +4891,16 @@ void Mob::SlowMitigation(Mob* caster) if (GetSlowMitigation() && caster && caster->IsClient()) { if ((GetSlowMitigation() > 0) && (GetSlowMitigation() < 26)) - caster->Message_StringID(Chat::SpellFailure, SLOW_MOSTLY_SUCCESSFUL); + caster->MessageString(Chat::SpellFailure, SLOW_MOSTLY_SUCCESSFUL); else if ((GetSlowMitigation() >= 26) && (GetSlowMitigation() < 74)) - caster->Message_StringID(Chat::SpellFailure, SLOW_PARTIALLY_SUCCESSFUL); + caster->MessageString(Chat::SpellFailure, SLOW_PARTIALLY_SUCCESSFUL); else if ((GetSlowMitigation() >= 74) && (GetSlowMitigation() < 101)) - caster->Message_StringID(Chat::SpellFailure, SLOW_SLIGHTLY_SUCCESSFUL); + caster->MessageString(Chat::SpellFailure, SLOW_SLIGHTLY_SUCCESSFUL); else if (GetSlowMitigation() > 100) - caster->Message_StringID(Chat::SpellFailure, SPELL_OPPOSITE_EFFECT); + caster->MessageString(Chat::SpellFailure, SPELL_OPPOSITE_EFFECT); } } diff --git a/zone/mob.h b/zone/mob.h index d2ebe3934..5134f1ace 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -722,12 +722,12 @@ public: inline void SetRareSpawn(bool in) { rare_spawn = in; } virtual void Message(uint32 type, const char* message, ...) { } - virtual void Message_StringID(uint32 type, uint32 string_id, uint32 distance = 0) { } - virtual void Message_StringID(uint32 type, uint32 string_id, const char* message, const char* message2 = 0, + virtual void MessageString(uint32 type, uint32 string_id, uint32 distance = 0) { } + virtual void MessageString(uint32 type, uint32 string_id, const char* message, const char* message2 = 0, const char* message3 = 0, const char* message4 = 0, const char* message5 = 0, const char* message6 = 0, const char* message7 = 0, const char* message8 = 0, const char* message9 = 0, uint32 distance = 0) { } - virtual void FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id) { } - virtual void FilteredMessage_StringID(Mob *sender, uint32 type, eqFilterType filter, + virtual void FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id) { } + virtual void FilteredMessageString(Mob *sender, uint32 type, eqFilterType filter, uint32 string_id, const char *message1, const char *message2 = nullptr, const char *message3 = nullptr, const char *message4 = nullptr, const char *message5 = nullptr, const char *message6 = nullptr, diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index e71a28a05..6b7218417 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -578,7 +578,7 @@ void NPC::AI_Stop() { void Client::AI_Stop() { Mob::AI_Stop(); - this->Message_StringID(Chat::Red,PLAYER_REGAIN); + this->MessageString(Chat::Red,PLAYER_REGAIN); auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct)); Charm_Struct *ps = (Charm_Struct*)app->pBuffer; @@ -2029,14 +2029,14 @@ void Mob::StartEnrage() // start the timer. need to call IsEnraged frequently since we dont have callback timers :-/ bEnraged = true; - entity_list.MessageClose_StringID(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_START, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_START, GetCleanName()); } void Mob::ProcessEnrage(){ if(IsEnraged()){ Timer *timer = GetSpecialAbilityTimer(SPECATK_ENRAGE); if(timer && timer->Check()){ - entity_list.MessageClose_StringID(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_END, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::NPCEnrage, NPC_ENRAGE_END, GetCleanName()); int enraged_cooldown = GetSpecialAbilityParam(SPECATK_ENRAGE, 2); enraged_cooldown = enraged_cooldown > 0 ? enraged_cooldown : EnragedTimer; @@ -2057,9 +2057,23 @@ bool Mob::Flurry(ExtraAttackOptions *opts) Mob *target = GetTarget(); if (target) { if (!IsPet()) { - entity_list.MessageClose_StringID(this, true, 200, Chat::NPCFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); + entity_list.MessageCloseString( + this, + true, + 200, + Chat::NPCFlurry, + NPC_FLURRY, + GetCleanName(), + target->GetCleanName()); } else { - entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, NPC_FLURRY, GetCleanName(), target->GetCleanName()); + entity_list.MessageCloseString( + this, + true, + 200, + Chat::PetFlurry, + NPC_FLURRY, + GetCleanName(), + target->GetCleanName()); } int num_attacks = GetSpecialAbilityParam(SPECATK_FLURRY, 1); @@ -2096,9 +2110,9 @@ bool Mob::Rampage(ExtraAttackOptions *opts) { int index_hit = 0; if (!IsPet()) - entity_list.MessageClose_StringID(this, true, 200, Chat::NPCRampage, NPC_RAMPAGE, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::NPCRampage, NPC_RAMPAGE, GetCleanName()); else - entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, NPC_RAMPAGE, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::PetFlurry, NPC_RAMPAGE, GetCleanName()); int rampage_targets = GetSpecialAbilityParam(SPECATK_RAMPAGE, 1); if (rampage_targets == 0) // if set to 0 or not set in the DB @@ -2153,9 +2167,9 @@ void Mob::AreaRampage(ExtraAttackOptions *opts) { int index_hit = 0; if (!IsPet()) { // do not know every pet AA so thought it safer to add this - entity_list.MessageClose_StringID(this, true, 200, Chat::NPCRampage, AE_RAMPAGE, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::NPCRampage, AE_RAMPAGE, GetCleanName()); } else { - entity_list.MessageClose_StringID(this, true, 200, Chat::PetFlurry, AE_RAMPAGE, GetCleanName()); + entity_list.MessageCloseString(this, true, 200, Chat::PetFlurry, AE_RAMPAGE, GetCleanName()); } int rampage_targets = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 1); diff --git a/zone/npc.cpp b/zone/npc.cpp index 3f31d57da..30bf0b614 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -1744,17 +1744,17 @@ void NPC::Disarm(Client* client, int chance) { SendWearChange(matslot); if ((CastToMob()->GetBodyType() == BT_Humanoid || CastToMob()->GetBodyType() == BT_Summoned) && eslot == EQEmu::invslot::slotPrimary) Say("Ahh! My weapon!"); - client->Message_StringID(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); + client->MessageString(Chat::Skills, DISARM_SUCCESS, this->GetCleanName()); if (chance != 1000) client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 4); return; } - client->Message_StringID(Chat::Skills, DISARM_FAILED); + client->MessageString(Chat::Skills, DISARM_FAILED); if (chance != 1000) client->CheckIncreaseSkill(EQEmu::skills::SkillDisarm, nullptr, 2); return; } - client->Message_StringID(Chat::Skills, DISARM_FAILED); + client->MessageString(Chat::Skills, DISARM_FAILED); } void Mob::NPCSpecialAttacks(const char* parse, int permtag, bool reset, bool remove) { @@ -2592,7 +2592,7 @@ void NPC::DoNPCEmote(uint8 event_, uint16 emoteid) else if(nes->type == 2) this->Shout("%s",nes->text); else if(nes->type == 3) - entity_list.MessageClose_StringID(this, true, 200, 10, GENERIC_STRING, nes->text); + entity_list.MessageCloseString(this, true, 200, 10, GENERIC_STRING, nes->text); else this->Say("%s",nes->text); } diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp index 7da290439..059504328 100644 --- a/zone/oldcode.cpp +++ b/zone/oldcode.cpp @@ -1198,7 +1198,7 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0] char val1[20]={0}; char val2[20]={0}; uint32 remain = p_timers.GetRemainingTime(pTimerDisciplineReuse); - Message_StringID(Chat::WhiteSmoke,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); + MessageString(Chat::WhiteSmoke,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); //Message(0,"You can use a new discipline in %i minutes %i seconds.", (disc_timer.GetRemainingTime()/1000)/60, disc_timer.GetRemainingTime()/1000%60); return; } diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index 5dd4ce5be..9ad3a6e8b 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -3702,7 +3702,7 @@ XS(XS_Mob_Message_StringID) { distance = (uint32) SvUV(ST(3)); } - THIS->Message_StringID(type, string_id, distance); + THIS->MessageString(type, string_id, distance); } XSRETURN_EMPTY; } diff --git a/zone/raids.cpp b/zone/raids.cpp index e4c5b3552..51fd2296f 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -1712,12 +1712,12 @@ const char *Raid::GetClientNameByIndex(uint8 index) return members[index].membername; } -void Raid::RaidMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { +void Raid::RaidMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2,const char* message3,const char* message4,const char* message5,const char* message6,const char* message7,const char* message8,const char* message9, uint32 distance) { uint32 i; for (i = 0; i < MAX_RAID_MEMBERS; i++) { if(members[i].member) { if(members[i].member != sender) - members[i].member->Message_StringID(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, distance); + members[i].member->MessageString(type, string_id, message, message2, message3, message4, message5, message6, message7, message8, message9, distance); } } } diff --git a/zone/raids.h b/zone/raids.h index 26f5a0880..260ae6c71 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -152,7 +152,7 @@ public: //Actual Implementation Stuff - void RaidMessage_StringID(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); + void RaidMessageString(Mob* sender, uint32 type, uint32 string_id, const char* message,const char* message2=0,const char* message3=0,const char* message4=0,const char* message5=0,const char* message6=0,const char* message7=0,const char* message8=0,const char* message9=0, uint32 distance = 0); void CastGroupSpell(Mob* caster,uint16 spellid, uint32 gid); void SplitExp(uint32 exp, Mob* other); uint32 GetTotalRaidDamage(Mob* other); diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 35b865610..3940834b8 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -177,7 +177,7 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 auto fbash = GetFuriousBash(itm->Focus.Effect); hate = hate * (100 + fbash) / 100; if (fbash) - Message_StringID(Chat::Spells, GLOWS_RED, itm->Name); + MessageString(Chat::Spells, GLOWS_RED, itm->Name); } } } @@ -530,7 +530,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { if(IsClient()) { const EQEmu::ItemInstance *wpn = CastToClient()->GetInv().GetItem(EQEmu::invslot::slotPrimary); if (!wpn || (wpn->GetItem()->ItemType != EQEmu::item::ItemType1HPiercing)){ - Message_StringID(Chat::Red, BACKSTAB_WEAPON); + MessageString(Chat::Red, BACKSTAB_WEAPON); return; } } @@ -720,11 +720,11 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) { float dist = DistanceSquared(m_Position, other->GetPosition()); if(dist > range) { Log(Logs::Detail, Logs::Combat, "Ranged attack out of range... client should catch this. (%f > %f).\n", dist, range); - Message_StringID(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. + MessageString(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. return; } else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ - Message_StringID(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. + MessageString(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. return; } @@ -1273,11 +1273,11 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51 float dist = DistanceSquared(m_Position, other->GetPosition()); if(dist > range) { Log(Logs::Detail, Logs::Combat, "Throwing attack out of range... client should catch this. (%f > %f).\n", dist, range); - Message_StringID(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. + MessageString(Chat::Red,TARGET_OUT_OF_RANGE);//Client enforces range and sends the message, this is a backup just incase. return; } else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){ - Message_StringID(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. + MessageString(Chat::Yellow,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase. return; } @@ -1566,7 +1566,7 @@ void NPC::DoClassAttacks(Mob *target) { //general stuff, for all classes.... //only gets used when their primary ability get used too if (taunting && HasOwner() && target->IsNPC() && target->GetBodyType() != BT_Undead && taunt_time) { - this->GetOwner()->Message_StringID(Chat::PetResponse, PET_TAUNTING); + this->GetOwner()->MessageString(Chat::PetResponse, PET_TAUNTING); Taunt(target->CastToNPC(), false); } @@ -1898,7 +1898,7 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, // Support for how taunt worked pre 2000 on LIVE - Can not taunt NPC over your level. if ((RuleB(Combat, TauntOverLevel) == false) && (level_difference < 0) || who->GetSpecialAbility(IMMUNE_TAUNT)) { - Message_StringID(Chat::SpellFailure, FAILED_TAUNT); + MessageString(Chat::SpellFailure, FAILED_TAUNT); return; } @@ -1955,10 +1955,10 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, if (who->CanTalk()) who->Say_StringID(SUCCESSFUL_TAUNT, GetCleanName()); } else { - Message_StringID(Chat::SpellFailure, FAILED_TAUNT); + MessageString(Chat::SpellFailure, FAILED_TAUNT); } } else { - Message_StringID(Chat::SpellFailure, FAILED_TAUNT); + MessageString(Chat::SpellFailure, FAILED_TAUNT); } if (HasSkillProcs()) @@ -2003,7 +2003,7 @@ void Mob::InstillDoubt(Mob *who) { SpellOnTarget(229, who, false, true, -2000); //is there a success message? } else { - Message_StringID(Chat::LightBlue,NOT_SCARING); + MessageString(Chat::LightBlue,NOT_SCARING); //Idea from WR: /* if (target->IsNPC() && zone->random.Int(0,99) < 10 ) { entity_list.MessageClose(target, false, 50, Chat::NPCRampage, "%s lashes out in anger!",target->GetName()); @@ -2033,8 +2033,9 @@ int Mob::TryHeadShot(Mob *defender, EQEmu::skills::SkillType skillInUse) chance = chance * norm / 100; chance += aabonuses.HeadShot[0] + spellbonuses.HeadShot[0] + itembonuses.HeadShot[0]; if (zone->random.Int(1, 1000) <= chance) { - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, FATAL_BOW_SHOT, - GetName()); + entity_list.MessageCloseString( + this, false, 200, Chat::MeleeCrit, FATAL_BOW_SHOT, + GetName()); return HeadShot_Dmg; } } @@ -2078,8 +2079,9 @@ int Mob::TryAssassinate(Mob *defender, EQEmu::skills::SkillType skillInUse) if (Assassinate_Dmg && Assassinate_Level && (defender->GetLevel() <= Assassinate_Level)) { if (zone->random.Int(1, 1000) <= chance) { - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, ASSASSINATES, - GetName()); + entity_list.MessageCloseString( + this, false, 200, Chat::MeleeCrit, ASSASSINATES, + GetName()); return Assassinate_Dmg; } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index af5a63ffc..1f8acfa2f 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -471,7 +471,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(zone->random.Roll(RuleI(Spells, SuccorFailChance))) { //2% Fail chance by default if(IsClient()) { - CastToClient()->Message_StringID(Chat::SpellFailure,SUCCOR_FAIL); + CastToClient()->MessageString(Chat::SpellFailure,SUCCOR_FAIL); } break; } @@ -703,7 +703,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))))) { if (caster) - caster->Message_StringID(Chat::SpellFailure, IMMUNE_STUN); + caster->MessageString(Chat::SpellFailure, IMMUNE_STUN); } else { int stun_resist = itembonuses.StunResist+spellbonuses.StunResist; if (IsClient()) @@ -718,7 +718,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Stun(effect_value); } else { if (IsClient()) - Message_StringID(Chat::Stun, SHAKE_OFF_STUN); + MessageString(Chat::Stun, SHAKE_OFF_STUN); Log(Logs::Detail, Logs::Combat, "Stun Resisted. We had %d percent resist chance.", stun_resist); } @@ -847,14 +847,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(ClosestMob) { - Message_StringID(Chat::Spells, MessageID); + MessageString(Chat::Spells, MessageID); SetHeading(CalculateHeadingToTarget(ClosestMob->GetX(), ClosestMob->GetY())); SetTarget(ClosestMob); CastToClient()->SendTargetCommand(ClosestMob->GetID()); SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0, true); } else - Message_StringID(Chat::Red, SENSE_NOTHING); + MessageString(Chat::Red, SENSE_NOTHING); } } break; @@ -939,14 +939,14 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { if(!zone->CanBind()) { - Message_StringID(Chat::SpellFailure, CANNOT_BIND); + MessageString(Chat::SpellFailure, CANNOT_BIND); break; } if(!zone->IsCity()) { if(caster != this) { - Message_StringID(Chat::SpellFailure, CANNOT_BIND); + MessageString(Chat::SpellFailure, CANNOT_BIND); break; } else @@ -1039,7 +1039,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if(zone->random.Roll(effect_value)) Gate(spells[spell_id].base2[i] - 1); else if (caster) - caster->Message_StringID(Chat::SpellFailure,GATE_FAIL); + caster->MessageString(Chat::SpellFailure,GATE_FAIL); } break; } @@ -1051,7 +1051,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1077,7 +1077,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1103,7 +1103,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetSpecialAbility(UNDISPELLABLE)){ if (caster) - caster->Message_StringID(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); + caster->MessageString(Chat::SpellFailure, SPELL_NO_EFFECT, spells[spell_id].name); break; } @@ -1235,7 +1235,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(GetPet()) { - Message_StringID(Chat::Shout, ONLY_ONE_PET); + MessageString(Chat::Shout, ONLY_ONE_PET); } else { @@ -1537,7 +1537,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove && caster && (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))) { if (caster) - caster->Message_StringID(Chat::Shout, IMMUNE_STUN); + caster->MessageString(Chat::Shout, IMMUNE_STUN); } else { @@ -1627,7 +1627,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove if (zone->random.Int(0, 99) > spells[spell_id].base[i]) { CastToClient()->SetFeigned(false); - entity_list.MessageClose_StringID(this, false, 200, 10, STRING_FEIGNFAILED, GetName()); + entity_list.MessageCloseString(this, false, 200, 10, STRING_FEIGNFAILED, GetName()); } else { CastToClient()->SetFeigned(true); } @@ -1644,12 +1644,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove { if(caster == this) { - Message_StringID(Chat::Spells, + MessageString(Chat::Spells, SENTINEL_TRIG_YOU); } else { - caster->Message_StringID(Chat::Spells, + caster->MessageString(Chat::Spells, SENTINEL_TRIG_OTHER, GetCleanName()); } } @@ -1790,26 +1790,26 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove Corpse *corpse = entity_list.GetCorpseByOwner(TargetClient); if(corpse) { if(TargetClient == this->CastToClient()) - Message_StringID(Chat::LightBlue, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName()); + MessageString(Chat::LightBlue, SUMMONING_CORPSE, TargetClient->CastToMob()->GetCleanName()); else - Message_StringID(Chat::LightBlue, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName()); + MessageString(Chat::LightBlue, SUMMONING_CORPSE_OTHER, TargetClient->CastToMob()->GetCleanName()); corpse->Summon(CastToClient(), true, true); } else { // No corpse found in the zone - Message_StringID(Chat::LightBlue, CORPSE_CANT_SENSE); + MessageString(Chat::LightBlue, CORPSE_CANT_SENSE); } } else if (caster) { char level[4]; ConvertArray(effect_value, level); - caster->Message_StringID(Chat::SpellFailure, + caster->MessageString(Chat::SpellFailure, SPELL_LEVEL_REQ, level); } } else { - Message_StringID(Chat::LightBlue, TARGET_NOT_FOUND); + MessageString(Chat::LightBlue, TARGET_NOT_FOUND); Log(Logs::General, Logs::Error, "%s attempted to cast spell id %u with spell effect SE_SummonCorpse, but could not cast target into a Client object.", GetCleanName(), spell_id); } } @@ -2725,7 +2725,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove case SE_MassGroupBuff:{ SetMGB(true); - Message_StringID(Chat::Disciplines, MGB_STRING); + MessageString(Chat::Disciplines, MGB_STRING); break; } @@ -3643,7 +3643,7 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster) case SE_Invisibility2: case SE_InvisVsUndead2: { if (buff.ticsremaining <= 3 && buff.ticsremaining > 1) { - Message_StringID(Chat::Spells, INVIS_BEGIN_BREAK); + MessageString(Chat::Spells, INVIS_BEGIN_BREAK); } break; } @@ -4047,7 +4047,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) if(p->IsPet()) notify = p->GetOwner(); if(p) { - notify->Message_StringID(Chat::SpellWornOff, SPELL_WORN_OFF_OF, + notify->MessageString(Chat::SpellWornOff, SPELL_WORN_OFF_OF, spells[buffs[slot].spellid].name, GetCleanName()); } } @@ -5406,7 +5406,7 @@ int16 Client::GetFocusEffect(focusType type, uint16 spell_id) default: break; } - Message_StringID(Chat::Spells, string_id, UsedItem->Name); + MessageString(Chat::Spells, string_id, UsedItem->Name); } } @@ -5814,9 +5814,15 @@ bool Mob::TryDeathSave() { Message(263, "The gods have healed you for %i points of damage.", HealAmt); if(spellbonuses.DeathSave[0] == 2) - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); + entity_list.MessageCloseString( + this, + false, + 200, + Chat::MeleeCrit, + DIVINE_INTERVENTION, + GetCleanName()); else - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); + entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); SendHPUpdate(); BuffFadeBySlot(buffSlot); @@ -5847,9 +5853,15 @@ bool Mob::TryDeathSave() { Message(263, "The gods have healed you for %i points of damage.", HealAmt); if(spellbonuses.DeathSave[0] == 2) - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); + entity_list.MessageCloseString( + this, + false, + 200, + Chat::MeleeCrit, + DIVINE_INTERVENTION, + GetCleanName()); else - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); + entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); SendHPUpdate(); BuffFadeBySlot(buffSlot); @@ -6802,11 +6814,11 @@ void Client::BreakFeignDeathWhenCastOn(bool IsResisted) chance *= 2; if(chance && (zone->random.Roll(chance))){ - Message_StringID(Chat::SpellFailure,FD_CAST_ON_NO_BREAK); + MessageString(Chat::SpellFailure,FD_CAST_ON_NO_BREAK); return; } SetFeigned(false); - Message_StringID(Chat::SpellFailure,FD_CAST_ON); + MessageString(Chat::SpellFailure,FD_CAST_ON); } } diff --git a/zone/spells.cpp b/zone/spells.cpp index 2b4056434..f6cf829c5 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -180,9 +180,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell casting canceled: not able to cast now. Valid? %d, casting %d, waiting? %d, spellend? %d, stunned? %d, feared? %d, mezed? %d, silenced? %d, amnesiad? %d", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced(), IsAmnesiad() ); if(IsSilenced() && !IsDiscipline(spell_id)) - Message_StringID(Chat::Red, SILENCED_STRING); + MessageString(Chat::Red, SILENCED_STRING); if(IsAmnesiad() && IsDiscipline(spell_id)) - Message_StringID(Chat::Red, MELEE_SILENCE); + MessageString(Chat::Red, MELEE_SILENCE); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); if(casting_spell_id && IsNPC()) @@ -197,7 +197,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, int chance = CastToClient()->GetFocusEffect(focusFcMute, spell_id);//Client only if (zone->random.Roll(chance)) { - Message_StringID(Chat::Red, SILENCED_STRING); + MessageString(Chat::Red, SILENCED_STRING); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); return(false); @@ -205,7 +205,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, } if(IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()){ - Message_StringID(Chat::Red, SPELL_WOULDNT_HOLD); + MessageString(Chat::Red, SPELL_WOULDNT_HOLD); if(IsClient()) CastToClient()->SendSpellBarEnable(spell_id); if(casting_spell_id && IsNPC()) @@ -257,7 +257,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item with an invalid class"); } else { - Message_StringID(Chat::Red, MUST_EQUIP_ITEM); + MessageString(Chat::Red, MUST_EQUIP_ITEM); } return(false); } @@ -276,7 +276,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, } else { - Message_StringID(Chat::Red, CANNOT_USE_ITEM); + MessageString(Chat::Red, CANNOT_USE_ITEM); } } return(false); @@ -289,7 +289,7 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, database.SetHackerFlag(CastToClient()->AccountName(), CastToClient()->GetCleanName(), "Clicking equip-only item without equiping it"); } else { - Message_StringID(Chat::Red, MUST_EQUIP_ITEM); + MessageString(Chat::Red, MUST_EQUIP_ITEM); } return(false); } @@ -370,18 +370,18 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Mob::SetMana(GetMana() - use_mana); // We send StopCasting which will update mana StopCasting(); - Message_StringID(Chat::SpellFailure, fizzle_msg); + MessageString(Chat::SpellFailure, fizzle_msg); /** * Song Failure message */ - entity_list.FilteredMessageClose_StringID( + entity_list.FilteredMessageCloseString( this, true, - RuleI(Range, SpellMessages), + RuleI(Range, SpellMessages), Chat::SpellFailure, (IsClient() ? FilterPCSpells : FilterNPCSpells), - (fizzle_msg == MISS_NOTE ? MISSED_NOTE_OTHER : SPELL_FIZZLE_OTHER), + (fizzle_msg == MISS_NOTE ? MISSED_NOTE_OTHER : SPELL_FIZZLE_OTHER), /* MessageFormat: You miss a note, bringing your song to a close! (if missed note) MessageFormat: A missed note brings %1's song to a close! @@ -428,7 +428,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell Error: no target. spell=%d", spell_id); if(IsClient()) { //clients produce messages... npcs should not for this case - Message_StringID(Chat::Red, SPELL_NEED_TAR); + MessageString(Chat::Red, SPELL_NEED_TAR); InterruptSpell(); } else { InterruptSpell(0, 0, 0); //the 0 args should cause no messages @@ -461,7 +461,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", spell_id, my_curmana, mana_cost); if(IsClient()) { //clients produce messages... npcs should not for this case - Message_StringID(Chat::Red, INSUFFICIENT_MANA); + MessageString(Chat::Red, INSUFFICIENT_MANA); InterruptSpell(); } else { InterruptSpell(0, 0, 0); //the 0 args should cause no messages @@ -518,7 +518,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, if (IsClient() && slot == CastingSlot::Item && item_slot != 0xFFFFFFFF) { auto item = CastToClient()->GetInv().GetItem(item_slot); if (item && item->GetItem()) - Message_StringID(Chat::Spells, BEGINS_TO_GLOW, item->GetItem()->Name); + MessageString(Chat::Spells, BEGINS_TO_GLOW, item->GetItem()->Name); } if (!DoCastingChecks()) { @@ -575,13 +575,13 @@ bool Mob::DoCastingChecks() if (spell_target && spells[spell_id].targettype != ST_Self && !spell_target->CheckSpellLevelRestriction(spell_id)) { Log(Logs::Detail, Logs::Spells, "Spell %d failed: recipient did not meet the level restrictions", spell_id); if (!IsBardSong(spell_id)) - Message_StringID(Chat::SpellFailure, SPELL_TOO_POWERFUL); + MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL); return false; } } if (spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()) { - Message_StringID(Chat::Red, CAST_OUTDOORS); + MessageString(Chat::Red, CAST_OUTDOORS); return false; } @@ -680,7 +680,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillPercussionInstruments) > 0) // no skill increases if not trained in the instrument CheckIncreaseSkill(EQEmu::skills::SkillPercussionInstruments, nullptr, -15); else - Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); // tell the client that they need instrument training + MessageString(Chat::Red,NO_INSTRUMENT_SKILL); // tell the client that they need instrument training } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -690,7 +690,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillStringedInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillStringedInstruments, nullptr, -15); else - Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); + MessageString(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -700,7 +700,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillWindInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillWindInstruments, nullptr, -15); else - Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); + MessageString(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -710,7 +710,7 @@ void Client::CheckSongSkillIncrease(uint16 spell_id){ if (GetRawSkill(EQEmu::skills::SkillBrassInstruments) > 0) CheckIncreaseSkill(EQEmu::skills::SkillBrassInstruments, nullptr, -15); else - Message_StringID(Chat::Red,NO_INSTRUMENT_SKILL); + MessageString(Chat::Red,NO_INSTRUMENT_SKILL); } else CheckIncreaseSkill(EQEmu::skills::SkillSinging, nullptr, -15); @@ -861,7 +861,7 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid) } if(casting_spell_aa_id && IsClient()) { //Rest AA Timer on failed cast - CastToClient()->Message_StringID(Chat::SpellFailure, ABILITY_FAILED); + CastToClient()->MessageString(Chat::SpellFailure, ABILITY_FAILED); CastToClient()->ResetAlternateAdvancementTimer(casting_spell_aa_id); } @@ -940,7 +940,7 @@ void Mob::StopCasting() if (IsClient()) { auto c = CastToClient(); if (casting_spell_aa_id) { //Rest AA Timer on failed cast - c->Message_StringID(Chat::SpellFailure, ABILITY_FAILED); + c->MessageString(Chat::SpellFailure, ABILITY_FAILED); c->ResetAlternateAdvancementTimer(casting_spell_aa_id); } @@ -969,7 +969,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(IsClient() && slot != CastingSlot::Item && slot != CastingSlot::PotionBelt && spells[spell_id].recast_time > 1000) { // 10 is item if(!CastToClient()->GetPTimers().Expired(&database, pTimerSpellStart + spell_id, false)) { //should we issue a message or send them a spell gem packet? - Message_StringID(Chat::Red, SPELL_RECAST); + MessageString(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: spell reuse timer not expired", spell_id); StopCasting(); return; @@ -983,7 +983,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(itm && itm->GetItem()->RecastDelay > 0) { if(!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + itm->GetItem()->RecastType), false)) { - Message_StringID(Chat::Red, SPELL_RECAST); + MessageString(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: item spell reuse timer not expired", spell_id); StopCasting(); return; @@ -1015,7 +1015,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if (casting_spell_id != spell_id) { Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: already casting", spell_id); - Message_StringID(Chat::Red,ALREADY_CASTING); + MessageString(Chat::Red,ALREADY_CASTING); InterruptSpell(); return; } @@ -1133,8 +1133,14 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo } // if we got here, we regained concentration regain_conc = true; - Message_StringID(Chat::Spells, REGAIN_AND_CONTINUE); - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), Chat::Spells, OTHER_REGAIN_CAST, this->GetCleanName()); + MessageString(Chat::Spells, REGAIN_AND_CONTINUE); + entity_list.MessageCloseString( + this, + true, + RuleI(Range, SpellMessages), + Chat::Spells, + OTHER_REGAIN_CAST, + this->GetCleanName()); } } @@ -1170,7 +1176,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13000: if(itembonuses.percussionMod == 0) { // check for the appropriate instrument type HasInstrument = false; - c->Message_StringID(Chat::Red, SONG_NEEDS_DRUM); // send an error message if missing + c->MessageString(Chat::Red, SONG_NEEDS_DRUM); // send an error message if missing } break; @@ -1178,7 +1184,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13001: if(itembonuses.windMod == 0) { HasInstrument = false; - c->Message_StringID(Chat::Red, SONG_NEEDS_WIND); + c->MessageString(Chat::Red, SONG_NEEDS_WIND); } break; @@ -1186,7 +1192,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13011: if(itembonuses.stringedMod == 0) { HasInstrument = false; - c->Message_StringID(Chat::Red, SONG_NEEDS_STRINGS); + c->MessageString(Chat::Red, SONG_NEEDS_STRINGS); } break; @@ -1194,7 +1200,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo case 13012: if(itembonuses.brassMod == 0) { HasInstrument = false; - c->Message_StringID(Chat::Red, SONG_NEEDS_BRASS); + c->MessageString(Chat::Red, SONG_NEEDS_BRASS); } break; @@ -1222,13 +1228,13 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo { if (!missingreags) { - c->Message_StringID(Chat::Red, MISSING_SPELL_COMP); + c->MessageString(Chat::Red, MISSING_SPELL_COMP); missingreags=true; } const EQEmu::ItemData *item = database.GetItem(component); if(item) { - c->Message_StringID(Chat::Red, MISSING_SPELL_COMP_ITEM, item->Name); + c->MessageString(Chat::Red, MISSING_SPELL_COMP_ITEM, item->Name); Log(Logs::Detail, Logs::Spells, "Spell %d: Canceled. Missing required reagent %s (%d)", spell_id, item->Name, component); } else { @@ -1324,7 +1330,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(IsClient() && fromaug && recastdelay > 0) { if(!CastToClient()->GetPTimers().Expired(&database, (pTimerItemStart + recasttype), false)) { - Message_StringID(Chat::Red, SPELL_RECAST); + MessageString(Chat::Red, SPELL_RECAST); Log(Logs::Detail, Logs::Spells, "Casting of %d canceled: item spell reuse timer not expired", spell_id); StopCasting(); return; @@ -1502,7 +1508,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce targetType = ST_Target; if (spell_target && !spell_target->PassCastRestriction(true, spells[spell_id].CastRestriction)){ - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } @@ -1512,7 +1518,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if (spell_target && ((spell_target->IsNPC() && spell_target->IsEngaged()) || (spell_target->IsClient() && spell_target->CastToClient()->GetAggroCount()))) { - Message_StringID(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string + MessageString(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string return false; } } @@ -1520,9 +1526,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce else if (IsBeneficialSpell(spell_id)) { if ((IsNPC() && IsEngaged()) || (IsClient() && CastToClient()->GetAggroCount())) { if (IsDiscipline(spell_id)) - Message_StringID(Chat::Red, NO_ABILITY_IN_COMBAT); + MessageString(Chat::Red, NO_ABILITY_IN_COMBAT); else - Message_StringID(Chat::Red, NO_CAST_IN_COMBAT); + MessageString(Chat::Red, NO_CAST_IN_COMBAT); return false; } @@ -1535,7 +1541,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if (spell_target && ((spell_target->IsNPC() && !spell_target->IsEngaged()) || (spell_target->IsClient() && !spell_target->CastToClient()->GetAggroCount()))) { - Message_StringID(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string + MessageString(Chat::Red, SPELL_NO_EFFECT); // Unsure correct string return false; } } @@ -1543,9 +1549,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce else if (IsBeneficialSpell(spell_id)) { if ((IsNPC() && !IsEngaged()) || (IsClient() && !CastToClient()->GetAggroCount())) { if (IsDiscipline(spell_id)) - Message_StringID(Chat::Red, NO_ABILITY_OUT_OF_COMBAT); + MessageString(Chat::Red, NO_ABILITY_OUT_OF_COMBAT); else - Message_StringID(Chat::Red, NO_CAST_OUT_OF_COMBAT); + MessageString(Chat::Red, NO_CAST_OUT_OF_COMBAT); return false; } @@ -1582,9 +1588,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (undead)", spell_id, mob_body); if(!spell_target) - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); else - Message_StringID(Chat::Red,CANNOT_AFFECT_NPC); + MessageString(Chat::Red,CANNOT_AFFECT_NPC); return false; } CastAction = SingleTarget; @@ -1596,7 +1602,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce { //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (summoned)", spell_id, mob_body); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } CastAction = SingleTarget; @@ -1611,7 +1617,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (summoned pet)", spell_id, mob_body); - Message_StringID(Chat::Red, SPELL_NEED_TAR); + MessageString(Chat::Red, SPELL_NEED_TAR); return false; } @@ -1635,9 +1641,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce //invalid target Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target of body type %d (want body Type %d)", spell_id, mob_body, target_bt); if(!spell_target) - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); else - Message_StringID(Chat::Red,CANNOT_AFFECT_NPC); + MessageString(Chat::Red,CANNOT_AFFECT_NPC); return false; } CastAction = SingleTarget; @@ -1652,7 +1658,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (ldon object)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } else @@ -1660,14 +1666,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target->IsNPC()) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } if(spell_target->GetClass() != LDON_TREASURE) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } } @@ -1676,7 +1682,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (normal)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; // can't cast these unless we have a target } CastAction = SingleTarget; @@ -1692,7 +1698,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) message = SPELL_NEED_TAR; else if(!spell_target->IsCorpse()) message = ONLY_ON_CORPSES; else if(!spell_target->IsPlayerCorpse()) message = CORPSE_NOT_VALID; - Message_StringID(Chat::Red, message); + MessageString(Chat::Red, message); return false; } CastAction = SingleTarget; @@ -1704,7 +1710,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (no pet)", spell_id); - Message_StringID(Chat::Red,NO_PET); + MessageString(Chat::Red,NO_PET); return false; // can't cast these unless we have a target } CastAction = SingleTarget; @@ -1775,7 +1781,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (AOE)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } ae_center = spell_target; @@ -1800,7 +1806,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce } if (spell_target && spell_target->IsPet() && spells[spell_id].targettype == ST_GroupNoPets){ - Message_StringID(Chat::Red,NO_CAST_ON_PET); + MessageString(Chat::Red,NO_CAST_ON_PET); return false; } @@ -1812,7 +1818,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(!spell_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: invalid target (Group Required: Single Target)", spell_id); - Message_StringID(Chat::Red,SPELL_NEED_TAR); + MessageString(Chat::Red,SPELL_NEED_TAR); return false; } @@ -1929,14 +1935,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce if(group_id_caster == 0 || group_id_target == 0) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: Attempted to cast a Single Target Group spell on a ungrouped member.", spell_id); - Message_StringID(Chat::Red, TARGET_GROUP_MEMBER); + MessageString(Chat::Red, TARGET_GROUP_MEMBER); return false; } if(group_id_caster != group_id_target) { Log(Logs::Detail, Logs::Spells, "Spell %d canceled: Attempted to cast a Single Target Group spell on a ungrouped member.", spell_id); - Message_StringID(Chat::Red, TARGET_GROUP_MEMBER); + MessageString(Chat::Red, TARGET_GROUP_MEMBER); return false; } @@ -2030,7 +2036,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if( spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()){ if(IsClient()){ if(!CastToClient()->GetGM()){ - Message_StringID(Chat::Red, CAST_OUTDOORS); + MessageString(Chat::Red, CAST_OUTDOORS); return false; } } @@ -2112,14 +2118,14 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(!spells[spell_id].npc_no_los && spell_target && IsDetrimentalSpell(spell_id) && !CheckLosFN(spell_target) && !IsHarmonySpell(spell_id) && spells[spell_id].targettype != ST_TargetOptional) { Log(Logs::Detail, Logs::Spells, "Spell %d: cannot see target %s", spell_id, spell_target->GetName()); - Message_StringID(Chat::Red,CANT_SEE_TARGET); + MessageString(Chat::Red,CANT_SEE_TARGET); return false; } // check to see if target is a caster mob before performing a mana tap if(spell_target && IsManaTapSpell(spell_id)) { if(spell_target->GetCasterClass() == 'N') { - Message_StringID(Chat::Red, TARGET_NO_MANA); + MessageString(Chat::Red, TARGET_NO_MANA); return false; } } @@ -2143,13 +2149,13 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); + MessageString(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } else if (dist2 < min_range2){ //target is too close range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2); - Message_StringID(Chat::Red, TARGET_TOO_CLOSE); + MessageString(Chat::Red, TARGET_TOO_CLOSE); return(false); } @@ -2164,13 +2170,13 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, ui if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); + MessageString(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } else if (dist2 < min_range2){ //target is too close range. Log(Logs::Detail, Logs::Spells, "Spell %d: Spell target is too close (squared: %f < %f)", spell_id, dist2, min_range2); - Message_StringID(Chat::Red, TARGET_TOO_CLOSE); + MessageString(Chat::Red, TARGET_TOO_CLOSE); return(false); } @@ -2520,7 +2526,7 @@ bool Mob::ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, CastingSlot slo if(spell_target && IsDetrimentalSpell(spell_id) && !CheckLosFN(spell_target)) { Log(Logs::Detail, Logs::Spells, "Bard Song Pulse %d: cannot see target %s", spell_target->GetName()); - Message_StringID(Chat::Red, CANT_SEE_TARGET); + MessageString(Chat::Red, CANT_SEE_TARGET); return(false); } @@ -2535,7 +2541,7 @@ bool Mob::ApplyNextBardPulse(uint16 spell_id, Mob *spell_target, CastingSlot slo if(dist2 > range2) { //target is out of range. Log(Logs::Detail, Logs::Spells, "Bard Song Pulse %d: Spell target is out of range (squared: %f > %f)", spell_id, dist2, range2); - Message_StringID(Chat::Red, TARGET_OUT_OF_RANGE); + MessageString(Chat::Red, TARGET_OUT_OF_RANGE); return(false); } } @@ -2894,7 +2900,7 @@ int Mob::CheckStackConflict(uint16 spellid1, int caster_level1, uint16 spellid2, if (spellbonuses.Screech == 1) { if (effect2 == SE_Screech && sp2.base[i] == -1) { - Message_StringID(Chat::SpellFailure, SCREECH_BUFF_BLOCK, sp2.name); + MessageString(Chat::SpellFailure, SCREECH_BUFF_BLOCK, sp2.name); return -1; } } @@ -3425,7 +3431,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r if(IsDetrimentalSpell(spell_id) && !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id)) { if(!IsClient() || !CastToClient()->GetGM()) { - Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); + MessageString(Chat::SpellFailure, SPELL_NO_HOLD); return false; } } @@ -3590,7 +3596,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible) { - spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3600,7 +3606,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible_undead) { - spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3610,7 +3616,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { if(spelltar->invisible_animals) { - spelltar->Message_StringID(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); + spelltar->MessageString(Chat::SpellFailure, ALREADY_INVIS, GetCleanName()); safe_delete(action_packet); return false; } @@ -3690,7 +3696,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r Log(Logs::Detail, Logs::Spells, "Beneficial ae bard song %d can't take hold %s -> %s, IBA? %d", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); } else { Log(Logs::Detail, Logs::Spells, "Beneficial spell %d can't take hold %s -> %s, IBA? %d", spell_id, GetName(), spelltar->GetName(), IsBeneficialAllowed(spelltar)); - Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); + MessageString(Chat::SpellFailure, SPELL_NO_HOLD); } safe_delete(action_packet); return false; @@ -3700,7 +3706,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r else if ( !IsAttackAllowed(spelltar, true) && !IsResurrectionEffects(spell_id)) // Detrimental spells - PVP check { Log(Logs::Detail, Logs::Spells, "Detrimental spell %d can't take hold %s -> %s", spell_id, GetName(), spelltar->GetName()); - spelltar->Message_StringID(Chat::SpellFailure, YOU_ARE_PROTECTED, GetCleanName()); + spelltar->MessageString(Chat::SpellFailure, YOU_ARE_PROTECTED, GetCleanName()); safe_delete(action_packet); return false; } @@ -3737,7 +3743,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r focus = CalcFocusEffect(focusBlockNextSpell, buffs[b].spellid, spell_id); if(focus) { CheckNumHitsRemaining(NumHit::MatchingSpells, b); - Message_StringID(Chat::SpellFailure, SPELL_WOULDNT_HOLD); + MessageString(Chat::SpellFailure, SPELL_WOULDNT_HOLD); safe_delete(action_packet); return false; } @@ -3786,7 +3792,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r if (reflect_chance) { if (RuleB(Spells, ReflectMessagesClose)) { - entity_list.MessageClose_StringID( + entity_list.MessageCloseString( this, /* Sender */ false, /* Skip Sender */ RuleI(Range, SpellMessages), /* Range */ @@ -3797,7 +3803,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r ); } else { - Message_StringID(Chat::Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); + MessageString(Chat::Spells, SPELL_REFLECT, GetCleanName(), spelltar->GetCleanName()); } CheckNumHitsRemaining(NumHit::ReflectSpell); @@ -3829,12 +3835,12 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r Log(Logs::Detail, Logs::Spells, "Spell %d was completely resisted by %s", spell_id, spelltar->GetName()); if (spells[spell_id].resisttype == RESIST_PHYSICAL){ - Message_StringID(Chat::SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); - spelltar->Message_StringID(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); + MessageString(Chat::SpellFailure, PHYSICAL_RESIST_FAIL,spells[spell_id].name); + spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); } else { - Message_StringID(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name); - spelltar->Message_StringID(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); + MessageString(Chat::SpellFailure, TARGET_RESISTED, spells[spell_id].name); + spelltar->MessageString(Chat::SpellFailure, YOU_RESIST, spells[spell_id].name); } if (spelltar->IsAIControlled()) { @@ -3899,7 +3905,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r { Log(Logs::Detail, Logs::Spells, "Spell %d failed: recipient did not meet the level restrictions", spell_id); if(!IsBardSong(spell_id)) - Message_StringID(Chat::SpellFailure, SPELL_TOO_POWERFUL); + MessageString(Chat::SpellFailure, SPELL_TOO_POWERFUL); safe_delete(action_packet); return false; } @@ -3911,7 +3917,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r // spell. It's most likely a buff that can't stack. Log(Logs::Detail, Logs::Spells, "Spell %d could not apply its effects %s -> %s\n", spell_id, GetName(), spelltar->GetName()); if(casting_spell_aa_id) - Message_StringID(Chat::SpellFailure, SPELL_NO_HOLD); + MessageString(Chat::SpellFailure, SPELL_NO_HOLD); safe_delete(action_packet); return false; } @@ -3998,7 +4004,7 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) /* if(!can_rez) { if(Caster && Caster->IsClient()) - Caster->Message_StringID(Chat::WhiteSmoke, CORPSE_TOO_OLD); + Caster->MessageString(Chat::WhiteSmoke, CORPSE_TOO_OLD); return; } */ @@ -4226,7 +4232,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNMEZABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Mez spells."); - caster->Message_StringID(Chat::SpellFailure, CANNOT_MEZ); + caster->MessageString(Chat::SpellFailure, CANNOT_MEZ); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4244,7 +4250,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) (!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity)))) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Mez spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(Chat::SpellFailure, CANNOT_MEZ_WITH_SPELL); + caster->MessageString(Chat::SpellFailure, CANNOT_MEZ_WITH_SPELL); AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } @@ -4254,7 +4260,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNSLOWABLE) && IsEffectInSpell(spell_id, SE_AttackSpeed)) { Log(Logs::Detail, Logs::Spells, "We are immune to Slow spells."); - caster->Message_StringID(Chat::Red, IMMUNE_ATKSPEED); + caster->MessageString(Chat::Red, IMMUNE_ATKSPEED); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4270,7 +4276,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) effect_index = GetSpellEffectIndex(spell_id, SE_Fear); if(GetSpecialAbility(UNFEARABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Fear spells."); - caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->MessageString(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4281,13 +4287,13 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) } else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false)) { Log(Logs::Detail, Logs::Spells, "Clients cannot fear eachother!"); - caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->MessageString(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } else if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) { Log(Logs::Detail, Logs::Spells, "Level is %d, cannot be feared by this spell.", GetLevel()); - caster->Message_StringID(Chat::Shout, FEAR_TOO_HIGH); + caster->MessageString(Chat::Shout, FEAR_TOO_HIGH); int32 aggro = caster->CheckAggroAmount(spell_id, this); if (aggro > 0) { AddToHateList(caster, aggro); @@ -4300,7 +4306,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { Message(Chat::Red, "Your are immune to fear."); Log(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!"); - caster->Message_StringID(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up + caster->MessageString(Chat::Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up return true; } } @@ -4310,7 +4316,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetSpecialAbility(UNCHARMABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Charm spells."); - caster->Message_StringID(Chat::Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up + caster->MessageString(Chat::Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4336,7 +4342,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0) { Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Charm spell (%d)", GetLevel(), spells[spell_id].max[effect_index]); - caster->Message_StringID(Chat::Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up + caster->MessageString(Chat::Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up AddToHateList(caster, 1,0,true,false,false,spell_id); return true; } @@ -4351,7 +4357,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) { if(GetSpecialAbility(UNSNAREABLE)) { Log(Logs::Detail, Logs::Spells, "We are immune to Snare spells."); - caster->Message_StringID(Chat::Red, IMMUNE_MOVEMENT); + caster->MessageString(Chat::Red, IMMUNE_MOVEMENT); int32 aggro = caster->CheckAggroAmount(spell_id, this); if(aggro > 0) { AddToHateList(caster, aggro); @@ -4367,7 +4373,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot lifetap yourself."); - caster->Message_StringID(Chat::SpellFailure, CANT_DRAIN_SELF); + caster->MessageString(Chat::SpellFailure, CANT_DRAIN_SELF); return true; } } @@ -4377,7 +4383,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster) if(this == caster) { Log(Logs::Detail, Logs::Spells, "You cannot sacrifice yourself."); - caster->Message_StringID(Chat::SpellFailure, CANNOT_SAC_SELF); + caster->MessageString(Chat::SpellFailure, CANNOT_SAC_SELF); return true; } } diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 07e6da7fb..9230871c8 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -304,12 +304,12 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, container->GetItem()->Icon, atoi(container->GetItem()->IDFile + 2)); - user->Message_StringID(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); + user->MessageString(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); if (RuleB(Inventory, DeleteTransformationMold)) user->DeleteItemInInventory(in_combine->container_slot, 0, true); } else if (inst) { - user->Message_StringID(Chat::LightBlue, TRANSFORM_FAILED, inst->GetItem()->Name); + user->MessageString(Chat::LightBlue, TRANSFORM_FAILED, inst->GetItem()->Name); } auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); @@ -324,10 +324,10 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob user->DeleteItemInInventory(EQEmu::InventoryProfile::CalcSlotId(in_combine->container_slot, 0), 0, true); container->Clear(); user->SummonItem(new_weapon->ID, inst->GetCharges(), inst->GetAugmentItemID(0), inst->GetAugmentItemID(1), inst->GetAugmentItemID(2), inst->GetAugmentItemID(3), inst->GetAugmentItemID(4), inst->GetAugmentItemID(5), inst->IsAttuned(), EQEmu::invslot::slotCursor, 0, 0); - user->Message_StringID(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); + user->MessageString(Chat::LightBlue, TRANSFORM_COMPLETE, inst->GetItem()->Name); } else if (inst) { - user->Message_StringID(Chat::LightBlue, DETRANSFORM_FAILED, inst->GetItem()->Name); + user->MessageString(Chat::LightBlue, DETRANSFORM_FAILED, inst->GetItem()->Name); } auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); @@ -337,7 +337,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob DBTradeskillRecipe_Struct spec; if (!database.GetTradeRecipe(container, c_type, some_id, user->CharacterID(), &spec)) { - user->Message_StringID(Chat::Emote,TRADESKILL_NOCOMBINE); + user->MessageString(Chat::Emote,TRADESKILL_NOCOMBINE); auto outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0); user->QueuePacket(outapp); safe_delete(outapp); @@ -422,7 +422,7 @@ void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Ob // Update Made count if (success) { if (!spec.has_learnt && ((spec.must_learn&0x10) != 0x10)) { - user->Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); + user->MessageString(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); } database.UpdateRecipeMadecount(spec.recipe_id, user->CharacterID(), spec.madecount+1); } @@ -540,13 +540,13 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac safe_delete(outapp); - user->Message_StringID(Chat::Skills, TRADESKILL_MISSING_COMPONENTS); + user->MessageString(Chat::Skills, TRADESKILL_MISSING_COMPONENTS); for (auto it = MissingItems.begin(); it != MissingItems.end(); ++it) { const EQEmu::ItemData* item = database.GetItem(*it); if(item) - user->Message_StringID(Chat::Skills, TRADESKILL_MISSING_ITEM, item->Name); + user->MessageString(Chat::Skills, TRADESKILL_MISSING_ITEM, item->Name); } return; @@ -593,7 +593,7 @@ void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac if (success) { if (!spec.has_learnt && ((spec.must_learn & 0x10) != 0x10)) { - user->Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); + user->MessageString(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, spec.name.c_str()); } database.UpdateRecipeMadecount(spec.recipe_id, user->CharacterID(), spec.madecount+1); } @@ -951,7 +951,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { // above critical still stands. // Mastery modifier is: 10%/25%/50% for rank one/two/three chance = 95.0f + (float(user_skill - spec->trivial) / 40.0f); - Message_StringID(Chat::Emote, TRADESKILL_TRIVIAL); + MessageString(Chat::Emote, TRADESKILL_TRIVIAL); } else if(chance < 5) { // Minimum chance is always 5 chance = 5; @@ -978,7 +978,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { if(over_trivial < 0) CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill); - Message_StringID(Chat::LightBlue, TRADESKILL_SUCCEED, spec->name.c_str()); + MessageString(Chat::LightBlue, TRADESKILL_SUCCEED, spec->name.c_str()); Log(Logs::Detail, Logs::Tradeskills, "Tradeskill success"); @@ -1010,7 +1010,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) { if(over_trivial < 0) CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill); - Message_StringID(Chat::Emote,TRADESKILL_FAILED); + MessageString(Chat::Emote,TRADESKILL_FAILED); Log(Logs::Detail, Logs::Tradeskills, "Tradeskill failed"); if (this->GetGroup()) @@ -1404,7 +1404,7 @@ void Client::LearnRecipe(uint32 recipeID) if (row[1] != nullptr) return; - Message_StringID(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, row[0]); + MessageString(Chat::LightBlue, TRADESKILL_LEARN_RECIPE, row[0]); // Actually learn the recipe now query = StringFormat("INSERT INTO char_recipe_list " "SET recipe_id = %u, char_id = %u, madecount = 0 " diff --git a/zone/trading.cpp b/zone/trading.cpp index 80e5dc851..2d8f03e4f 100644 --- a/zone/trading.cpp +++ b/zone/trading.cpp @@ -2475,7 +2475,7 @@ void Client::ShowBuyLines(const EQApplicationPacket *app) { QueuePacket(app); if(bir->Approval == 0) { - Message_StringID(Chat::Yellow, TRADER_BUSY); + MessageString(Chat::Yellow, TRADER_BUSY); return; } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 6493188bf..4d1399f68 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -211,7 +211,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) else if (scm->queued == 2) // tell queue was full client->Tell_StringID(QUEUE_TELL_FULL, scm->to, scm->message); else if (scm->queued == 3) // person was offline - client->Message_StringID(Chat::EchoTell, TOLD_NOT_ONLINE, scm->to); + client->MessageString(Chat::EchoTell, TOLD_NOT_ONLINE, scm->to); else // normal tell echo "You told Soanso, 'something'" // tell echo doesn't use language, so it looks normal to you even if nobody can understand your tells client->ChannelMessageSend(scm->from, scm->to, scm->chan_num, 0, 100, scm->message); @@ -414,7 +414,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Client* client = entity_list.GetClientByID(wars->id); if (client) { if (pack->size == 64)//no results - client->Message_StringID(Chat::White, WHOALL_NO_RESULTS); + client->MessageString(Chat::White, WHOALL_NO_RESULTS); else { auto outapp = new EQApplicationPacket(OP_WhoAllResponse, pack->size); memcpy(outapp->pBuffer, pack->pBuffer, pack->size); @@ -783,7 +783,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) Client* c = entity_list.GetClientByName(Rezzer); if (c) - c->Message_StringID(Chat::SpellWornOff, REZZ_ALREADY_PENDING); + c->MessageString(Chat::SpellWornOff, REZZ_ALREADY_PENDING); break; } @@ -1485,7 +1485,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ServerOP_Consent_Struct* s = (ServerOP_Consent_Struct*)pack->pBuffer; Client* client = entity_list.GetClientByName(s->ownername); if (client) { - client->Message_StringID(Chat::White, s->message_string_id); + client->MessageString(Chat::White, s->message_string_id); } break; } @@ -1729,7 +1729,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) if (c) { c->ClearPendingAdventureDoorClick(); - c->Message_StringID(Chat::Red, 5141); + c->MessageString(Chat::Red, 5141); } break; } diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 869ef4eb4..5950d4025 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -723,7 +723,7 @@ void Client::Gate(uint8 bindnum) { } void NPC::Gate(uint8 bindnum) { - entity_list.MessageClose_StringID(this, true, RuleI(Range, SpellMessages), Chat::Spells, GATES, GetCleanName()); + entity_list.MessageCloseString(this, true, RuleI(Range, SpellMessages), Chat::Spells, GATES, GetCleanName()); Mob::Gate(bindnum); } From a28ea6419fe32d6acb2e8485f9d2355ce27aa29b Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 00:14:34 -0500 Subject: [PATCH 148/491] Beginning of #npceditmass --- zone/command.cpp | 842 +++++++++++++++++++++++++++-------------------- zone/command.h | 1 + 2 files changed, 478 insertions(+), 365 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index d95f07e8a..cf6cc6d6b 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef _WINDOWS #define strcasecmp _stricmp @@ -105,7 +106,7 @@ LinkedList cleanup_commandlist; */ int command_notavail(Client *c, const char *message) { - c->Message(13, "Commands not available."); + c->Message(Chat::Red, "Commands not available."); return -1; } @@ -151,7 +152,7 @@ Access Levels: int command_init(void) { commandaliases.clear(); - + if ( command_add("acceptrules", "[acceptrules] - Accept the EQEmu Agreement", 0, command_acceptrules) || command_add("advnpcspawn", "[maketype|makegroup|addgroupentry|addgroupspawn][removegroupspawn|movespawn|editgroupbox|cleargroupbox]", 150, command_advnpcspawn) || @@ -282,6 +283,7 @@ int command_init(void) command_add("network", "- Admin commands for the udp network interface.", 250, command_network) || command_add("npccast", "[targetname/entityid] [spellid] - Causes NPC target to cast spellid on targetname/entityid", 80, command_npccast) || command_add("npcedit", "[column] [value] - Mega NPC editing command", 100, command_npcedit) || + command_add("npceditmass", "[name-search] [column] [value] - Mass (Zone wide) NPC data editing command", 100, command_npceditmass) || command_add("npcemote", "[message] - Make your NPC target emote a message.", 150, command_npcemote) || command_add("npcloot", "[show/money/add/remove] [itemid/all/money: pp gp sp cp] - Manipulate the loot an NPC is carrying", 80, command_npcloot) || command_add("npcsay", "[message] - Make your NPC target say a message.", 150, command_npcsay) || @@ -445,7 +447,7 @@ int command_init(void) command_deinit(); return -1; } - + std::map>> command_settings; database.GetCommandSettings(command_settings); @@ -572,7 +574,7 @@ int command_realdispatch(Client *c, const char *message) CommandRecord *cur = commandlist[cstr]; if(c->Admin() < cur->access){ - c->Message(13,"Your access level is not high enough to use this command."); + c->Message(Chat::Red,"Your access level is not high enough to use this command."); return(-1); } @@ -691,7 +693,7 @@ void command_incstat(Client* c, const Seperator* sep){ void command_resetaa(Client* c,const Seperator *sep) { if(c->GetTarget() && c->GetTarget()->IsClient()){ c->GetTarget()->CastToClient()->ResetAA(); - c->Message(13,"Successfully reset %s's AAs", c->GetTarget()->GetName()); + c->Message(Chat::Red,"Successfully reset %s's AAs", c->GetTarget()->GetName()); } else c->Message(0,"Usage: Target a client and use #resetaa to reset the AA data in their Profile."); @@ -739,7 +741,7 @@ void command_setfaction(Client *c, const Seperator *sep) } auto npcTypeID = c->GetTarget()->CastToNPC()->GetNPCTypeID(); - c->Message(15,"Setting NPC %u to faction %i", npcTypeID, atoi(sep->argplus[1])); + c->Message(Chat::Yellow,"Setting NPC %u to faction %i", npcTypeID, atoi(sep->argplus[1])); std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i", atoi(sep->argplus[1]), npcTypeID); @@ -763,7 +765,7 @@ void command_wc(Client *c, const Seperator *sep) ); } else if (c->GetTarget() == nullptr) { - c->Message(13, "You must have a target to do a wear change."); + c->Message(Chat::Red, "You must have a target to do a wear change."); } else { uint32 hero_forge_model = 0; @@ -802,7 +804,7 @@ void command_heromodel(Client *c, const Seperator *sep) c->Message(0, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)"); } else if (c->GetTarget() == nullptr) { - c->Message(13, "You must have a target to do a wear change for Hero's Forge Models."); + c->Message(Chat::Red, "You must have a target to do a wear change for Hero's Forge Models."); } else { uint32 hero_forge_model = atoi(sep->arg[1]); @@ -823,7 +825,7 @@ void command_heromodel(Client *c, const Seperator *sep) } } else { - c->Message(13, "Hero's Forge Model must be greater than 0."); + c->Message(Chat::Red, "Hero's Forge Model must be greater than 0."); } } } @@ -1192,7 +1194,7 @@ void command_peqzone(Client *c, const Seperator *sep) uint32 timeleft = c->GetPTimers().GetRemainingTime(pTimerPeqzoneReuse)/60; if(!c->GetPTimers().Expired(&database, pTimerPeqzoneReuse, false)) { - c->Message(13,"You must wait %i minute(s) before using this ability again.", timeleft); + c->Message(Chat::Red,"You must wait %i minute(s) before using this ability again.", timeleft); return; } @@ -1221,11 +1223,11 @@ void command_peqzone(Client *c, const Seperator *sep) zoneid = atoi(sep->arg[1]); destzone = database.GetPEQZone(zoneid, 0); if(destzone == 0){ - c->Message(13, "You cannot use this command to enter that zone!"); + c->Message(Chat::Red, "You cannot use this command to enter that zone!"); return; } if(zoneid == zone->GetZoneID()) { - c->Message(13, "You cannot use this command on the zone you are in!"); + c->Message(Chat::Red, "You cannot use this command on the zone you are in!"); return; } } @@ -1243,11 +1245,11 @@ void command_peqzone(Client *c, const Seperator *sep) return; } if(destzone == 0){ - c->Message(13, "You cannot use this command to enter that zone!"); + c->Message(Chat::Red, "You cannot use this command to enter that zone!"); return; } if(zoneid == zone->GetZoneID()) { - c->Message(13, "You cannot use this command on the zone you are in!"); + c->Message(Chat::Red, "You cannot use this command on the zone you are in!"); return; } } @@ -1279,7 +1281,7 @@ void command_movechar(Client *c, const Seperator *sep) else c->Message(0, "Character has been moved."); else - c->Message(13,"You cannot move characters that are not on your account."); + c->Message(Chat::Red,"You cannot move characters that are not on your account."); } else c->Message(0, "Character Does Not Exist"); @@ -1365,7 +1367,7 @@ void command_viewpetition(Client *c, const Seperator *sep) return; } - c->Message(13," ID : Character Name , Petition Text"); + c->Message(Chat::Red," ID : Character Name , Petition Text"); std::string query = "SELECT petid, charname, petitiontext FROM petitions ORDER BY petid"; auto results = database.QueryDatabase(query); @@ -1375,13 +1377,13 @@ void command_viewpetition(Client *c, const Seperator *sep) Log(Logs::General, Logs::Normal, "View petition request from %s, petition number: %i", c->GetName(), atoi(sep->argplus[1]) ); if (results.RowCount() == 0) { - c->Message(13,"There was an error in your request: ID not found! Please check the Id and try again."); + c->Message(Chat::Red,"There was an error in your request: ID not found! Please check the Id and try again."); return; } for (auto row = results.begin(); row != results.end(); ++row) if (strcasecmp(row[0], sep->argplus[1]) == 0) - c->Message(15, " %s: %s , %s ", row[0], row[1], row[2]); + c->Message(Chat::Yellow, " %s: %s , %s ", row[0], row[1], row[2]); } @@ -1400,13 +1402,13 @@ void command_petitioninfo(Client *c, const Seperator *sep) Log(Logs::General, Logs::Normal, "Petition information request from %s, petition number:", c->GetName(), atoi(sep->argplus[1]) ); if (results.RowCount() == 0) { - c->Message(13,"There was an error in your request: ID not found! Please check the Id and try again."); + c->Message(Chat::Red,"There was an error in your request: ID not found! Please check the Id and try again."); return; } for (auto row = results.begin(); row != results.end(); ++row) if (strcasecmp(row[0],sep->argplus[1])== 0) - c->Message(13," ID : %s Character Name: %s Account Name: %s Zone: %s Character Class: %s Character Race: %s Character Level: %s", row[0],row[1],row[2],row[3],row[4],row[5],row[6]); + c->Message(Chat::Red," ID : %s Character Name: %s Account Name: %s Zone: %s Character Class: %s Character Race: %s Character Level: %s", row[0],row[1],row[2],row[3],row[4],row[5],row[6]); } @@ -1417,7 +1419,7 @@ void command_delpetition(Client *c, const Seperator *sep) return; } - c->Message(13,"Attempting to delete petition number: %i", atoi(sep->argplus[1])); + c->Message(Chat::Red,"Attempting to delete petition number: %i", atoi(sep->argplus[1])); std::string query = StringFormat("DELETE FROM petitions WHERE petid = %i", atoi(sep->argplus[1])); auto results = database.QueryDatabase(query); if (!results.Success()) @@ -1696,7 +1698,7 @@ void command_date(Client *c, const Seperator *sep) { //yyyy mm dd hh mm local if(sep->arg[3][0]==0 || !sep->IsNumber(1) || !sep->IsNumber(2) || !sep->IsNumber(3)) { - c->Message(13, "Usage: #date yyyy mm dd [HH MM]"); + c->Message(Chat::Red, "Usage: #date yyyy mm dd [HH MM]"); } else { int h=0, m=0; @@ -1710,7 +1712,7 @@ void command_date(Client *c, const Seperator *sep) m=eqTime.minute; else m=atoi(sep->arg[5]); - c->Message(13, "Setting world time to %s-%s-%s %i:%i...", sep->arg[1], sep->arg[2], sep->arg[3], h, m); + c->Message(Chat::Red, "Setting world time to %s-%s-%s %i:%i...", sep->arg[1], sep->arg[2], sep->arg[3], h, m); zone->SetDate(atoi(sep->arg[1]), atoi(sep->arg[2]), atoi(sep->arg[3]), h, m); } } @@ -1718,15 +1720,15 @@ void command_date(Client *c, const Seperator *sep) void command_timezone(Client *c, const Seperator *sep) { if(sep->arg[1][0]==0 && !sep->IsNumber(1)) { - c->Message(13, "Usage: #timezone HH [MM]"); - c->Message(13, "Current timezone is: %ih %im", zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneMin()); + c->Message(Chat::Red, "Usage: #timezone HH [MM]"); + c->Message(Chat::Red, "Current timezone is: %ih %im", zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneMin()); } else { uint8 hours = atoi(sep->arg[1]); uint8 minutes = atoi(sep->arg[2]); if(!sep->IsNumber(2)) minutes = 0; - c->Message(13, "Setting timezone to %i h %i m", hours, minutes); + c->Message(Chat::Red, "Setting timezone to %i h %i m", hours, minutes); uint32 ntz=(hours*60)+minutes; zone->zone_time.setEQTimeZone(ntz); database.SetZoneTZ(zone->GetZoneID(), zone->GetInstanceVersion(), ntz); @@ -1765,7 +1767,7 @@ void command_hideme(Client *c, const Seperator *sep) else { c->SetHideMe(state); - c->Message_StringID(MT_Broadcasts, c->GetHideMe() ? NOW_INVISIBLE : NOW_VISIBLE, c->GetName()); + c->MessageString(Chat::Broadcasts, c->GetHideMe() ? NOW_INVISIBLE : NOW_VISIBLE, c->GetName()); } } @@ -2109,7 +2111,7 @@ void command_itemtest(Client *c, const Seperator *sep) //Using this to determine new item layout FILE* f = nullptr; if (!(f = fopen("c:\\EQEMUcvs\\ItemDump.txt", "rb"))) { - c->Message(13, "Error: Could not open c:\\EQEMUcvs\\ItemDump.txt"); + c->Message(Chat::Red, "Error: Could not open c:\\EQEMUcvs\\ItemDump.txt"); return; } @@ -2283,10 +2285,10 @@ void command_sendzonespawns(Client *c, const Seperator *sep) void command_zsave(Client *c, const Seperator *sep) { if (zone->SaveZoneCFG()) { - c->Message(13, "Zone header saved successfully."); + c->Message(Chat::Red, "Zone header saved successfully."); } else { - c->Message(13, "ERROR: Zone header data was NOT saved."); + c->Message(Chat::Red, "ERROR: Zone header data was NOT saved."); } } @@ -2625,7 +2627,7 @@ void command_castspell(Client *c, const Seperator *sep) ((spellid >= 1342) && (spellid <= 1348)) || (spellid == 1923) || (spellid == 1924) || (spellid == 3355)) && c->Admin() < commandCastSpecials) - c->Message(13, "Unable to cast spell."); + c->Message(Chat::Red, "Unable to cast spell."); else if (spellid >= SPDAT_RECORDS) c->Message(0, "Error: #CastSpell: Argument out of range"); else @@ -2846,7 +2848,7 @@ void command_spawn(Client *c, const Seperator *sep) void command_test(Client *c, const Seperator *sep) { - c->Message(15, "Triggering test command"); + c->Message(Chat::Yellow, "Triggering test command"); if (sep->arg[1]) { c->SetPrimaryWeaponOrnamentation(atoi(sep->arg[1])); @@ -3297,8 +3299,8 @@ void command_interrogateinv(Client *c, const Seperator *sep) if (c->Admin() < commandInterrogateInv) { if (c->GetInterrogateInvState()) { - c->Message(13, "The last use of #interrogateinv on this inventory instance discovered an error..."); - c->Message(13, "Logging out, zoning or re-arranging items at this point will result in item loss!"); + c->Message(Chat::Red, "The last use of #interrogateinv on this inventory instance discovered an error..."); + c->Message(Chat::Red, "Logging out, zoning or re-arranging items at this point will result in item loss!"); return; } target = c; @@ -3325,7 +3327,7 @@ void command_interrogateinv(Client *c, const Seperator *sep) bool success = target->InterrogateInventory(c, log, silent, allowtrip, error); if (!success) - c->Message(13, "An unknown error occurred while processing Client::InterrogateInventory()"); + c->Message(Chat::Red, "An unknown error occurred while processing Client::InterrogateInventory()"); } void command_invsnapshot(Client *c, const Seperator *sep) @@ -3353,7 +3355,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) "" "takes snapshot of character inventory" ""; - + if (c->Admin() >= commandInvSnapshot) window_text.append( "" @@ -3543,7 +3545,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) std::string window_title = StringFormat("Snapshot Parse for %s @ %u", tc->GetName(), timestamp); std::string window_text = "Slot: ItemID - Description
"; - + for (auto iter : parse_list) { auto item_data = database.GetItem(iter.second); std::string window_line = StringFormat("%i: %u - %s
", iter.first, iter.second, (item_data ? item_data->Name : "[error]")); @@ -3569,7 +3571,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) } uint32 timestamp = atoul(sep->arg[2]); - + if (!database.ValidateCharacterInvSnapshotTimestamp(tc->CharacterID(), timestamp)) { c->Message(0, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); return; @@ -3584,7 +3586,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) std::string window_title = StringFormat("Snapshot Comparison for %s @ %u", tc->GetName(), timestamp); std::string window_text = "Slot: (action) Snapshot -> Inventory
"; - + auto inv_iter = inv_compare_list.begin(); auto iss_iter = iss_compare_list.begin(); @@ -3649,7 +3651,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) tc->SetNextInvSnapshot(RuleI(Character, InvSnapshotMinIntervalM)); } else { - c->Message(13, "Failed to take pre-restore inventory snapshot of %s (id: %u).", + c->Message(Chat::Red, "Failed to take pre-restore inventory snapshot of %s (id: %u).", tc->GetName(), tc->CharacterID()); return; } @@ -3662,10 +3664,10 @@ void command_invsnapshot(Client *c, const Seperator *sep) timestamp, tc->GetName(), tc->CharacterID()); } else { - c->Message(13, "Failed to apply snapshot %u to %s's (id: %u) inventory.", + c->Message(Chat::Red, "Failed to apply snapshot %u to %s's (id: %u) inventory.", timestamp, tc->GetName(), tc->CharacterID()); } - + return; } } @@ -3824,7 +3826,7 @@ void command_reloadworld(Client *c, const Seperator *sep) void command_reloadmerchants(Client *c, const Seperator *sep) { entity_list.ReloadMerchants(); - c->Message(15, "Reloading merchants."); + c->Message(Chat::Yellow, "Reloading merchants."); } void command_reloadlevelmods(Client *c, const Seperator *sep) @@ -3833,9 +3835,9 @@ void command_reloadlevelmods(Client *c, const Seperator *sep) { if(RuleB(Zone, LevelBasedEXPMods)){ zone->LoadLevelEXPMods(); - c->Message(15, "Level based EXP Mods have been reloaded zonewide"); + c->Message(Chat::Yellow, "Level based EXP Mods have been reloaded zonewide"); }else{ - c->Message(15, "Level based EXP Mods are disabled in rules!"); + c->Message(Chat::Yellow, "Level based EXP Mods are disabled in rules!"); } } } @@ -3968,10 +3970,10 @@ void command_listpetition(Client *c, const Seperator *sep) if (results.RowCount() == 0) return; - c->Message(13," ID : Character Name , Account Name"); + c->Message(Chat::Red," ID : Character Name , Account Name"); for (auto row = results.begin(); row != results.end(); ++row) - c->Message(15, " %s: %s , %s ", row[0],row[1],row[2]); + c->Message(Chat::Yellow, " %s: %s , %s ", row[0],row[1],row[2]); } void command_equipitem(Client *c, const Seperator *sep) @@ -4007,7 +4009,7 @@ void command_equipitem(Client *c, const Seperator *sep) if (partialmove) { // remove this con check if someone can figure out removing charges from cursor stack issue below // mi->number_in_stack is always from_inst->GetCharges() when partialmove is false - c->Message(13, "Error: Partial stack added to existing stack exceeds allowable stacksize"); + c->Message(Chat::Red, "Error: Partial stack added to existing stack exceeds allowable stacksize"); safe_delete(outapp); return; } @@ -4035,16 +4037,16 @@ void command_equipitem(Client *c, const Seperator *sep) //} } else { - c->Message(13, "Error: Unable to equip current item"); + c->Message(Chat::Red, "Error: Unable to equip current item"); } safe_delete(outapp); // also send out a wear change packet? } else if (from_inst == nullptr) - c->Message(13, "Error: There is no item on your cursor"); + c->Message(Chat::Red, "Error: There is no item on your cursor"); else - c->Message(13, "Error: Item on your cursor cannot be equipped"); + c->Message(Chat::Red, "Error: Item on your cursor cannot be equipped"); } else c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position"); @@ -4482,7 +4484,7 @@ void command_gmzone(Client *c, const Seperator *sep) uint16 instance_id = 0; if (zone_id == 0) { - c->Message(13, "Invalid zone specified"); + c->Message(Chat::Red, "Invalid zone specified"); return; } @@ -4496,21 +4498,21 @@ void command_gmzone(Client *c, const Seperator *sep) if (existing_zone_instance.length() > 0) { instance_id = std::stoi(existing_zone_instance); - c->Message(15, "Found already created instance (%s) (%u)", zone_short_name, instance_id); + c->Message(Chat::Yellow, "Found already created instance (%s) (%u)", zone_short_name, instance_id); } if (instance_id == 0) { if (!database.GetUnusedInstanceID(instance_id)) { - c->Message(13, "Server was unable to find a free instance id."); + c->Message(Chat::Red, "Server was unable to find a free instance id."); return; } if (!database.CreateInstance(instance_id, zone_id, zone_version, duration)) { - c->Message(13, "Server was unable to create a new instance."); + c->Message(Chat::Red, "Server was unable to create a new instance."); return; } - c->Message(15, "New private GM instance %s was created with id %lu.", zone_short_name, (unsigned long) instance_id); + c->Message(Chat::Yellow, "New private GM instance %s was created with id %lu.", zone_short_name, (unsigned long) instance_id); DataBucket::SetData(bucket_key, std::to_string(instance_id)); } @@ -4528,10 +4530,10 @@ void command_gmzone(Client *c, const Seperator *sep) &min_status, &min_level )) { - c->Message(13, "Failed to find safe coordinates for specified zone"); + c->Message(Chat::Red, "Failed to find safe coordinates for specified zone"); } - c->Message(15, "Zoning to private GM instance (%s) (%u)", zone_short_name, instance_id); + c->Message(Chat::Yellow, "Zoning to private GM instance (%s) (%u)", zone_short_name, instance_id); c->AssignToInstance(instance_id); c->MovePC(zone_id, instance_id, target_x, target_y, target_z, 0, 1); @@ -4549,13 +4551,13 @@ void command_title(Client *c, const Seperator *sep) if(!target_mob) target_mob = c; if(!target_mob->IsClient()) { - c->Message(13, "#title only works on players."); + c->Message(Chat::Red, "#title only works on players."); return; } Client *t = target_mob->CastToClient(); if(strlen(sep->arg[1]) > 31) { - c->Message(13, "Title must be 31 characters or less."); + c->Message(Chat::Red, "Title must be 31 characters or less."); return; } @@ -4576,13 +4578,13 @@ void command_title(Client *c, const Seperator *sep) t->Save(); if(removed) { - c->Message(13, "%s's title has been removed.", t->GetName(), sep->arg[1]); + c->Message(Chat::Red, "%s's title has been removed.", t->GetName(), sep->arg[1]); if(t != c) - t->Message(13, "Your title has been removed.", sep->arg[1]); + t->Message(Chat::Red, "Your title has been removed.", sep->arg[1]); } else { - c->Message(13, "%s's title has been changed to '%s'.", t->GetName(), sep->arg[1]); + c->Message(Chat::Red, "%s's title has been changed to '%s'.", t->GetName(), sep->arg[1]); if(t != c) - t->Message(13, "Your title has been changed to '%s'.", sep->arg[1]); + t->Message(Chat::Red, "Your title has been changed to '%s'.", sep->arg[1]); } } } @@ -4599,13 +4601,13 @@ void command_titlesuffix(Client *c, const Seperator *sep) if(!target_mob) target_mob = c; if(!target_mob->IsClient()) { - c->Message(13, "#titlesuffix only works on players."); + c->Message(Chat::Red, "#titlesuffix only works on players."); return; } Client *t = target_mob->CastToClient(); if(strlen(sep->arg[1]) > 31) { - c->Message(13, "Title suffix must be 31 characters or less."); + c->Message(Chat::Red, "Title suffix must be 31 characters or less."); return; } @@ -4627,13 +4629,13 @@ void command_titlesuffix(Client *c, const Seperator *sep) t->Save(); if(removed) { - c->Message(13, "%s's title suffix has been removed.", t->GetName(), sep->arg[1]); + c->Message(Chat::Red, "%s's title suffix has been removed.", t->GetName(), sep->arg[1]); if(t != c) - t->Message(13, "Your title suffix has been removed.", sep->arg[1]); + t->Message(Chat::Red, "Your title suffix has been removed.", sep->arg[1]); } else { - c->Message(13, "%s's title suffix has been changed to '%s'.", t->GetName(), sep->arg[1]); + c->Message(Chat::Red, "%s's title suffix has been changed to '%s'.", t->GetName(), sep->arg[1]); if(t != c) - t->Message(13, "Your title suffix has been changed to '%s'.", sep->arg[1]); + t->Message(Chat::Red, "Your title suffix has been changed to '%s'.", sep->arg[1]); } } } @@ -5190,7 +5192,7 @@ void command_name(Client *c, const Seperator *sep) target->Kick("Name was changed"); } else - c->Message(13, "ERROR: Unable to rename %s. Check that the new name '%s' isn't already taken.", oldname, sep->arg[2]); + c->Message(Chat::Red, "ERROR: Unable to rename %s. Check that the new name '%s' isn't already taken.", oldname, sep->arg[2]); free(oldname); } } @@ -5295,7 +5297,7 @@ void command_killallnpcs(Client *c, const Seperator *sep) count++; } - c->Message(15, "Killed (%i) npc(s)", count); + c->Message(Chat::Yellow, "Killed (%i) npc(s)", count); } void command_haste(Client *c, const Seperator *sep) @@ -5437,8 +5439,8 @@ void command_spawnfix(Client *c, const Seperator *sep) { c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(13, "Update failed! MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -5488,13 +5490,13 @@ void command_goto(Client *c, const Seperator *sep) client->GetZ(), client->GetHeading()); - c->Message(15, "Goto player '%s' same zone", player_name_string.c_str()); + c->Message(Chat::Yellow, "Goto player '%s' same zone", player_name_string.c_str()); } else if (c->GotoPlayer(player_name_string)) { - c->Message(15, "Goto player '%s' different zone", player_name_string.c_str()); + c->Message(Chat::Yellow, "Goto player '%s' different zone", player_name_string.c_str()); } else { - c->Message(15, "Player '%s' not found", player_name_string.c_str()); + c->Message(Chat::Yellow, "Player '%s' not found", player_name_string.c_str()); } } @@ -5520,13 +5522,13 @@ void command_iteminfo(Client *c, const Seperator *sep) { auto inst = c->GetInv()[EQEmu::invslot::slotCursor]; if (!inst) { - c->Message(13, "Error: You need an item on your cursor for this command"); + c->Message(Chat::Red, "Error: You need an item on your cursor for this command"); return; } auto item = inst->GetItem(); if (!item) { Log(Logs::General, Logs::Inventory, "(%s) Command #iteminfo processed an item with no data pointer"); - c->Message(13, "Error: This item has no data reference"); + c->Message(Chat::Red, "Error: This item has no data reference"); return; } @@ -5628,12 +5630,12 @@ void command_time(Client *c, const Seperator *sep) if(sep->IsNumber(2)) { minutes=atoi(sep->arg[2]); } - c->Message(13, "Setting world time to %s:%i (Timezone: 0)...", sep->arg[1], minutes); + c->Message(Chat::Red, "Setting world time to %s:%i (Timezone: 0)...", sep->arg[1], minutes); zone->SetTime(atoi(sep->arg[1])+1, minutes); Log(Logs::General, Logs::Zone_Server, "%s :: Setting world time to %s:%i (Timezone: 0)...", c->GetCleanName(), sep->arg[1], minutes); } else { - c->Message(13, "To set the Time: #time HH [MM]"); + c->Message(Chat::Red, "To set the Time: #time HH [MM]"); TimeOfDay_Struct eqTime; zone->zone_time.GetCurrentEQTimeOfDay( time(0), &eqTime); sprintf(timeMessage,"%02d:%s%d %s (Timezone: %ih %im)", @@ -5644,7 +5646,7 @@ void command_time(Client *c, const Seperator *sep) zone->zone_time.getEQTimeZoneHr(), zone->zone_time.getEQTimeZoneMin() ); - c->Message(13, "It is now %s.", timeMessage); + c->Message(Chat::Red, "It is now %s.", timeMessage); Log(Logs::General, Logs::Zone_Server, "Current Time is: %s", timeMessage); } } @@ -5762,19 +5764,19 @@ void command_guild(Client *c, const Seperator *sep) if(guild_id == 0) guild_id = GUILD_NONE; else if(!guild_mgr.GuildExists(guild_id)) { - c->Message(13, "Guild %d does not exist.", guild_id); + c->Message(Chat::Red, "Guild %d does not exist.", guild_id); return; } uint32 charid = database.GetCharacterID(sep->arg[2]); if(charid == 0) { - c->Message(13, "Unable to find character '%s'", charid); + c->Message(Chat::Red, "Unable to find character '%s'", charid); return; } //we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now if(admin < minStatusToEditOtherGuilds) { - c->Message(13, "Access denied."); + c->Message(Chat::Red, "Access denied."); return; } @@ -5788,7 +5790,7 @@ void command_guild(Client *c, const Seperator *sep) } if(!guild_mgr.SetGuild(charid, guild_id, GUILD_MEMBER)) { - c->Message(13, "Error putting '%s' into guild %d", sep->arg[2], guild_id); + c->Message(Chat::Red, "Error putting '%s' into guild %d", sep->arg[2], guild_id); } else { c->Message(0, "%s has been put into guild %d", sep->arg[2], guild_id); } @@ -5821,13 +5823,13 @@ void command_guild(Client *c, const Seperator *sep) else { uint32 charid = database.GetCharacterID(sep->arg[2]); if(charid == 0) { - c->Message(13, "Unable to find character '%s'", charid); + c->Message(Chat::Red, "Unable to find character '%s'", charid); return; } //we could do the checking we need for guild_mgr.CheckGMStatus, but im lazy right now if(admin < minStatusToEditOtherGuilds) { - c->Message(13, "Access denied."); + c->Message(Chat::Red, "Access denied."); return; } @@ -5835,7 +5837,7 @@ void command_guild(Client *c, const Seperator *sep) sep->arg[2], charid, rank); if(!guild_mgr.SetGuildRank(charid, rank)) - c->Message(13, "Error while setting rank %d on '%s'.", rank, sep->arg[2]); + c->Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, sep->arg[2]); else c->Message(0, "%s has been set to rank %d", sep->arg[2], rank); } @@ -5852,7 +5854,7 @@ void command_guild(Client *c, const Seperator *sep) } else if((leader=database.GetCharacterID(sep->arg[2])) != 0) { //got it from the db.. } else { - c->Message(13, "Unable to find char '%s'", sep->arg[2]); + c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]); return; } if (leader == 0) { @@ -5867,7 +5869,7 @@ void command_guild(Client *c, const Seperator *sep) else { if(admin < minStatusToEditOtherGuilds) { - c->Message(13, "Access denied."); + c->Message(Chat::Red, "Access denied."); return; } @@ -5904,10 +5906,10 @@ void command_guild(Client *c, const Seperator *sep) if(admin < minStatusToEditOtherGuilds) { //this person is not allowed to just edit any guild, check this guild's min status. if(c->GuildID() != id) { - c->Message(13, "Access denied to edit other people's guilds"); + c->Message(Chat::Red, "Access denied to edit other people's guilds"); return; } else if(!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(13, "Access denied to edit your guild with GM commands."); + c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); return; } } @@ -5938,10 +5940,10 @@ void command_guild(Client *c, const Seperator *sep) if(admin < minStatusToEditOtherGuilds) { //this person is not allowed to just edit any guild, check this guild's min status. if(c->GuildID() != id) { - c->Message(13, "Access denied to edit other people's guilds"); + c->Message(Chat::Red, "Access denied to edit other people's guilds"); return; } else if(!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(13, "Access denied to edit your guild with GM commands."); + c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); return; } } @@ -5968,7 +5970,7 @@ void command_guild(Client *c, const Seperator *sep) } else if((leader=database.GetCharacterID(sep->arg[2])) != 0) { //got it from the db.. } else { - c->Message(13, "Unable to find char '%s'", sep->arg[2]); + c->Message(Chat::Red, "Unable to find char '%s'", sep->arg[2]); return; } @@ -5989,10 +5991,10 @@ void command_guild(Client *c, const Seperator *sep) if(admin < minStatusToEditOtherGuilds) { //this person is not allowed to just edit any guild, check this guild's min status. if(c->GuildID() != id) { - c->Message(13, "Access denied to edit other people's guilds"); + c->Message(Chat::Red, "Access denied to edit other people's guilds"); return; } else if(!guild_mgr.CheckGMStatus(id, admin)) { - c->Message(13, "Access denied to edit your guild with GM commands."); + c->Message(Chat::Red, "Access denied to edit your guild with GM commands."); return; } } @@ -6010,7 +6012,7 @@ void command_guild(Client *c, const Seperator *sep) } else if (strcasecmp(sep->arg[1], "list") == 0) { if(admin < minStatusToEditOtherGuilds) { - c->Message(13, "Access denied."); + c->Message(Chat::Red, "Access denied."); return; } guild_mgr.ListGuilds(c); @@ -6150,7 +6152,7 @@ void command_findaliases(Client *c, const Seperator *sep) auto find_iter = commandaliases.find(sep->arg[1]); if (find_iter == commandaliases.end()) { - c->Message(15, "No commands or aliases match '%s'", sep->arg[1]); + c->Message(Chat::Yellow, "No commands or aliases match '%s'", sep->arg[1]); return; } @@ -6478,14 +6480,14 @@ void command_scribespells(Client *c, const Seperator *sep) break; } if (spell_id < 0 || spell_id >= SPDAT_RECORDS) { - c->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); + c->Message(Chat::Red, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); return; } if (book_slot < 0 || book_slot >= EQEmu::spells::SPELLBOOK_SIZE) { - c->Message(13, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE); + c->Message(Chat::Red, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE); return; } - + while (true) { if (spells[spell_id].classes[WARRIOR] == 0) // check if spell exists break; @@ -6498,7 +6500,7 @@ void command_scribespells(Client *c, const Seperator *sep) uint16 spell_id_ = (uint16)spell_id; if ((spell_id_ != spell_id) || (spell_id != spell_id_)) { - c->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); + c->Message(Chat::Red, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); return; } @@ -6554,17 +6556,17 @@ void command_scribespell(Client *c, const Seperator *sep) { if(book_slot >= 0 && t->FindSpellBookSlotBySpellID(spell_id) < 0) t->ScribeSpell(spell_id, book_slot); else { - t->Message(13, "Unable to scribe spell: %s (%i) to your spellbook.", spells[spell_id].name, spell_id); + t->Message(Chat::Red, "Unable to scribe spell: %s (%i) to your spellbook.", spells[spell_id].name, spell_id); if(t != c) - c->Message(13, "Unable to scribe spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); + c->Message(Chat::Red, "Unable to scribe spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); } } else - c->Message(13, "Your target can not scribe this spell."); + c->Message(Chat::Red, "Your target can not scribe this spell."); } else - c->Message(13, "Spell ID: %i is an unknown spell and cannot be scribed.", spell_id); + c->Message(Chat::Red, "Spell ID: %i is an unknown spell and cannot be scribed.", spell_id); } void command_unscribespell(Client *c, const Seperator *sep) { @@ -6596,10 +6598,10 @@ void command_unscribespell(Client *c, const Seperator *sep) { Log(Logs::General, Logs::Normal, "Unscribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); } else { - t->Message(13, "Unable to unscribe spell: %s (%i) from your spellbook. This spell is not scribed.", spells[spell_id].name, spell_id); + t->Message(Chat::Red, "Unable to unscribe spell: %s (%i) from your spellbook. This spell is not scribed.", spells[spell_id].name, spell_id); if(t != c) - c->Message(13, "Unable to unscribe spell: %s (%i) for %s due to spell not scribed.", spells[spell_id].name, spell_id, t->GetName()); + c->Message(Chat::Red, "Unable to unscribe spell: %s (%i) for %s due to spell not scribed.", spells[spell_id].name, spell_id, t->GetName()); } } } @@ -6618,7 +6620,7 @@ void command_untraindisc(Client *c, const Seperator *sep) { Client *t = c; if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) t = c->GetTarget()->CastToClient(); - + for (int i = 0; i < MAX_PP_DISCIPLINES; i++) { if (t->GetPP().disciplines.values[i] == atoi(sep->arg[1])) { t->UntrainDisc(i, 1); @@ -6631,7 +6633,7 @@ void command_untraindiscs(Client *c, const Seperator *sep) { Client *t = c; if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) t = c->GetTarget()->CastToClient(); - + t->UntrainDiscAll(); } @@ -6734,7 +6736,7 @@ void command_summonitem(Client *c, const Seperator *sep) } if (item_status > c->Admin()) - c->Message(13, "Error: Insufficient status to summon this item."); + c->Message(Chat::Red, "Error: Insufficient status to summon this item."); else if (sep->argnum == 2 && sep->IsNumber(2)) c->SummonItem(itemid, atoi(sep->arg[2])); else if (sep->argnum == 3) @@ -6752,17 +6754,17 @@ void command_summonitem(Client *c, const Seperator *sep) else { c->SummonItem(itemid); } - + } void command_giveitem(Client *c, const Seperator *sep) { if (!sep->IsNumber(1)) { - c->Message(13, "Usage: #summonitem [item id] [charges], charges are optional"); + c->Message(Chat::Red, "Usage: #summonitem [item id] [charges], charges are optional"); } else if(c->GetTarget() == nullptr) { - c->Message(13, "You must target a client to give the item to."); + c->Message(Chat::Red, "You must target a client to give the item to."); } else if(!c->GetTarget()->IsClient()) { - c->Message(13, "You can only give items to players with this command."); + c->Message(Chat::Red, "You can only give items to players with this command."); } else { Client *t = c->GetTarget()->CastToClient(); uint32 itemid = atoi(sep->arg[1]); @@ -6773,7 +6775,7 @@ void command_giveitem(Client *c, const Seperator *sep) } if (item_status > c->Admin()) - c->Message(13, "Error: Insufficient status to summon this item."); + c->Message(Chat::Red, "Error: Insufficient status to summon this item."); else if (sep->argnum==2 && sep->IsNumber(2)) t->SummonItem(itemid, atoi(sep->arg[2])); else if (sep->argnum==3) @@ -6797,13 +6799,13 @@ void command_giveitem(Client *c, const Seperator *sep) void command_givemoney(Client *c, const Seperator *sep) { if (!sep->IsNumber(1)) { //as long as the first one is a number, we'll just let atoi convert the rest to 0 or a number - c->Message(13, "Usage: #Usage: #givemoney [pp] [gp] [sp] [cp]"); + c->Message(Chat::Red, "Usage: #Usage: #givemoney [pp] [gp] [sp] [cp]"); } else if(c->GetTarget() == nullptr) { - c->Message(13, "You must target a player to give money to."); + c->Message(Chat::Red, "You must target a player to give money to."); } else if(!c->GetTarget()->IsClient()) { - c->Message(13, "You can only give money to players with this command."); + c->Message(Chat::Red, "You can only give money to players with this command."); } else { //TODO: update this to the client, otherwise the client doesn't show any weight change until you zone, move an item, etc @@ -6899,17 +6901,17 @@ void command_setaapts(Client *c, const Seperator *sep) else if(!strcasecmp(sep->arg[1], "group")) { t->GetPP().group_leadership_points = atoi(sep->arg[2]); t->GetPP().group_leadership_exp = 0; - t->Message(MT_Experience, "Setting Group AA points to %u", t->GetPP().group_leadership_points); + t->Message(Chat::Experience, "Setting Group AA points to %u", t->GetPP().group_leadership_points); t->SendLeadershipEXPUpdate(); } else if(!strcasecmp(sep->arg[1], "raid")) { t->GetPP().raid_leadership_points = atoi(sep->arg[2]); t->GetPP().raid_leadership_exp = 0; - t->Message(MT_Experience, "Setting Raid AA points to %u", t->GetPP().raid_leadership_points); + t->Message(Chat::Experience, "Setting Raid AA points to %u", t->GetPP().raid_leadership_points); t->SendLeadershipEXPUpdate(); } else { t->GetPP().aapoints = atoi(sep->arg[2]); t->GetPP().expAA = 0; - t->Message(MT_Experience, "Setting personal AA points to %u", t->GetPP().aapoints); + t->Message(Chat::Experience, "Setting personal AA points to %u", t->GetPP().aapoints); t->SendAlternateAdvancementStats(); } } @@ -6993,7 +6995,7 @@ if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { } if(account_id == 0) { - c->Message(13, "Character does not exist."); + c->Message(Chat::Red, "Character does not exist."); return; } @@ -7001,7 +7003,7 @@ if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { "WHERE id = %i", EscapeString(message).c_str(), account_id); auto results = database.QueryDatabase(query); - c->Message(13, "Account number %i with the character %s has been banned with message: \"%s\"", account_id, sep->arg[1], message.c_str()); + c->Message(Chat::Red, "Account number %i with the character %s has been banned with message: \"%s\"", account_id, sep->arg[1], message.c_str()); ServerPacket flagUpdatePack(ServerOP_FlagUpdate, 6); *((uint32*)&flagUpdatePack.pBuffer[0]) = account_id; @@ -7064,7 +7066,7 @@ void command_suspend(Client *c, const Seperator *sep) safe_delete_array(escName); if (accountID <= 0) { - c->Message(13,"Character does not exist."); + c->Message(Chat::Red,"Character does not exist."); return; } @@ -7074,9 +7076,9 @@ void command_suspend(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if(duration) - c->Message(13,"Account number %i with the character %s has been temporarily suspended for %i day(s).", accountID, sep->arg[1], duration); + c->Message(Chat::Red,"Account number %i with the character %s has been temporarily suspended for %i day(s).", accountID, sep->arg[1], duration); else - c->Message(13,"Account number %i with the character %s is no longer suspended.", accountID, sep->arg[1]); + c->Message(Chat::Red,"Account number %i with the character %s is no longer suspended.", accountID, sep->arg[1]); Client *bannedClient = entity_list.GetClientByName(sep->arg[1]); @@ -7120,7 +7122,7 @@ void command_revoke(Client *c, const Seperator *sep) uint32 characterID = database.GetAccountIDByChar(sep->arg[1]); if(characterID == 0) { - c->Message(13,"Character does not exist."); + c->Message(Chat::Red,"Character does not exist."); return; } @@ -7128,7 +7130,7 @@ void command_revoke(Client *c, const Seperator *sep) std::string query = StringFormat("UPDATE account SET revoked = %d WHERE id = %i", flag, characterID); auto results = database.QueryDatabase(query); - c->Message(13,"%s account number %i with the character %s.", flag? "Revoking": "Unrevoking", characterID, sep->arg[1]); + c->Message(Chat::Red,"%s account number %i with the character %s.", flag? "Revoking": "Unrevoking", characterID, sep->arg[1]); Client* revokee = entity_list.GetClientByAccID(characterID); if(revokee) { @@ -7137,7 +7139,7 @@ void command_revoke(Client *c, const Seperator *sep) return; } - c->Message(13, "#revoke: Couldn't find %s in this zone, passing request to worldserver.", sep->arg[1]); + c->Message(Chat::Red, "#revoke: Couldn't find %s in this zone, passing request to worldserver.", sep->arg[1]); auto outapp = new ServerPacket(ServerOP_Revoke, sizeof(RevokeStruct)); RevokeStruct *revoke = (RevokeStruct *)outapp->pBuffer; @@ -7254,6 +7256,115 @@ void command_npcemote(Client *c, const Seperator *sep) } } +void command_npceditmass(Client *c, const Seperator *sep) +{ + std::string query = SQL( + SELECT + COLUMN_NAME + FROM + INFORMATION_SCHEMA.COLUMNS + WHERE + table_name = 'npc_types' + AND + COLUMN_NAME != 'id' + ); + + std::string search_column, search_value, change_column, change_value; + if (sep->arg[1]) { + search_column = sep->arg[1]; + } + if (sep->arg[2]) { + search_value = sep->arg[2]; + } + if (sep->arg[3]) { + change_column = sep->arg[3]; + } + if (sep->arg[4]) { + change_value = sep->arg[4]; + } + + bool valid_change_column = false; + bool valid_search_column = false; + auto results = database.QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + if (row[0] == change_column) { + valid_change_column = true; + } + if (row[0] == search_column) { + valid_search_column = true; + } + } + + if (!valid_search_column) { + c->Message(Chat::Red, "You must specify a valid search column. [%s] is not valid", search_column.c_str()); + return; + } + + if (!valid_change_column) { + c->Message(Chat::Red, "You must specify a valid change column. [%s] is not valid", change_column.c_str()); + return; + } + + if (!valid_search_column || !valid_change_column) { + c->Message(Chat::Red, "One requested column is invalid"); + return; + } + + query = fmt::format( + SQL( + select + id, + name, + {0}, + {1} + from + npc_types + where + id IN( + select + spawnentry.npcID + from + spawnentry + join spawn2 on spawn2.spawngroupID = spawnentry.spawngroupID + where + spawn2.zone = '{2}' and spawn2.version = {3} + ) + ), + search_column, + change_column, + zone->GetShortName(), + zone->GetInstanceVersion() + ); + + results = database.QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + + std::string npc_id = row[0]; + std::string npc_name = row[1]; + std::string search_column_value = str_tolower(row[2]); + std::string change_column_current_value = row[3]; + + if (search_column_value.find(search_value) == std::string::npos) { + continue; + } + + c->Message( + 15, + fmt::format( + "NPC ({0}) [{1}] ({2}) [{3}] Current ({4}) [{5}] New [{6}]", + npc_id, + npc_name, + search_column, + search_column_value, + change_column, + change_column_current_value, + change_value + ).c_str() + ); + } +} + void command_npcedit(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { c->Message(0, "Error: Must have NPC targeted"); @@ -7348,497 +7459,497 @@ void command_npcedit(Client *c, const Seperator *sep) uint32 npcTypeID = c->GetTarget()->CastToNPC()->GetNPCTypeID(); if (strcasecmp(sep->arg[1], "name") == 0) { - c->Message(15,"NPCID %u now has the name %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has the name %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET name = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "lastname") == 0) { - c->Message(15,"NPCID %u now has the lastname %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has the lastname %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET lastname = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "flymode") == 0) { - c->Message(15,"NPCID %u now has flymode [%s]", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has flymode [%s]", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET flymode = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "race") == 0) { - c->Message(15,"NPCID %u now has the race %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has the race %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET race = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "class") == 0) { - c->Message(15,"NPCID %u is now class %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now class %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET class = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "bodytype") == 0) { - c->Message(15,"NPCID %u now has type %i bodytype.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has type %i bodytype.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET bodytype = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "hp") == 0) { - c->Message(15,"NPCID %u now has %i Hitpoints.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Hitpoints.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET hp = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "gender") == 0) { - c->Message(15,"NPCID %u is now gender %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now gender %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET gender = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "texture") == 0) { - c->Message(15,"NPCID %u now uses texture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses texture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET texture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "helmtexture") == 0) { - c->Message(15,"NPCID %u now uses helmtexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses helmtexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET helmtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "armtexture") == 0) { - c->Message(15,"NPCID %u now uses armtexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses armtexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET armtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "bracertexture") == 0) { - c->Message(15,"NPCID %u now uses bracertexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses bracertexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET bracertexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "handtexture") == 0) { - c->Message(15,"NPCID %u now uses handtexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses handtexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET handtexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "legtexture") == 0) { - c->Message(15,"NPCID %u now uses legtexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses legtexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET legtexture = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "feettexture") == 0) { - c->Message(15,"NPCID %u now uses feettexture %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses feettexture %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET feettexture = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "herosforgemodel") == 0) { - c->Message(15,"NPCID %u now uses herosforgemodel %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses herosforgemodel %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET herosforgemodel = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "size") == 0) { - c->Message(15,"NPCID %u is now size %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now size %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET size = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "hpregen") == 0) { - c->Message(15,"NPCID %u now regens %i hitpoints per tick.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now regens %i hitpoints per tick.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET hp_regen_rate = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "manaregen") == 0) { - c->Message(15,"NPCID %u now regens %i mana per tick.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now regens %i mana per tick.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET mana_regen_rate = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "loottable") == 0) { - c->Message(15,"NPCID %u is now on loottable_id %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now on loottable_id %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET loottable_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "merchantid") == 0) { - c->Message(15,"NPCID %u is now merchant_id %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now merchant_id %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET merchant_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "alt_currency_id") == 0) { - c->Message(15,"NPCID %u now has field 'alt_currency_id' set to %s.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has field 'alt_currency_id' set to %s.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET alt_currency_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "npc_spells_effects_id") == 0) { - c->Message(15,"NPCID %u now has field 'npc_spells_effects_id' set to %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has field 'npc_spells_effects_id' set to %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET npc_spells_effects_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "adventure_template_id") == 0) { - c->Message(15,"NPCID %u now has field 'adventure_template_id' set to %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has field 'adventure_template_id' set to %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET adventure_template_id = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "trap_template") == 0) { - c->Message(15,"NPCID %u now has field 'trap_template' set to %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has field 'trap_template' set to %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET trap_template = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "special_abilities") == 0) { - c->Message(15,"NPCID %u now has field 'special_abilities' set to %s.", npcTypeID, sep->argplus[2]); + c->Message(Chat::Yellow,"NPCID %u now has field 'special_abilities' set to %s.", npcTypeID, sep->argplus[2]); std::string query = StringFormat("UPDATE npc_types SET special_abilities = '%s' WHERE id = %i", sep->argplus[2],npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "spell") == 0) { - c->Message(15,"NPCID %u now uses spell list %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now uses spell list %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET npc_spells_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "faction") == 0) { - c->Message(15,"NPCID %u is now faction %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now faction %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET npc_faction_id = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "damage") == 0) { - c->Message(15,"NPCID %u now hits from %i to %i", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + c->Message(Chat::Yellow,"NPCID %u now hits from %i to %i", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); std::string query = StringFormat("UPDATE npc_types SET mindmg = %i, maxdmg = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "meleetype") == 0) { - c->Message(15,"NPCID %u now has a primary melee type of %i and a secondary melee type of %i.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + c->Message(Chat::Yellow,"NPCID %u now has a primary melee type of %i and a secondary melee type of %i.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); std::string query = StringFormat("UPDATE npc_types SET prim_melee_type = %i, sec_melee_type = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "rangedtype") == 0) { - c->Message(15,"NPCID %u now has a ranged type of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a ranged type of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET ranged_type = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "ammoidfile") == 0) { - c->Message(15,"NPCID %u's ammo id file is now %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u's ammo id file is now %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET ammoidfile = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "aggroradius") == 0) { - c->Message(15,"NPCID %u now has an aggro radius of %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has an aggro radius of %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET aggroradius = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "assistradius") == 0) { - c->Message(15,"NPCID %u now has an assist radius of %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has an assist radius of %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET assistradius = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "social") == 0) { - c->Message(15,"NPCID %u social status is now %i", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u social status is now %i", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET social = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "runspeed") == 0) { - c->Message(15,"NPCID %u now runs at %f", npcTypeID, atof(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now runs at %f", npcTypeID, atof(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET runspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "walkspeed") == 0) { - c->Message(15,"NPCID %u now walks at %f", npcTypeID, atof(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now walks at %f", npcTypeID, atof(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET walkspeed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "AGI") == 0) { - c->Message(15,"NPCID %u now has %i Agility.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Agility.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET AGI = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "CHA") == 0) { - c->Message(15,"NPCID %u now has %i Charisma.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Charisma.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET CHA = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "DEX") == 0) { - c->Message(15,"NPCID %u now has %i Dexterity.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Dexterity.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET DEX = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "INT") == 0) { - c->Message(15,"NPCID %u now has %i Intelligence.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Intelligence.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET _INT = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "STA") == 0) { - c->Message(15,"NPCID %u now has %i Stamina.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Stamina.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET STA = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "STR") == 0) { - c->Message(15,"NPCID %u now has %i Strength.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Strength.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET STR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "WIS") == 0) { - c->Message(15,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET WIS = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "MR") == 0) { - c->Message(15,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Magic Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET MR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "DR") == 0) { - c->Message(15,"NPCID %u now has a Disease Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Disease Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET DR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "CR") == 0) { - c->Message(15,"NPCID %u now has a Cold Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Cold Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET CR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "FR") == 0) { - c->Message(15,"NPCID %u now has a Fire Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Fire Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET FR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "PR") == 0) { - c->Message(15,"NPCID %u now has a Poison Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Poison Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET PR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Corrup") == 0) { - c->Message(15,"NPCID %u now has a Corruption Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Corruption Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET corrup = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "PhR") == 0) { - c->Message(15,"NPCID %u now has a Physical Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a Physical Resistance of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET PhR = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "seeinvis") == 0) { - c->Message(15,"NPCID %u now has seeinvis set to %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has seeinvis set to %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET see_invis = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "seeinvisundead") == 0) { - c->Message(15,"NPCID %u now has seeinvisundead set to %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has seeinvisundead set to %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET see_invis_undead = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "seehide") == 0) { - c->Message(15,"NPCID %u now has seehide set to %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has seehide set to %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET see_hide = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "seeimprovedhide") == 0) { - c->Message(15,"NPCID %u now has seeimprovedhide set to %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has seeimprovedhide set to %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET see_improved_hide = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "AC") == 0) { - c->Message(15,"NPCID %u now has %i Armor Class.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Armor Class.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET ac = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "ATK") == 0) { - c->Message(15,"NPCID %u now has %i Attack.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Attack.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET atk = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Accuracy") == 0) { - c->Message(15,"NPCID %u now has %i Accuracy.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Accuracy.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET accuracy = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Avoidance") == 0) { - c->Message(15,"NPCID %u now has %i Avoidance.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has %i Avoidance.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET avoidance = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "level") == 0) { - c->Message(15,"NPCID %u is now level %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u is now level %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET level = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "maxlevel") == 0) { - c->Message(15,"NPCID %u now has a maximum level of %i.", npcTypeID, atoi(sep->argplus[2])); + c->Message(Chat::Yellow,"NPCID %u now has a maximum level of %i.", npcTypeID, atoi(sep->argplus[2])); std::string query = StringFormat("UPDATE npc_types SET maxlevel = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "qglobal") == 0) { - c->Message(15,"Quest globals have been %s for NPCID %u", atoi(sep->arg[2]) == 0 ? "disabled" : "enabled", npcTypeID); + c->Message(Chat::Yellow,"Quest globals have been %s for NPCID %u", atoi(sep->arg[2]) == 0 ? "disabled" : "enabled", npcTypeID); std::string query = StringFormat("UPDATE npc_types SET qglobal = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "npcaggro") == 0) { - c->Message(15,"NPCID %u will now %s other NPCs with negative faction npc_value", npcTypeID, atoi(sep->arg[2]) == 0? "not aggro": "aggro"); + c->Message(Chat::Yellow,"NPCID %u will now %s other NPCs with negative faction npc_value", npcTypeID, atoi(sep->arg[2]) == 0? "not aggro": "aggro"); std::string query = StringFormat("UPDATE npc_types SET npc_aggro = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "spawn_limit") == 0) { - c->Message(15,"NPCID %u now has a spawn limit of %i", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow,"NPCID %u now has a spawn limit of %i", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET spawn_limit = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Attackspeed") == 0) { - c->Message(15,"NPCID %u now has attack_speed set to %f", npcTypeID, atof(sep->arg[2])); + c->Message(Chat::Yellow,"NPCID %u now has attack_speed set to %f", npcTypeID, atof(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET attack_speed = %f WHERE id = %i", atof(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Attackdelay") == 0) { - c->Message(15,"NPCID %u now has attack_delay set to %i", npcTypeID,atoi(sep->arg[2])); + c->Message(Chat::Yellow,"NPCID %u now has attack_delay set to %i", npcTypeID,atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET attack_delay = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "Attackcount") == 0) { - c->Message(15,"NPCID %u now has attack_count set to %i", npcTypeID,atoi(sep->arg[2])); + c->Message(Chat::Yellow,"NPCID %u now has attack_count set to %i", npcTypeID,atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET attack_count = %i WHERE id = %i", atoi(sep->argplus[2]),npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "findable") == 0) { - c->Message(15,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not findable": "findable"); + c->Message(Chat::Yellow,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not findable": "findable"); std::string query = StringFormat("UPDATE npc_types SET findable = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "trackable") == 0) { - c->Message(15,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not trackable": "trackable"); + c->Message(Chat::Yellow,"NPCID %u is now %s", npcTypeID, atoi(sep->arg[2]) == 0? "not trackable": "trackable"); std::string query = StringFormat("UPDATE npc_types SET trackable = %i WHERE id = %i", atoi(sep->argplus[2]) == 0? 0: 1, npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "weapon") == 0) { - c->Message(15,"NPCID %u will have item graphic %i set to his primary and item graphic %i set to his secondary on repop.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); + c->Message(Chat::Yellow,"NPCID %u will have item graphic %i set to his primary and item graphic %i set to his secondary on repop.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3])); std::string query = StringFormat("UPDATE npc_types SET d_melee_texture1 = %i, d_melee_texture2 = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "featuresave") == 0) { - c->Message(15,"NPCID %u saved with all current facial feature settings", npcTypeID); + c->Message(Chat::Yellow,"NPCID %u saved with all current facial feature settings", npcTypeID); Mob* target = c->GetTarget(); std::string query = StringFormat("UPDATE npc_types " "SET luclin_haircolor = %i, luclin_beardcolor = %i, " @@ -7856,14 +7967,14 @@ void command_npcedit(Client *c, const Seperator *sep) } if (strcasecmp(sep->arg[1], "color") == 0) { - c->Message(15,"NPCID %u now has %i red, %i green, and %i blue tinting on their armor.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); + c->Message(Chat::Yellow,"NPCID %u now has %i red, %i green, and %i blue tinting on their armor.", npcTypeID, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); std::string query = StringFormat("UPDATE npc_types SET armortint_red = %i, armortint_green = %i, armortint_blue = %i WHERE id = %i", atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "armortint_id") == 0) { - c->Message(15,"NPCID %u now has field 'armortint_id' set to %s", npcTypeID, sep->arg[2]); + c->Message(Chat::Yellow,"NPCID %u now has field 'armortint_id' set to %s", npcTypeID, sep->arg[2]); std::string query = StringFormat("UPDATE npc_types SET armortint_id = '%s' WHERE id = %i", sep->argplus[2], npcTypeID); database.QueryDatabase(query); return; @@ -7889,7 +8000,7 @@ void command_npcedit(Client *c, const Seperator *sep) return; } - c->Message(15,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, c->GetTarget()->CastToNPC()->GetSp2() ); + c->Message(Chat::Yellow,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, c->GetTarget()->CastToNPC()->GetSp2() ); std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation, c->GetTarget()->CastToNPC()->GetSp2()); database.QueryDatabase(query); @@ -7898,42 +8009,42 @@ void command_npcedit(Client *c, const Seperator *sep) } if (strcasecmp(sep->arg[1], "scalerate") == 0) { - c->Message(15,"NPCID %u now has a scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow,"NPCID %u now has a scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET scalerate = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "healscale") == 0) { - c->Message(15, "NPCID %u now has a heal scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow, "NPCID %u now has a heal scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET healscale = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "spellscale") == 0) { - c->Message(15, "NPCID %u now has a spell scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow, "NPCID %u now has a spell scaling rate of %i.", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET spellscale = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "no_target") == 0) { - c->Message(15, "NPCID %u is now %s.", npcTypeID, atoi(sep->arg[2]) == 0? "targetable": "untargetable"); + c->Message(Chat::Yellow, "NPCID %u is now %s.", npcTypeID, atoi(sep->arg[2]) == 0? "targetable": "untargetable"); std::string query = StringFormat("UPDATE npc_types SET no_target_hotkey = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "version") == 0) { - c->Message(15, "NPCID %u is now version %i.", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow, "NPCID %u is now version %i.", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET version = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; } if (strcasecmp(sep->arg[1], "slow_mitigation") == 0) { - c->Message(15, "NPCID %u's slow mitigation limit is now %i.", npcTypeID, atoi(sep->arg[2])); + c->Message(Chat::Yellow, "NPCID %u's slow mitigation limit is now %i.", npcTypeID, atoi(sep->arg[2])); std::string query = StringFormat("UPDATE npc_types SET slow_mitigation = %i WHERE id = %i", atoi(sep->argplus[2]), npcTypeID); database.QueryDatabase(query); return; @@ -7981,7 +8092,7 @@ void command_qglobal(Client *c, const Seperator *sep) { Mob *target = c->GetTarget(); if(!target || !target->IsNPC()) { - c->Message(13, "NPC Target Required!"); + c->Message(Chat::Red, "NPC Target Required!"); return; } @@ -7990,11 +8101,11 @@ void command_qglobal(Client *c, const Seperator *sep) { target->GetNPCTypeID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - c->Message(15, "Could not update database."); + c->Message(Chat::Yellow, "Could not update database."); return; } - c->Message(15, "Success! Changes take effect on zone reboot."); + c->Message(Chat::Yellow, "Success! Changes take effect on zone reboot."); return; } @@ -8003,26 +8114,26 @@ void command_qglobal(Client *c, const Seperator *sep) { target->GetNPCTypeID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - c->Message(15, "Could not update database."); + c->Message(Chat::Yellow, "Could not update database."); return; } - c->Message(15, "Success! Changes take effect on zone reboot."); + c->Message(Chat::Yellow, "Success! Changes take effect on zone reboot."); return; } if(!strcasecmp(sep->arg[1], "view")) { const NPCType *type = database.LoadNPCTypesData(target->GetNPCTypeID()); if(!type) - c->Message(15, "Invalid NPC type."); + c->Message(Chat::Yellow, "Invalid NPC type."); else if(type->qglobal) - c->Message(15, "This NPC has quest globals active."); + c->Message(Chat::Yellow, "This NPC has quest globals active."); else - c->Message(15, "This NPC has quest globals disabled."); + c->Message(Chat::Yellow, "This NPC has quest globals disabled."); return; } - c->Message(15, "Invalid action specified."); + c->Message(Chat::Yellow, "Invalid action specified."); } void command_path(Client *c, const Seperator *sep) @@ -8065,7 +8176,7 @@ void command_ucs(Client *c, const Seperator *sep) { if (!c) return; - + Log(Logs::Detail, Logs::UCS_Server, "Character %s attempting ucs reconnect while ucs server is %savailable", c->GetName(), (zone->IsUCSServerAvailable() ? "" : "un")); @@ -8149,7 +8260,7 @@ void command_undyeme(Client *c, const Seperator *sep) { if(c) { c->Undye(); - c->Message(13, "Dye removed from all slots. Please zone for the process to complete."); + c->Message(Chat::Red, "Dye removed from all slots. Please zone for the process to complete."); } } @@ -8203,7 +8314,7 @@ void command_aggro(Client *c, const Seperator *sep) } float d = atof(sep->arg[1]); if(d == 0.0f) { - c->Message(13, "Error: distance argument required."); + c->Message(Chat::Red, "Error: distance argument required."); return; } bool verbose = false; @@ -8330,13 +8441,13 @@ void command_flagedit(Client *c, const Seperator *sep) { } } if(zoneid < 1) { - c->Message(13, "zone required. see help."); + c->Message(Chat::Red, "zone required. see help."); return; } char flag_name[128]; if(sep->argplus[3][0] == '\0') { - c->Message(13, "flag name required. see help."); + c->Message(Chat::Red, "flag name required. see help."); return; } database.DoEscapeString(flag_name, sep->argplus[3], 64); @@ -8347,11 +8458,11 @@ void command_flagedit(Client *c, const Seperator *sep) { flag_name, zoneid, zone->GetInstanceVersion()); auto results = database.QueryDatabase(query); if(!results.Success()) { - c->Message(13, "Error updating zone: %s", results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Error updating zone: %s", results.ErrorMessage().c_str()); return; } - c->Message(15, "Success! Zone %s now requires a flag, named %s", database.GetZoneName(zoneid), flag_name); + c->Message(Chat::Yellow, "Success! Zone %s now requires a flag, named %s", database.GetZoneName(zoneid), flag_name); return; } @@ -8365,7 +8476,7 @@ void command_flagedit(Client *c, const Seperator *sep) { } if(zoneid < 1) { - c->Message(13, "zone required. see help."); + c->Message(Chat::Red, "zone required. see help."); return; } @@ -8374,11 +8485,11 @@ void command_flagedit(Client *c, const Seperator *sep) { zoneid, zone->GetInstanceVersion()); auto results = database.QueryDatabase(query); if(!results.Success()) { - c->Message(15, "Error updating zone: %s", results.ErrorMessage().c_str()); + c->Message(Chat::Yellow, "Error updating zone: %s", results.ErrorMessage().c_str()); return; } - c->Message(15, "Success! Zone %s no longer requires a flag.", database.GetZoneName(zoneid)); + c->Message(Chat::Yellow, "Success! Zone %s no longer requires a flag.", database.GetZoneName(zoneid)); return; } @@ -8406,13 +8517,13 @@ void command_flagedit(Client *c, const Seperator *sep) { } } if(zoneid < 1) { - c->Message(13, "zone required. see help."); + c->Message(Chat::Red, "zone required. see help."); return; } Mob *t = c->GetTarget(); if(t == nullptr || !t->IsClient()) { - c->Message(13, "client target required"); + c->Message(Chat::Red, "client target required"); return; } @@ -8429,13 +8540,13 @@ void command_flagedit(Client *c, const Seperator *sep) { } } if(zoneid < 1) { - c->Message(13, "zone required. see help."); + c->Message(Chat::Red, "zone required. see help."); return; } Mob *t = c->GetTarget(); if(t == nullptr || !t->IsClient()) { - c->Message(13, "client target required"); + c->Message(Chat::Red, "client target required"); return; } @@ -8443,7 +8554,7 @@ void command_flagedit(Client *c, const Seperator *sep) { return; } - c->Message(15, "Invalid action specified. use '#flagedit help' for help"); + c->Message(Chat::Yellow, "Invalid action specified. use '#flagedit help' for help"); } void command_serverrules(Client *c, const Seperator *sep) @@ -8531,7 +8642,7 @@ void command_rules(Client *c, const Seperator *sep) { } else if(!strcasecmp(sep->arg[1], "listsets")) { std::map sets; if(!RuleManager::Instance()->ListRulesets(&database, sets)) { - c->Message(13, "Failed to list rule sets!"); + c->Message(Chat::Red, "Failed to list rule sets!"); return; } @@ -8550,11 +8661,11 @@ void command_rules(Client *c, const Seperator *sep) { //make sure this is a valid rule set.. int rsid = RuleManager::Instance()->GetRulesetID(&database, sep->arg[2]); if(rsid < 0) { - c->Message(13, "Unknown rule set '%s'", sep->arg[2]); + c->Message(Chat::Red, "Unknown rule set '%s'", sep->arg[2]); return; } if(!database.SetVariable("RuleSet", sep->arg[2])) { - c->Message(13, "Failed to update variables table to change selected rule set"); + c->Message(Chat::Red, "Failed to update variables table to change selected rule set"); return; } @@ -8566,7 +8677,7 @@ void command_rules(Client *c, const Seperator *sep) { //make sure this is a valid rule set.. int rsid = RuleManager::Instance()->GetRulesetID(&database, sep->arg[2]); if(rsid < 0) { - c->Message(13, "Unknown rule set '%s'", sep->arg[2]); + c->Message(Chat::Red, "Unknown rule set '%s'", sep->arg[2]); return; } RuleManager::Instance()->LoadRules(&database, sep->arg[2], true); @@ -8581,7 +8692,7 @@ void command_rules(Client *c, const Seperator *sep) { int prersid = RuleManager::Instance()->GetActiveRulesetID(); int rsid = RuleManager::Instance()->GetRulesetID(&database, sep->arg[2]); if(rsid < 0) { - c->Message(13, "Unable to query ruleset ID after store, it most likely failed."); + c->Message(Chat::Red, "Unable to query ruleset ID after store, it most likely failed."); } else { c->Message(0, "Stored rules as ruleset '%s' (%d)", sep->arg[2], rsid); if(prersid != rsid) { @@ -8589,41 +8700,41 @@ void command_rules(Client *c, const Seperator *sep) { } } } else { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); return; } } else if(!strcasecmp(sep->arg[1], "reset")) { RuleManager::Instance()->ResetRules(true); c->Message(0, "The running ruleset has been set to defaults"); - + } else if(!strcasecmp(sep->arg[1], "get")) { if(sep->argnum != 2) { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); return; } std::string value; if(!RuleManager::Instance()->GetRule(sep->arg[2], value)) - c->Message(13, "Unable to find rule %s", sep->arg[2]); + c->Message(Chat::Red, "Unable to find rule %s", sep->arg[2]); else c->Message(0, "%s - %s", sep->arg[2], value.c_str()); } else if(!strcasecmp(sep->arg[1], "set")) { if(sep->argnum != 3) { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); return; } if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], nullptr, false, true)) { - c->Message(13, "Failed to modify rule"); + c->Message(Chat::Red, "Failed to modify rule"); } else { c->Message(0, "Rule modified locally."); } } else if(!strcasecmp(sep->arg[1], "setdb")) { if(sep->argnum != 3) { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); return; } if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true, true)) { - c->Message(13, "Failed to modify rule"); + c->Message(Chat::Red, "Failed to modify rule"); } else { c->Message(0, "Rule modified locally and in the database."); } @@ -8631,7 +8742,7 @@ void command_rules(Client *c, const Seperator *sep) { if(sep->argnum == 1) { std::vector rule_list; if(!RuleManager::Instance()->ListCategories(rule_list)) { - c->Message(13, "Failed to list categories!"); + c->Message(Chat::Red, "Failed to list categories!"); return; } c->Message(0, "Rule Categories:"); @@ -8647,7 +8758,7 @@ void command_rules(Client *c, const Seperator *sep) { catfilt = sep->arg[2]; std::vector rule_list; if(!RuleManager::Instance()->ListRules(catfilt, rule_list)) { - c->Message(13, "Failed to list rules!"); + c->Message(Chat::Red, "Failed to list rules!"); return; } c->Message(0, "Rules in category %s:", sep->arg[2]); @@ -8658,11 +8769,11 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(0, " %s", *cur); } } else { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); } } else if(!strcasecmp(sep->arg[1], "values")) { if(sep->argnum != 2) { - c->Message(13, "Invalid argument count, see help."); + c->Message(Chat::Red, "Invalid argument count, see help."); return; } else { const char *catfilt = nullptr; @@ -8670,7 +8781,7 @@ void command_rules(Client *c, const Seperator *sep) { catfilt = sep->arg[2]; std::vector rule_list; if(!RuleManager::Instance()->ListRules(catfilt, rule_list)) { - c->Message(13, "Failed to list rules!"); + c->Message(Chat::Red, "Failed to list rules!"); return; } c->Message(0, "Rules & values in category %s:", sep->arg[2]); @@ -8684,7 +8795,7 @@ void command_rules(Client *c, const Seperator *sep) { } } else { - c->Message(15, "Invalid action specified. use '#rules help' for help"); + c->Message(Chat::Yellow, "Invalid action specified. use '#rules help' for help"); } } @@ -8724,44 +8835,44 @@ void command_task(Client *c, const Seperator *sep) { if(Count <= 0) Count = 1; } - c->Message(15, "Updating Task %i, Activity %i, Count %i", TaskID, ActivityID, Count); + c->Message(Chat::Yellow, "Updating Task %i, Activity %i, Count %i", TaskID, ActivityID, Count); c->UpdateTaskActivity(TaskID, ActivityID, Count); } return; } if(!strcasecmp(sep->arg[1], "reloadall")) { - c->Message(15, "Sending reloadtasks to world"); + c->Message(Chat::Yellow, "Sending reloadtasks to world"); worldserver.SendReloadTasks(RELOADTASKS); - c->Message(15, "Back again"); + c->Message(Chat::Yellow, "Back again"); return; } if(!strcasecmp(sep->arg[1], "reload")) { if(sep->arg[2][0] != '\0') { if(!strcasecmp(sep->arg[2], "lists")) { - c->Message(15, "Sending reload lists to world"); + c->Message(Chat::Yellow, "Sending reload lists to world"); worldserver.SendReloadTasks(RELOADTASKGOALLISTS); - c->Message(15, "Back again"); + c->Message(Chat::Yellow, "Back again"); return; } if(!strcasecmp(sep->arg[2], "prox")) { - c->Message(15, "Sending reload proximities to world"); + c->Message(Chat::Yellow, "Sending reload proximities to world"); worldserver.SendReloadTasks(RELOADTASKPROXIMITIES); - c->Message(15, "Back again"); + c->Message(Chat::Yellow, "Back again"); return; } if(!strcasecmp(sep->arg[2], "sets")) { - c->Message(15, "Sending reload task sets to world"); + c->Message(Chat::Yellow, "Sending reload task sets to world"); worldserver.SendReloadTasks(RELOADTASKSETS); - c->Message(15, "Back again"); + c->Message(Chat::Yellow, "Back again"); return; } if(!strcasecmp(sep->arg[2], "task") && (sep->arg[3][0] != '\0')) { int TaskID = atoi(sep->arg[3]); if((TaskID > 0) && (TaskID < MAXTASKS)) { - c->Message(15, "Sending reload task %i to world"); + c->Message(Chat::Yellow, "Sending reload task %i to world"); worldserver.SendReloadTasks(RELOADTASKS, TaskID); - c->Message(15, "Back again"); + c->Message(Chat::Yellow, "Back again"); return; } } @@ -8776,7 +8887,7 @@ void command_reloadtitles(Client *c, const Seperator *sep) auto pack = new ServerPacket(ServerOP_ReloadTitles, 0); worldserver.SendPacket(pack); safe_delete(pack); - c->Message(15, "Player Titles Reloaded."); + c->Message(Chat::Yellow, "Player Titles Reloaded."); } @@ -8820,7 +8931,7 @@ void command_traindisc(Client *c, const Seperator *sep) for( ; spell_id < SPDAT_RECORDS; ++spell_id) { if (spell_id < 0 || spell_id >= SPDAT_RECORDS) { - c->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); + c->Message(Chat::Red, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS); return; } @@ -8833,10 +8944,10 @@ void command_traindisc(Client *c, const Seperator *sep) break; if (spells[spell_id].skill == 52) break; - + uint16 spell_id_ = (uint16)spell_id; if ((spell_id_ != spell_id) || (spell_id != spell_id_)) { - c->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); + c->Message(Chat::Red, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_); return; } @@ -8845,7 +8956,7 @@ void command_traindisc(Client *c, const Seperator *sep) for (uint32 r = 0; r < MAX_PP_DISCIPLINES; ++r) { if (t->GetPP().disciplines.values[r] == spell_id_) { - t->Message(13, "You already know this discipline."); + t->Message(Chat::Red, "You already know this discipline."); break; // continue the 1st loop } else if (t->GetPP().disciplines.values[r] == 0) { @@ -9033,7 +9144,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9053,7 +9164,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9076,7 +9187,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9098,7 +9209,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9129,8 +9240,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep) std::string query = StringFormat("DELETE FROM spawn2 WHERE id = '%i'", s2->GetID()); auto results = database.QueryDatabase(query); if(!results.Success()) { - c->Message(13, "Update failed! MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9158,8 +9269,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep) c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(),s2->GetID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(13, "Update failed! MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9198,8 +9309,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep) "WHERE id = '%i'", new_rs, new_var, s2->GetID()); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(13, "Update failed! MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9227,8 +9338,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep) version, c->GetTarget()->CastToNPC()->GetSp2()); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(13, "Update failed! MySQL gave the following error:"); - c->Message(13, results.ErrorMessage().c_str()); + c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); + c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } @@ -9508,26 +9619,26 @@ void command_netstats(Client *c, const Seperator *sep) if (c->GetTarget() && c->GetTarget()->IsClient()) { client = c->GetTarget()->CastToClient(); } - + if (strcasecmp(sep->arg[1], "reset") == 0) { auto connection = c->Connection(); c->Message(0, "Resetting client stats (packet loss will not read correctly after reset)."); connection->ResetStats(); return; } - + auto connection = c->Connection(); auto opts = connection->GetManager()->GetOptions(); auto eqs_stats = connection->GetStats(); auto &stats = eqs_stats.DaybreakStats; auto now = EQ::Net::Clock::now(); auto sec_since_stats_reset = std::chrono::duration_cast>(now - stats.created).count(); - + c->Message(0, "Netstats:"); c->Message(0, "--------------------------------------------------------------------"); c->Message(0, "Sent Bytes: %u (%.2f/sec)", stats.sent_bytes, stats.sent_bytes / sec_since_stats_reset); c->Message(0, "Recv Bytes: %u (%.2f/sec)", stats.recv_bytes, stats.recv_bytes / sec_since_stats_reset); - c->Message(0, "Bytes Before Encode (Sent): %u, Compression Rate: %.2f%%", stats.bytes_before_encode, + c->Message(0, "Bytes Before Encode (Sent): %u, Compression Rate: %.2f%%", stats.bytes_before_encode, static_cast(stats.bytes_before_encode - stats.sent_bytes) / static_cast(stats.bytes_before_encode) * 100.0); c->Message(0, "Bytes After Decode (Recv): %u, Compression Rate: %.2f%%", stats.bytes_after_decode, static_cast(stats.bytes_after_decode - stats.recv_bytes) / static_cast(stats.bytes_after_decode) * 100.0); @@ -9549,11 +9660,11 @@ void command_netstats(Client *c, const Seperator *sep) c->Message(0, "Resent Fragments: %u (%.2f/sec)", stats.resent_fragments, stats.resent_fragments / sec_since_stats_reset); c->Message(0, "Resent Non-Fragments: %u (%.2f/sec)", stats.resent_full, stats.resent_full / sec_since_stats_reset); c->Message(0, "Dropped Datarate Packets: %u (%.2f/sec)", stats.dropped_datarate_packets, stats.dropped_datarate_packets / sec_since_stats_reset); - + if (opts.daybreak_options.outgoing_data_rate > 0.0) { c->Message(0, "Outgoing Link Saturation %.2f%% (%.2fkb/sec)", 100.0 * (1.0 - ((opts.daybreak_options.outgoing_data_rate - stats.datarate_remaining) / opts.daybreak_options.outgoing_data_rate)), opts.daybreak_options.outgoing_data_rate); } - + if (strcasecmp(sep->arg[1], "full") == 0) { c->Message(0, "--------------------------------------------------------------------"); c->Message(0, "Sent Packet Types"); @@ -9573,7 +9684,7 @@ void command_netstats(Client *c, const Seperator *sep) } } } - + c->Message(0, "--------------------------------------------------------------------"); } } @@ -10761,22 +10872,22 @@ void command_raidloot(Client *c, const Seperator *sep) if(strcasecmp(sep->arg[1], "LEADER") == 0) { - c->Message(15, "Loot type changed to: 1"); + c->Message(Chat::Yellow, "Loot type changed to: 1"); r->ChangeLootType(1); } else if(strcasecmp(sep->arg[1], "GROUPLEADER") == 0) { - c->Message(15, "Loot type changed to: 2"); + c->Message(Chat::Yellow, "Loot type changed to: 2"); r->ChangeLootType(2); } else if(strcasecmp(sep->arg[1], "SELECTED") == 0) { - c->Message(15, "Loot type changed to: 3"); + c->Message(Chat::Yellow, "Loot type changed to: 3"); r->ChangeLootType(3); } else if(strcasecmp(sep->arg[1], "ALL") == 0) { - c->Message(15, "Loot type changed to: 4"); + c->Message(Chat::Yellow, "Loot type changed to: 4"); r->ChangeLootType(4); } else @@ -11052,7 +11163,7 @@ void command_reloadallrules(Client *c, const Seperator *sep) { auto pack = new ServerPacket(ServerOP_ReloadRules, 0); worldserver.SendPacket(pack); - c->Message(13, "Successfully sent the packet to world to reload rules globally. (including world)"); + c->Message(Chat::Red, "Successfully sent the packet to world to reload rules globally. (including world)"); safe_delete(pack); } @@ -11064,7 +11175,7 @@ void command_reloadworldrules(Client *c, const Seperator *sep) { auto pack = new ServerPacket(ServerOP_ReloadRulesWorld, 0); worldserver.SendPacket(pack); - c->Message(13, "Successfully sent the packet to world to reload rules. (only world)"); + c->Message(Chat::Red, "Successfully sent the packet to world to reload rules. (only world)"); safe_delete(pack); } } @@ -11080,11 +11191,11 @@ void command_camerashake(Client *c, const Seperator *sep) scss->duration = atoi(sep->arg[1]); scss->intensity = atoi(sep->arg[2]); worldserver.SendPacket(pack); - c->Message(13, "Successfully sent the packet to world! Shake it, world, shake it!"); + c->Message(Chat::Red, "Successfully sent the packet to world! Shake it, world, shake it!"); safe_delete(pack); } else { - c->Message(13, "Usage -- #camerashake [duration], [intensity [1-10])"); + c->Message(Chat::Red, "Usage -- #camerashake [duration], [intensity [1-10])"); } } return; @@ -11096,7 +11207,7 @@ void command_disarmtrap(Client *c, const Seperator *sep) if(!target) { - c->Message(13, "You must have a target."); + c->Message(Chat::Red, "You must have a target."); return; } @@ -11106,13 +11217,13 @@ void command_disarmtrap(Client *c, const Seperator *sep) { if(DistanceSquaredNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - c->Message(13, "%s is too far away.", target->GetCleanName()); + c->Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } c->HandleLDoNDisarm(target->CastToNPC(), c->GetSkill(EQEmu::skills::SkillDisarmTraps), LDoNTypeMechanical); } else - c->Message(13, "You do not have the disarm trap skill."); + c->Message(Chat::Red, "You do not have the disarm trap skill."); } } @@ -11121,7 +11232,7 @@ void command_sensetrap(Client *c, const Seperator *sep) Mob * target = c->GetTarget(); if(!target) { - c->Message(13, "You must have a target."); + c->Message(Chat::Red, "You must have a target."); return; } @@ -11131,13 +11242,13 @@ void command_sensetrap(Client *c, const Seperator *sep) { if(DistanceSquaredNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - c->Message(13, "%s is too far away.", target->GetCleanName()); + c->Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } c->HandleLDoNSenseTraps(target->CastToNPC(), c->GetSkill(EQEmu::skills::SkillSenseTraps), LDoNTypeMechanical); } else - c->Message(13, "You do not have the sense traps skill."); + c->Message(Chat::Red, "You do not have the sense traps skill."); } } @@ -11146,7 +11257,7 @@ void command_picklock(Client *c, const Seperator *sep) Mob * target = c->GetTarget(); if(!target) { - c->Message(13, "You must have a target."); + c->Message(Chat::Red, "You must have a target."); return; } @@ -11156,20 +11267,20 @@ void command_picklock(Client *c, const Seperator *sep) { if(DistanceSquaredNoZ(c->GetPosition(), target->GetPosition()) > RuleI(Adventure, LDoNTrapDistanceUse)) { - c->Message(13, "%s is too far away.", target->GetCleanName()); + c->Message(Chat::Red, "%s is too far away.", target->GetCleanName()); return; } c->HandleLDoNPickLock(target->CastToNPC(), c->GetSkill(EQEmu::skills::SkillPickLock), LDoNTypeMechanical); } else - c->Message(13, "You do not have the pick locks skill."); + c->Message(Chat::Red, "You do not have the pick locks skill."); } } void command_profanity(Client *c, const Seperator *sep) { std::string arg1(sep->arg[1]); - + while (true) { if (arg1.compare("list") == 0) { // do nothing @@ -11182,21 +11293,21 @@ void command_profanity(Client *c, const Seperator *sep) } else if (arg1.compare("add") == 0) { if (!EQEmu::ProfanityManager::AddProfanity(&database, sep->arg[2])) - c->Message(CC_Red, "Could not add '%s' to the profanity list.", sep->arg[2]); + c->Message(Chat::Red, "Could not add '%s' to the profanity list.", sep->arg[2]); auto pack = new ServerPacket(ServerOP_RefreshCensorship); worldserver.SendPacket(pack); safe_delete(pack); } else if (arg1.compare("del") == 0) { if (!EQEmu::ProfanityManager::RemoveProfanity(&database, sep->arg[2])) - c->Message(CC_Red, "Could not delete '%s' from the profanity list.", sep->arg[2]); + c->Message(Chat::Red, "Could not delete '%s' from the profanity list.", sep->arg[2]); auto pack = new ServerPacket(ServerOP_RefreshCensorship); worldserver.SendPacket(pack); safe_delete(pack); } else if (arg1.compare("reload") == 0) { if (!EQEmu::ProfanityManager::UpdateProfanityList(&database)) - c->Message(CC_Red, "Could not reload the profanity list."); + c->Message(Chat::Red, "Could not reload the profanity list."); auto pack = new ServerPacket(ServerOP_RefreshCensorship); worldserver.SendPacket(pack); safe_delete(pack); @@ -11217,10 +11328,10 @@ void command_profanity(Client *c, const Seperator *sep) popup.append("** End of List **
"); c->SendPopupToClient("Profanity List", popup.c_str()); - + return; } - + c->Message(0, "Usage: #profanity [list] - shows profanity list"); c->Message(0, "Usage: #profanity [clear] - deletes all entries"); c->Message(0, "Usage: #profanity [add] [] - adds entry"); @@ -11255,7 +11366,7 @@ void command_mysql(Client *c, const Seperator *sep) case 's': optionS = true; break; case 'h': optionH = true; break; default: - c->Message(15, "%s, there is no option '%c'", c->GetName(), sep->arg[argnum][1]); + c->Message(Chat::Yellow, "%s, there is no option '%c'", c->GetName(), sep->arg[argnum][1]); return; } ++argnum; @@ -11278,7 +11389,7 @@ void command_mysql(Client *c, const Seperator *sep) query.insert(pos, "%%"); pos = query.find('#'); } - c->Message(15, "---Running query: '%s'", query.c_str()); + c->Message(Chat::Yellow, "---Running query: '%s'", query.c_str()); for (auto row = results.begin(); row != results.end(); ++row) { std::stringstream lineText; @@ -11322,7 +11433,7 @@ void command_xtargets(Client *c, const Seperator *sep) if((NewMax < 5) || (NewMax > XTARGET_HARDCAP)) { - c->Message(13, "Number of XTargets must be between 5 and %i", XTARGET_HARDCAP); + c->Message(Chat::Red, "Number of XTargets must be between 5 and %i", XTARGET_HARDCAP); return; } t->SetMaxXTargets(NewMax); @@ -11359,7 +11470,7 @@ void command_zopp(Client *c, const Seperator *sep) const EQEmu::ItemData* FakeItem = database.GetItem(itemid); if (!FakeItem) { - c->Message(13, "Error: Item [%u] is not a valid item id.", itemid); + c->Message(Chat::Red, "Error: Item [%u] is not a valid item id.", itemid); return; } @@ -11369,12 +11480,12 @@ void command_zopp(Client *c, const Seperator *sep) item_status = static_cast(item->MinStatus); } if (item_status > c->Admin()) { - c->Message(13, "Error: Insufficient status to use this command."); + c->Message(Chat::Red, "Error: Insufficient status to use this command."); return; } if (charges < 0 || charges > FakeItem->StackSize) { - c->Message(13, "Warning: The specified charge count does not meet expected criteria!"); + c->Message(Chat::Red, "Warning: The specified charge count does not meet expected criteria!"); c->Message(0, "Processing request..results may cause unpredictable behavior."); } @@ -11601,7 +11712,7 @@ void command_tune(Client *c, const Seperator *sep) if (!pct_mitigation) { - c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); + c->Message(Chat::Red, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); return; } @@ -11636,7 +11747,7 @@ void command_tune(Client *c, const Seperator *sep) if (!pct_mitigation) { - c->Message(13, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); + c->Message(Chat::Red, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); return; } @@ -11672,7 +11783,7 @@ void command_tune(Client *c, const Seperator *sep) if (!hit_chance) { - c->Message(10, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); + c->Message(Chat::NPCQuestSay, "#Tune - Error must enter the desired percent mitigation on defender. Ie. Defender to mitigate on average 20 pct of max damage."); return; } @@ -11687,7 +11798,7 @@ void command_tune(Client *c, const Seperator *sep) if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit)) { - c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit)); + c->Message(Chat::NPCQuestSay, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit)); return; } @@ -11729,7 +11840,7 @@ void command_tune(Client *c, const Seperator *sep) if (hit_chance > RuleR(Combat,MaxChancetoHit) || hit_chance < RuleR(Combat,MinChancetoHit)) { - c->Message(10, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit)); + c->Message(Chat::NPCQuestSay, "#Tune - Error hit chance out of bounds. [Max %.2f Min .2f]", RuleR(Combat,MaxChancetoHit),RuleR(Combat,MinChancetoHit)); return; } @@ -11776,7 +11887,7 @@ void command_logs(Client *c, const Seperator *sep){ if (strcasecmp(sep->arg[1], "reload_all") == 0){ auto pack = new ServerPacket(ServerOP_ReloadLogs, 0); worldserver.SendPacket(pack); - c->Message(13, "Successfully sent the packet to world to reload log settings from the database for all zones"); + c->Message(Chat::Red, "Successfully sent the packet to world to reload log settings from the database for all zones"); safe_delete(pack); } /* #logs list_settings */ @@ -11821,8 +11932,8 @@ void command_logs(Client *c, const Seperator *sep){ c->Message(0, "--- #logs set gmsay 20 1 - Would output Quest errors to gmsay"); } if (logs_set == 1){ - c->Message(15, "Your Log Settings have been applied"); - c->Message(15, "Output Method: %s :: Debug Level: %i - Category: %s", sep->arg[2], atoi(sep->arg[4]), Logs::LogCategoryName[atoi(sep->arg[3])]); + c->Message(Chat::Yellow, "Your Log Settings have been applied"); + c->Message(Chat::Yellow, "Output Method: %s :: Debug Level: %i - Category: %s", sep->arg[2], atoi(sep->arg[4]), Logs::LogCategoryName[atoi(sep->arg[3])]); } /* We use a general 'is_category_enabled' now, let's update when we update any output settings This is used in hot places of code to check if its enabled in any way before triggering logs @@ -11901,19 +12012,20 @@ void command_hotfix(Client *c, const Seperator *sep) { } c->Message(0, "Creating and applying hotfix"); - std::thread t1([c,hotfix_name]() { + std::thread t1( + [c, hotfix_name]() { #ifdef WIN32 - if(hotfix_name.length() > 0) { - system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); - } else { - system(StringFormat("shared_memory").c_str()); - } + if(hotfix_name.length() > 0) { + if(system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str())); + } else { + if(system(StringFormat("shared_memory").c_str())); + } #else if(hotfix_name.length() > 0) { - system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + if(system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str())); } else { - system(StringFormat("./shared_memory").c_str()); + if(system(StringFormat("./shared_memory").c_str())); } #endif database.SetVariable("hotfix_name", hotfix_name); @@ -11945,16 +12057,16 @@ void command_load_shared_memory(Client *c, const Seperator *sep) { std::thread t1([c,hotfix_name]() { #ifdef WIN32 if(hotfix_name.length() > 0) { - system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + if(system(StringFormat("shared_memory -hotfix=%s", hotfix_name.c_str()).c_str())); } else { - system(StringFormat("shared_memory").c_str()); + if(system(StringFormat("shared_memory").c_str())); } #else if(hotfix_name.length() > 0) { - system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str()); + if(system(StringFormat("./shared_memory -hotfix=%s", hotfix_name.c_str()).c_str())); } else { - system(StringFormat("./shared_memory").c_str()); + if(system(StringFormat("./shared_memory").c_str())); } #endif c->Message(0, "Shared memory segment finished loading."); @@ -11984,7 +12096,7 @@ void command_reloadperlexportsettings(Client *c, const Seperator *sep) { auto pack = new ServerPacket(ServerOP_ReloadPerlExportSettings, 0); worldserver.SendPacket(pack); - c->Message(13, "Successfully sent the packet to world to reload Perl Export settings"); + c->Message(Chat::Red, "Successfully sent the packet to world to reload Perl Export settings"); safe_delete(pack); } @@ -11998,16 +12110,16 @@ void command_trapinfo(Client *c, const Seperator *sep) void command_reloadtraps(Client *c, const Seperator *sep) { entity_list.UpdateAllTraps(true, true); - c->Message(CC_Default, "Traps reloaded for %s.", zone->GetShortName()); + c->Message(Chat::Default, "Traps reloaded for %s.", zone->GetShortName()); } void command_scale(Client *c, const Seperator *sep) { if (sep->argnum == 0) { - c->Message(15, "# Usage # "); - c->Message(15, "#scale [static/dynamic] (With targeted NPC)"); - c->Message(15, "#scale [npc_name_search] [static/dynamic] (To make zone-wide changes)"); - c->Message(15, "#scale all [static/dynamic]"); + c->Message(Chat::Yellow, "# Usage # "); + c->Message(Chat::Yellow, "#scale [static/dynamic] (With targeted NPC)"); + c->Message(Chat::Yellow, "#scale [npc_name_search] [static/dynamic] (To make zone-wide changes)"); + c->Message(Chat::Yellow, "#scale all [static/dynamic]"); return; } @@ -12019,11 +12131,11 @@ void command_scale(Client *c, const Seperator *sep) bool apply_status = false; if (strcasecmp(sep->arg[1], "dynamic") == 0) { - c->Message(15, "Applying global base scaling to npc dynamically (All stats set to zeroes)..."); + c->Message(Chat::Yellow, "Applying global base scaling to npc dynamically (All stats set to zeroes)..."); apply_status = npc_scale_manager->ApplyGlobalBaseScalingToNPCDynamically(npc); } else if (strcasecmp(sep->arg[1], "static") == 0) { - c->Message(15, "Applying global base scaling to npc statically (Copying base stats onto NPC)..."); + c->Message(Chat::Yellow, "Applying global base scaling to npc statically (Copying base stats onto NPC)..."); apply_status = npc_scale_manager->ApplyGlobalBaseScalingToNPCStatically(npc); } else { @@ -12031,15 +12143,15 @@ void command_scale(Client *c, const Seperator *sep) } if (apply_status) { - c->Message(15, "Applied to NPC '%s' successfully!", npc->GetName()); + c->Message(Chat::Yellow, "Applied to NPC '%s' successfully!", npc->GetName()); } else { - c->Message(15, "Failed to load scaling data from the database " + c->Message(Chat::Yellow, "Failed to load scaling data from the database " "for this npc / type, see 'NPCScaling' log for more info"); } } else if (c->GetTarget() && sep->argnum < 2) { - c->Message(15, "Target must be an npc!"); + c->Message(Chat::Yellow, "Target must be an npc!"); } /** @@ -12056,9 +12168,9 @@ void command_scale(Client *c, const Seperator *sep) } if (scale_type.length() <= 0) { - c->Message(15, "You must first set if you intend on using static versus dynamic for these changes"); - c->Message(15, "#scale [npc_name_search] [static/dynamic]"); - c->Message(15, "#scale all [static/dynamic]"); + c->Message(Chat::Yellow, "You must first set if you intend on using static versus dynamic for these changes"); + c->Message(Chat::Yellow, "#scale [npc_name_search] [static/dynamic]"); + c->Message(Chat::Yellow, "#scale all [static/dynamic]"); return; } @@ -12108,7 +12220,7 @@ void command_scale(Client *c, const Seperator *sep) } if (strcasecmp(sep->arg[3], "apply") == 0) { - c->Message(15, "%s scaling applied against (%i) NPC's", sep->arg[2], found_count); + c->Message(Chat::Yellow, "%s scaling applied against (%i) NPC's", sep->arg[2], found_count); } else { @@ -12118,7 +12230,7 @@ void command_scale(Client *c, const Seperator *sep) sep->arg[2] ); - c->Message(15, "Found (%i) NPC's that match this search...", found_count); + c->Message(Chat::Yellow, "Found (%i) NPC's that match this search...", found_count); c->Message( 15, "To apply these changes, click <%s> or type %s", EQEmu::SayLinkEngine::GenerateQuestSaylink(saylink, false, "Apply").c_str(), @@ -12155,7 +12267,7 @@ void command_who(Client *c, const Seperator *sep) return; if (results.RowCount() == 0) { - c->Message(15, "No results found"); + c->Message(Chat::Yellow, "No results found"); return; } @@ -12167,8 +12279,8 @@ void command_who(Client *c, const Seperator *sep) int found_count = 0; - c->Message(5, "Players in EverQuest"); - c->Message(5, "--------------------"); + c->Message(Chat::Magenta, "Players in EverQuest"); + c->Message(Chat::Magenta, "--------------------"); for (auto row = results.begin(); row != results.end(); ++row) { auto account_id = static_cast(atoi(row[0])); @@ -12245,7 +12357,7 @@ void command_who(Client *c, const Seperator *sep) "There are no players in EverQuest that match those who filters." ); - c->Message(5, message.c_str()); + c->Message(Chat::Magenta, message.c_str()); } void command_network(Client *c, const Seperator *sep) @@ -12255,7 +12367,7 @@ void command_network(Client *c, const Seperator *sep) auto eqsi = c->Connection(); auto manager = eqsi->GetManager(); auto opts = manager->GetOptions(); - + if (!strcasecmp(sep->arg[2], "all")) { c->Message(0, "max_packet_size: %llu", (uint64_t)opts.daybreak_options.max_packet_size); @@ -12313,19 +12425,19 @@ void command_network(Client *c, const Seperator *sep) auto eqsi = c->Connection(); auto manager = eqsi->GetManager(); auto opts = manager->GetOptions(); - + if (!strcasecmp(sep->arg[3], "")) { c->Message(0, "Missing value for set"); return; } - + std::string value = sep->arg[3]; if (!strcasecmp(sep->arg[2], "max_connection_count")) { opts.daybreak_options.max_connection_count = std::stoull(value); manager->SetOptions(opts); - } + } else if (!strcasecmp(sep->arg[2], "keepalive_delay_ms")) { opts.daybreak_options.keepalive_delay_ms = std::stoull(value); @@ -12443,12 +12555,12 @@ void command_bot(Client *c, const Seperator *sep) if (parse->PlayerHasQuestSub(EVENT_COMMAND)) { int i = parse->EventPlayer(EVENT_COMMAND, c, bot_message, 0); if (i == 0 && !RuleB(Chat, SuppressCommandErrors)) { - c->Message(13, "Bot command '%s' not recognized.", bot_message.c_str()); + c->Message(Chat::Red, "Bot command '%s' not recognized.", bot_message.c_str()); } } else { if (!RuleB(Chat, SuppressCommandErrors)) - c->Message(13, "Bot command '%s' not recognized.", bot_message.c_str()); + c->Message(Chat::Red, "Bot command '%s' not recognized.", bot_message.c_str()); } } } diff --git a/zone/command.h b/zone/command.h index e11b7bcfb..d6ce90a23 100644 --- a/zone/command.h +++ b/zone/command.h @@ -182,6 +182,7 @@ void command_netstats(Client *c, const Seperator *sep); void command_network(Client *c, const Seperator *sep); void command_npccast(Client *c, const Seperator *sep); void command_npcedit(Client *c, const Seperator *sep); +void command_npceditmass(Client *c, const Seperator *sep); void command_npcemote(Client *c, const Seperator *sep); void command_npcloot(Client *c, const Seperator *sep); void command_npcsay(Client *c, const Seperator *sep); From 665efe09f310e0c62264a4a197992d35035d6b64 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 00:27:04 -0500 Subject: [PATCH 149/491] Fill function calls using magic numbers --- zone/aggro.cpp | 46 +- zone/bot.cpp | 8 +- zone/client.cpp | 48 +- zone/command.cpp | 2642 +++++++++++++++++----------------- zone/corpse.cpp | 16 +- zone/entity.cpp | 12 +- zone/global_loot_manager.cpp | 4 +- zone/groups.cpp | 10 +- zone/guild_mgr.cpp | 36 +- zone/hate_list.cpp | 2 +- zone/inventory.cpp | 6 +- zone/mob.cpp | 64 +- zone/mob_ai.cpp | 2 +- zone/mob_info.cpp | 2 +- zone/npc.cpp | 30 +- zone/object.cpp | 2 +- zone/pathfinder_nav_mesh.cpp | 2 +- zone/pathfinder_waypoint.cpp | 10 +- zone/questmgr.cpp | 20 +- zone/raids.cpp | 2 +- zone/special_attacks.cpp | 2 +- zone/spell_effects.cpp | 10 +- zone/spells.cpp | 4 +- zone/tasks.cpp | 26 +- zone/tune.cpp | 98 +- zone/waypoints.cpp | 6 +- zone/worldserver.cpp | 2 +- zone/zone.cpp | 22 +- zone/zonedb.cpp | 4 +- zone/zoning.cpp | 6 +- 30 files changed, 1572 insertions(+), 1572 deletions(-) diff --git a/zone/aggro.cpp b/zone/aggro.cpp index 8a3da1092..ca565e0b9 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -52,12 +52,12 @@ void EntityList::CheckClientAggro(Client *around) void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbose) { float d2 = d*d; - towho->Message(0, "Describing aggro for %s", from_who->GetName()); + towho->Message(Chat::White, "Describing aggro for %s", from_who->GetName()); bool engaged = from_who->IsEngaged(); if(engaged) { Mob *top = from_who->GetHateTop(); - towho->Message(0, ".. I am currently fighting with %s", top == nullptr?"(nullptr)":top->GetName()); + towho->Message(Chat::White, ".. I am currently fighting with %s", top == nullptr?"(nullptr)":top->GetName()); } bool check_npcs = from_who->WillAggroNPCs(); @@ -77,7 +77,7 @@ void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbo if(!database.GetFactionName(my_primary, namebuf, sizeof(namebuf))) strcpy(namebuf, "(Unknown)"); } - towho->Message(0, ".. I am on faction %s (%d)\n", namebuf, my_primary); + towho->Message(Chat::White, ".. I am on faction %s (%d)\n", namebuf, my_primary); } for (auto it = mob_list.begin(); it != mob_list.end(); ++it) { @@ -91,11 +91,11 @@ void EntityList::DescribeAggro(Client *towho, NPC *from_who, float d, bool verbo if (engaged) { uint32 amm = from_who->GetHateAmount(mob); if (amm == 0) - towho->Message(0, "... %s is not on my hate list.", mob->GetName()); + towho->Message(Chat::White, "... %s is not on my hate list.", mob->GetName()); else - towho->Message(0, "... %s is on my hate list with value %lu", mob->GetName(), (unsigned long)amm); + towho->Message(Chat::White, "... %s is on my hate list with value %lu", mob->GetName(), (unsigned long)amm); } else if (!check_npcs && mob->IsNPC()) { - towho->Message(0, "... %s is an NPC and my npc_aggro is disabled.", mob->GetName()); + towho->Message(Chat::White, "... %s is an NPC and my npc_aggro is disabled.", mob->GetName()); } else { from_who->DescribeAggro(towho, mob, verbose); } @@ -114,13 +114,13 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { if(( t1 > iAggroRange) || ( t2 > iAggroRange) || ( t3 > iAggroRange) ) { - towho->Message(0, "...%s is out of range (fast). distances (%.3f,%.3f,%.3f), range %.3f", mob->GetName(), + towho->Message(Chat::White, "...%s is out of range (fast). distances (%.3f,%.3f,%.3f), range %.3f", mob->GetName(), t1, t2, t3, iAggroRange); return; } if(mob->IsInvisible(this)) { - towho->Message(0, "...%s is invisible to me. ", mob->GetName()); + towho->Message(Chat::White, "...%s is invisible to me. ", mob->GetName()); return; } if((mob->IsClient() && @@ -131,13 +131,13 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { ) )) { - towho->Message(0, "...%s is my owner. ", mob->GetName()); + towho->Message(Chat::White, "...%s is my owner. ", mob->GetName()); return; } if(mob == GetOwner()) { - towho->Message(0, "...%s a GM or is not connected. ", mob->GetName()); + towho->Message(Chat::White, "...%s a GM or is not connected. ", mob->GetName()); return; } @@ -145,7 +145,7 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { float iAggroRange2 = iAggroRange*iAggroRange; if( dist2 > iAggroRange2 ) { - towho->Message(0, "...%s is out of range. %.3f > %.3f ", mob->GetName(), + towho->Message(Chat::White, "...%s is out of range. %.3f > %.3f ", mob->GetName(), dist2, iAggroRange2); return; } @@ -154,14 +154,14 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { { if (GetLevel() < RuleI(Aggro, MinAggroLevel) && mob->GetLevelCon(GetLevel()) == CON_GRAY && GetBodyType() != 3) { - towho->Message(0, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2); + towho->Message(Chat::White, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2); return; } } else { if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GRAY ) { - towho->Message(0, "...%s is red to me (basically)", mob->GetName(), + towho->Message(Chat::White, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2); return; } @@ -178,9 +178,9 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { mob_primary = own->GetPrimaryFaction(); if(mob_primary == 0) { - towho->Message(0, "...%s has no primary faction", mob->GetName()); + towho->Message(Chat::White, "...%s has no primary faction", mob->GetName()); } else if(mob_primary < 0) { - towho->Message(0, "...%s is on special faction %d", mob->GetName(), mob_primary); + towho->Message(Chat::White, "...%s is on special faction %d", mob->GetName(), mob_primary); } else { char namebuf[256]; if(!database.GetFactionName(mob_primary, namebuf, sizeof(namebuf))) @@ -193,22 +193,22 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { struct NPCFaction* fac = *cur; if ((int32)fac->factionID == mob_primary) { if (fac->npc_value > 0) { - towho->Message(0, "...%s is on ALLY faction %s (%d) with %d", mob->GetName(), namebuf, mob_primary, fac->npc_value); + towho->Message(Chat::White, "...%s is on ALLY faction %s (%d) with %d", mob->GetName(), namebuf, mob_primary, fac->npc_value); res = true; break; } else if (fac->npc_value < 0) { - towho->Message(0, "...%s is on ENEMY faction %s (%d) with %d", mob->GetName(), namebuf, mob_primary, fac->npc_value); + towho->Message(Chat::White, "...%s is on ENEMY faction %s (%d) with %d", mob->GetName(), namebuf, mob_primary, fac->npc_value); res = true; break; } else { - towho->Message(0, "...%s is on NEUTRAL faction %s (%d) with 0", mob->GetName(), namebuf, mob_primary); + towho->Message(Chat::White, "...%s is on NEUTRAL faction %s (%d) with 0", mob->GetName(), namebuf, mob_primary); res = true; break; } } } if(!res) { - towho->Message(0, "...%s is on faction %s (%d), which I have no entry for.", mob->GetName(), namebuf, mob_primary); + towho->Message(Chat::White, "...%s is on faction %s (%d), which I have no entry for.", mob->GetName(), namebuf, mob_primary); } } } @@ -222,18 +222,18 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) { || fv == FACTION_THREATENLY )) { - towho->Message(0, "...%s faction not low enough. value='%s'", mob->GetName(), FactionValueToString(fv)); + towho->Message(Chat::White, "...%s faction not low enough. value='%s'", mob->GetName(), FactionValueToString(fv)); return; } if(fv == FACTION_THREATENLY) { - towho->Message(0, "...%s threatening to me, so they only have a %d chance per check of attacking.", mob->GetName()); + towho->Message(Chat::White, "...%s threatening to me, so they only have a %d chance per check of attacking.", mob->GetName()); } if(!CheckLosFN(mob)) { - towho->Message(0, "...%s is out of sight.", mob->GetName()); + towho->Message(Chat::White, "...%s is out of sight.", mob->GetName()); } - towho->Message(0, "...%s meets all conditions, I should be attacking them.", mob->GetName()); + towho->Message(Chat::White, "...%s meets all conditions, I should be attacking them.", mob->GetName()); } /* diff --git a/zone/bot.cpp b/zone/bot.cpp index daef58a9a..4398f2fd5 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3256,7 +3256,7 @@ bool Bot::Spawn(Client* botCharacterOwner) { this->texture = 0; //0xFF; if(this->Save()) - this->GetBotOwner()->CastToClient()->Message(0, "%s saved.", this->GetCleanName()); + this->GetBotOwner()->CastToClient()->Message(Chat::White, "%s saved.", this->GetCleanName()); else this->GetBotOwner()->CastToClient()->Message(Chat::Red, "%s save failed!", this->GetCleanName()); @@ -5987,7 +5987,7 @@ bool Bot::ProcessGuildRemoval(Client* guildOfficer, std::string botName) { GuildManageRemove_Struct* gm = (GuildManageRemove_Struct*) outapp->pBuffer; gm->guildeqid = guildOfficer->GuildID(); strcpy(gm->member, botName.c_str()); - guildOfficer->Message(0, "%s successfully removed from your guild.", botName.c_str()); + guildOfficer->Message(Chat::White, "%s successfully removed from your guild.", botName.c_str()); entity_list.QueueClientsGuild(guildOfficer, outapp, false, gm->guildeqid); safe_delete(outapp); } @@ -8180,7 +8180,7 @@ void Bot::CalcBotStats(bool showtext) { } //if(this->Save()) - // this->GetBotOwner()->CastToClient()->Message(0, "%s saved.", this->GetCleanName()); + // this->GetBotOwner()->CastToClient()->Message(Chat::White, "%s saved.", this->GetCleanName()); //else // this->GetBotOwner()->CastToClient()->Message(Chat::Red, "%s save failed!", this->GetCleanName()); @@ -8868,7 +8868,7 @@ bool Bot::UseDiscipline(uint32 spell_id, uint32 target) { SetDisciplineRecastTimer(spells[spell_id].EndurTimerIndex, spell.recast_time); } else { uint32 remain = (GetDisciplineRemainingTime(this, spells[spell_id].EndurTimerIndex) / 1000); - GetOwner()->Message(0, "%s can use this discipline in %d minutes %d seconds.", GetCleanName(), (remain / 60), (remain % 60)); + GetOwner()->Message(Chat::White, "%s can use this discipline in %d minutes %d seconds.", GetCleanName(), (remain / 60), (remain % 60)); return false; } } diff --git a/zone/client.cpp b/zone/client.cpp index dfee9a340..bf2fb3a0d 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -3845,7 +3845,7 @@ void Client::SendRules(Client* client) auto lines = SplitString(rules, '\n'); for (auto&& e : lines) - client->Message(0, "%s", e.c_str()); + client->Message(Chat::White, "%s", e.c_str()); } void Client::SetEndurance(int32 newEnd) @@ -5748,7 +5748,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) { strcpy(insr->text, requestee->GetInspectMessage().text); // There could be an OP for this..or not... (Ti clients are not processed here..this message is generated client-side) - if(requestee->IsClient() && (requestee != requester)) { requestee->Message(0, "%s is looking at your equipment...", requester->GetName()); } + if(requestee->IsClient() && (requestee != requester)) { requestee->Message(Chat::White, "%s is looking at your equipment...", requester->GetName()); } requester->QueuePacket(outapp); // Send answer to requester safe_delete(outapp); @@ -6855,30 +6855,30 @@ void Client::SendStatsWindow(Client* client, bool use_window) } client->Message(Chat::Yellow, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName()); - client->Message(0, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR()); - client->Message(0, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap()); - client->Message(0, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0)); - client->Message(0, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense()); - client->Message(0, " offense: %i mitigation ac: %i", offense(skill), GetMitigationAC()); + client->Message(Chat::White, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR()); + client->Message(Chat::White, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap()); + client->Message(Chat::White, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0)); + client->Message(Chat::White, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense()); + client->Message(Chat::White, " offense: %i mitigation ac: %i", offense(skill), GetMitigationAC()); if(CalcMaxMana() > 0) - client->Message(0, " Mana: %i/%i Mana Regen: %i/%i", GetMana(), GetMaxMana(), CalcManaRegen(), CalcManaRegenCap()); - client->Message(0, " End.: %i/%i End. Regen: %i/%i",GetEndurance(), GetMaxEndurance(), CalcEnduranceRegen(), CalcEnduranceRegenCap()); - client->Message(0, " ATK: %i Worn/Spell ATK %i/%i Server Side ATK: %i", GetTotalATK(), RuleI(Character, ItemATKCap), GetATKBonus(), GetATK()); - client->Message(0, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i)", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste); - client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); - client->Message(0, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA()); - client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR()); - client->Message(0, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup()); - client->Message(0, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects()); - client->Message(0, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit()); + client->Message(Chat::White, " Mana: %i/%i Mana Regen: %i/%i", GetMana(), GetMaxMana(), CalcManaRegen(), CalcManaRegenCap()); + client->Message(Chat::White, " End.: %i/%i End. Regen: %i/%i",GetEndurance(), GetMaxEndurance(), CalcEnduranceRegen(), CalcEnduranceRegenCap()); + client->Message(Chat::White, " ATK: %i Worn/Spell ATK %i/%i Server Side ATK: %i", GetTotalATK(), RuleI(Character, ItemATKCap), GetATKBonus(), GetATK()); + client->Message(Chat::White, " Haste: %i / %i (Item: %i + Spell: %i + Over: %i)", GetHaste(), RuleI(Character, HasteCap), itembonuses.haste, spellbonuses.haste + spellbonuses.hastetype2, spellbonuses.hastetype3 + ExtraHaste); + client->Message(Chat::White, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); + client->Message(Chat::White, " hSTR: %i hSTA: %i hDEX: %i hAGI: %i hINT: %i hWIS: %i hCHA: %i", GetHeroicSTR(), GetHeroicSTA(), GetHeroicDEX(), GetHeroicAGI(), GetHeroicINT(), GetHeroicWIS(), GetHeroicCHA()); + client->Message(Chat::White, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR()); + client->Message(Chat::White, " hMR: %i hPR: %i hFR: %i hCR: %i hDR: %i hCorruption: %i", GetHeroicMR(), GetHeroicPR(), GetHeroicFR(), GetHeroicCR(), GetHeroicDR(), GetHeroicCorrup()); + client->Message(Chat::White, " Shielding: %i Spell Shield: %i DoT Shielding: %i Stun Resist: %i Strikethrough: %i Avoidance: %i Accuracy: %i Combat Effects: %i", GetShielding(), GetSpellShield(), GetDoTShield(), GetStunResist(), GetStrikeThrough(), GetAvoidance(), GetAccuracy(), GetCombatEffects()); + client->Message(Chat::White, " Heal Amt.: %i Spell Dmg.: %i Clairvoyance: %i DS Mitigation: %i", GetHealAmt(), GetSpellDmg(), GetClair(), GetDSMit()); if(GetClass() == BARD) - client->Message(0, " Singing: %i Brass: %i String: %i Percussion: %i Wind: %i", GetSingMod(), GetBrassMod(), GetStringMod(), GetPercMod(), GetWindMod()); + client->Message(Chat::White, " Singing: %i Brass: %i String: %i Percussion: %i Wind: %i", GetSingMod(), GetBrassMod(), GetStringMod(), GetPercMod(), GetWindMod()); Extra_Info: - client->Message(0, " BaseRace: %i Gender: %i BaseGender: %i Texture: %i HelmTexture: %i", GetBaseRace(), GetGender(), GetBaseGender(), GetTexture(), GetHelmTexture()); + client->Message(Chat::White, " BaseRace: %i Gender: %i BaseGender: %i Texture: %i HelmTexture: %i", GetBaseRace(), GetGender(), GetBaseGender(), GetTexture(), GetHelmTexture()); if (client->Admin() >= 100) { - client->Message(0, " CharID: %i EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", CharacterID(), GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); + client->Message(Chat::White, " CharID: %i EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", CharacterID(), GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); } } @@ -7248,17 +7248,17 @@ void Client::ShowXTargets(Client *c) return; for(int i = 0; i < GetMaxXTargets(); ++i) - c->Message(0, "Xtarget Slot: %i, Type: %2i, ID: %4i, Name: %s", i, XTargets[i].Type, XTargets[i].ID, XTargets[i].Name); + c->Message(Chat::White, "Xtarget Slot: %i, Type: %2i, ID: %4i, Name: %s", i, XTargets[i].Type, XTargets[i].ID, XTargets[i].Name); auto &list = GetXTargetAutoMgr()->get_list(); // yeah, I kept having to do something for debugging to tell if managers were the same object or not :P // so lets use the address as an "ID" - c->Message(0, "XTargetAutoMgr ID %p size %d", GetXTargetAutoMgr(), list.size()); + c->Message(Chat::White, "XTargetAutoMgr ID %p size %d", GetXTargetAutoMgr(), list.size()); int count = 0; for (auto &e : list) { - c->Message(0, "spawn id %d count %d", e.spawn_id, e.count); + c->Message(Chat::White, "spawn id %d count %d", e.spawn_id, e.count); count++; if (count == 20) { // lets not spam too many ... - c->Message(0, " ... "); + c->Message(Chat::White, " ... "); break; } } diff --git a/zone/command.cpp b/zone/command.cpp index cf6cc6d6b..5ee0f1b1c 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -672,9 +672,9 @@ void command_setstat(Client* c, const Seperator* sep){ c->GetTarget()->CastToClient()->SetStats(atoi(sep->arg[1]),atoi(sep->arg[2])); } else{ - c->Message(0,"This command is used to permanently increase or decrease a players stats."); - c->Message(0,"Usage: #setstat {type} {value the stat should be}"); - c->Message(0,"Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); + c->Message(Chat::White,"This command is used to permanently increase or decrease a players stats."); + c->Message(Chat::White,"Usage: #setstat {type} {value the stat should be}"); + c->Message(Chat::White,"Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); } } @@ -683,10 +683,10 @@ void command_incstat(Client* c, const Seperator* sep){ c->GetTarget()->CastToClient()->IncStats(atoi(sep->arg[1]),atoi(sep->arg[2])); } else{ - c->Message(0,"This command is used to permanently increase or decrease a players stats."); - c->Message(0,"Usage: #setstat {type} {value by which to increase or decrease}"); - c->Message(0,"Note: The value is in increments of 2, so a value of 3 will actually increase the stat by 6"); - c->Message(0,"Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); + c->Message(Chat::White,"This command is used to permanently increase or decrease a players stats."); + c->Message(Chat::White,"Usage: #setstat {type} {value by which to increase or decrease}"); + c->Message(Chat::White,"Note: The value is in increments of 2, so a value of 3 will actually increase the stat by 6"); + c->Message(Chat::White,"Types: Str: 0, Sta: 1, Agi: 2, Dex: 3, Int: 4, Wis: 5, Cha: 6"); } } @@ -696,14 +696,14 @@ void command_resetaa(Client* c,const Seperator *sep) { c->Message(Chat::Red,"Successfully reset %s's AAs", c->GetTarget()->GetName()); } else - c->Message(0,"Usage: Target a client and use #resetaa to reset the AA data in their Profile."); + c->Message(Chat::White,"Usage: Target a client and use #resetaa to reset the AA data in their Profile."); } void command_help(Client *c, const Seperator *sep) { int commands_shown=0; - c->Message(0, "Available EQEMu commands:"); + c->Message(Chat::White, "Available EQEMu commands:"); std::map::iterator cur,end; cur = commandlist.begin(); @@ -719,24 +719,24 @@ void command_help(Client *c, const Seperator *sep) if(c->Admin() < cur->second->access) continue; commands_shown++; - c->Message(0, " %c%s %s", COMMAND_CHAR, cur->first.c_str(), cur->second->desc == nullptr?"":cur->second->desc); + c->Message(Chat::White, " %c%s %s", COMMAND_CHAR, cur->first.c_str(), cur->second->desc == nullptr?"":cur->second->desc); } - c->Message(0, "%d command%s listed.", commands_shown, commands_shown!=1?"s":""); + c->Message(Chat::White, "%d command%s listed.", commands_shown, commands_shown!=1?"s":""); } void command_version(Client *c, const Seperator *sep) { - c->Message(0, "Current version information."); - c->Message(0, " %s", CURRENT_VERSION); - c->Message(0, " Compiled on: %s at %s", COMPILE_DATE, COMPILE_TIME); - c->Message(0, " Last modified on: %s", LAST_MODIFIED); + c->Message(Chat::White, "Current version information."); + c->Message(Chat::White, " %s", CURRENT_VERSION); + c->Message(Chat::White, " Compiled on: %s at %s", COMPILE_DATE, COMPILE_TIME); + c->Message(Chat::White, " Last modified on: %s", LAST_MODIFIED); } void command_setfaction(Client *c, const Seperator *sep) { if((sep->arg[1][0] == 0 || strcasecmp(sep->arg[1],"*")==0) || ((c->GetTarget()==0) || (c->GetTarget()->IsClient()))) { - c->Message(0, "Usage: #setfaction [faction number]"); + c->Message(Chat::White, "Usage: #setfaction [faction number]"); return; } @@ -751,9 +751,9 @@ void command_setfaction(Client *c, const Seperator *sep) void command_serversidename(Client *c, const Seperator *sep) { if(c->GetTarget()) - c->Message(0, c->GetTarget()->GetName()); + c->Message(Chat::White, c->GetTarget()->GetName()); else - c->Message(0, "Error: no target"); + c->Message(Chat::White, "Error: no target"); } void command_wc(Client *c, const Seperator *sep) @@ -801,7 +801,7 @@ void command_wc(Client *c, const Seperator *sep) void command_heromodel(Client *c, const Seperator *sep) { if (sep->argnum < 1) { - c->Message(0, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)"); + c->Message(Chat::White, "Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)"); } else if (c->GetTarget() == nullptr) { c->Message(Chat::Red, "You must have a target to do a wear change for Hero's Forge Models."); @@ -836,12 +836,12 @@ void command_setanim(Client *c, const Seperator *sep) if (c->GetTarget() && sep->IsNumber(1)) { int num = atoi(sep->arg[1]); if (num < 0 || num >= _eaMaxAppearance) { - c->Message(0, "Invalid animation number, between 0 and %d", _eaMaxAppearance - 1); + c->Message(Chat::White, "Invalid animation number, between 0 and %d", _eaMaxAppearance - 1); } c->GetTarget()->SetAppearance(EmuAppearance(num)); } else { - c->Message(0, "Usage: #setanim [animnum]"); + c->Message(Chat::White, "Usage: #setanim [animnum]"); } } @@ -853,50 +853,50 @@ void command_serverinfo(Client *c, const Seperator *sep) auto rss = EQ::GetRSS(); auto uptime = EQ::GetUptime(); - c->Message(0, "Operating System Information"); - c->Message(0, "=================================================="); - c->Message(0, "System: %s", os.sysname.c_str()); - c->Message(0, "Release: %s", os.release.c_str()); - c->Message(0, "Version: %s", os.version.c_str()); - c->Message(0, "Machine: %s", os.machine.c_str()); - c->Message(0, "Uptime: %.2f seconds", uptime); - c->Message(0, "=================================================="); - c->Message(0, "CPU Information"); - c->Message(0, "=================================================="); + c->Message(Chat::White, "Operating System Information"); + c->Message(Chat::White, "=================================================="); + c->Message(Chat::White, "System: %s", os.sysname.c_str()); + c->Message(Chat::White, "Release: %s", os.release.c_str()); + c->Message(Chat::White, "Version: %s", os.version.c_str()); + c->Message(Chat::White, "Machine: %s", os.machine.c_str()); + c->Message(Chat::White, "Uptime: %.2f seconds", uptime); + c->Message(Chat::White, "=================================================="); + c->Message(Chat::White, "CPU Information"); + c->Message(Chat::White, "=================================================="); for (size_t i = 0; i < cpus.size(); ++i) { auto &cp = cpus[i]; - c->Message(0, "CPU #%i: %s, Speed: %.2fGhz", i, cp.model.c_str(), cp.speed); + c->Message(Chat::White, "CPU #%i: %s, Speed: %.2fGhz", i, cp.model.c_str(), cp.speed); } - c->Message(0, "=================================================="); - c->Message(0, "Process Information"); - c->Message(0, "=================================================="); - c->Message(0, "PID: %u", pid); - c->Message(0, "RSS: %.2f MB", rss / 1048576.0); - c->Message(0, "=================================================="); + c->Message(Chat::White, "=================================================="); + c->Message(Chat::White, "Process Information"); + c->Message(Chat::White, "=================================================="); + c->Message(Chat::White, "PID: %u", pid); + c->Message(Chat::White, "RSS: %.2f MB", rss / 1048576.0); + c->Message(Chat::White, "=================================================="); } void command_getvariable(Client *c, const Seperator *sep) { std::string tmp; if (database.GetVariable(sep->argplus[1], tmp)) - c->Message(0, "%s = %s", sep->argplus[1], tmp.c_str()); + c->Message(Chat::White, "%s = %s", sep->argplus[1], tmp.c_str()); else - c->Message(0, "GetVariable(%s) returned false", sep->argplus[1]); + c->Message(Chat::White, "GetVariable(%s) returned false", sep->argplus[1]); } void command_chat(Client *c, const Seperator *sep) { if (sep->arg[2][0] == 0) - c->Message(0, "Usage: #chat [channum] [message]"); + c->Message(Chat::White, "Usage: #chat [channum] [message]"); else if (!worldserver.SendChannelMessage(0, 0, (uint8) atoi(sep->arg[1]), 0, 0, 100, sep->argplus[2])) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); } void command_npcloot(Client *c, const Seperator *sep) { if (c->GetTarget() == 0) - c->Message(0, "Error: No target"); + c->Message(Chat::White, "Error: No target"); // #npcloot show else if (strcasecmp(sep->arg[1], "show") == 0) { @@ -905,11 +905,11 @@ void command_npcloot(Client *c, const Seperator *sep) else if (c->GetTarget()->IsCorpse()) c->GetTarget()->CastToCorpse()->QueryLoot(c); else - c->Message(0, "Error: Target's type doesnt have loot"); + c->Message(Chat::White, "Error: Target's type doesnt have loot"); } // These 2 types are *BAD* for the next few commands else if (c->GetTarget()->IsClient() || c->GetTarget()->IsCorpse()) - c->Message(0, "Error: Invalid target type, try a NPC =)."); + c->Message(Chat::White, "Error: Invalid target type, try a NPC =)."); // #npcloot add else if (strcasecmp(sep->arg[1], "add") == 0) { @@ -923,22 +923,22 @@ void command_npcloot(Client *c, const Seperator *sep) c->GetTarget()->CastToNPC()->AddItem(item, atoi(sep->arg[3]), 0); else c->GetTarget()->CastToNPC()->AddItem(item, 1, 0); - c->Message(0, "Added item(%i) to the %s's loot.", item, c->GetTarget()->GetName()); + c->Message(Chat::White, "Added item(%i) to the %s's loot.", item, c->GetTarget()->GetName()); } else - c->Message(0, "Error: #npcloot add: Item(%i) does not exist!", item); + c->Message(Chat::White, "Error: #npcloot add: Item(%i) does not exist!", item); } else if (!sep->IsNumber(2)) - c->Message(0, "Error: #npcloot add: Itemid must be a number."); + c->Message(Chat::White, "Error: #npcloot add: Itemid must be a number."); else - c->Message(0, "Error: #npcloot add: This is not a valid target."); + c->Message(Chat::White, "Error: #npcloot add: This is not a valid target."); } // #npcloot remove else if (strcasecmp(sep->arg[1], "remove") == 0) { //#npcloot remove all if (strcasecmp(sep->arg[2], "all") == 0) - c->Message(0, "Error: #npcloot remove all: Not yet implemented."); + c->Message(Chat::White, "Error: #npcloot remove all: Not yet implemented."); //#npcloot remove itemid else { @@ -946,12 +946,12 @@ void command_npcloot(Client *c, const Seperator *sep) { uint32 item = atoi(sep->arg[2]); c->GetTarget()->CastToNPC()->RemoveItem(item); - c->Message(0, "Removed item(%i) from the %s's loot.", item, c->GetTarget()->GetName()); + c->Message(Chat::White, "Removed item(%i) from the %s's loot.", item, c->GetTarget()->GetName()); } else if (!sep->IsNumber(2)) - c->Message(0, "Error: #npcloot remove: Item must be a number."); + c->Message(Chat::White, "Error: #npcloot remove: Item must be a number."); else - c->Message(0, "Error: #npcloot remove: This is not a valid target."); + c->Message(Chat::White, "Error: #npcloot remove: This is not a valid target."); } } // #npcloot money @@ -962,16 +962,16 @@ void command_npcloot(Client *c, const Seperator *sep) if ((atoi(sep->arg[2]) < 34465 && atoi(sep->arg[2]) >= 0) && (atoi(sep->arg[3]) < 34465 && atoi(sep->arg[3]) >= 0) && (atoi(sep->arg[4]) < 34465 && atoi(sep->arg[4]) >= 0) && (atoi(sep->arg[5]) < 34465 && atoi(sep->arg[5]) >= 0)) { c->GetTarget()->CastToNPC()->AddCash(atoi(sep->arg[5]), atoi(sep->arg[4]), atoi(sep->arg[3]), atoi(sep->arg[2])); - c->Message(0, "Set %i Platinum, %i Gold, %i Silver, and %i Copper as %s's money.", atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), c->GetTarget()->GetName()); + c->Message(Chat::White, "Set %i Platinum, %i Gold, %i Silver, and %i Copper as %s's money.", atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), atoi(sep->arg[5]), c->GetTarget()->GetName()); } else - c->Message(0, "Error: #npcloot money: Values must be between 0-34465."); + c->Message(Chat::White, "Error: #npcloot money: Values must be between 0-34465."); } else - c->Message(0, "Usage: #npcloot money platinum gold silver copper"); + c->Message(Chat::White, "Usage: #npcloot money platinum gold silver copper"); } else - c->Message(0, "Usage: #npcloot [show/money/add/remove] [itemid/all/money: pp gp sp cp]"); + c->Message(Chat::White, "Usage: #npcloot [show/money/add/remove] [itemid/all/money: pp gp sp cp]"); } void command_gm(Client *c, const Seperator *sep) @@ -984,10 +984,10 @@ void command_gm(Client *c, const Seperator *sep) if(sep->arg[1][0] != 0) { t->SetGM(state); - c->Message(0, "%s is %s a GM.", t->GetName(), state?"now":"no longer"); + c->Message(Chat::White, "%s is %s a GM.", t->GetName(), state?"now":"no longer"); } else - c->Message(0, "Usage: #gm [on/off]"); + c->Message(Chat::White, "Usage: #gm [on/off]"); } // there's no need for this, as /summon already takes care of it @@ -1009,11 +1009,11 @@ void command_summon(Client *c, const Seperator *sep) else { if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected."); + c->Message(Chat::White, "Error: World server disconnected."); else { // player is in another zone //Taking this command out until we test the factor of 8 in ServerOP_ZonePlayer - //c->Message(0, "Summoning player from another zone not yet implemented."); + //c->Message(Chat::White, "Summoning player from another zone not yet implemented."); //return; auto pack = new ServerPacket(ServerOP_ZonePlayer, sizeof(ServerZonePlayer_Struct)); @@ -1038,9 +1038,9 @@ void command_summon(Client *c, const Seperator *sep) else { /*if(c->Admin() < 150) - c->Message(0, "You need a NPC/corpse target for this command"); + c->Message(Chat::White, "You need a NPC/corpse target for this command"); else*/ - c->Message(0, "Usage: #summon [charname] Either target or charname is required"); + c->Message(Chat::White, "Usage: #summon [charname] Either target or charname is required"); return; } @@ -1049,23 +1049,23 @@ void command_summon(Client *c, const Seperator *sep) if (t->IsNPC()) { // npc target - c->Message(0, "Summoning NPC %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); + c->Message(Chat::White, "Summoning NPC %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); t->CastToNPC()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); t->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f)); } else if (t->IsCorpse()) { // corpse target - c->Message(0, "Summoning corpse %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); + c->Message(Chat::White, "Summoning corpse %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); t->CastToCorpse()->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); } else if (t->IsClient()) { /*if(c->Admin() < 150) { - c->Message(0, "You may not summon a player."); + c->Message(Chat::White, "You may not summon a player."); return; }*/ - c->Message(0, "Summoning player %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); + c->Message(Chat::White, "Summoning player %s to %1.1f, %1.1f, %1.1f", t->GetName(), c->GetX(), c->GetY(), c->GetZ()); t->CastToClient()->MovePC(zone->GetZoneID(), zone->GetInstanceID(), c->GetX(), c->GetY(), c->GetZ(), c->GetHeading(), 2, GMSummon); } } @@ -1074,7 +1074,7 @@ void command_zone(Client *c, const Seperator *sep) { if(c->Admin() < commandZoneToCoords && (sep->IsNumber(2) || sep->IsNumber(3) || sep->IsNumber(4))) { - c->Message(0, "Your status is not high enough to zone to specific coordinates."); + c->Message(Chat::White, "Your status is not high enough to zone to specific coordinates."); return; } @@ -1083,29 +1083,29 @@ void command_zone(Client *c, const Seperator *sep) if (sep->IsNumber(1)) { if(atoi(sep->arg[1])==26 && (c->Admin() < commandZoneToSpecials)){ //cshome - c->Message(0, "Only Guides and above can goto that zone."); + c->Message(Chat::White, "Only Guides and above can goto that zone."); return; } zoneid = atoi(sep->arg[1]); } else if (sep->arg[1][0] == 0) { - c->Message(0, "Usage: #zone [zonename]"); - c->Message(0, "Optional Usage: #zone [zonename] y x z"); + c->Message(Chat::White, "Usage: #zone [zonename]"); + c->Message(Chat::White, "Optional Usage: #zone [zonename] y x z"); return; } else if (zone->GetZoneID() == 184 && c->Admin() < commandZoneToSpecials) { // Zone: 'Load' - c->Message(0, "The Gods brought you here, only they can send you away."); + c->Message(Chat::White, "The Gods brought you here, only they can send you away."); return; } else { if((strcasecmp(sep->arg[1], "cshome")==0) && (c->Admin() < commandZoneToSpecials)){ - c->Message(0, "Only Guides and above can goto that zone."); + c->Message(Chat::White, "Only Guides and above can goto that zone."); return; } zoneid = database.GetZoneID(sep->arg[1]); if(zoneid == 0) { - c->Message(0, "Unable to locate zone '%s'", sep->arg[1]); + c->Message(Chat::White, "Unable to locate zone '%s'", sep->arg[1]); return; } } @@ -1130,14 +1130,14 @@ void command_zone_instance(Client *c, const Seperator *sep) { if(c->Admin() < commandZoneToCoords && (sep->IsNumber(2) || sep->IsNumber(3) || sep->IsNumber(4))) { - c->Message(0, "Your status is not high enough to zone to specific coordinates."); + c->Message(Chat::White, "Your status is not high enough to zone to specific coordinates."); return; } if (sep->arg[1][0] == 0) { - c->Message(0, "Usage: #zoneinstance [instance id]"); - c->Message(0, "Optional Usage: #zoneinstance [instance id] y x z"); + c->Message(Chat::White, "Usage: #zoneinstance [instance id]"); + c->Message(Chat::White, "Optional Usage: #zoneinstance [instance id] y x z"); return; } @@ -1149,26 +1149,26 @@ void command_zone_instance(Client *c, const Seperator *sep) instanceid = atoi(sep->arg[1]); if(!instanceid) { - c->Message(0, "Must enter a valid instance id."); + c->Message(Chat::White, "Must enter a valid instance id."); return; } zoneid = database.ZoneIDFromInstanceID(instanceid); if(!zoneid) { - c->Message(0, "Instance not found or zone is set to null."); + c->Message(Chat::White, "Instance not found or zone is set to null."); return; } } else { - c->Message(0, "Must enter a valid instance id."); + c->Message(Chat::White, "Must enter a valid instance id."); return; } if(!database.VerifyInstanceAlive(instanceid, c->CharacterID())) { - c->Message(0, "Instance ID expiried or you are not apart of this instance."); + c->Message(Chat::White, "Instance ID expiried or you are not apart of this instance."); return; } @@ -1199,7 +1199,7 @@ void command_peqzone(Client *c, const Seperator *sep) } if(c->GetHPRatio() < 75) { - c->Message(0, "You cannot use this command with less than 75 percent health."); + c->Message(Chat::White, "You cannot use this command with less than 75 percent health."); return; } @@ -1212,7 +1212,7 @@ void command_peqzone(Client *c, const Seperator *sep) || c->AutoAttackEnabled() || c->GetInvul() ) { - c->Message(0, "You cannot use this command in your current state. Settle down and wait."); + c->Message(Chat::White, "You cannot use this command in your current state. Settle down and wait."); return; } @@ -1233,15 +1233,15 @@ void command_peqzone(Client *c, const Seperator *sep) } else if (sep->arg[1][0] == 0 || sep->IsNumber(2) || sep->IsNumber(3) || sep->IsNumber(4) || sep->IsNumber(5)) { - c->Message(0, "Usage: #peqzone [zonename]"); - c->Message(0, "Optional Usage: #peqzone [zoneid]"); + c->Message(Chat::White, "Usage: #peqzone [zonename]"); + c->Message(Chat::White, "Optional Usage: #peqzone [zoneid]"); return; } else { zoneid = database.GetZoneID(sep->arg[1]); destzone = database.GetPEQZone(zoneid, 0); if(zoneid == 0) { - c->Message(0, "Unable to locate zone '%s'", sep->arg[1]); + c->Message(Chat::White, "Unable to locate zone '%s'", sep->arg[1]); return; } if(destzone == 0){ @@ -1267,9 +1267,9 @@ void command_peqzone(Client *c, const Seperator *sep) void command_movechar(Client *c, const Seperator *sep) { if(sep->arg[1][0]==0 || sep->arg[2][0] == 0) - c->Message(0, "Usage: #movechar [charactername] [zonename]"); + c->Message(Chat::White, "Usage: #movechar [charactername] [zonename]"); else if (c->Admin() < commandMovecharToSpecials && strcasecmp(sep->arg[2], "cshome") == 0 || strcasecmp(sep->arg[2], "load") == 0 || strcasecmp(sep->arg[2], "load2") == 0) - c->Message(0, "Invalid zone name"); + c->Message(Chat::White, "Invalid zone name"); else { uint32 tmp = database.GetAccountIDByChar(sep->arg[1]); @@ -1277,14 +1277,14 @@ void command_movechar(Client *c, const Seperator *sep) { if (c->Admin() >= commandMovecharSelfOnly || tmp == c->AccountID()) if (!database.MoveCharacterToZone((char*) sep->arg[1], (char*) sep->arg[2])) - c->Message(0, "Character Move Failed!"); + c->Message(Chat::White, "Character Move Failed!"); else - c->Message(0, "Character has been moved."); + c->Message(Chat::White, "Character has been moved."); else c->Message(Chat::Red,"You cannot move characters that are not on your account."); } else - c->Message(0, "Character Does Not Exist"); + c->Message(Chat::White, "Character Does Not Exist"); } } @@ -1293,7 +1293,7 @@ void command_movement(Client *c, const Seperator *sep) auto &mgr = MobMovementManager::Get(); if (sep->arg[1][0] == 0) { - c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet"); + c->Message(Chat::White, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet"); return; } @@ -1309,7 +1309,7 @@ void command_movement(Client *c, const Seperator *sep) { auto target = c->GetTarget(); if (target == nullptr) { - c->Message(0, "No target found."); + c->Message(Chat::White, "No target found."); return; } @@ -1319,7 +1319,7 @@ void command_movement(Client *c, const Seperator *sep) { auto target = c->GetTarget(); if (target == nullptr) { - c->Message(0, "No target found."); + c->Message(Chat::White, "No target found."); return; } @@ -1329,7 +1329,7 @@ void command_movement(Client *c, const Seperator *sep) { auto target = c->GetTarget(); if (target == nullptr) { - c->Message(0, "No target found."); + c->Message(Chat::White, "No target found."); return; } @@ -1339,7 +1339,7 @@ void command_movement(Client *c, const Seperator *sep) { auto target = c->GetTarget(); if (target == nullptr) { - c->Message(0, "No target found."); + c->Message(Chat::White, "No target found."); return; } @@ -1349,21 +1349,21 @@ void command_movement(Client *c, const Seperator *sep) { auto target = c->GetTarget(); if (target == nullptr) { - c->Message(0, "No target found."); + c->Message(Chat::White, "No target found."); return; } mgr.SendCommandToClients(target, atof(sep->arg[2]), atof(sep->arg[3]), atof(sep->arg[4]), atof(sep->arg[5]), atoi(sep->arg[6]), ClientRangeAny); } else { - c->Message(0, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet"); + c->Message(Chat::White, "Usage: #movement stats/clearstats/walkto/runto/rotateto/stop/packet"); } } void command_viewpetition(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) { - c->Message(0, "Usage: #viewpetition (petition number) Type #listpetition for a list"); + c->Message(Chat::White, "Usage: #viewpetition (petition number) Type #listpetition for a list"); return; } @@ -1390,7 +1390,7 @@ void command_viewpetition(Client *c, const Seperator *sep) void command_petitioninfo(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) { - c->Message(0, "Usage: #petitioninfo (petition number) Type #listpetition for a list"); + c->Message(Chat::White, "Usage: #petitioninfo (petition number) Type #listpetition for a list"); return; } @@ -1415,7 +1415,7 @@ void command_petitioninfo(Client *c, const Seperator *sep) void command_delpetition(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1],"*") == 0) { - c->Message(0, "Usage: #delpetition (petition number) Type #listpetition for a list"); + c->Message(Chat::White, "Usage: #delpetition (petition number) Type #listpetition for a list"); return; } @@ -1431,7 +1431,7 @@ void command_delpetition(Client *c, const Seperator *sep) void command_listnpcs(Client *c, const Seperator *sep) { - c->Message(0, "Deprecated, use the #list command (#list npcs )"); + c->Message(Chat::White, "Deprecated, use the #list command (#list npcs )"); } void command_list(Client *c, const Seperator *sep) @@ -1688,9 +1688,9 @@ void command_list(Client *c, const Seperator *sep) } } else { - c->Message(0, "Usage of #list"); - c->Message(0, "- #list [npcs|players|corpses|doors|objects] [search]"); - c->Message(0, "- Example: #list npc (Blank for all)"); + c->Message(Chat::White, "Usage of #list"); + c->Message(Chat::White, "- #list [npcs|players|corpses|doors|objects] [search]"); + c->Message(Chat::White, "- Example: #list npc (Blank for all)"); } } @@ -1752,10 +1752,10 @@ void command_invul(Client *c, const Seperator *sep) if(sep->arg[1][0] != 0) { t->SetInvul(state); - c->Message(0, "%s is %s invulnerable from attack.", t->GetName(), state?"now":"no longer"); + c->Message(Chat::White, "%s is %s invulnerable from attack.", t->GetName(), state?"now":"no longer"); } else - c->Message(0, "Usage: #invulnerable [on/off]"); + c->Message(Chat::White, "Usage: #invulnerable [on/off]"); } void command_hideme(Client *c, const Seperator *sep) @@ -1763,7 +1763,7 @@ void command_hideme(Client *c, const Seperator *sep) bool state=atobool(sep->arg[1]); if(sep->arg[1][0]==0) - c->Message(0, "Usage: #hideme [on/off]"); + c->Message(Chat::White, "Usage: #hideme [on/off]"); else { c->SetHideMe(state); @@ -1774,7 +1774,7 @@ void command_hideme(Client *c, const Seperator *sep) void command_emote(Client *c, const Seperator *sep) { if (sep->arg[3][0] == 0) - c->Message(0, "Usage: #emote [name | world | zone] type# message"); + c->Message(Chat::White, "Usage: #emote [name | world | zone] type# message"); else { if (strcasecmp(sep->arg[1], "zone") == 0){ char* newmessage=0; @@ -1786,7 +1786,7 @@ void command_emote(Client *c, const Seperator *sep) } } else if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else if (strcasecmp(sep->arg[1], "world") == 0) worldserver.SendEmoteMessage(0, 0, atoi(sep->arg[2]), sep->argplus[3]); else @@ -1798,42 +1798,42 @@ void command_fov(Client *c, const Seperator *sep) { if(c->GetTarget()) if(c->BehindMob(c->GetTarget(), c->GetX(), c->GetY())) - c->Message(0, "You are behind mob %s, it is looking to %d", c->GetTarget()->GetName(), c->GetTarget()->GetHeading()); + c->Message(Chat::White, "You are behind mob %s, it is looking to %d", c->GetTarget()->GetName(), c->GetTarget()->GetHeading()); else - c->Message(0, "You are NOT behind mob %s, it is looking to %d", c->GetTarget()->GetName(), c->GetTarget()->GetHeading()); + c->Message(Chat::White, "You are NOT behind mob %s, it is looking to %d", c->GetTarget()->GetName(), c->GetTarget()->GetHeading()); else - c->Message(0, "I Need a target!"); + c->Message(Chat::White, "I Need a target!"); } void command_npcstats(Client *c, const Seperator *sep) { if (c->GetTarget() == 0) - c->Message(0, "ERROR: No target!"); + c->Message(Chat::White, "ERROR: No target!"); else if (!c->GetTarget()->IsNPC()) - c->Message(0, "ERROR: Target is not a NPC!"); + c->Message(Chat::White, "ERROR: Target is not a NPC!"); else { auto target_npc = c->GetTarget()->CastToNPC(); - c->Message(0, "# NPC Stats"); - c->Message(0, "- Name: %s NpcID: %u", target_npc->GetName(), target_npc->GetNPCTypeID()); - c->Message(0, "- Race: %i Level: %i Class: %i Material: %i", target_npc->GetRace(), target_npc->GetLevel(), target_npc->GetClass(), target_npc->GetTexture()); - c->Message(0, "- Current HP: %i Max HP: %i", target_npc->GetHP(), target_npc->GetMaxHP()); - //c->Message(0, "Weapon Item Number: %s", target_npc->GetWeapNo()); - c->Message(0, "- Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType()); - c->Message(0, "- Runspeed: %.3f Walkspeed: %.3f", static_cast(0.025f * target_npc->GetRunspeed()), static_cast(0.025f * target_npc->GetWalkspeed())); - c->Message(0, "- Spawn Group: %i Grid: %i", target_npc->GetSp2(), target_npc->GetGrid()); + c->Message(Chat::White, "# NPC Stats"); + c->Message(Chat::White, "- Name: %s NpcID: %u", target_npc->GetName(), target_npc->GetNPCTypeID()); + c->Message(Chat::White, "- Race: %i Level: %i Class: %i Material: %i", target_npc->GetRace(), target_npc->GetLevel(), target_npc->GetClass(), target_npc->GetTexture()); + c->Message(Chat::White, "- Current HP: %i Max HP: %i", target_npc->GetHP(), target_npc->GetMaxHP()); + //c->Message(Chat::White, "Weapon Item Number: %s", target_npc->GetWeapNo()); + c->Message(Chat::White, "- Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType()); + c->Message(Chat::White, "- Runspeed: %.3f Walkspeed: %.3f", static_cast(0.025f * target_npc->GetRunspeed()), static_cast(0.025f * target_npc->GetWalkspeed())); + c->Message(Chat::White, "- Spawn Group: %i Grid: %i", target_npc->GetSp2(), target_npc->GetGrid()); if (target_npc->proximity) { - c->Message(0, "- Proximity: Enabled"); - c->Message(0, "-- Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ()); - c->Message(0, "-- Min_X: %1.3f(%1.3f), Max_X: %1.3f(%1.3f), X_Range: %1.3f", target_npc->proximity->min_x, (target_npc->proximity->min_x - target_npc->GetX()), target_npc->proximity->max_x, (target_npc->proximity->max_x - target_npc->GetX()), (target_npc->proximity->max_x - target_npc->proximity->min_x)); - c->Message(0, "-- Min_Y: %1.3f(%1.3f), Max_Y: %1.3f(%1.3f), Y_Range: %1.3f", target_npc->proximity->min_y, (target_npc->proximity->min_y - target_npc->GetY()), target_npc->proximity->max_y, (target_npc->proximity->max_y - target_npc->GetY()), (target_npc->proximity->max_y - target_npc->proximity->min_y)); - c->Message(0, "-- Min_Z: %1.3f(%1.3f), Max_Z: %1.3f(%1.3f), Z_Range: %1.3f", target_npc->proximity->min_z, (target_npc->proximity->min_z - target_npc->GetZ()), target_npc->proximity->max_z, (target_npc->proximity->max_z - target_npc->GetZ()), (target_npc->proximity->max_z - target_npc->proximity->min_z)); - c->Message(0, "-- Say: %s", (target_npc->proximity->say ? "Enabled" : "Disabled")); + c->Message(Chat::White, "- Proximity: Enabled"); + c->Message(Chat::White, "-- Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ()); + c->Message(Chat::White, "-- Min_X: %1.3f(%1.3f), Max_X: %1.3f(%1.3f), X_Range: %1.3f", target_npc->proximity->min_x, (target_npc->proximity->min_x - target_npc->GetX()), target_npc->proximity->max_x, (target_npc->proximity->max_x - target_npc->GetX()), (target_npc->proximity->max_x - target_npc->proximity->min_x)); + c->Message(Chat::White, "-- Min_Y: %1.3f(%1.3f), Max_Y: %1.3f(%1.3f), Y_Range: %1.3f", target_npc->proximity->min_y, (target_npc->proximity->min_y - target_npc->GetY()), target_npc->proximity->max_y, (target_npc->proximity->max_y - target_npc->GetY()), (target_npc->proximity->max_y - target_npc->proximity->min_y)); + c->Message(Chat::White, "-- Min_Z: %1.3f(%1.3f), Max_Z: %1.3f(%1.3f), Z_Range: %1.3f", target_npc->proximity->min_z, (target_npc->proximity->min_z - target_npc->GetZ()), target_npc->proximity->max_z, (target_npc->proximity->max_z - target_npc->GetZ()), (target_npc->proximity->max_z - target_npc->proximity->min_z)); + c->Message(Chat::White, "-- Say: %s", (target_npc->proximity->say ? "Enabled" : "Disabled")); } else { - c->Message(0, "-Proximity: Disabled"); + c->Message(Chat::White, "-Proximity: Disabled"); } - c->Message(0, ""); - c->Message(0, "EmoteID: %i", target_npc->GetEmoteID()); + c->Message(Chat::White, ""); + c->Message(Chat::White, "EmoteID: %i", target_npc->GetEmoteID()); target_npc->QueryLoot(c); } } @@ -1842,13 +1842,13 @@ void command_zclip(Client *c, const Seperator *sep) { // modifys and resends zhdr packet if(sep->arg[2][0]==0) - c->Message(0, "Usage: #zclip "); + c->Message(Chat::White, "Usage: #zclip "); else if(atoi(sep->arg[1])<=0) - c->Message(0, "ERROR: Min clip can not be zero or less!"); + c->Message(Chat::White, "ERROR: Min clip can not be zero or less!"); else if(atoi(sep->arg[2])<=0) - c->Message(0, "ERROR: Max clip can not be zero or less!"); + c->Message(Chat::White, "ERROR: Max clip can not be zero or less!"); else if(atoi(sep->arg[1])>atoi(sep->arg[2])) - c->Message(0, "ERROR: Min clip is greater than max clip!"); + c->Message(Chat::White, "ERROR: Min clip is greater than max clip!"); else { zone->newzone_data.minclip = atof(sep->arg[1]); zone->newzone_data.maxclip = atof(sep->arg[2]); @@ -1874,27 +1874,27 @@ void command_npccast(Client *c, const Seperator *sep) if (spelltar) c->GetTarget()->CastSpell(atoi(sep->arg[2]), spelltar->GetID()); else - c->Message(0, "Error: %s not found", sep->arg[1]); + c->Message(Chat::White, "Error: %s not found", sep->arg[1]); } else if (c->GetTarget() && c->GetTarget()->IsNPC() && sep->IsNumber(1) && sep->IsNumber(2) ) { Mob* spelltar = entity_list.GetMob(atoi(sep->arg[1])); if (spelltar) c->GetTarget()->CastSpell(atoi(sep->arg[2]), spelltar->GetID()); else - c->Message(0, "Error: target ID %i not found", atoi(sep->arg[1])); + c->Message(Chat::White, "Error: target ID %i not found", atoi(sep->arg[1])); } else - c->Message(0, "Usage: (needs NPC targeted) #npccast targetname/entityid spellid"); + c->Message(Chat::White, "Usage: (needs NPC targeted) #npccast targetname/entityid spellid"); } void command_zstats(Client *c, const Seperator *sep) { - c->Message(0, "Zone Header Data:"); - c->Message(0, "Sky Type: %i", zone->newzone_data.sky); - c->Message(0, "Fog Colour: Red: %i; Blue: %i; Green %i", zone->newzone_data.fog_red[0], zone->newzone_data.fog_green[0], zone->newzone_data.fog_blue[0]); - c->Message(0, "Safe Coords: %f, %f, %f", zone->newzone_data.safe_x, zone->newzone_data.safe_y, zone->newzone_data.safe_z); - c->Message(0, "Underworld Coords: %f", zone->newzone_data.underworld); - c->Message(0, "Clip Plane: %f - %f", zone->newzone_data.minclip, zone->newzone_data.maxclip); + c->Message(Chat::White, "Zone Header Data:"); + c->Message(Chat::White, "Sky Type: %i", zone->newzone_data.sky); + c->Message(Chat::White, "Fog Colour: Red: %i; Blue: %i; Green %i", zone->newzone_data.fog_red[0], zone->newzone_data.fog_green[0], zone->newzone_data.fog_blue[0]); + c->Message(Chat::White, "Safe Coords: %f, %f, %f", zone->newzone_data.safe_x, zone->newzone_data.safe_y, zone->newzone_data.safe_z); + c->Message(Chat::White, "Underworld Coords: %f", zone->newzone_data.underworld); + c->Message(Chat::White, "Clip Plane: %f - %f", zone->newzone_data.minclip, zone->newzone_data.maxclip); } void command_permaclass(Client *c, const Seperator *sep) @@ -1905,12 +1905,12 @@ void command_permaclass(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(sep->arg[1][0]==0) { - c->Message(0,"Usage: #permaclass "); + c->Message(Chat::White,"Usage: #permaclass "); } else if(!t->IsClient()) - c->Message(0,"Target is not a client."); + c->Message(Chat::White,"Target is not a client."); else { - c->Message(0, "Setting %s's class...Sending to char select.", t->GetName()); + c->Message(Chat::White, "Setting %s's class...Sending to char select.", t->GetName()); Log(Logs::General, Logs::Normal, "Class change request from %s for %s, requested class:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); t->SetBaseClass(atoi(sep->arg[1])); t->Save(); @@ -1926,13 +1926,13 @@ void command_permarace(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(sep->arg[1][0]==0) { - c->Message(0,"Usage: #permarace "); - c->Message(0,"NOTE: Not all models are global. If a model is not global, it will appear as a human on character select and in zones without the model."); + c->Message(Chat::White,"Usage: #permarace "); + c->Message(Chat::White,"NOTE: Not all models are global. If a model is not global, it will appear as a human on character select and in zones without the model."); } else if(!t->IsClient()) - c->Message(0,"Target is not a client."); + c->Message(Chat::White,"Target is not a client."); else { - c->Message(0, "Setting %s's race - zone to take effect", t->GetName()); + c->Message(Chat::White, "Setting %s's race - zone to take effect", t->GetName()); Log(Logs::General, Logs::Normal, "Permanant race change request from %s for %s, requested race:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); uint32 tmp = Mob::GetDefaultGender(atoi(sep->arg[1]), t->GetBaseGender()); t->SetBaseRace(atoi(sep->arg[1])); @@ -1950,13 +1950,13 @@ void command_permagender(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(sep->arg[1][0]==0) { - c->Message(0,"Usage: #permagender "); - c->Message(0,"Gender Numbers: 0=Male, 1=Female, 2=Neuter"); + c->Message(Chat::White,"Usage: #permagender "); + c->Message(Chat::White,"Gender Numbers: 0=Male, 1=Female, 2=Neuter"); } else if(!t->IsClient()) - c->Message(0,"Target is not a client."); + c->Message(Chat::White,"Target is not a client."); else { - c->Message(0, "Setting %s's gender - zone to take effect", t->GetName()); + c->Message(Chat::White, "Setting %s's gender - zone to take effect", t->GetName()); Log(Logs::General, Logs::Normal, "Permanant gender change request from %s for %s, requested gender:%i", c->GetName(), t->GetName(), atoi(sep->arg[1]) ); t->SetBaseGender(atoi(sep->arg[1])); t->Save(); @@ -1967,12 +1967,12 @@ void command_permagender(Client *c, const Seperator *sep) void command_weather(Client *c, const Seperator *sep) { if (!(sep->arg[1][0] == '0' || sep->arg[1][0] == '1' || sep->arg[1][0] == '2' || sep->arg[1][0] == '3')) { - c->Message(0, "Usage: #weather <0/1/2/3> - Off/Rain/Snow/Manual."); + c->Message(Chat::White, "Usage: #weather <0/1/2/3> - Off/Rain/Snow/Manual."); } else if(zone->zone_weather == 0) { if(sep->arg[1][0] == '3') { // Put in modifications here because it had a very good chance at screwing up the client's weather system if rain was sent during snow -T7 if(sep->arg[2][0] != 0 && sep->arg[3][0] != 0) { - c->Message(0, "Sending weather packet... TYPE=%s, INTENSITY=%s", sep->arg[2], sep->arg[3]); + c->Message(Chat::White, "Sending weather packet... TYPE=%s, INTENSITY=%s", sep->arg[2], sep->arg[3]); zone->zone_weather = atoi(sep->arg[2]); auto outapp = new EQApplicationPacket(OP_Weather, 8); outapp->pBuffer[0] = atoi(sep->arg[2]); @@ -1981,7 +1981,7 @@ void command_weather(Client *c, const Seperator *sep) safe_delete(outapp); } else { - c->Message(0, "Manual Usage: #weather 3 "); + c->Message(Chat::White, "Manual Usage: #weather 3 "); } } else if(sep->arg[1][0] == '2') { @@ -2035,16 +2035,16 @@ void command_zheader(Client *c, const Seperator *sep) { // sends zhdr packet if(sep->arg[1][0]==0) { - c->Message(0, "Usage: #zheader "); + c->Message(Chat::White, "Usage: #zheader "); } else if(database.GetZoneID(sep->argplus[1])==0) - c->Message(0, "Invalid Zone Name: %s", sep->argplus[1]); + c->Message(Chat::White, "Invalid Zone Name: %s", sep->argplus[1]); else { if (zone->LoadZoneCFG(sep->argplus[1], 0)) - c->Message(0, "Successfully loaded zone header for %s from database.", sep->argplus[1]); + c->Message(Chat::White, "Successfully loaded zone header for %s from database.", sep->argplus[1]); else - c->Message(0, "Failed to load zone header %s from database", sep->argplus[1]); + c->Message(Chat::White, "Failed to load zone header %s from database", sep->argplus[1]); auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(c, outapp); @@ -2056,9 +2056,9 @@ void command_zsky(Client *c, const Seperator *sep) { // modifys and resends zhdr packet if(sep->arg[1][0]==0) - c->Message(0, "Usage: #zsky "); + c->Message(Chat::White, "Usage: #zsky "); else if(atoi(sep->arg[1])<0||atoi(sep->arg[1])>255) - c->Message(0, "ERROR: Sky type can not be less than 0 or greater than 255!"); + c->Message(Chat::White, "ERROR: Sky type can not be less than 0 or greater than 255!"); else { zone->newzone_data.sky = atoi(sep->arg[1]); auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); @@ -2072,13 +2072,13 @@ void command_zcolor(Client *c, const Seperator *sep) { // modifys and resends zhdr packet if (sep->arg[3][0]==0) - c->Message(0, "Usage: #zcolor "); + c->Message(Chat::White, "Usage: #zcolor "); else if (atoi(sep->arg[1])<0||atoi(sep->arg[1])>255) - c->Message(0, "ERROR: Red can not be less than 0 or greater than 255!"); + c->Message(Chat::White, "ERROR: Red can not be less than 0 or greater than 255!"); else if (atoi(sep->arg[2])<0||atoi(sep->arg[2])>255) - c->Message(0, "ERROR: Green can not be less than 0 or greater than 255!"); + c->Message(Chat::White, "ERROR: Green can not be less than 0 or greater than 255!"); else if (atoi(sep->arg[3])<0||atoi(sep->arg[3])>255) - c->Message(0, "ERROR: Blue can not be less than 0 or greater than 255!"); + c->Message(Chat::White, "ERROR: Blue can not be less than 0 or greater than 255!"); else { for (int z=0; z<4; z++) { zone->newzone_data.fog_red[z] = atoi(sep->arg[1]); @@ -2131,7 +2131,7 @@ void command_gassign(Client *c, const Seperator *sep) database.AssignGrid(c, atoi(sep->arg[1]), spawn2id); } else - c->Message(0, "Usage: #gassign [num] - must have an npc target!"); + c->Message(Chat::White, "Usage: #gassign [num] - must have an npc target!"); } void command_ai(Client *c, const Seperator *sep) @@ -2143,37 +2143,37 @@ void command_ai(Client *c, const Seperator *sep) if (target->IsNPC()) target->CastToNPC()->SetNPCFactionID(atoi(sep->arg[2])); else - c->Message(0, "%s is not an NPC.", target->GetName()); + c->Message(Chat::White, "%s is not an NPC.", target->GetName()); } else - c->Message(0, "Usage: (targeted) #ai factionid [factionid]"); + c->Message(Chat::White, "Usage: (targeted) #ai factionid [factionid]"); } else if (strcasecmp(sep->arg[1], "spellslist") == 0) { if (target && sep->IsNumber(2) && atoi(sep->arg[2]) >= 0) { if (target->IsNPC()) target->CastToNPC()->AI_AddNPCSpells(atoi(sep->arg[2])); else - c->Message(0, "%s is not an NPC.", target->GetName()); + c->Message(Chat::White, "%s is not an NPC.", target->GetName()); } else - c->Message(0, "Usage: (targeted) #ai spellslist [npc_spells_id]"); + c->Message(Chat::White, "Usage: (targeted) #ai spellslist [npc_spells_id]"); } else if (strcasecmp(sep->arg[1], "con") == 0) { if (target && sep->arg[2][0] != 0) { Mob* tar2 = entity_list.GetMob(sep->arg[2]); if (tar2) - c->Message(0, "%s considering %s: %i", target->GetName(), tar2->GetName(), tar2->GetReverseFactionCon(target)); + c->Message(Chat::White, "%s considering %s: %i", target->GetName(), tar2->GetName(), tar2->GetReverseFactionCon(target)); else - c->Message(0, "Error: %s not found.", sep->arg[2]); + c->Message(Chat::White, "Error: %s not found.", sep->arg[2]); } else - c->Message(0, "Usage: (targeted) #ai con [mob name]"); + c->Message(Chat::White, "Usage: (targeted) #ai con [mob name]"); } else if (strcasecmp(sep->arg[1], "guard") == 0) { if (target && target->IsNPC()) target->CastToNPC()->SaveGuardSpot(target->GetPosition()); else - c->Message(0, "Usage: (targeted) #ai guard - sets npc to guard the current location (use #summon to move)"); + c->Message(Chat::White, "Usage: (targeted) #ai guard - sets npc to guard the current location (use #summon to move)"); } else if (strcasecmp(sep->arg[1], "roambox") == 0) { if (target && target->IsAIControlled() && target->IsNPC()) { @@ -2196,39 +2196,39 @@ void command_ai(Client *c, const Seperator *sep) target->CastToNPC()->AI_SetRoambox(atof(sep->arg[2]), atof(sep->arg[3]), tmp, tmp2); } else { - c->Message(0, "Usage: #ai roambox dist max_x min_x max_y min_y [delay] [mindelay]"); - c->Message(0, "Usage: #ai roambox dist roamdist [delay] [mindelay]"); + c->Message(Chat::White, "Usage: #ai roambox dist max_x min_x max_y min_y [delay] [mindelay]"); + c->Message(Chat::White, "Usage: #ai roambox dist roamdist [delay] [mindelay]"); } } else - c->Message(0, "You need a AI NPC targeted"); + c->Message(Chat::White, "You need a AI NPC targeted"); } else if (strcasecmp(sep->arg[1], "stop") == 0 && c->Admin() >= commandToggleAI) { if (target) { if (target->IsAIControlled()) target->AI_Stop(); else - c->Message(0, "Error: Target is not AI controlled"); + c->Message(Chat::White, "Error: Target is not AI controlled"); } else - c->Message(0, "Usage: Target a Mob with AI enabled and use this to turn off their AI."); + c->Message(Chat::White, "Usage: Target a Mob with AI enabled and use this to turn off their AI."); } else if (strcasecmp(sep->arg[1], "start") == 0 && c->Admin() >= commandToggleAI) { if (target) { if (!target->IsAIControlled()) target->AI_Start(); else - c->Message(0, "Error: Target is already AI controlled"); + c->Message(Chat::White, "Error: Target is already AI controlled"); } else - c->Message(0, "Usage: Target a Mob with AI disabled and use this to turn on their AI."); + c->Message(Chat::White, "Usage: Target a Mob with AI disabled and use this to turn on their AI."); } else { - c->Message(0, "#AI Sub-commands"); - c->Message(0, " factionid"); - c->Message(0, " spellslist"); - c->Message(0, " con"); - c->Message(0, " guard"); + c->Message(Chat::White, "#AI Sub-commands"); + c->Message(Chat::White, " factionid"); + c->Message(Chat::White, " spellslist"); + c->Message(Chat::White, " con"); + c->Message(Chat::White, " guard"); } } @@ -2240,7 +2240,7 @@ void command_worldshutdown(Client *c, const Seperator *sep) if (worldserver.Connected()) { if(sep->IsNumber(1) && sep->IsNumber(2) && ((time=atoi(sep->arg[1]))>0) && ((interval=atoi(sep->arg[2]))>0)) { worldserver.SendEmoteMessage(0,0,15,":SYSTEM MSG:World coming down in %i minutes, everyone log out before this time.", (time / 60 )); - c->Message(0, "Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval); + c->Message(Chat::White, "Sending shutdown packet now, World will shutdown in: %i minutes with an interval of: %i seconds", (time / 60), interval); auto pack = new ServerPacket(ServerOP_ShutdownAll, sizeof(WorldShutDown_Struct)); WorldShutDown_Struct* wsd = (WorldShutDown_Struct*)pack->pBuffer; wsd->time=time*1000; @@ -2250,7 +2250,7 @@ void command_worldshutdown(Client *c, const Seperator *sep) } else if(strcasecmp(sep->arg[1], "now") == 0){ worldserver.SendEmoteMessage(0,0,15,":SYSTEM MSG:World coming down, everyone log out now."); - c->Message(0, "Sending shutdown packet"); + c->Message(Chat::White, "Sending shutdown packet"); auto pack = new ServerPacket; pack->opcode = ServerOP_ShutdownAll; pack->size=0; @@ -2258,7 +2258,7 @@ void command_worldshutdown(Client *c, const Seperator *sep) safe_delete(pack); } else if(strcasecmp(sep->arg[1], "disable") == 0){ - c->Message(0, "Shutdown prevented, next time I may not be so forgiving..."); + c->Message(Chat::White, "Shutdown prevented, next time I may not be so forgiving..."); auto pack = new ServerPacket(ServerOP_ShutdownAll, sizeof(WorldShutDown_Struct)); WorldShutDown_Struct* wsd = (WorldShutDown_Struct*)pack->pBuffer; wsd->time=0; @@ -2267,14 +2267,14 @@ void command_worldshutdown(Client *c, const Seperator *sep) safe_delete(pack); } else{ - c->Message(0,"#worldshutdown - Shuts down the server and all zones."); - c->Message(0,"Usage: #worldshutdown now - Shuts down the server and all zones immediately."); - c->Message(0,"Usage: #worldshutdown disable - Stops the server from a previously scheduled shut down."); - c->Message(0,"Usage: #worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds."); + c->Message(Chat::White,"#worldshutdown - Shuts down the server and all zones."); + c->Message(Chat::White,"Usage: #worldshutdown now - Shuts down the server and all zones immediately."); + c->Message(Chat::White,"Usage: #worldshutdown disable - Stops the server from a previously scheduled shut down."); + c->Message(Chat::White,"Usage: #worldshutdown [timer] [interval] - Shuts down the server and all zones after [timer] seconds and sends warning every [interval] seconds."); } } else - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); } void command_sendzonespawns(Client *c, const Seperator *sep) @@ -2307,7 +2307,7 @@ void command_dbspawn2(Client *c, const Seperator *sep) database.CreateSpawn2(c, atoi(sep->arg[1]), zone->GetShortName(), c->GetPosition(), atoi(sep->arg[2]), atoi(sep->arg[3]), cond, cond_min); } else { - c->Message(0, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]"); + c->Message(Chat::White, "Usage: #dbspawn2 spawngroup respawn variance [condition_id] [condition_min]"); } } @@ -2319,36 +2319,36 @@ void command_shutdown(Client *c, const Seperator *sep) void command_delacct(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0) - c->Message(0, "Format: #delacct accountname"); + c->Message(Chat::White, "Format: #delacct accountname"); else if (database.DeleteAccount(sep->arg[1])) - c->Message(0, "The account was deleted."); + c->Message(Chat::White, "The account was deleted."); else - c->Message(0, "Unable to delete account."); + c->Message(Chat::White, "Unable to delete account."); } void command_setpass(Client *c, const Seperator *sep) { if(sep->argnum != 2) - c->Message(0, "Format: #setpass accountname password"); + c->Message(Chat::White, "Format: #setpass accountname password"); else { int16 tmpstatus = 0; uint32 tmpid = database.GetAccountIDByName(sep->arg[1], &tmpstatus); if (!tmpid) - c->Message(0, "Error: Account not found"); + c->Message(Chat::White, "Error: Account not found"); else if (tmpstatus > c->Admin()) - c->Message(0, "Cannot change password: Account's status is higher than yours"); + c->Message(Chat::White, "Cannot change password: Account's status is higher than yours"); else if (database.SetLocalPassword(tmpid, sep->arg[2])) - c->Message(0, "Password changed."); + c->Message(Chat::White, "Password changed."); else - c->Message(0, "Error changing password."); + c->Message(Chat::White, "Error changing password."); } } void command_setlsinfo(Client *c, const Seperator *sep) { if(sep->argnum != 2) - c->Message(0, "Format: #setlsinfo email password"); + c->Message(Chat::White, "Format: #setlsinfo email password"); else { auto pack = new ServerPacket(ServerOP_LSAccountUpdate, sizeof(ServerLSAccountUpdate_Struct)); ServerLSAccountUpdate_Struct* s = (ServerLSAccountUpdate_Struct *) pack->pBuffer; @@ -2357,14 +2357,14 @@ void command_setlsinfo(Client *c, const Seperator *sep) strn0cpy(s->useremail, sep->arg[1], 100); strn0cpy(s->userpassword, sep->arg[2], 50); worldserver.SendPacket(pack); - c->Message(0, "Login Server update packet sent."); + c->Message(Chat::White, "Login Server update packet sent."); } } void command_grid(Client *c, const Seperator *sep) { if (strcasecmp("max", sep->arg[1]) == 0) { - c->Message(0, "Highest grid ID in this zone: %d", database.GetHighestGrid(zone->GetZoneID())); + c->Message(Chat::White, "Highest grid ID in this zone: %d", database.GetHighestGrid(zone->GetZoneID())); } else if (strcasecmp("add", sep->arg[1]) == 0) { database.ModifyGrid(c, false, atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), zone->GetZoneID()); @@ -2374,7 +2374,7 @@ void command_grid(Client *c, const Seperator *sep) Mob *target = c->GetTarget(); if (!target || !target->IsNPC()) { - c->Message(0, "You need a NPC target!"); + c->Message(Chat::White, "You need a NPC target!"); return; } @@ -2389,12 +2389,12 @@ void command_grid(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Error querying database."); - c->Message(0, query.c_str()); + c->Message(Chat::White, "Error querying database."); + c->Message(Chat::White, query.c_str()); } if (results.RowCount() == 0) { - c->Message(0, "No grid found"); + c->Message(Chat::White, "No grid found"); return; } @@ -2430,8 +2430,8 @@ void command_grid(Client *c, const Seperator *sep) database.ModifyGrid(c, true, atoi(sep->arg[2]), 0, 0, zone->GetZoneID()); } else { - c->Message(0, "Usage: #grid add/delete grid_num wandertype pausetype"); - c->Message(0, "Usage: #grid max - displays the highest grid ID used in this zone (for add)"); + c->Message(Chat::White, "Usage: #grid add/delete grid_num wandertype pausetype"); + c->Message(Chat::White, "Usage: #grid max - displays the highest grid ID used in this zone (for add)"); } } @@ -2454,7 +2454,7 @@ void command_wp(Client *c, const Seperator *sep) else if (strcasecmp("delete", sep->arg[1]) == 0) database.DeleteWaypoint(c, atoi(sep->arg[2]),wp,zone->GetZoneID()); else - c->Message(0,"Usage: #wp add/delete grid_num pause wp_num [-h]"); + c->Message(Chat::White,"Usage: #wp add/delete grid_num pause wp_num [-h]"); } void command_iplookup(Client *c, const Seperator *sep) @@ -2474,15 +2474,15 @@ void command_size(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0, "Usage: #size [0 - 255] (Decimal increments are allowed)"); + c->Message(Chat::White, "Usage: #size [0 - 255] (Decimal increments are allowed)"); else { float newsize = atof(sep->arg[1]); if (newsize > 255) - c->Message(0, "Error: #size: Size can not be greater than 255."); + c->Message(Chat::White, "Error: #size: Size can not be greater than 255."); else if (newsize < 0) - c->Message(0, "Error: #size: Size can not be less than 0."); + c->Message(Chat::White, "Error: #size: Size can not be less than 0."); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -2503,7 +2503,7 @@ void command_size(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails, newsize); - c->Message(0,"Size = %f", atof(sep->arg[1])); + c->Message(Chat::White,"Size = %f", atof(sep->arg[1])); } } } @@ -2525,7 +2525,7 @@ void command_flymode(Client *c, const Seperator *sep) Mob *t = c; if (strlen(sep->arg[1]) == 1 && !(sep->arg[1][0] == '0' || sep->arg[1][0] == '1' || sep->arg[1][0] == '2' || sep->arg[1][0] == '3' || sep->arg[1][0] == '4' || sep->arg[1][0] == '5')) - c->Message(0, "#flymode [0/1/2/3/4/5]"); + c->Message(Chat::White, "#flymode [0/1/2/3/4/5]"); else { if (c->GetTarget()) { t = c->GetTarget(); @@ -2536,22 +2536,22 @@ void command_flymode(Client *c, const Seperator *sep) t->SetFlyMode(static_cast(fm)); t->SendAppearancePacket(AT_Levitate, fm); if (sep->arg[1][0] == '0') { - c->Message(0, "Setting %s to Grounded", t->GetName()); + c->Message(Chat::White, "Setting %s to Grounded", t->GetName()); } else if (sep->arg[1][0] == '1') { - c->Message(0, "Setting %s to Flying", t->GetName()); + c->Message(Chat::White, "Setting %s to Flying", t->GetName()); } else if (sep->arg[1][0] == '2') { - c->Message(0, "Setting %s to Levitating", t->GetName()); + c->Message(Chat::White, "Setting %s to Levitating", t->GetName()); } else if (sep->arg[1][0] == '3') { - c->Message(0, "Setting %s to In Water", t->GetName()); + c->Message(Chat::White, "Setting %s to In Water", t->GetName()); } else if (sep->arg[1][0] == '4') { - c->Message(0, "Setting %s to Floating(Boat)", t->GetName()); + c->Message(Chat::White, "Setting %s to Floating(Boat)", t->GetName()); } else if (sep->arg[1][0] == '5') { - c->Message(0, "Setting %s to Levitating While Running", t->GetName()); + c->Message(Chat::White, "Setting %s to Levitating While Running", t->GetName()); } } } @@ -2563,24 +2563,24 @@ void command_showskills(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsClient()) t=c->GetTarget()->CastToClient(); - c->Message(0, "Skills for %s", t->GetName()); + c->Message(Chat::White, "Skills for %s", t->GetName()); for (EQEmu::skills::SkillType i = EQEmu::skills::Skill1HBlunt; i <= EQEmu::skills::HIGHEST_SKILL; i = (EQEmu::skills::SkillType)(i + 1)) - c->Message(0, "Skill [%d] is at [%d] - %u", i, t->GetSkill(i), t->GetRawSkill(i)); + c->Message(Chat::White, "Skill [%d] is at [%d] - %u", i, t->GetSkill(i), t->GetRawSkill(i)); } void command_findspell(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) - c->Message(0, "Usage: #FindSpell [spellname]"); + c->Message(Chat::White, "Usage: #FindSpell [spellname]"); else if (SPDAT_RECORDS <= 0) - c->Message(0, "Spells not loaded"); + c->Message(Chat::White, "Spells not loaded"); else if (Seperator::IsNumber(sep->argplus[1])) { int spellid = atoi(sep->argplus[1]); if (spellid <= 0 || spellid >= SPDAT_RECORDS) { - c->Message(0, "Error: Number out of range"); + c->Message(Chat::White, "Error: Number out of range"); } else { - c->Message(0, " %i: %s", spellid, spells[spellid].name); + c->Message(Chat::White, " %i: %s", spellid, spells[spellid].name); } } else { @@ -2597,7 +2597,7 @@ void command_findspell(Client *c, const Seperator *sep) strupr(sName); char* pdest = strstr(sName, sCriteria); if ((pdest != nullptr) && (count <=20)) { - c->Message(0, " %i: %s", i, spells[i].name); + c->Message(Chat::White, " %i: %s", i, spells[i].name); count++; } else if (count > 20) @@ -2605,16 +2605,16 @@ void command_findspell(Client *c, const Seperator *sep) } } if (count > 20) - c->Message(0, "20 spells found... max reached."); + c->Message(Chat::White, "20 spells found... max reached."); else - c->Message(0, "%i spells found.", count); + c->Message(Chat::White, "%i spells found.", count); } } void command_castspell(Client *c, const Seperator *sep) { if (!sep->IsNumber(1)) - c->Message(0, "Usage: #CastSpell spellid"); + c->Message(Chat::White, "Usage: #CastSpell spellid"); else { uint16 spellid = atoi(sep->arg[1]); /* @@ -2629,7 +2629,7 @@ void command_castspell(Client *c, const Seperator *sep) c->Admin() < commandCastSpecials) c->Message(Chat::Red, "Unable to cast spell."); else if (spellid >= SPDAT_RECORDS) - c->Message(0, "Error: #CastSpell: Argument out of range"); + c->Message(Chat::White, "Error: #CastSpell: Argument out of range"); else if (c->GetTarget() == 0) if(c->Admin() >= commandInstacast) @@ -2648,51 +2648,51 @@ void command_setlanguage(Client *c, const Seperator *sep) { if (strcasecmp(sep->arg[1], "list" ) == 0 ) { - c->Message(0, "Languages:"); - c->Message(0, "(0) Common Tongue"); - c->Message(0, "(1) Barbarian"); - c->Message(0, "(2) Erudian"); - c->Message(0, "(3) Elvish"); - c->Message(0, "(4) Dark Elvish"); - c->Message(0, "(5) Dwarvish"); - c->Message(0, "(6) Troll"); - c->Message(0, "(7) Ogre"); - c->Message(0, "(8) Gnomish"); - c->Message(0, "(9) Halfling"); - c->Message(0, "(10) Thieves Cant"); - c->Message(0, "(11) Old Erudian"); - c->Message(0, "(12) Elder Elvish"); - c->Message(0, "(13) Froglok"); - c->Message(0, "(14) Goblin"); - c->Message(0, "(15) Gnoll"); - c->Message(0, "(16) Combine Tongue"); - c->Message(0, "(17) Elder Teir`Dal"); - c->Message(0, "(18) Lizardman"); - c->Message(0, "(19) Orcish"); - c->Message(0, "(20) Faerie"); - c->Message(0, "(21) Dragon"); - c->Message(0, "(22) Elder Dragon"); - c->Message(0, "(23) Dark Speech"); - c->Message(0, "(24) Vah Shir"); - c->Message(0, "(25) Alaran"); - c->Message(0, "(26) Hadal"); - c->Message(0, "(27) Unknown1"); + c->Message(Chat::White, "Languages:"); + c->Message(Chat::White, "(0) Common Tongue"); + c->Message(Chat::White, "(1) Barbarian"); + c->Message(Chat::White, "(2) Erudian"); + c->Message(Chat::White, "(3) Elvish"); + c->Message(Chat::White, "(4) Dark Elvish"); + c->Message(Chat::White, "(5) Dwarvish"); + c->Message(Chat::White, "(6) Troll"); + c->Message(Chat::White, "(7) Ogre"); + c->Message(Chat::White, "(8) Gnomish"); + c->Message(Chat::White, "(9) Halfling"); + c->Message(Chat::White, "(10) Thieves Cant"); + c->Message(Chat::White, "(11) Old Erudian"); + c->Message(Chat::White, "(12) Elder Elvish"); + c->Message(Chat::White, "(13) Froglok"); + c->Message(Chat::White, "(14) Goblin"); + c->Message(Chat::White, "(15) Gnoll"); + c->Message(Chat::White, "(16) Combine Tongue"); + c->Message(Chat::White, "(17) Elder Teir`Dal"); + c->Message(Chat::White, "(18) Lizardman"); + c->Message(Chat::White, "(19) Orcish"); + c->Message(Chat::White, "(20) Faerie"); + c->Message(Chat::White, "(21) Dragon"); + c->Message(Chat::White, "(22) Elder Dragon"); + c->Message(Chat::White, "(23) Dark Speech"); + c->Message(Chat::White, "(24) Vah Shir"); + c->Message(Chat::White, "(25) Alaran"); + c->Message(Chat::White, "(26) Hadal"); + c->Message(Chat::White, "(27) Unknown1"); } else if( c->GetTarget() == 0 ) { - c->Message(0, "Error: #setlanguage: No target."); + c->Message(Chat::White, "Error: #setlanguage: No target."); } else if( !c->GetTarget()->IsClient() ) { - c->Message(0, "Error: Target must be a player."); + c->Message(Chat::White, "Error: Target must be a player."); } else if ( !sep->IsNumber(1) || atoi(sep->arg[1]) < 0 || atoi(sep->arg[1]) > 27 || !sep->IsNumber(2) || atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > 100 ) { - c->Message(0, "Usage: #setlanguage [language ID] [value] (0-27, 0-100)"); - c->Message(0, "Try #setlanguage list for a list of language IDs"); + c->Message(Chat::White, "Usage: #setlanguage [language ID] [value] (0-27, 0-100)"); + c->Message(Chat::White, "Try #setlanguage list for a list of language IDs"); } else { @@ -2706,19 +2706,19 @@ void command_setlanguage(Client *c, const Seperator *sep) void command_setskill(Client *c, const Seperator *sep) { if (c->GetTarget() == nullptr) { - c->Message(0, "Error: #setskill: No target."); + c->Message(Chat::White, "Error: #setskill: No target."); } else if (!c->GetTarget()->IsClient()) { - c->Message(0, "Error: #setskill: Target must be a client."); + c->Message(Chat::White, "Error: #setskill: Target must be a client."); } else if ( !sep->IsNumber(1) || atoi(sep->arg[1]) < 0 || atoi(sep->arg[1]) > EQEmu::skills::HIGHEST_SKILL || !sep->IsNumber(2) || atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > HIGHEST_CAN_SET_SKILL ) { - c->Message(0, "Usage: #setskill skill x "); - c->Message(0, " skill = 0 to %d", EQEmu::skills::HIGHEST_SKILL); - c->Message(0, " x = 0 to %d", HIGHEST_CAN_SET_SKILL); + c->Message(Chat::White, "Usage: #setskill skill x "); + c->Message(Chat::White, " skill = 0 to %d", EQEmu::skills::HIGHEST_SKILL); + c->Message(Chat::White, " x = 0 to %d", HIGHEST_CAN_SET_SKILL); } else { Log(Logs::General, Logs::Normal, "Set skill request from %s, target:%s skill_id:%i value:%i", c->GetName(), c->GetTarget()->GetName(), atoi(sep->arg[1]), atoi(sep->arg[2]) ); @@ -2732,12 +2732,12 @@ void command_setskill(Client *c, const Seperator *sep) void command_setskillall(Client *c, const Seperator *sep) { if (c->GetTarget() == 0) - c->Message(0, "Error: #setallskill: No target."); + c->Message(Chat::White, "Error: #setallskill: No target."); else if (!c->GetTarget()->IsClient()) - c->Message(0, "Error: #setskill: Target must be a client."); + c->Message(Chat::White, "Error: #setskill: Target must be a client."); else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < 0 || atoi(sep->arg[1]) > HIGHEST_CAN_SET_SKILL) { - c->Message(0, "Usage: #setskillall value "); - c->Message(0, " value = 0 to %d", HIGHEST_CAN_SET_SKILL); + c->Message(Chat::White, "Usage: #setskillall value "); + c->Message(Chat::White, " value = 0 to %d", HIGHEST_CAN_SET_SKILL); } else { if (c->Admin() >= commandSetSkillsOther || c->GetTarget()==c || c->GetTarget()==0) { @@ -2748,7 +2748,7 @@ void command_setskillall(Client *c, const Seperator *sep) } } else - c->Message(0, "Error: Your status is not high enough to set anothers skills"); + c->Message(Chat::White, "Error: Your status is not high enough to set anothers skills"); } } @@ -2765,11 +2765,11 @@ void command_race(Client *c, const Seperator *sep) target->SendIllusionPacket(race); } else { - c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); + c->Message(Chat::White, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); } } else { - c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); + c->Message(Chat::White, "Usage: #race [0-732, 2253-2259] (0 for back to normal)"); } } @@ -2783,13 +2783,13 @@ void command_gender(Client *c, const Seperator *sep) t->SendIllusionPacket(t->GetRace(), atoi(sep->arg[1])); } else - c->Message(0, "Usage: #gender [0/1/2]"); + c->Message(Chat::White, "Usage: #gender [0/1/2]"); } void command_makepet(Client *c, const Seperator *sep) { if (sep->arg[1][0] == '\0') - c->Message(0, "Usage: #makepet pet_type_name (will not survive across zones)"); + c->Message(Chat::White, "Usage: #makepet pet_type_name (will not survive across zones)"); else c->MakePet(0, sep->arg[1]); } @@ -2799,7 +2799,7 @@ void command_level(Client *c, const Seperator *sep) uint16 level = atoi(sep->arg[1]); if ((level <= 0) || ((level > RuleI(Character, MaxLevel)) && (c->Admin() < commandLevelAboveCap))) { - c->Message(0, "Error: #Level: Invalid Level"); + c->Message(Chat::White, "Error: #Level: Invalid Level"); } else if (c->Admin() < RuleI(GM, MinStatusToLevelTarget)) { c->SetLevel(level, true); @@ -2809,11 +2809,11 @@ void command_level(Client *c, const Seperator *sep) #endif } else if (!c->GetTarget()) { - c->Message(0, "Error: #Level: No target"); + c->Message(Chat::White, "Error: #Level: No target"); } else { if (!c->GetTarget()->IsNPC() && ((c->Admin() < commandLevelNPCAboveCap) && (level > RuleI(Character, MaxLevel)))) { - c->Message(0, "Error: #Level: Invalid Level"); + c->Message(Chat::White, "Error: #Level: Invalid Level"); } else { c->GetTarget()->SetLevel(level, true); @@ -2833,16 +2833,16 @@ void command_spawn(Client *c, const Seperator *sep) if (sep->arg[1][0] != 0){ Client* client = entity_list.GetClientByName(sep->arg[1]); if(client){ - c->Message(0,"You cannot spawn a mob with the same name as a character!"); + c->Message(Chat::White,"You cannot spawn a mob with the same name as a character!"); return; } } NPC* npc = NPC::SpawnNPC(sep->argplus[1], c->GetPosition(), c); if (!npc) { - c->Message(0, "Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."); - c->Message(0, "Name Format: NPCFirstname_NPCLastname - All numbers in a name are stripped and \"_\" characters become a space."); - c->Message(0, "Note: Using \"-\" for gender will autoselect the gender for the race. Using \"-\" for HP will use the calculated maximum HP."); + c->Message(Chat::White, "Format: #spawn name race level material hp gender class priweapon secweapon merchantid bodytype - spawns a npc those parameters."); + c->Message(Chat::White, "Name Format: NPCFirstname_NPCLastname - All numbers in a name are stripped and \"_\" characters become a space."); + c->Message(Chat::White, "Note: Using \"-\" for gender will autoselect the gender for the race. Using \"-\" for HP will use the calculated maximum HP."); } } @@ -2900,7 +2900,7 @@ void command_texture(Client *c, const Seperator *sep) } } else - c->Message(0, "Usage: #texture [texture] [helmtexture] (0-255, 255 for show equipment)"); + c->Message(Chat::White, "Usage: #texture [texture] [helmtexture] (0-255, 255 for show equipment)"); } void command_npctypespawn(Client *c, const Seperator *sep) @@ -2919,17 +2919,17 @@ void command_npctypespawn(Client *c, const Seperator *sep) entity_list.AddNPC(npc); } else - c->Message(0, "NPC Type %i not found", atoi(sep->arg[1])); + c->Message(Chat::White, "NPC Type %i not found", atoi(sep->arg[1])); } else - c->Message(0, "Usage: #npctypespawn npctypeid factionid"); + c->Message(Chat::White, "Usage: #npctypespawn npctypeid factionid"); } void command_heal(Client *c, const Seperator *sep) { if (c->GetTarget()==0) - c->Message(0, "Error: #Heal: No Target."); + c->Message(Chat::White, "Error: #Heal: No Target."); else c->GetTarget()->Heal(); } @@ -2941,12 +2941,12 @@ void command_appearance(Client *c, const Seperator *sep) // sends any appearance packet // Dev debug command, for appearance types if (sep->arg[2][0] == 0) - c->Message(0, "Usage: #appearance type value"); + c->Message(Chat::White, "Usage: #appearance type value"); else { if ((c->GetTarget())) t=c->GetTarget(); t->SendAppearancePacket(atoi(sep->arg[1]), atoi(sep->arg[2])); - c->Message(0, "Sending appearance packet: target=%s, type=%s, value=%s", t->GetName(), sep->arg[1], sep->arg[2]); + c->Message(Chat::White, "Sending appearance packet: target=%s, type=%s, value=%s", t->GetName(), sep->arg[1], sep->arg[2]); } } @@ -2957,10 +2957,10 @@ void command_nukeitem(Client *c, const Seperator *sep) if (c->GetTarget() && c->GetTarget()->IsClient() && (sep->IsNumber(1) || sep->IsHexNumber(1))) { itemid=sep->IsNumber(1)?atoi(sep->arg[1]):hextoi(sep->arg[1]); numitems = c->GetTarget()->CastToClient()->NukeItem(itemid); - c->Message(0, " %u items deleted", numitems); + c->Message(Chat::White, " %u items deleted", numitems); } else - c->Message(0, "Usage: (targted) #nukeitem itemnum - removes the item from the player's inventory"); + c->Message(Chat::White, "Usage: (targted) #nukeitem itemnum - removes the item from the player's inventory"); } void command_peekinv(Client *c, const Seperator *sep) @@ -3000,7 +3000,7 @@ void command_peekinv(Client *c, const Seperator *sep) return; if (c->GetTarget() && !c->GetTarget()->IsClient()) { - c->Message(0, "You must target a PC for this command."); + c->Message(Chat::White, "You must target a PC for this command."); return; } @@ -3021,9 +3021,9 @@ void command_peekinv(Client *c, const Seperator *sep) else if (strcasecmp(sep->arg[1], "world") == 0) { scopeMask |= peekWorld; } if (!scopeMask) { - c->Message(0, "Usage: #peekinv [equip|gen|cursor|poss|limbo|curlim|trib|bank|shbank|allbank|trade|world|all]"); - c->Message(0, "- Displays a portion of the targeted user's inventory"); - c->Message(0, "- Caution: 'all' is a lot of information!"); + c->Message(Chat::White, "Usage: #peekinv [equip|gen|cursor|poss|limbo|curlim|trib|bank|shbank|allbank|trade|world|all]"); + c->Message(Chat::White, "- Displays a portion of the targeted user's inventory"); + c->Message(Chat::White, "- Caution: 'all' is a lot of information!"); return; } @@ -3039,7 +3039,7 @@ void command_peekinv(Client *c, const Seperator *sep) EQEmu::SayLinkEngine linker; linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); - c->Message(0, "Displaying inventory for %s...", targetClient->GetName()); + c->Message(Chat::White, "Displaying inventory for %s...", targetClient->GetName()); Object* objectTradeskill = targetClient->GetTradeskillObject(); @@ -3051,11 +3051,11 @@ void command_peekinv(Client *c, const Seperator *sep) if (scopeBit & peekWorld) { if (objectTradeskill == nullptr) { - c->Message(1, "No world tradeskill object selected..."); + c->Message(Chat::Default, "No world tradeskill object selected..."); continue; } else { - c->Message(0, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID()); + c->Message(Chat::White, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID()); } } @@ -3259,7 +3259,7 @@ void command_peekinv(Client *c, const Seperator *sep) } if (!itemsFound) - c->Message(0, "No items found."); + c->Message(Chat::White, "No items found."); } void command_interrogateinv(Client *c, const Seperator *sep) @@ -3278,14 +3278,14 @@ void command_interrogateinv(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "help") == 0) { if (c->Admin() < commandInterrogateInv) { - c->Message(0, "Usage: #interrogateinv"); - c->Message(0, " Displays your inventory's current in-memory nested storage references"); + c->Message(Chat::White, "Usage: #interrogateinv"); + c->Message(Chat::White, " Displays your inventory's current in-memory nested storage references"); } else { - c->Message(0, "Usage: #interrogateinv [log] [silent]"); - c->Message(0, " Displays your or your Player target inventory's current in-memory nested storage references"); - c->Message(0, " [log] - Logs interrogation to file"); - c->Message(0, " [silent] - Omits the in-game message portion of the interrogation"); + c->Message(Chat::White, "Usage: #interrogateinv [log] [silent]"); + c->Message(Chat::White, " Displays your or your Player target inventory's current in-memory nested storage references"); + c->Message(Chat::White, " [log] - Logs interrogation to file"); + c->Message(Chat::White, " [silent] - Omits the in-game message portion of the interrogation"); } return; } @@ -3314,7 +3314,7 @@ void command_interrogateinv(Client *c, const Seperator *sep) target = c->GetTarget()->CastToClient(); } else { - c->Message(1, "Use of this command is limited to Client entities"); + c->Message(Chat::Default, "Use of this command is limited to Client entities"); return; } @@ -3413,7 +3413,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "gcount") == 0) { auto is_count = database.CountInvSnapshots(); - c->Message(0, "There %s %i inventory snapshot%s.", (is_count == 1 ? "is" : "are"), is_count, (is_count == 1 ? "" : "s")); + c->Message(Chat::White, "There %s %i inventory snapshot%s.", (is_count == 1 ? "is" : "are"), is_count, (is_count == 1 ? "" : "s")); return; } @@ -3421,11 +3421,11 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "gclear") == 0) { if (strcmp(sep->arg[2], "now") == 0) { database.ClearInvSnapshots(true); - c->Message(0, "Inventory snapshots cleared using current time."); + c->Message(Chat::White, "Inventory snapshots cleared using current time."); } else { database.ClearInvSnapshots(); - c->Message(0, "Inventory snapshots cleared using RuleI(Character, InvSnapshotHistoryD) (%i day%s).", + c->Message(Chat::White, "Inventory snapshots cleared using RuleI(Character, InvSnapshotHistoryD) (%i day%s).", RuleI(Character, InvSnapshotHistoryD), (RuleI(Character, InvSnapshotHistoryD) == 1 ? "" : "s")); } @@ -3434,7 +3434,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) } if (!c->GetTarget() || !c->GetTarget()->IsClient()) { - c->Message(0, "Target must be a client."); + c->Message(Chat::White, "Target must be a client."); return; } @@ -3443,12 +3443,12 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "capture") == 0) { if (database.SaveCharacterInvSnapshot(tc->CharacterID())) { tc->SetNextInvSnapshot(RuleI(Character, InvSnapshotMinIntervalM)); - c->Message(0, "Successful inventory snapshot taken of %s - setting next interval for %i minute%s.", + c->Message(Chat::White, "Successful inventory snapshot taken of %s - setting next interval for %i minute%s.", tc->GetName(), RuleI(Character, InvSnapshotMinIntervalM), (RuleI(Character, InvSnapshotMinIntervalM) == 1 ? "" : "s")); } else { tc->SetNextInvSnapshot(RuleI(Character, InvSnapshotMinRetryM)); - c->Message(0, "Failed to take inventory snapshot of %s - retrying in %i minute%s.", + c->Message(Chat::White, "Failed to take inventory snapshot of %s - retrying in %i minute%s.", tc->GetName(), RuleI(Character, InvSnapshotMinRetryM), (RuleI(Character, InvSnapshotMinRetryM) == 1 ? "" : "s")); } @@ -3458,7 +3458,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (c->Admin() >= commandInvSnapshot) { if (strcmp(sep->arg[1], "count") == 0) { auto is_count = database.CountCharacterInvSnapshots(tc->CharacterID()); - c->Message(0, "%s (id: %u) has %i inventory snapshot%s.", tc->GetName(), tc->CharacterID(), is_count, (is_count == 1 ? "" : "s")); + c->Message(Chat::White, "%s (id: %u) has %i inventory snapshot%s.", tc->GetName(), tc->CharacterID(), is_count, (is_count == 1 ? "" : "s")); return; } @@ -3466,11 +3466,11 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "clear") == 0) { if (strcmp(sep->arg[2], "now") == 0) { database.ClearCharacterInvSnapshots(tc->CharacterID(), true); - c->Message(0, "%s\'s (id: %u) inventory snapshots cleared using current time.", tc->GetName(), tc->CharacterID()); + c->Message(Chat::White, "%s\'s (id: %u) inventory snapshots cleared using current time.", tc->GetName(), tc->CharacterID()); } else { database.ClearCharacterInvSnapshots(tc->CharacterID()); - c->Message(0, "%s\'s (id: %u) inventory snapshots cleared using RuleI(Character, InvSnapshotHistoryD) (%i day%s).", + c->Message(Chat::White, "%s\'s (id: %u) inventory snapshots cleared using RuleI(Character, InvSnapshotHistoryD) (%i day%s).", tc->GetName(), tc->CharacterID(), RuleI(Character, InvSnapshotHistoryD), (RuleI(Character, InvSnapshotHistoryD) == 1 ? "" : "s")); } @@ -3482,7 +3482,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) database.ListCharacterInvSnapshots(tc->CharacterID(), is_list); if (is_list.empty()) { - c->Message(0, "No inventory snapshots for %s (id: %u)", tc->GetName(), tc->CharacterID()); + c->Message(Chat::White, "No inventory snapshots for %s (id: %u)", tc->GetName(), tc->CharacterID()); return; } @@ -3528,14 +3528,14 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "parse") == 0) { if (!sep->IsNumber(2)) { - c->Message(0, "A timestamp is required to use this option."); + c->Message(Chat::White, "A timestamp is required to use this option."); return; } uint32 timestamp = atoul(sep->arg[2]); if (!database.ValidateCharacterInvSnapshotTimestamp(tc->CharacterID(), timestamp)) { - c->Message(0, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); + c->Message(Chat::White, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); return; } @@ -3554,7 +3554,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) window_text.append(window_line); } else { - c->Message(0, "Too many snapshot entries to list..."); + c->Message(Chat::White, "Too many snapshot entries to list..."); break; } } @@ -3566,14 +3566,14 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "compare") == 0) { if (!sep->IsNumber(2)) { - c->Message(0, "A timestamp is required to use this option."); + c->Message(Chat::White, "A timestamp is required to use this option."); return; } uint32 timestamp = atoul(sep->arg[2]); if (!database.ValidateCharacterInvSnapshotTimestamp(tc->CharacterID(), timestamp)) { - c->Message(0, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); + c->Message(Chat::White, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); return; } @@ -3624,7 +3624,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) window_text.append(window_line); } else { - c->Message(0, "Too many comparison entries to list..."); + c->Message(Chat::White, "Too many comparison entries to list..."); break; } } @@ -3636,14 +3636,14 @@ void command_invsnapshot(Client *c, const Seperator *sep) if (strcmp(sep->arg[1], "restore") == 0) { if (!sep->IsNumber(2)) { - c->Message(0, "A timestamp is required to use this option."); + c->Message(Chat::White, "A timestamp is required to use this option."); return; } uint32 timestamp = atoul(sep->arg[2]); if (!database.ValidateCharacterInvSnapshotTimestamp(tc->CharacterID(), timestamp)) { - c->Message(0, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); + c->Message(Chat::White, "No inventory snapshots for %s (id: %u) exist at %u.", tc->GetName(), tc->CharacterID(), timestamp); return; } @@ -3660,7 +3660,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) // cannot delete all valid item slots from client..so, we worldkick tc->WorldKick(); // self restores update before the 'kick' is processed - c->Message(0, "Successfully applied snapshot %u to %s's (id: %u) inventory.", + c->Message(Chat::White, "Successfully applied snapshot %u to %s's (id: %u) inventory.", timestamp, tc->GetName(), tc->CharacterID()); } else { @@ -3676,7 +3676,7 @@ void command_invsnapshot(Client *c, const Seperator *sep) void command_findnpctype(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0) { - c->Message(0, "Usage: #findnpctype [search criteria]"); + c->Message(Chat::White, "Usage: #findnpctype [search criteria]"); return; } @@ -3721,7 +3721,7 @@ void command_findnpctype(Client *c, const Seperator *sep) void command_findzone(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0) { - c->Message(0, "Usage: #findzone [search criteria]"); + c->Message(Chat::White, "Usage: #findzone [search criteria]"); return; } @@ -3768,27 +3768,27 @@ void command_findzone(Client *c, const Seperator *sep) void command_viewnpctype(Client *c, const Seperator *sep) { if (!sep->IsNumber(1)) - c->Message(0, "Usage: #viewnpctype [npctype id]"); + c->Message(Chat::White, "Usage: #viewnpctype [npctype id]"); else { uint32 npctypeid=atoi(sep->arg[1]); const NPCType* npct = database.LoadNPCTypesData(npctypeid); if (npct) { - c->Message(0, " NPCType Info, "); - c->Message(0, " NPCTypeID: %u", npct->npc_id); - c->Message(0, " Name: %s", npct->name); - c->Message(0, " Level: %i", npct->level); - c->Message(0, " Race: %i", npct->race); - c->Message(0, " Class: %i", npct->class_); - c->Message(0, " MinDmg: %i", npct->min_dmg); - c->Message(0, " MaxDmg: %i", npct->max_dmg); - c->Message(0, " Special Abilities: %s", npct->special_abilities); - c->Message(0, " Spells: %i", npct->npc_spells_id); - c->Message(0, " Loot Table: %i", npct->loottable_id); - c->Message(0, " NPCFactionID: %i", npct->npc_faction_id); + c->Message(Chat::White, " NPCType Info, "); + c->Message(Chat::White, " NPCTypeID: %u", npct->npc_id); + c->Message(Chat::White, " Name: %s", npct->name); + c->Message(Chat::White, " Level: %i", npct->level); + c->Message(Chat::White, " Race: %i", npct->race); + c->Message(Chat::White, " Class: %i", npct->class_); + c->Message(Chat::White, " MinDmg: %i", npct->min_dmg); + c->Message(Chat::White, " MaxDmg: %i", npct->max_dmg); + c->Message(Chat::White, " Special Abilities: %s", npct->special_abilities); + c->Message(Chat::White, " Spells: %i", npct->npc_spells_id); + c->Message(Chat::White, " Loot Table: %i", npct->loottable_id); + c->Message(Chat::White, " NPCFactionID: %i", npct->npc_faction_id); } else - c->Message(0, "NPC #%d not found", npctypeid); + c->Message(Chat::White, "NPC #%d not found", npctypeid); } } @@ -3796,13 +3796,13 @@ void command_reloadqst(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) { - c->Message(0, "Clearing quest memory cache."); + c->Message(Chat::White, "Clearing quest memory cache."); entity_list.ClearAreas(); parse->ReloadQuests(); } else { - c->Message(0, "Clearing quest memory cache and stopping timers."); + c->Message(Chat::White, "Clearing quest memory cache and stopping timers."); entity_list.ClearAreas(); parse->ReloadQuests(true); } @@ -3816,7 +3816,7 @@ void command_corpsefix(Client *c, const Seperator *sep) void command_reloadworld(Client *c, const Seperator *sep) { - c->Message(0, "Reloading quest cache and repopping zones worldwide."); + c->Message(Chat::White, "Reloading quest cache and repopping zones worldwide."); auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct)); ReloadWorld_Struct* RW = (ReloadWorld_Struct*) pack->pBuffer; RW->Option = ((atoi(sep->arg[1]) == 1) ? 1 : 0); @@ -3845,15 +3845,15 @@ void command_reloadlevelmods(Client *c, const Seperator *sep) void command_reloadzps(Client *c, const Seperator *sep) { database.LoadStaticZonePoints(&zone->zone_point_list, zone->GetShortName(), zone->GetInstanceVersion()); - c->Message(0, "Reloading server zone_points."); + c->Message(Chat::White, "Reloading server zone_points."); } void command_zoneshutdown(Client *c, const Seperator *sep) { if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else if (sep->arg[1][0] == 0) - c->Message(0, "Usage: #zoneshutdown zoneshortname"); + c->Message(Chat::White, "Usage: #zoneshutdown zoneshortname"); else { auto pack = new ServerPacket(ServerOP_ZoneShutdown, sizeof(ServerZoneStateChange_struct)); ServerZoneStateChange_struct* s = (ServerZoneStateChange_struct *) pack->pBuffer; @@ -3870,9 +3870,9 @@ void command_zoneshutdown(Client *c, const Seperator *sep) void command_zonebootup(Client *c, const Seperator *sep) { if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else if (sep->arg[2][0] == 0) { - c->Message(0, "Usage: #zonebootup ZoneServerID# zoneshortname"); + c->Message(Chat::White, "Usage: #zonebootup ZoneServerID# zoneshortname"); } else { auto pack = new ServerPacket(ServerOP_ZoneBootup, sizeof(ServerZoneStateChange_struct)); @@ -3889,20 +3889,20 @@ void command_zonebootup(Client *c, const Seperator *sep) void command_kick(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) - c->Message(0, "Usage: #kick [charname]"); + c->Message(Chat::White, "Usage: #kick [charname]"); else { Client* client = entity_list.GetClientByName(sep->arg[1]); if (client != 0) { if (client->Admin() <= c->Admin()) { - client->Message(0, "You have been kicked by %s", c->GetName()); + client->Message(Chat::White, "You have been kicked by %s", c->GetName()); auto outapp = new EQApplicationPacket(OP_GMKick, 0); client->QueuePacket(outapp); client->Kick("Ordered kicked by command"); - c->Message(0, "Kick: local: kicking %s", sep->arg[1]); + c->Message(Chat::White, "Kick: local: kicking %s", sep->arg[1]); } } else if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else { auto pack = new ServerPacket(ServerOP_KickPlayer, sizeof(ServerKickPlayer_Struct)); ServerKickPlayer_Struct* skp = (ServerKickPlayer_Struct*) pack->pBuffer; @@ -3922,10 +3922,10 @@ void command_attack(Client *c, const Seperator *sep) if (sictar) c->GetTarget()->CastToNPC()->AddToHateList(sictar, 1, 0); else - c->Message(0, "Error: %s not found", sep->arg[1]); + c->Message(Chat::White, "Error: %s not found", sep->arg[1]); } else - c->Message(0, "Usage: (needs NPC targeted) #attack targetname"); + c->Message(Chat::White, "Usage: (needs NPC targeted) #attack targetname"); } void command_lock(Client *c, const Seperator *sep) @@ -4027,7 +4027,7 @@ void command_equipitem(Client *c, const Seperator *sep) // di->to_slot = 0xFFFFFFFF; // di->number_in_stack = 0xFFFFFFFF; - // c->Message(0, "Deleting %i charges from stack", movecount); // debug line..delete + // c->Message(Chat::White, "Deleting %i charges from stack", movecount); // debug line..delete // for (int16 deletecount=0; deletecount < movecount; deletecount++) // have to use 'movecount' because mi->number_in_stack is 'ENCODED' at this point (i.e., 99 charges returns 22...) @@ -4049,7 +4049,7 @@ void command_equipitem(Client *c, const Seperator *sep) c->Message(Chat::Red, "Error: Item on your cursor cannot be equipped"); } else - c->Message(0, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position"); + c->Message(Chat::White, "Usage: #equipitem slotid[0-21] - equips the item on your cursor to the position"); } void command_zonelock(Client *c, const Seperator *sep) @@ -4069,7 +4069,7 @@ void command_zonelock(Client *c, const Seperator *sep) worldserver.SendPacket(pack); } else - c->Message(0, "Usage: #zonelock lock [zonename]"); + c->Message(Chat::White, "Usage: #zonelock lock [zonename]"); } else if (strcasecmp(sep->arg[1], "unlock") == 0 && c->Admin() >= commandLockZones) { uint16 tmp = database.GetZoneID(sep->arg[2]); @@ -4079,15 +4079,15 @@ void command_zonelock(Client *c, const Seperator *sep) worldserver.SendPacket(pack); } else - c->Message(0, "Usage: #zonelock unlock [zonename]"); + c->Message(Chat::White, "Usage: #zonelock unlock [zonename]"); } else { - c->Message(0, "#zonelock sub-commands"); - c->Message(0, " list"); + c->Message(Chat::White, "#zonelock sub-commands"); + c->Message(Chat::White, " list"); if(c->Admin() >= commandLockZones) { - c->Message(0, " lock [zonename]"); - c->Message(0, " unlock [zonename]"); + c->Message(Chat::White, " lock [zonename]"); + c->Message(Chat::White, " unlock [zonename]"); } } safe_delete(pack); @@ -4100,24 +4100,24 @@ void command_corpse(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "DeletePlayerCorpses") == 0 && c->Admin() >= commandEditPlayerCorpses) { int32 tmp = entity_list.DeletePlayerCorpses(); if (tmp >= 0) - c->Message(0, "%i corpses deleted.", tmp); + c->Message(Chat::White, "%i corpses deleted.", tmp); else - c->Message(0, "DeletePlayerCorpses Error #%i", tmp); + c->Message(Chat::White, "DeletePlayerCorpses Error #%i", tmp); } else if (strcasecmp(sep->arg[1], "delete") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target the corpse you wish to delete"); + c->Message(Chat::White, "Error: Target the corpse you wish to delete"); else if (target->IsNPCCorpse()) { - c->Message(0, "Depoping %s.", target->GetName()); + c->Message(Chat::White, "Depoping %s.", target->GetName()); target->CastToCorpse()->Delete(); } else if (c->Admin() >= commandEditPlayerCorpses) { - c->Message(0, "Deleting %s.", target->GetName()); + c->Message(Chat::White, "Deleting %s.", target->GetName()); target->CastToCorpse()->Delete(); } else - c->Message(0, "Insufficient status to delete player corpse."); + c->Message(Chat::White, "Insufficient status to delete player corpse."); } else if (strcasecmp(sep->arg[1], "ListNPC") == 0) { entity_list.ListNPCCorpses(c); @@ -4128,101 +4128,101 @@ void command_corpse(Client *c, const Seperator *sep) else if (strcasecmp(sep->arg[1], "DeleteNPCCorpses") == 0) { int32 tmp = entity_list.DeleteNPCCorpses(); if (tmp >= 0) - c->Message(0, "%d corpses deleted.", tmp); + c->Message(Chat::White, "%d corpses deleted.", tmp); else - c->Message(0, "DeletePlayerCorpses Error #%d", tmp); + c->Message(Chat::White, "DeletePlayerCorpses Error #%d", tmp); } else if (strcasecmp(sep->arg[1], "charid") == 0 && c->Admin() >= commandEditPlayerCorpses) { if (target == 0 || !target->IsPlayerCorpse()) - c->Message(0, "Error: Target must be a player corpse."); + c->Message(Chat::White, "Error: Target must be a player corpse."); else if (!sep->IsNumber(2)) - c->Message(0, "Error: charid must be a number."); + c->Message(Chat::White, "Error: charid must be a number."); else - c->Message(0, "Setting CharID=%u on PlayerCorpse '%s'", target->CastToCorpse()->SetCharID(atoi(sep->arg[2])), target->GetName()); + c->Message(Chat::White, "Setting CharID=%u on PlayerCorpse '%s'", target->CastToCorpse()->SetCharID(atoi(sep->arg[2])), target->GetName()); } else if (strcasecmp(sep->arg[1], "ResetLooter") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target the corpse you wish to reset"); + c->Message(Chat::White, "Error: Target the corpse you wish to reset"); else target->CastToCorpse()->ResetLooter(); } else if (strcasecmp(sep->arg[1], "RemoveCash") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target the corpse you wish to remove the cash from"); + c->Message(Chat::White, "Error: Target the corpse you wish to remove the cash from"); else if (!target->IsPlayerCorpse() || c->Admin() >= commandEditPlayerCorpses) { - c->Message(0, "Removing Cash from %s.", target->GetName()); + c->Message(Chat::White, "Removing Cash from %s.", target->GetName()); target->CastToCorpse()->RemoveCash(); } else - c->Message(0, "Insufficient status to modify player corpse."); + c->Message(Chat::White, "Insufficient status to modify player corpse."); } else if (strcasecmp(sep->arg[1], "InspectLoot") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target must be a corpse."); + c->Message(Chat::White, "Error: Target must be a corpse."); else target->CastToCorpse()->QueryLoot(c); } else if (strcasecmp(sep->arg[1], "lock") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target must be a corpse."); + c->Message(Chat::White, "Error: Target must be a corpse."); else { target->CastToCorpse()->Lock(); - c->Message(0, "Locking %s...", target->GetName()); + c->Message(Chat::White, "Locking %s...", target->GetName()); } } else if (strcasecmp(sep->arg[1], "unlock") == 0) { if (target == 0 || !target->IsCorpse()) - c->Message(0, "Error: Target must be a corpse."); + c->Message(Chat::White, "Error: Target must be a corpse."); else { target->CastToCorpse()->UnLock(); - c->Message(0, "Unlocking %s...", target->GetName()); + c->Message(Chat::White, "Unlocking %s...", target->GetName()); } } else if (strcasecmp(sep->arg[1], "depop") == 0) { if (target == 0 || !target->IsPlayerCorpse()) - c->Message(0, "Error: Target must be a player corpse."); + c->Message(Chat::White, "Error: Target must be a player corpse."); else if (c->Admin() >= commandEditPlayerCorpses && target->IsPlayerCorpse()) { - c->Message(0, "Depoping %s.", target->GetName()); + c->Message(Chat::White, "Depoping %s.", target->GetName()); target->CastToCorpse()->DepopPlayerCorpse(); if(!sep->arg[2][0] || atoi(sep->arg[2]) != 0) target->CastToCorpse()->Bury(); } else - c->Message(0, "Insufficient status to depop player corpse."); + c->Message(Chat::White, "Insufficient status to depop player corpse."); } else if (strcasecmp(sep->arg[1], "depopall") == 0) { if (target == 0 || !target->IsClient()) - c->Message(0, "Error: Target must be a player."); + c->Message(Chat::White, "Error: Target must be a player."); else if (c->Admin() >= commandEditPlayerCorpses && target->IsClient()) { - c->Message(0, "Depoping %s\'s corpses.", target->GetName()); + c->Message(Chat::White, "Depoping %s\'s corpses.", target->GetName()); target->CastToClient()->DepopAllCorpses(); if(!sep->arg[2][0] || atoi(sep->arg[2]) != 0) target->CastToClient()->BuryPlayerCorpses(); } else - c->Message(0, "Insufficient status to depop player corpse."); + c->Message(Chat::White, "Insufficient status to depop player corpse."); } else if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1], "help") == 0) { - c->Message(0, "#Corpse Sub-Commands:"); - c->Message(0, " DeleteNPCCorpses"); - c->Message(0, " Delete - Delete targetted corpse"); - c->Message(0, " ListNPC"); - c->Message(0, " ListPlayer"); - c->Message(0, " Lock - GM locks the corpse - cannot be looted by non-GM"); - c->Message(0, " UnLock"); - c->Message(0, " RemoveCash"); - c->Message(0, " InspectLoot"); - c->Message(0, " [to remove items from corpses, loot them]"); - c->Message(0, "Lead-GM status required to delete/modify player corpses"); - c->Message(0, " DeletePlayerCorpses"); - c->Message(0, " CharID [charid] - change player corpse's owner"); - c->Message(0, " Depop [bury] - Depops single target corpse."); - c->Message(0, " Depopall [bury] - Depops all target player's corpses."); - c->Message(0, "Set bury to 0 to skip burying the corpses."); + c->Message(Chat::White, "#Corpse Sub-Commands:"); + c->Message(Chat::White, " DeleteNPCCorpses"); + c->Message(Chat::White, " Delete - Delete targetted corpse"); + c->Message(Chat::White, " ListNPC"); + c->Message(Chat::White, " ListPlayer"); + c->Message(Chat::White, " Lock - GM locks the corpse - cannot be looted by non-GM"); + c->Message(Chat::White, " UnLock"); + c->Message(Chat::White, " RemoveCash"); + c->Message(Chat::White, " InspectLoot"); + c->Message(Chat::White, " [to remove items from corpses, loot them]"); + c->Message(Chat::White, "Lead-GM status required to delete/modify player corpses"); + c->Message(Chat::White, " DeletePlayerCorpses"); + c->Message(Chat::White, " CharID [charid] - change player corpse's owner"); + c->Message(Chat::White, " Depop [bury] - Depops single target corpse."); + c->Message(Chat::White, " Depopall [bury] - Depops all target player's corpses."); + c->Message(Chat::White, "Set bury to 0 to skip burying the corpses."); } else - c->Message(0, "Error, #corpse sub-command not found"); + c->Message(Chat::White, "Error, #corpse sub-command not found"); } void command_fixmob(Client *c, const Seperator *sep) @@ -4231,9 +4231,9 @@ void command_fixmob(Client *c, const Seperator *sep) const char* Usage = "Usage: #fixmob [race|gender|texture|helm|face|hair|haircolor|beard|beardcolor|heritage|tattoo|detail] [next|prev]"; if (!sep->arg[1]) - c->Message(0,Usage); + c->Message(Chat::White,Usage); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { @@ -4435,7 +4435,7 @@ void command_fixmob(Client *c, const Seperator *sep) if (ChangeType == nullptr) { - c->Message(0,Usage); + c->Message(Chat::White,Usage); } else { @@ -4443,7 +4443,7 @@ void command_fixmob(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0, "%s=%i", ChangeType, ChangeSetting); + c->Message(Chat::White, "%s=%i", ChangeType, ChangeSetting); } } } @@ -4459,19 +4459,19 @@ void command_gmspeed(Client *c, const Seperator *sep) if (sep->arg[1][0] != 0) { database.SetGMSpeed(t->AccountID(), state ? 1 : 0); - c->Message(0, "Turning GMSpeed %s for %s (zone to take effect)", state ? "On" : "Off", t->GetName()); + c->Message(Chat::White, "Turning GMSpeed %s for %s (zone to take effect)", state ? "On" : "Off", t->GetName()); } else { - c->Message(0, "Usage: #gmspeed [on/off]"); + c->Message(Chat::White, "Usage: #gmspeed [on/off]"); } } void command_gmzone(Client *c, const Seperator *sep) { if (!sep->arg[1]) { - c->Message(0, "Usage"); - c->Message(0, "-------"); - c->Message(0, "#gmzone [zone_short_name] [zone_version=0]"); + c->Message(Chat::White, "Usage"); + c->Message(Chat::White, "-------"); + c->Message(Chat::White, "#gmzone [zone_short_name] [zone_version=0]"); return; } @@ -4543,7 +4543,7 @@ void command_gmzone(Client *c, const Seperator *sep) void command_title(Client *c, const Seperator *sep) { if (sep->arg[1][0]==0) - c->Message(0, "Usage: #title [remove|text] [1 = Create row in title table] - remove or set title to 'text'"); + c->Message(Chat::White, "Usage: #title [remove|text] [1 = Create row in title table] - remove or set title to 'text'"); else { bool Save = (atoi(sep->arg[2]) == 1); @@ -4593,7 +4593,7 @@ void command_title(Client *c, const Seperator *sep) void command_titlesuffix(Client *c, const Seperator *sep) { if (sep->arg[1][0]==0) - c->Message(0, "Usage: #titlesuffix [remove|text] [1 = create row in title table] - remove or set title suffix to 'text'"); + c->Message(Chat::White, "Usage: #titlesuffix [remove|text] [1 = create row in title table] - remove or set title suffix to 'text'"); else { bool Save = (atoi(sep->arg[2]) == 1); @@ -4643,53 +4643,53 @@ void command_titlesuffix(Client *c, const Seperator *sep) void command_spellinfo(Client *c, const Seperator *sep) { if(sep->arg[1][0]==0) - c->Message(0, "Usage: #spellinfo [spell_id]"); + c->Message(Chat::White, "Usage: #spellinfo [spell_id]"); else { short int spell_id=atoi(sep->arg[1]); const struct SPDat_Spell_Struct *s=&spells[spell_id]; - c->Message(0, "Spell info for spell #%d:", spell_id); - c->Message(0, " name: %s", s->name); - c->Message(0, " player_1: %s", s->player_1); - c->Message(0, " teleport_zone: %s", s->teleport_zone); - c->Message(0, " you_cast: %s", s->you_cast); - c->Message(0, " other_casts: %s", s->other_casts); - c->Message(0, " cast_on_you: %s", s->cast_on_you); - c->Message(0, " spell_fades: %s", s->spell_fades); - c->Message(0, " range: %f", s->range); - c->Message(0, " aoerange: %f", s->aoerange); - c->Message(0, " pushback: %f", s->pushback); - c->Message(0, " pushup: %f", s->pushup); - c->Message(0, " cast_time: %d", s->cast_time); - c->Message(0, " recovery_time: %d", s->recovery_time); - c->Message(0, " recast_time: %d", s->recast_time); - c->Message(0, " buffdurationformula: %d", s->buffdurationformula); - c->Message(0, " buffduration: %d", s->buffduration); - c->Message(0, " AEDuration: %d", s->AEDuration); - c->Message(0, " mana: %d", s->mana); - c->Message(0, " base[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->base[0], s->base[1], s->base[2], s->base[3], s->base[4], s->base[5], s->base[6], s->base[7], s->base[8], s->base[9], s->base[10], s->base[11]); - c->Message(0, " base22[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->base2[0], s->base2[1], s->base2[2], s->base2[3], s->base2[4], s->base2[5], s->base2[6], s->base2[7], s->base2[8], s->base2[9], s->base2[10], s->base2[11]); - c->Message(0, " max[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->max[0], s->max[1], s->max[2], s->max[3], s->max[4], s->max[5], s->max[6], s->max[7], s->max[8], s->max[9], s->max[10], s->max[11]); - c->Message(0, " components[4]: %d, %d, %d, %d", s->components[0], s->components[1], s->components[2], s->components[3]); - c->Message(0, " component_counts[4]: %d, %d, %d, %d", s->component_counts[0], s->component_counts[1], s->component_counts[2], s->component_counts[3]); - c->Message(0, " NoexpendReagent[4]: %d, %d, %d, %d", s->NoexpendReagent[0], s->NoexpendReagent[1], s->NoexpendReagent[2], s->NoexpendReagent[3]); - c->Message(0, " formula[12]: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", s->formula[0], s->formula[1], s->formula[2], s->formula[3], s->formula[4], s->formula[5], s->formula[6], s->formula[7], s->formula[8], s->formula[9], s->formula[10], s->formula[11]); - c->Message(0, " goodEffect: %d", s->goodEffect); - c->Message(0, " Activated: %d", s->Activated); - c->Message(0, " resisttype: %d", s->resisttype); - c->Message(0, " effectid[12]: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", s->effectid[0], s->effectid[1], s->effectid[2], s->effectid[3], s->effectid[4], s->effectid[5], s->effectid[6], s->effectid[7], s->effectid[8], s->effectid[9], s->effectid[10], s->effectid[11]); - c->Message(0, " targettype: %d", s->targettype); - c->Message(0, " basediff: %d", s->basediff); - c->Message(0, " skill: %d", s->skill); - c->Message(0, " zonetype: %d", s->zonetype); - c->Message(0, " EnvironmentType: %d", s->EnvironmentType); - c->Message(0, " TimeOfDay: %d", s->TimeOfDay); - c->Message(0, " classes[15]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", + c->Message(Chat::White, "Spell info for spell #%d:", spell_id); + c->Message(Chat::White, " name: %s", s->name); + c->Message(Chat::White, " player_1: %s", s->player_1); + c->Message(Chat::White, " teleport_zone: %s", s->teleport_zone); + c->Message(Chat::White, " you_cast: %s", s->you_cast); + c->Message(Chat::White, " other_casts: %s", s->other_casts); + c->Message(Chat::White, " cast_on_you: %s", s->cast_on_you); + c->Message(Chat::White, " spell_fades: %s", s->spell_fades); + c->Message(Chat::White, " range: %f", s->range); + c->Message(Chat::White, " aoerange: %f", s->aoerange); + c->Message(Chat::White, " pushback: %f", s->pushback); + c->Message(Chat::White, " pushup: %f", s->pushup); + c->Message(Chat::White, " cast_time: %d", s->cast_time); + c->Message(Chat::White, " recovery_time: %d", s->recovery_time); + c->Message(Chat::White, " recast_time: %d", s->recast_time); + c->Message(Chat::White, " buffdurationformula: %d", s->buffdurationformula); + c->Message(Chat::White, " buffduration: %d", s->buffduration); + c->Message(Chat::White, " AEDuration: %d", s->AEDuration); + c->Message(Chat::White, " mana: %d", s->mana); + c->Message(Chat::White, " base[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->base[0], s->base[1], s->base[2], s->base[3], s->base[4], s->base[5], s->base[6], s->base[7], s->base[8], s->base[9], s->base[10], s->base[11]); + c->Message(Chat::White, " base22[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->base2[0], s->base2[1], s->base2[2], s->base2[3], s->base2[4], s->base2[5], s->base2[6], s->base2[7], s->base2[8], s->base2[9], s->base2[10], s->base2[11]); + c->Message(Chat::White, " max[12]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->max[0], s->max[1], s->max[2], s->max[3], s->max[4], s->max[5], s->max[6], s->max[7], s->max[8], s->max[9], s->max[10], s->max[11]); + c->Message(Chat::White, " components[4]: %d, %d, %d, %d", s->components[0], s->components[1], s->components[2], s->components[3]); + c->Message(Chat::White, " component_counts[4]: %d, %d, %d, %d", s->component_counts[0], s->component_counts[1], s->component_counts[2], s->component_counts[3]); + c->Message(Chat::White, " NoexpendReagent[4]: %d, %d, %d, %d", s->NoexpendReagent[0], s->NoexpendReagent[1], s->NoexpendReagent[2], s->NoexpendReagent[3]); + c->Message(Chat::White, " formula[12]: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", s->formula[0], s->formula[1], s->formula[2], s->formula[3], s->formula[4], s->formula[5], s->formula[6], s->formula[7], s->formula[8], s->formula[9], s->formula[10], s->formula[11]); + c->Message(Chat::White, " goodEffect: %d", s->goodEffect); + c->Message(Chat::White, " Activated: %d", s->Activated); + c->Message(Chat::White, " resisttype: %d", s->resisttype); + c->Message(Chat::White, " effectid[12]: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", s->effectid[0], s->effectid[1], s->effectid[2], s->effectid[3], s->effectid[4], s->effectid[5], s->effectid[6], s->effectid[7], s->effectid[8], s->effectid[9], s->effectid[10], s->effectid[11]); + c->Message(Chat::White, " targettype: %d", s->targettype); + c->Message(Chat::White, " basediff: %d", s->basediff); + c->Message(Chat::White, " skill: %d", s->skill); + c->Message(Chat::White, " zonetype: %d", s->zonetype); + c->Message(Chat::White, " EnvironmentType: %d", s->EnvironmentType); + c->Message(Chat::White, " TimeOfDay: %d", s->TimeOfDay); + c->Message(Chat::White, " classes[15]: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", s->classes[0], s->classes[1], s->classes[2], s->classes[3], s->classes[4], s->classes[5], s->classes[6], s->classes[7], s->classes[8], s->classes[9], s->classes[10], s->classes[11], s->classes[12], s->classes[13], s->classes[14]); - c->Message(0, " CastingAnim: %d", s->CastingAnim); - c->Message(0, " SpellAffectIndex: %d", s->SpellAffectIndex); - c->Message(0, " RecourseLink: %d", s->RecourseLink); + c->Message(Chat::White, " CastingAnim: %d", s->CastingAnim); + c->Message(Chat::White, " SpellAffectIndex: %d", s->SpellAffectIndex); + c->Message(Chat::White, " RecourseLink: %d", s->RecourseLink); } } @@ -4704,7 +4704,7 @@ void command_lastname(Client *c, const Seperator *sep) if(strlen(sep->arg[1]) <= 70) t->ChangeLastName(sep->arg[1]); else - c->Message(0, "Usage: #lastname where is less than 70 chars long"); + c->Message(Chat::White, "Usage: #lastname where is less than 70 chars long"); } void command_memspell(Client *c, const Seperator *sep) @@ -4714,7 +4714,7 @@ void command_memspell(Client *c, const Seperator *sep) if (!(sep->IsNumber(1) && sep->IsNumber(2))) { - c->Message(0, "Usage: #MemSpell slotid spellid"); + c->Message(Chat::White, "Usage: #MemSpell slotid spellid"); } else { @@ -4722,12 +4722,12 @@ void command_memspell(Client *c, const Seperator *sep) spell_id = atoi(sep->arg[2]); if (slot > EQEmu::spells::SPELL_GEM_COUNT || spell_id >= SPDAT_RECORDS) { - c->Message(0, "Error: #MemSpell: Arguement out of range"); + c->Message(Chat::White, "Error: #MemSpell: Arguement out of range"); } else { c->MemSpell(spell_id, slot); - c->Message(0, "Spell slot changed, have fun!"); + c->Message(Chat::White, "Spell slot changed, have fun!"); } } } @@ -4735,21 +4735,21 @@ void command_memspell(Client *c, const Seperator *sep) void command_save(Client *c, const Seperator *sep) { if (c->GetTarget() == 0) - c->Message(0, "Error: no target"); + c->Message(Chat::White, "Error: no target"); else if (c->GetTarget()->IsClient()) { if (c->GetTarget()->CastToClient()->Save(2)) - c->Message(0, "%s successfully saved.", c->GetTarget()->GetName()); + c->Message(Chat::White, "%s successfully saved.", c->GetTarget()->GetName()); else - c->Message(0, "Manual save for %s failed.", c->GetTarget()->GetName()); + c->Message(Chat::White, "Manual save for %s failed.", c->GetTarget()->GetName()); } else if (c->GetTarget()->IsPlayerCorpse()) { if (c->GetTarget()->CastToMob()->Save()) - c->Message(0, "%s successfully saved. (dbid=%u)", c->GetTarget()->GetName(), c->GetTarget()->CastToCorpse()->GetCorpseDBID()); + c->Message(Chat::White, "%s successfully saved. (dbid=%u)", c->GetTarget()->GetName(), c->GetTarget()->CastToCorpse()->GetCorpseDBID()); else - c->Message(0, "Manual save for %s failed.", c->GetTarget()->GetName()); + c->Message(Chat::White, "Manual save for %s failed.", c->GetTarget()->GetName()); } else - c->Message(0, "Error: target not a Client/PlayerCorpse"); + c->Message(Chat::White, "Error: target not a Client/PlayerCorpse"); } void command_showstats(Client *c, const Seperator *sep) @@ -4762,7 +4762,7 @@ void command_showstats(Client *c, const Seperator *sep) void command_showzonegloballoot(Client *c, const Seperator *sep) { - c->Message(0, "GlobalLoot for %s (%d:%d)", zone->GetShortName(), zone->GetZoneID(), zone->GetInstanceVersion()); + c->Message(Chat::White, "GlobalLoot for %s (%d:%d)", zone->GetShortName(), zone->GetZoneID(), zone->GetInstanceVersion()); zone->ShowZoneGlobalLoot(c); } @@ -4789,7 +4789,7 @@ void command_bind(Client *c, const Seperator *sep) if (c->GetTarget()->IsClient()) c->GetTarget()->CastToClient()->SetBindPoint(); else - c->Message(0, "Error: target not a Player"); + c->Message(Chat::White, "Error: target not a Player"); } else c->SetBindPoint(); } @@ -4797,9 +4797,9 @@ void command_bind(Client *c, const Seperator *sep) void command_depop(Client *c, const Seperator *sep) { if (c->GetTarget() == 0 || !(c->GetTarget()->IsNPC() || c->GetTarget()->IsNPCCorpse())) - c->Message(0, "You must have a NPC target for this command. (maybe you meant #depopzone?)"); + c->Message(Chat::White, "You must have a NPC target for this command. (maybe you meant #depopzone?)"); else { - c->Message(0, "Depoping '%s'.", c->GetTarget()->GetName()); + c->Message(Chat::White, "Depoping '%s'.", c->GetTarget()->GetName()); c->GetTarget()->Depop(); } } @@ -4807,7 +4807,7 @@ void command_depop(Client *c, const Seperator *sep) void command_depopzone(Client *c, const Seperator *sep) { zone->Depop(); - c->Message(0, "Zone depoped."); + c->Message(Chat::White, "Zone depoped."); } void command_devtools(Client *c, const Seperator *sep) @@ -4849,8 +4849,8 @@ void command_devtools(Client *c, const Seperator *sep) /** * Print menu */ - c->Message(0, "| [Devtools] Window %s", window_toggle_command.c_str()); - c->Message(0, "| [Devtools] Search %s", menu_commands_search.c_str()); + c->Message(Chat::White, "| [Devtools] Window %s", window_toggle_command.c_str()); + c->Message(Chat::White, "| [Devtools] Search %s", menu_commands_search.c_str()); } void command_repop(Client *c, const Seperator *sep) @@ -4872,11 +4872,11 @@ void command_repop(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); iterator.Advance(); } - c->Message(0, "Zone depop: Force resetting spawn timers."); + c->Message(Chat::White, "Zone depop: Force resetting spawn timers."); } if (!sep->IsNumber(timearg)) { - c->Message(0, "Zone depopped - repopping now."); + c->Message(Chat::White, "Zone depopped - repopping now."); zone->Repop(); @@ -4885,7 +4885,7 @@ void command_repop(Client *c, const Seperator *sep) return; } - c->Message(0, "Zone depoped. Repop in %i seconds", atoi(sep->arg[timearg])); + c->Message(Chat::White, "Zone depoped. Repop in %i seconds", atoi(sep->arg[timearg])); zone->Repop(atoi(sep->arg[timearg]) * 1000); zone->spawn2_timer.Trigger(); @@ -4908,13 +4908,13 @@ void command_repopclose(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); iterator.Advance(); } - c->Message(0, "Zone depop: Force resetting spawn timers."); + c->Message(Chat::White, "Zone depop: Force resetting spawn timers."); } if (sep->IsNumber(1)) { repop_distance = atoi(sep->arg[1]); } - c->Message(0, "Zone depoped. Repopping NPC's within %i distance units", repop_distance); + c->Message(Chat::White, "Zone depoped. Repopping NPC's within %i distance units", repop_distance); zone->RepopClose(c->GetPosition(), repop_distance); } @@ -4942,7 +4942,7 @@ void command_spawnstatus(Client *c, const Seperator *sep) } else if(strcmp(sep->arg[1], "help") == 0) { - c->Message(0, "Usage: #spawnstatus <[a]ll | [d]isabled | [e]nabled | {Spawn2 ID}>"); + c->Message(Chat::White, "Usage: #spawnstatus <[a]ll | [d]isabled | [e]nabled | {Spawn2 ID}>"); } else { zone->SpawnStatus(c); @@ -4961,7 +4961,7 @@ void command_zuwcoords(Client *c, const Seperator *sep) { // modifys and resends zhdr packet if(sep->arg[1][0]==0) - c->Message(0, "Usage: #zuwcoords "); + c->Message(Chat::White, "Usage: #zuwcoords "); else { zone->newzone_data.underworld = atof(sep->arg[1]); //float newdata = atof(sep->arg[1]); @@ -4976,7 +4976,7 @@ void command_zuwcoords(Client *c, const Seperator *sep) void command_zunderworld(Client *c, const Seperator *sep) { if(sep->arg[1][0]==0) - c->Message(0, "Usage: #zunderworld "); + c->Message(Chat::White, "Usage: #zunderworld "); else { zone->newzone_data.underworld = atof(sep->arg[1]); } @@ -4986,7 +4986,7 @@ void command_zsafecoords(Client *c, const Seperator *sep) { // modifys and resends zhdr packet if(sep->arg[3][0]==0) - c->Message(0, "Usage: #zsafecoords "); + c->Message(Chat::White, "Usage: #zsafecoords "); else { zone->newzone_data.safe_x = atof(sep->arg[1]); zone->newzone_data.safe_y = atof(sep->arg[2]); @@ -5010,7 +5010,7 @@ void command_freeze(Client *c, const Seperator *sep) if (c->GetTarget() != 0) c->GetTarget()->SendAppearancePacket(AT_Anim, ANIM_FREEZE); else - c->Message(0, "ERROR: Freeze requires a target."); + c->Message(Chat::White, "ERROR: Freeze requires a target."); } void command_unfreeze(Client *c, const Seperator *sep) @@ -5018,7 +5018,7 @@ void command_unfreeze(Client *c, const Seperator *sep) if (c->GetTarget() != 0) c->GetTarget()->SendAppearancePacket(AT_Anim, ANIM_STAND); else - c->Message(0, "ERROR: Unfreeze requires a target."); + c->Message(Chat::White, "ERROR: Unfreeze requires a target."); } void command_push(Client *c, const Seperator *sep) @@ -5028,7 +5028,7 @@ void command_push(Client *c, const Seperator *sep) t = c->GetTarget(); if (!sep->arg[1] || !sep->IsNumber(1)) { - c->Message(0, "ERROR: Must provide at least a push back."); + c->Message(Chat::White, "ERROR: Must provide at least a push back."); return; } @@ -5051,7 +5051,7 @@ void command_push(Client *c, const Seperator *sep) void command_proximity(Client *c, const Seperator *sep) { if (!c->GetTarget() && !c->GetTarget()->IsNPC()) { - c->Message(0, "You must target an NPC"); + c->Message(Chat::White, "You must target an NPC"); return; } @@ -5130,10 +5130,10 @@ void command_pvp(Client *c, const Seperator *sep) if(sep->arg[1][0] != 0) { t->SetPVP(state); - c->Message(0, "%s now follows the ways of %s.", t->GetName(), state?"discord":"order"); + c->Message(Chat::White, "%s now follows the ways of %s.", t->GetName(), state?"discord":"order"); } else - c->Message(0, "Usage: #pvp [on/off]"); + c->Message(Chat::White, "Usage: #pvp [on/off]"); } void command_setxp(Client *c, const Seperator *sep) @@ -5145,12 +5145,12 @@ void command_setxp(Client *c, const Seperator *sep) if (sep->IsNumber(1)) { if (atoi(sep->arg[1]) > 9999999) - c->Message(0, "Error: Value too high."); + c->Message(Chat::White, "Error: Value too high."); else t->AddEXP(atoi(sep->arg[1])); } else - c->Message(0, "Usage: #setxp number"); + c->Message(Chat::White, "Usage: #setxp number"); } void command_setpvppoints(Client *c, const Seperator *sep) @@ -5162,7 +5162,7 @@ void command_setpvppoints(Client *c, const Seperator *sep) if (sep->IsNumber(1)) { if (atoi(sep->arg[1]) > 9999999) - c->Message(0, "Error: Value too high."); + c->Message(Chat::White, "Error: Value too high."); else { t->SetPVPPoints(atoi(sep->arg[1])); @@ -5171,7 +5171,7 @@ void command_setpvppoints(Client *c, const Seperator *sep) } } else - c->Message(0, "Usage: #setpvppoints number"); + c->Message(Chat::White, "Usage: #setpvppoints number"); } void command_name(Client *c, const Seperator *sep) @@ -5179,16 +5179,16 @@ void command_name(Client *c, const Seperator *sep) Client *target; if( (strlen(sep->arg[1]) == 0) || (!(c->GetTarget() && c->GetTarget()->IsClient())) ) - c->Message(0, "Usage: #name newname (requires player target)"); + c->Message(Chat::White, "Usage: #name newname (requires player target)"); else { target = c->GetTarget()->CastToClient(); char *oldname = strdup(target->GetName()); if(target->ChangeFirstName(sep->arg[1], c->GetName())) { - c->Message(0, "Successfully renamed %s to %s", oldname, sep->arg[1]); + c->Message(Chat::White, "Successfully renamed %s to %s", oldname, sep->arg[1]); // until we get the name packet working right this will work - c->Message(0, "Sending player to char select."); + c->Message(Chat::White, "Sending player to char select."); target->Kick("Name was changed"); } else @@ -5203,17 +5203,17 @@ void command_tempname(Client *c, const Seperator *sep) target = c->GetTarget(); if(!target) - c->Message(0, "Usage: #tempname newname (requires a target)"); + c->Message(Chat::White, "Usage: #tempname newname (requires a target)"); else if(strlen(sep->arg[1]) > 0) { char *oldname = strdup(target->GetName()); target->TempName(sep->arg[1]); - c->Message(0, "Renamed %s to %s", oldname, sep->arg[1]); + c->Message(Chat::White, "Renamed %s to %s", oldname, sep->arg[1]); free(oldname); } else { target->TempName(); - c->Message(0, "Restored the original name"); + c->Message(Chat::White, "Restored the original name"); } } @@ -5223,34 +5223,34 @@ void command_petname(Client *c, const Seperator *sep) target = c->GetTarget(); if(!target) - c->Message(0, "Usage: #petname newname (requires a target)"); + c->Message(Chat::White, "Usage: #petname newname (requires a target)"); else if(target->IsPet() && (target->GetOwnerID() == c->GetID()) && strlen(sep->arg[1]) > 0) { char *oldname = strdup(target->GetName()); target->TempName(sep->arg[1]); - c->Message(0, "Renamed %s to %s", oldname, sep->arg[1]); + c->Message(Chat::White, "Renamed %s to %s", oldname, sep->arg[1]); free(oldname); } else { target->TempName(); - c->Message(0, "Restored the original name"); + c->Message(Chat::White, "Restored the original name"); } } void command_npcspecialattk(Client *c, const Seperator *sep) { if (c->GetTarget()==0 || c->GetTarget()->IsClient() || strlen(sep->arg[1]) <= 0 || strlen(sep->arg[2]) <= 0) - c->Message(0, "Usage: #npcspecialattk *flagchar* *permtag* (Flags are E(nrage) F(lurry) R(ampage) S(ummon), permtag is 1 = True, 0 = False)."); + c->Message(Chat::White, "Usage: #npcspecialattk *flagchar* *permtag* (Flags are E(nrage) F(lurry) R(ampage) S(ummon), permtag is 1 = True, 0 = False)."); else { c->GetTarget()->CastToNPC()->NPCSpecialAttacks(sep->arg[1],atoi(sep->arg[2])); - c->Message(0, "NPC Special Attack set."); + c->Message(Chat::White, "NPC Special Attack set."); } } void command_kill(Client *c, const Seperator *sep) { if (!c->GetTarget()) { - c->Message(0, "Error: #Kill: No target."); + c->Message(Chat::White, "Error: #Kill: No target."); } else if (!c->GetTarget()->IsClient() || c->GetTarget()->CastToClient()->Admin() <= c->Admin()) @@ -5310,23 +5310,23 @@ void command_haste(Client *c, const Seperator *sep) c->SetExtraHaste(Haste); // SetAttackTimer must be called to make this take effect, so player needs to change // the primary weapon. - c->Message(0, "Haste set to %d%% - Need to re-equip primary weapon before it takes effect", Haste); + c->Message(Chat::White, "Haste set to %d%% - Need to re-equip primary weapon before it takes effect", Haste); } else - c->Message(0, "Usage: #haste [percentage]"); + c->Message(Chat::White, "Usage: #haste [percentage]"); } void command_damage(Client *c, const Seperator *sep) { if (c->GetTarget()==0) - c->Message(0, "Error: #Damage: No Target."); + c->Message(Chat::White, "Error: #Damage: No Target."); else if (!sep->IsNumber(1)) { - c->Message(0, "Usage: #damage x"); + c->Message(Chat::White, "Usage: #damage x"); } else { int32 nkdmg = atoi(sep->arg[1]); if (nkdmg > 2100000000) - c->Message(0, "Enter a value less then 2,100,000,000."); + c->Message(Chat::White, "Enter a value less then 2,100,000,000."); else c->GetTarget()->Damage(c, nkdmg, SPELL_UNKNOWN, EQEmu::skills::SkillHandtoHand, false); } @@ -5334,7 +5334,7 @@ void command_damage(Client *c, const Seperator *sep) void command_zonespawn(Client *c, const Seperator *sep) { - c->Message(0, "This command is not yet implemented."); + c->Message(Chat::White, "This command is not yet implemented."); return; /* this was kept from client.cpp verbatim (it was commented out) */ @@ -5383,7 +5383,7 @@ void command_npcspawn(Client *c, const Seperator *sep) extra = 1; } database.NPCSpawnDB(0, zone->GetShortName(), zone->GetInstanceVersion(), c, target->CastToNPC(), extra); - c->Message(0, "%s created successfully!", target->GetName()); + c->Message(Chat::White, "%s created successfully!", target->GetName()); } else if (strcasecmp(sep->arg[1], "add") == 0) { if (atoi(sep->arg[2])) @@ -5396,42 +5396,42 @@ void command_npcspawn(Client *c, const Seperator *sep) extra = 1200; } database.NPCSpawnDB(1, zone->GetShortName(), zone->GetInstanceVersion(), c, target->CastToNPC(), extra); - c->Message(0, "%s added successfully!", target->GetName()); + c->Message(Chat::White, "%s added successfully!", target->GetName()); } else if (strcasecmp(sep->arg[1], "update") == 0) { database.NPCSpawnDB(2, zone->GetShortName(), zone->GetInstanceVersion(), c, target->CastToNPC()); - c->Message(0, "%s updated!", target->GetName()); + c->Message(Chat::White, "%s updated!", target->GetName()); } else if (strcasecmp(sep->arg[1], "remove") == 0) { database.NPCSpawnDB(3, zone->GetShortName(), zone->GetInstanceVersion(), c, target->CastToNPC()); - c->Message(0, "%s removed successfully from database!", target->GetName()); + c->Message(Chat::White, "%s removed successfully from database!", target->GetName()); target->Depop(false); } else if (strcasecmp(sep->arg[1], "delete") == 0) { database.NPCSpawnDB(4, zone->GetShortName(), zone->GetInstanceVersion(), c, target->CastToNPC()); - c->Message(0, "%s deleted from database!", target->GetName()); + c->Message(Chat::White, "%s deleted from database!", target->GetName()); target->Depop(false); } else { - c->Message(0, "Error: #npcspawn: Invalid command."); - c->Message(0, "Usage: #npcspawn [create|add|update|remove|delete]"); + c->Message(Chat::White, "Error: #npcspawn: Invalid command."); + c->Message(Chat::White, "Usage: #npcspawn [create|add|update|remove|delete]"); } } else - c->Message(0, "Error: #npcspawn: You must have a NPC targeted!"); + c->Message(Chat::White, "Error: #npcspawn: You must have a NPC targeted!"); } void command_spawnfix(Client *c, const Seperator *sep) { Mob *targetMob = c->GetTarget(); if (!targetMob || !targetMob->IsNPC()) { - c->Message(0, "Error: #spawnfix: Need an NPC target."); + c->Message(Chat::White, "Error: #spawnfix: Need an NPC target."); return; } Spawn2* s2 = targetMob->CastToNPC()->respawn2; if(!s2) { - c->Message(0, "#spawnfix FAILED -- cannot determine which spawn entry in the database this mob came from."); + c->Message(Chat::White, "#spawnfix FAILED -- cannot determine which spawn entry in the database this mob came from."); return; } @@ -5444,7 +5444,7 @@ void command_spawnfix(Client *c, const Seperator *sep) { return; } - c->Message(0, "Updating coordinates successful."); + c->Message(Chat::White, "Updating coordinates successful."); targetMob->Depop(false); } @@ -5452,7 +5452,7 @@ void command_loc(Client *c, const Seperator *sep) { Mob *t=c->GetTarget()?c->GetTarget():c->CastToMob(); - c->Message(0, "%s's Location (XYZ): %1.2f, %1.2f, %1.2f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + c->Message(Chat::White, "%s's Location (XYZ): %1.2f, %1.2f, %1.2f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); } void command_goto(Client *c, const Seperator *sep) @@ -5513,8 +5513,8 @@ void command_goto(Client *c, const Seperator *sep) c->GetHeading()); } else { - c->Message(0, "Usage: #goto [x y z]"); - c->Message(0, "Usage: #goto [player_name]"); + c->Message(Chat::White, "Usage: #goto [x y z]"); + c->Message(Chat::White, "Usage: #goto [player_name]"); } } @@ -5536,41 +5536,41 @@ void command_iteminfo(Client *c, const Seperator *sep) linker.SetLinkType(EQEmu::saylink::SayLinkItemInst); linker.SetItemInst(inst); - c->Message(0, "*** Item Info for [%s] ***", linker.GenerateLink().c_str()); - c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass); - c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon); - c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice); - c->Message(0, ">> Material: 0x%02X, Color: 0x%08X, Tint: 0x%08X, Light: 0x%02X", item->Material, item->Color, inst->GetColor(), item->Light); - c->Message(0, ">> IsLore: %s, LoreGroup: %u, Lore: '%s'", (item->LoreFlag ? "TRUE" : "FALSE"), item->LoreGroup, item->Lore); - c->Message(0, ">> NoDrop: %u, NoRent: %u, NoPet: %u, NoTransfer: %u, FVNoDrop: %u", + c->Message(Chat::White, "*** Item Info for [%s] ***", linker.GenerateLink().c_str()); + c->Message(Chat::White, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass); + c->Message(Chat::White, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon); + c->Message(Chat::White, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice); + c->Message(Chat::White, ">> Material: 0x%02X, Color: 0x%08X, Tint: 0x%08X, Light: 0x%02X", item->Material, item->Color, inst->GetColor(), item->Light); + c->Message(Chat::White, ">> IsLore: %s, LoreGroup: %u, Lore: '%s'", (item->LoreFlag ? "TRUE" : "FALSE"), item->LoreGroup, item->Lore); + c->Message(Chat::White, ">> NoDrop: %u, NoRent: %u, NoPet: %u, NoTransfer: %u, FVNoDrop: %u", item->NoDrop, item->NoRent, (uint8)item->NoPet, (uint8)item->NoTransfer, item->FVNoDrop); if (item->IsClassBook()) { - c->Message(0, "*** This item is a Book (filename:'%s') ***", item->Filename); + c->Message(Chat::White, "*** This item is a Book (filename:'%s') ***", item->Filename); } else if (item->IsClassBag()) { - c->Message(0, "*** This item is a Container (%u slots) ***", item->BagSlots); + c->Message(Chat::White, "*** This item is a Container (%u slots) ***", item->BagSlots); } else { - c->Message(0, "*** This item is Common ***"); - c->Message(0, ">> Classes: %u, Races: %u, Slots: %u", item->Classes, item->Races, item->Slots); - c->Message(0, ">> ReqSkill: %u, ReqLevel: %u, RecLevel: %u", item->RecSkill, item->ReqLevel, item->RecLevel); - c->Message(0, ">> SkillModType: %u, SkillModValue: %i", item->SkillModType, item->SkillModValue); - c->Message(0, ">> BaneRaceType: %u, BaneRaceDamage: %u, BaneBodyType: %u, BaneBodyDamage: %i", + c->Message(Chat::White, "*** This item is Common ***"); + c->Message(Chat::White, ">> Classes: %u, Races: %u, Slots: %u", item->Classes, item->Races, item->Slots); + c->Message(Chat::White, ">> ReqSkill: %u, ReqLevel: %u, RecLevel: %u", item->RecSkill, item->ReqLevel, item->RecLevel); + c->Message(Chat::White, ">> SkillModType: %u, SkillModValue: %i", item->SkillModType, item->SkillModValue); + c->Message(Chat::White, ">> BaneRaceType: %u, BaneRaceDamage: %u, BaneBodyType: %u, BaneBodyDamage: %i", item->BaneDmgRace, item->BaneDmgRaceAmt, item->BaneDmgBody, item->BaneDmgAmt); - c->Message(0, ">> Magic: %s, SpellID: %i, ProcLevel: %u, Charges: %u, MaxCharges: %u", + c->Message(Chat::White, ">> Magic: %s, SpellID: %i, ProcLevel: %u, Charges: %u, MaxCharges: %u", (item->Magic ? "TRUE" : "FALSE"), item->Click.Effect, item->Click.Level, inst->GetCharges(), item->MaxCharges); - c->Message(0, ">> EffectType: 0x%02X, CastTime: %.2f", (uint8)item->Click.Type, ((double)item->CastTime / 1000)); + c->Message(Chat::White, ">> EffectType: 0x%02X, CastTime: %.2f", (uint8)item->Click.Type, ((double)item->CastTime / 1000)); } if (c->Admin() >= 200) - c->Message(0, ">> MinStatus: %u", item->MinStatus); + c->Message(Chat::White, ">> MinStatus: %u", item->MinStatus); } void command_uptime(Client *c, const Seperator *sep) { if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else { auto pack = new ServerPacket(ServerOP_Uptime, sizeof(ServerUptime_Struct)); @@ -5588,31 +5588,31 @@ void command_flag(Client *c, const Seperator *sep) if(sep->arg[2][0] == 0) { if (!c->GetTarget() || (c->GetTarget() && c->GetTarget() == c)) { c->UpdateAdmin(); - c->Message(0, "Refreshed your admin flag from DB."); + c->Message(Chat::White, "Refreshed your admin flag from DB."); } else if (c->GetTarget() && c->GetTarget() != c && c->GetTarget()->IsClient()) { c->GetTarget()->CastToClient()->UpdateAdmin(); - c->Message(0, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); - c->GetTarget()->Message(0, "%s refreshed your admin flag.", c->GetName()); + c->Message(Chat::White, "%s's admin flag has been refreshed.", c->GetTarget()->GetName()); + c->GetTarget()->Message(Chat::White, "%s refreshed your admin flag.", c->GetName()); } } else if (!sep->IsNumber(1) || atoi(sep->arg[1]) < -2 || atoi(sep->arg[1]) > 255 || strlen(sep->arg[2]) == 0) - c->Message(0, "Usage: #flag [status] [acctname]"); + c->Message(Chat::White, "Usage: #flag [status] [acctname]"); else if (c->Admin() < commandChangeFlags) { //this check makes banning players by less than this level //impossible, but i'll leave it in anyways - c->Message(0, "You may only refresh your own flag, doing so now."); + c->Message(Chat::White, "You may only refresh your own flag, doing so now."); c->UpdateAdmin(); } else { if (atoi(sep->arg[1]) > c->Admin()) - c->Message(0, "You cannot set people's status to higher than your own"); + c->Message(Chat::White, "You cannot set people's status to higher than your own"); else if (atoi(sep->arg[1]) < 0 && c->Admin() < commandBanPlayers) - c->Message(0, "You have too low of status to suspend/ban"); + c->Message(Chat::White, "You have too low of status to suspend/ban"); else if (!database.SetAccountStatus(sep->argplus[2], atoi(sep->arg[1]))) - c->Message(0, "Unable to set GM Flag."); + c->Message(Chat::White, "Unable to set GM Flag."); else { - c->Message(0, "Set GM Flag on account."); + c->Message(Chat::White, "Set GM Flag on account."); auto pack = new ServerPacket(ServerOP_FlagUpdate, 6); *((uint32*) pack->pBuffer) = database.GetAccountIDByName(sep->argplus[2]); *((int16*) &pack->pBuffer[4]) = atoi(sep->arg[1]); @@ -5657,14 +5657,14 @@ void command_guild(Client *c, const Seperator *sep) Mob *target=c->GetTarget(); if (strcasecmp(sep->arg[1], "help") == 0) { - c->Message(0, "GM Guild commands:"); - c->Message(0, " #guild list - lists all guilds on the server"); - c->Message(0, " #guild create {guildleader charname or CharID} guildname"); - c->Message(0, " #guild delete guildID"); - c->Message(0, " #guild rename guildID newname"); - c->Message(0, " #guild set charname guildID (0=no guild)"); - c->Message(0, " #guild setrank charname rank"); - c->Message(0, " #guild setleader guildID {guildleader charname or CharID}"); + c->Message(Chat::White, "GM Guild commands:"); + c->Message(Chat::White, " #guild list - lists all guilds on the server"); + c->Message(Chat::White, " #guild create {guildleader charname or CharID} guildname"); + c->Message(Chat::White, " #guild delete guildID"); + c->Message(Chat::White, " #guild rename guildID newname"); + c->Message(Chat::White, " #guild set charname guildID (0=no guild)"); + c->Message(Chat::White, " #guild setrank charname rank"); + c->Message(Chat::White, " #guild setleader guildID {guildleader charname or CharID}"); } else if (strcasecmp(sep->arg[1], "status") == 0 || strcasecmp(sep->arg[1], "stat") == 0) { Client* client = 0; @@ -5673,24 +5673,24 @@ void command_guild(Client *c, const Seperator *sep) else if (target != 0 && target->IsClient()) client = target->CastToClient(); if (client == 0) - c->Message(0, "You must target someone or specify a character name"); + c->Message(Chat::White, "You must target someone or specify a character name"); else if ((client->Admin() >= minStatusToEditOtherGuilds && admin < minStatusToEditOtherGuilds) && client->GuildID() != c->GuildID()) // no peeping for GMs, make sure tell message stays the same - c->Message(0, "You must target someone or specify a character name."); + c->Message(Chat::White, "You must target someone or specify a character name."); else { if (client->IsInAGuild()) - c->Message(0, "%s is not in a guild.", client->GetName()); + c->Message(Chat::White, "%s is not in a guild.", client->GetName()); else if (guild_mgr.IsGuildLeader(client->GuildID(), client->CharacterID())) - c->Message(0, "%s is the leader of <%s> rank: %s", client->GetName(), guild_mgr.GetGuildName(client->GuildID()), guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); + c->Message(Chat::White, "%s is the leader of <%s> rank: %s", client->GetName(), guild_mgr.GetGuildName(client->GuildID()), guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); else - c->Message(0, "%s is a member of <%s> rank: %s", client->GetName(), guild_mgr.GetGuildName(client->GuildID()), guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); + c->Message(Chat::White, "%s is a member of <%s> rank: %s", client->GetName(), guild_mgr.GetGuildName(client->GuildID()), guild_mgr.GetRankName(client->GuildID(), client->GuildRank())); } } else if (strcasecmp(sep->arg[1], "info") == 0) { if (sep->arg[2][0] == 0 && c->IsInAGuild()) { if (admin >= minStatusToEditOtherGuilds) - c->Message(0, "Usage: #guildinfo guild_id"); + c->Message(Chat::White, "Usage: #guildinfo guild_id"); else - c->Message(0, "You're not in a guild"); + c->Message(Chat::White, "You're not in a guild"); } else { uint32 tmp = GUILD_NONE; @@ -5706,19 +5706,19 @@ void command_guild(Client *c, const Seperator *sep) /* else if (strcasecmp(sep->arg[1], "edit") == 0) { if (c->GuildDBID() == 0) - c->Message(0, "You arent in a guild!"); + c->Message(Chat::White, "You arent in a guild!"); else if (!sep->IsNumber(2)) - c->Message(0, "Error: invalid rank #."); + c->Message(Chat::White, "Error: invalid rank #."); else if (atoi(sep->arg[2]) < 0 || atoi(sep->arg[2]) > GUILD_MAX_RANK) - c->Message(0, "Error: invalid rank #."); + c->Message(Chat::White, "Error: invalid rank #."); else if (!c->GuildRank() == 0) - c->Message(0, "You must be rank %s to use edit.", guilds[c->GuildEQID()].rank[0].rankname); + c->Message(Chat::White, "You must be rank %s to use edit.", guilds[c->GuildEQID()].rank[0].rankname); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { if (!helper_guild_edit(c, c->GuildDBID(), c->GuildEQID(), atoi(sep->arg[2]), sep->arg[3], sep->argplus[4])) { - c->Message(0, " #guild edit rank title newtitle"); - c->Message(0, " #guild edit rank permission 0/1"); + c->Message(Chat::White, " #guild edit rank title newtitle"); + c->Message(Chat::White, " #guild edit rank permission 0/1"); } else { ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, 5); @@ -5731,20 +5731,20 @@ void command_guild(Client *c, const Seperator *sep) } else if (strcasecmp(sep->arg[1], "gmedit") == 0 && admin >= 100) { if (!sep->IsNumber(2)) - c->Message(0, "Error: invalid guilddbid."); + c->Message(Chat::White, "Error: invalid guilddbid."); else if (!sep->IsNumber(3)) - c->Message(0, "Error: invalid rank #."); + c->Message(Chat::White, "Error: invalid rank #."); else if (atoi(sep->arg[3]) < 0 || atoi(sep->arg[3]) > GUILD_MAX_RANK) - c->Message(0, "Error: invalid rank #."); + c->Message(Chat::White, "Error: invalid rank #."); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { uint32 eqid = database.GetGuildEQID(atoi(sep->arg[2])); if (eqid == GUILD_NONE) - c->Message(0, "Error: Guild not found"); + c->Message(Chat::White, "Error: Guild not found"); else if (!helper_guild_edit(c, atoi(sep->arg[2]), eqid, atoi(sep->arg[3]), sep->arg[4], sep->argplus[5])) { - c->Message(0, " #guild gmedit guilddbid rank title newtitle"); - c->Message(0, " #guild gmedit guilddbid rank permission 0/1"); + c->Message(Chat::White, " #guild gmedit guilddbid rank title newtitle"); + c->Message(Chat::White, " #guild gmedit guilddbid rank permission 0/1"); } else { ServerPacket* pack = new ServerPacket(ServerOP_RefreshGuild, 5); @@ -5757,7 +5757,7 @@ void command_guild(Client *c, const Seperator *sep) */ else if (strcasecmp(sep->arg[1], "set") == 0) { if (!sep->IsNumber(3)) - c->Message(0, "Usage: #guild set charname guildgbid (0 = clear guildtag)"); + c->Message(Chat::White, "Usage: #guild set charname guildgbid (0 = clear guildtag)"); else { uint32 guild_id = atoi(sep->arg[3]); @@ -5792,24 +5792,24 @@ void command_guild(Client *c, const Seperator *sep) if(!guild_mgr.SetGuild(charid, guild_id, GUILD_MEMBER)) { c->Message(Chat::Red, "Error putting '%s' into guild %d", sep->arg[2], guild_id); } else { - c->Message(0, "%s has been put into guild %d", sep->arg[2], guild_id); + c->Message(Chat::White, "%s has been put into guild %d", sep->arg[2], guild_id); } } } /*else if (strcasecmp(sep->arg[1], "setdoor") == 0 && admin >= minStatusToEditOtherGuilds) { if (!sep->IsNumber(2)) - c->Message(0, "Usage: #guild setdoor guildEQid (0 = delete guilddoor)"); + c->Message(Chat::White, "Usage: #guild setdoor guildEQid (0 = delete guilddoor)"); else { // guild doors if((!guilds[atoi(sep->arg[2])].databaseID) && (atoi(sep->arg[2])!=0) ) { - c->Message(0, "These is no guild with this guildEQid"); + c->Message(Chat::White, "These is no guild with this guildEQid"); } else { c->SetIsSettingGuildDoor(true); - c->Message(0, "Click on a door you want to become a guilddoor"); + c->Message(Chat::White, "Click on a door you want to become a guilddoor"); c->SetSetGuildDoorID(atoi(sep->arg[2])); } } @@ -5817,9 +5817,9 @@ void command_guild(Client *c, const Seperator *sep) else if (strcasecmp(sep->arg[1], "setrank") == 0) { int rank = atoi(sep->arg[3]); if (!sep->IsNumber(3)) - c->Message(0, "Usage: #guild setrank charname rank"); + c->Message(Chat::White, "Usage: #guild setrank charname rank"); else if (rank < 0 || rank > GUILD_MAX_RANK) - c->Message(0, "Error: invalid rank #."); + c->Message(Chat::White, "Error: invalid rank #."); else { uint32 charid = database.GetCharacterID(sep->arg[2]); if(charid == 0) { @@ -5839,14 +5839,14 @@ void command_guild(Client *c, const Seperator *sep) if(!guild_mgr.SetGuildRank(charid, rank)) c->Message(Chat::Red, "Error while setting rank %d on '%s'.", rank, sep->arg[2]); else - c->Message(0, "%s has been set to rank %d", sep->arg[2], rank); + c->Message(Chat::White, "%s has been set to rank %d", sep->arg[2], rank); } } else if (strcasecmp(sep->arg[1], "create") == 0) { if (sep->arg[3][0] == 0) - c->Message(0, "Usage: #guild create {guildleader charname or CharID} guild name"); + c->Message(Chat::White, "Usage: #guild create {guildleader charname or CharID} guild name"); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { uint32 leader = 0; if (sep->IsNumber(2)) { @@ -5858,13 +5858,13 @@ void command_guild(Client *c, const Seperator *sep) return; } if (leader == 0) { - c->Message(0, "Guild leader not found."); + c->Message(Chat::White, "Guild leader not found."); return; } uint32 tmp = guild_mgr.FindGuildByLeader(leader); if (tmp != GUILD_NONE) { - c->Message(0, "Error: %s already is the leader of DB# %i '%s'.", sep->arg[2], tmp, guild_mgr.GetGuildName(tmp)); + c->Message(Chat::White, "Error: %s already is the leader of DB# %i '%s'.", sep->arg[2], tmp, guild_mgr.GetGuildName(tmp)); } else { @@ -5879,12 +5879,12 @@ void command_guild(Client *c, const Seperator *sep) sep->argplus[3], leader, (unsigned long)id); if (id == GUILD_NONE) - c->Message(0, "Guild creation failed."); + c->Message(Chat::White, "Guild creation failed."); else { - c->Message(0, "Guild created: Leader: %i, number %i: %s", leader, id, sep->argplus[3]); + c->Message(Chat::White, "Guild created: Leader: %i, number %i: %s", leader, id, sep->argplus[3]); if(!guild_mgr.SetGuild(leader, id, GUILD_LEADER)) - c->Message(0, "Unable to set guild leader's guild in the database. Your going to have to run #guild set"); + c->Message(Chat::White, "Unable to set guild leader's guild in the database. Your going to have to run #guild set"); } } @@ -5892,14 +5892,14 @@ void command_guild(Client *c, const Seperator *sep) } else if (strcasecmp(sep->arg[1], "delete") == 0) { if (!sep->IsNumber(2)) - c->Message(0, "Usage: #guild delete guildID"); + c->Message(Chat::White, "Usage: #guild delete guildID"); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { uint32 id = atoi(sep->arg[2]); if(!guild_mgr.GuildExists(id)) { - c->Message(0, "Guild %d does not exist!", id); + c->Message(Chat::White, "Guild %d does not exist!", id); return; } @@ -5918,22 +5918,22 @@ void command_guild(Client *c, const Seperator *sep) guild_mgr.GetGuildName(id), id); if (!guild_mgr.DeleteGuild(id)) - c->Message(0, "Guild delete failed."); + c->Message(Chat::White, "Guild delete failed."); else { - c->Message(0, "Guild %d deleted.", id); + c->Message(Chat::White, "Guild %d deleted.", id); } } } else if (strcasecmp(sep->arg[1], "rename") == 0) { if ((!sep->IsNumber(2)) || sep->arg[3][0] == 0) - c->Message(0, "Usage: #guild rename guildID newname"); + c->Message(Chat::White, "Usage: #guild rename guildID newname"); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { uint32 id = atoi(sep->arg[2]); if(!guild_mgr.GuildExists(id)) { - c->Message(0, "Guild %d does not exist!", id); + c->Message(Chat::White, "Guild %d does not exist!", id); return; } @@ -5952,17 +5952,17 @@ void command_guild(Client *c, const Seperator *sep) guild_mgr.GetGuildName(id), id, sep->argplus[3]); if (!guild_mgr.RenameGuild(id, sep->argplus[3])) - c->Message(0, "Guild rename failed."); + c->Message(Chat::White, "Guild rename failed."); else { - c->Message(0, "Guild %d renamed to %s", id, sep->argplus[3]); + c->Message(Chat::White, "Guild %d renamed to %s", id, sep->argplus[3]); } } } else if (strcasecmp(sep->arg[1], "setleader") == 0) { if (sep->arg[3][0] == 0 || !sep->IsNumber(2)) - c->Message(0, "Usage: #guild setleader guild_id {guildleader charname or CharID}"); + c->Message(Chat::White, "Usage: #guild setleader guild_id {guildleader charname or CharID}"); else if (!worldserver.Connected()) - c->Message(0, "Error: World server dirconnected"); + c->Message(Chat::White, "Error: World server dirconnected"); else { uint32 leader = 0; if (sep->IsNumber(2)) { @@ -5976,15 +5976,15 @@ void command_guild(Client *c, const Seperator *sep) uint32 tmpdb = guild_mgr.FindGuildByLeader(leader); if (leader == 0) - c->Message(0, "New leader not found."); + c->Message(Chat::White, "New leader not found."); else if (tmpdb != 0) { - c->Message(0, "Error: %s already is the leader of guild # %i", sep->arg[2], tmpdb); + c->Message(Chat::White, "Error: %s already is the leader of guild # %i", sep->arg[2], tmpdb); } else { uint32 id = atoi(sep->arg[2]); if(!guild_mgr.GuildExists(id)) { - c->Message(0, "Guild %d does not exist!", id); + c->Message(Chat::White, "Guild %d does not exist!", id); return; } @@ -6003,9 +6003,9 @@ void command_guild(Client *c, const Seperator *sep) guild_mgr.GetGuildName(id), id, leader); if(!guild_mgr.SetGuildLeader(id, leader)) - c->Message(0, "Guild leader change failed."); + c->Message(Chat::White, "Guild leader change failed."); else { - c->Message(0, "Guild leader changed: guild # %d, Leader: %s", id, sep->argplus[3]); + c->Message(Chat::White, "Guild leader changed: guild # %d, Leader: %s", id, sep->argplus[3]); } } } @@ -6018,7 +6018,7 @@ void command_guild(Client *c, const Seperator *sep) guild_mgr.ListGuilds(c); } else { - c->Message(0, "Unknown guild command, try #guild help"); + c->Message(Chat::White, "Unknown guild command, try #guild help"); } } /* @@ -6036,12 +6036,12 @@ bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const ch if (strcasecmp(what, "title") == 0) { if (strlen(value) > 100) - c->Message(0, "Error: Title has a maxium length of 100 characters."); + c->Message(Chat::White, "Error: Title has a maxium length of 100 characters."); else strcpy(grl.rankname, value); } else if (rank == 0) - c->Message(0, "Error: Rank 0's permissions can not be changed."); + c->Message(Chat::White, "Error: Rank 0's permissions can not be changed."); else { if (!(strlen(value) == 1 && (value[0] == '0' || value[0] == '1'))) @@ -6064,17 +6064,17 @@ bool helper_guild_edit(Client *c, uint32 dbid, uint32 eqid, uint8 rank, const ch else if (strcasecmp(what, "warpeace") == 0) grl.warpeace = (value[0] == '1'); else - c->Message(0, "Error: Permission name not recognized."); + c->Message(Chat::White, "Error: Permission name not recognized."); } if (!database.EditGuild(dbid, rank, &grl)) - c->Message(0, "Error: database.EditGuild() failed"); + c->Message(Chat::White, "Error: database.EditGuild() failed"); return true; }*/ void command_zonestatus(Client *c, const Seperator *sep) { if (!worldserver.Connected()) - c->Message(0, "Error: World server disconnected"); + c->Message(Chat::White, "Error: World server disconnected"); else { auto pack = new ServerPacket(ServerOP_ZoneStatus, strlen(c->GetName()) + 2); memset(pack->pBuffer, (uint8) c->Admin(), 1); @@ -6087,11 +6087,11 @@ void command_zonestatus(Client *c, const Seperator *sep) void command_doanim(Client *c, const Seperator *sep) { if (!sep->IsNumber(1)) - c->Message(0, "Usage: #DoAnim [number]"); + c->Message(Chat::White, "Usage: #DoAnim [number]"); else if (c->Admin() >= commandDoAnimOthers) if (c->GetTarget() == 0) - c->Message(0, "Error: You need a target."); + c->Message(Chat::White, "Error: You need a target."); else c->GetTarget()->DoAnim(atoi(sep->arg[1]),atoi(sep->arg[2])); else @@ -6102,13 +6102,13 @@ void command_randomfeatures(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!target) - c->Message(0,"Error: This command requires a target"); + c->Message(Chat::White,"Error: This command requires a target"); else { if (target->RandomizeFeatures()) - c->Message(0,"Features Randomized"); + c->Message(Chat::White,"Features Randomized"); else - c->Message(0,"This command requires a Playable Race as the target"); + c->Message(Chat::White,"This command requires a Playable Race as the target"); } } @@ -6116,9 +6116,9 @@ void command_face(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #face [number of face]"); + c->Message(Chat::White,"Usage: #face [number of face]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6139,14 +6139,14 @@ void command_face(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Face = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Face = %i", atoi(sep->arg[1])); } } void command_findaliases(Client *c, const Seperator *sep) { if (!sep->arg[1][0]) { - c->Message(0, "Usage: #findaliases [alias | command]"); + c->Message(Chat::White, "Usage: #findaliases [alias | command]"); return; } @@ -6158,30 +6158,30 @@ void command_findaliases(Client *c, const Seperator *sep) auto command_iter = commandlist.find(find_iter->second); if (find_iter->second.empty() || command_iter == commandlist.end()) { - c->Message(0, "An unknown condition occurred..."); + c->Message(Chat::White, "An unknown condition occurred..."); return; } - c->Message(0, "Available command aliases for '%s':", command_iter->first.c_str()); + c->Message(Chat::White, "Available command aliases for '%s':", command_iter->first.c_str()); int commandaliasesshown = 0; for (auto alias_iter = commandaliases.begin(); alias_iter != commandaliases.end(); ++alias_iter) { if (strcasecmp(find_iter->second.c_str(), alias_iter->second.c_str()) || c->Admin() < command_iter->second->access) continue; - c->Message(0, "%c%s", COMMAND_CHAR, alias_iter->first.c_str()); + c->Message(Chat::White, "%c%s", COMMAND_CHAR, alias_iter->first.c_str()); ++commandaliasesshown; } - c->Message(0, "%d command alias%s listed.", commandaliasesshown, commandaliasesshown != 1 ? "es" : ""); + c->Message(Chat::White, "%d command alias%s listed.", commandaliasesshown, commandaliasesshown != 1 ? "es" : ""); } void command_details(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #details [number of drakkin detail]"); + c->Message(Chat::White,"Usage: #details [number of drakkin detail]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6202,7 +6202,7 @@ void command_details(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Details = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Details = %i", atoi(sep->arg[1])); } } @@ -6210,9 +6210,9 @@ void command_heritage(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #heritage [number of Drakkin heritage]"); + c->Message(Chat::White,"Usage: #heritage [number of Drakkin heritage]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6233,7 +6233,7 @@ void command_heritage(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Heritage = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Heritage = %i", atoi(sep->arg[1])); } } @@ -6241,9 +6241,9 @@ void command_tattoo(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #tattoo [number of Drakkin tattoo]"); + c->Message(Chat::White,"Usage: #tattoo [number of Drakkin tattoo]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6264,7 +6264,7 @@ void command_tattoo(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Tattoo = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Tattoo = %i", atoi(sep->arg[1])); } } @@ -6272,9 +6272,9 @@ void command_helm(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #helm [number of helm texture]"); + c->Message(Chat::White,"Usage: #helm [number of helm texture]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6295,7 +6295,7 @@ void command_helm(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Helm = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Helm = %i", atoi(sep->arg[1])); } } @@ -6303,9 +6303,9 @@ void command_hair(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #hair [number of hair style]"); + c->Message(Chat::White,"Usage: #hair [number of hair style]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6326,7 +6326,7 @@ void command_hair(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Hair = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Hair = %i", atoi(sep->arg[1])); } } @@ -6334,9 +6334,9 @@ void command_haircolor(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #haircolor [number of hair color]"); + c->Message(Chat::White,"Usage: #haircolor [number of hair color]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6357,7 +6357,7 @@ void command_haircolor(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Hair Color = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Hair Color = %i", atoi(sep->arg[1])); } } @@ -6365,9 +6365,9 @@ void command_beard(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #beard [number of beard style]"); + c->Message(Chat::White,"Usage: #beard [number of beard style]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6388,7 +6388,7 @@ void command_beard(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Beard = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Beard = %i", atoi(sep->arg[1])); } } @@ -6396,9 +6396,9 @@ void command_beardcolor(Client *c, const Seperator *sep) { Mob *target=c->GetTarget(); if (!sep->IsNumber(1)) - c->Message(0,"Usage: #beardcolor [number of beard color]"); + c->Message(Chat::White,"Usage: #beardcolor [number of beard color]"); else if (!target) - c->Message(0,"Error: this command requires a target"); + c->Message(Chat::White,"Error: this command requires a target"); else { uint16 Race = target->GetRace(); uint8 Gender = target->GetGender(); @@ -6419,7 +6419,7 @@ void command_beardcolor(Client *c, const Seperator *sep) EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF, DrakkinHeritage, DrakkinTattoo, DrakkinDetails); - c->Message(0,"Beard Color = %i", atoi(sep->arg[1])); + c->Message(Chat::White,"Beard Color = %i", atoi(sep->arg[1])); } } @@ -6430,7 +6430,7 @@ void command_scribespells(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); if(sep->argnum < 1 || !sep->IsNumber(1)) { - c->Message(0, "FORMAT: #scribespells "); + c->Message(Chat::White, "FORMAT: #scribespells "); return; } @@ -6443,17 +6443,17 @@ void command_scribespells(Client *c, const Seperator *sep) min_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level if(max_level < 1 || min_level < 1) { - c->Message(0, "ERROR: Level must be greater than 1."); + c->Message(Chat::White, "ERROR: Level must be greater than 1."); return; } if (min_level > max_level) { - c->Message(0, "ERROR: Min Level must be less than or equal to Max Level."); + c->Message(Chat::White, "ERROR: Min Level must be less than or equal to Max Level."); return; } - t->Message(0, "Scribing spells to spellbook."); + t->Message(Chat::White, "Scribing spells to spellbook."); if(t != c) - c->Message(0, "Scribing spells for %s.", t->GetName()); + c->Message(Chat::White, "Scribing spells for %s.", t->GetName()); Log(Logs::General, Logs::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); int book_slot = t->GetNextAvailableSpellBookSlot(); @@ -6516,14 +6516,14 @@ void command_scribespells(Client *c, const Seperator *sep) } if (count > 0) { - t->Message(0, "Successfully scribed %i spells.", count); + t->Message(Chat::White, "Successfully scribed %i spells.", count); if (t != c) - c->Message(0, "Successfully scribed %i spells for %s.", count, t->GetName()); + c->Message(Chat::White, "Successfully scribed %i spells for %s.", count, t->GetName()); } else { - t->Message(0, "No spells scribed."); + t->Message(Chat::White, "No spells scribed."); if (t != c) - c->Message(0, "No spells scribed for %s.", t->GetName()); + c->Message(Chat::White, "No spells scribed for %s.", t->GetName()); } } @@ -6536,17 +6536,17 @@ void command_scribespell(Client *c, const Seperator *sep) { t=c->GetTarget()->CastToClient(); if(!sep->arg[1][0]) { - c->Message(0, "FORMAT: #scribespell "); + c->Message(Chat::White, "FORMAT: #scribespell "); return; } spell_id = atoi(sep->arg[1]); if(IsValidSpell(spell_id)) { - t->Message(0, "Scribing spell: %s (%i) to spellbook.", spells[spell_id].name, spell_id); + t->Message(Chat::White, "Scribing spell: %s (%i) to spellbook.", spells[spell_id].name, spell_id); if(t != c) - c->Message(0, "Scribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); + c->Message(Chat::White, "Scribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); Log(Logs::General, Logs::Normal, "Scribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); @@ -6578,7 +6578,7 @@ void command_unscribespell(Client *c, const Seperator *sep) { t=c->GetTarget()->CastToClient(); if(!sep->arg[1][0]) { - c->Message(0, "FORMAT: #unscribespell "); + c->Message(Chat::White, "FORMAT: #unscribespell "); return; } @@ -6590,10 +6590,10 @@ void command_unscribespell(Client *c, const Seperator *sep) { if(book_slot >= 0) { t->UnscribeSpell(book_slot); - t->Message(0, "Unscribing spell: %s (%i) from spellbook.", spells[spell_id].name, spell_id); + t->Message(Chat::White, "Unscribing spell: %s (%i) from spellbook.", spells[spell_id].name, spell_id); if(t != c) - c->Message(0, "Unscribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); + c->Message(Chat::White, "Unscribing spell: %s (%i) for %s.", spells[spell_id].name, spell_id, t->GetName()); Log(Logs::General, Logs::Normal, "Unscribe spell: %s (%i) request for %s from %s.", spells[spell_id].name, spell_id, t->GetName(), c->GetName()); } @@ -6642,7 +6642,7 @@ void command_wpinfo(Client *c, const Seperator *sep) Mob *t=c->GetTarget(); if (t == nullptr || !t->IsNPC()) { - c->Message(0,"You must target an NPC to use this."); + c->Message(Chat::White,"You must target an NPC to use this."); return; } @@ -6663,7 +6663,7 @@ void command_wpadd(Client *c, const Seperator *sep) if(s2info == nullptr) // Can't figure out where this mob's spawn came from... maybe a dynamic mob created by #spawn { - c->Message(0,"#wpadd FAILED -- Can't determine which spawn record in the database this mob came from!"); + c->Message(Chat::White,"#wpadd FAILED -- Can't determine which spawn record in the database this mob came from!"); return; } @@ -6673,7 +6673,7 @@ void command_wpadd(Client *c, const Seperator *sep) pause=atoi(sep->arg[1]); else { - c->Message(0,"Usage: #wpadd [pause] [-h]"); + c->Message(Chat::White,"Usage: #wpadd [pause] [-h]"); return; } } @@ -6686,10 +6686,10 @@ void command_wpadd(Client *c, const Seperator *sep) t->CastToNPC()->SetGrid(tmp_grid); t->CastToNPC()->AssignWaypoints(t->CastToNPC()->GetGrid()); - c->Message(0,"Waypoint added. Use #wpinfo to see waypoints for this NPC (may need to #repop first)."); + c->Message(Chat::White,"Waypoint added. Use #wpinfo to see waypoints for this NPC (may need to #repop first)."); } else - c->Message(0,"You must target an NPC to use this."); + c->Message(Chat::White,"You must target an NPC to use this."); } @@ -6718,14 +6718,14 @@ void command_summonitem(Client *c, const Seperator *sep) itemid = link_body.item_id; } else if (!sep->IsNumber(1)) { - c->Message(0, "Usage: #summonitem [item id | link] [charges], charges are optional"); + c->Message(Chat::White, "Usage: #summonitem [item id | link] [charges], charges are optional"); return; } else { itemid = atoi(sep->arg[1]); } if (!itemid) { - c->Message(0, "A valid item id number is required (derived: 0)"); + c->Message(Chat::White, "A valid item id number is required (derived: 0)"); return; } @@ -6810,14 +6810,14 @@ void command_givemoney(Client *c, const Seperator *sep) else { //TODO: update this to the client, otherwise the client doesn't show any weight change until you zone, move an item, etc c->GetTarget()->CastToClient()->AddMoneyToPP(atoi(sep->arg[4]), atoi(sep->arg[3]), atoi(sep->arg[2]), atoi(sep->arg[1]), true); - c->Message(0, "Added %i Platinum, %i Gold, %i Silver, and %i Copper to %s's inventory.", atoi(sep->arg[1]), atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), c->GetTarget()->GetName()); + c->Message(Chat::White, "Added %i Platinum, %i Gold, %i Silver, and %i Copper to %s's inventory.", atoi(sep->arg[1]), atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4]), c->GetTarget()->GetName()); } } void command_itemsearch(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) - c->Message(0, "Usage: #itemsearch [search string]"); + c->Message(Chat::White, "Usage: #itemsearch [search string]"); else { const char *search_criteria=sep->argplus[1]; @@ -6831,10 +6831,10 @@ void command_itemsearch(Client *c, const Seperator *sep) if (item) { linker.SetItemData(item); - c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str()); + c->Message(Chat::White, "%u: %s", item->ID, linker.GenerateLink().c_str()); } else { - c->Message(0, "Item #%s not found", search_criteria); + c->Message(Chat::White, "Item #%s not found", search_criteria); } return; @@ -6854,7 +6854,7 @@ void command_itemsearch(Client *c, const Seperator *sep) if (pdest != nullptr) { linker.SetItemData(item); - c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str()); + c->Message(Chat::White, "%u: %s", item->ID, linker.GenerateLink().c_str()); ++count; } @@ -6864,9 +6864,9 @@ void command_itemsearch(Client *c, const Seperator *sep) } if (count == 50) - c->Message(0, "50 items shown...too many results."); + c->Message(Chat::White, "50 items shown...too many results."); else - c->Message(0, "%i items found", count); + c->Message(Chat::White, "%i items found", count); } } @@ -6884,7 +6884,7 @@ void command_setaaxp(Client *c, const Seperator *sep) t->SetLeadershipEXP(atoi(sep->arg[2]), atoi(sep->arg[3])); } } else - c->Message(0, "Usage: #setaaxp ( )"); + c->Message(Chat::White, "Usage: #setaaxp ( )"); } void command_setaapts(Client *c, const Seperator *sep) @@ -6895,9 +6895,9 @@ void command_setaapts(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(sep->arg[1][0] == '\0' || sep->arg[2][0] == '\0') - c->Message(0, "Usage: #setaapts "); + c->Message(Chat::White, "Usage: #setaapts "); else if(atoi(sep->arg[2]) <= 0 || atoi(sep->arg[2]) > 5000) - c->Message(0, "You must have a number greater than 0 for points and no more than 5000."); + c->Message(Chat::White, "You must have a number greater than 0 for points and no more than 5000."); else if(!strcasecmp(sep->arg[1], "group")) { t->GetPP().group_leadership_points = atoi(sep->arg[2]); t->GetPP().group_leadership_exp = 0; @@ -6924,9 +6924,9 @@ void command_setcrystals(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(sep->arg[1][0] == '\0' || sep->arg[2][0] == '\0') - c->Message(0, "Usage: #setcrystals "); + c->Message(Chat::White, "Usage: #setcrystals "); else if(atoi(sep->arg[2]) <= 0 || atoi(sep->arg[2]) > 100000) - c->Message(0, "You must have a number greater than 0 for crystals and no more than 100000."); + c->Message(Chat::White, "You must have a number greater than 0 for crystals and no more than 100000."); else if(!strcasecmp(sep->arg[1], "radiant")) { t->SetRadiantCrystals(atoi(sep->arg[2])); @@ -6941,7 +6941,7 @@ void command_setcrystals(Client *c, const Seperator *sep) } else { - c->Message(0, "Usage: #setcrystals "); + c->Message(Chat::White, "Usage: #setcrystals "); } } @@ -6961,14 +6961,14 @@ void command_stun(Client *c, const Seperator *sep) t->CastToNPC()->Stun(duration); } else - c->Message(0, "Usage: #stun [duration]"); + c->Message(Chat::White, "Usage: #stun [duration]"); } void command_ban(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { - c->Message(0, "Usage: #ban "); + c->Message(Chat::White, "Usage: #ban "); return; } @@ -6990,7 +6990,7 @@ if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { } if(message.length() == 0) { - c->Message(0, "Usage: #ban "); + c->Message(Chat::White, "Usage: #ban "); return; } @@ -7028,7 +7028,7 @@ if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { void command_suspend(Client *c, const Seperator *sep) { if((sep->arg[1][0] == 0) || (sep->arg[2][0] == 0)) { - c->Message(0, "Usage: #suspend (Specify 0 days to lift the suspension immediately) "); + c->Message(Chat::White, "Usage: #suspend (Specify 0 days to lift the suspension immediately) "); return; } @@ -7055,7 +7055,7 @@ void command_suspend(Client *c, const Seperator *sep) } if(message.length() == 0) { - c->Message(0, "Usage: #suspend (Specify 0 days to lift the suspension immediately) "); + c->Message(Chat::White, "Usage: #suspend (Specify 0 days to lift the suspension immediately) "); return; } } @@ -7103,12 +7103,12 @@ void command_ipban(Client *c, const Seperator *sep) { if(sep->arg[1] == 0) { - c->Message(0, "Usage: #ipban [xxx.xxx.xxx.xxx]"); + c->Message(Chat::White, "Usage: #ipban [xxx.xxx.xxx.xxx]"); } else { if(database.AddBannedIP(sep->arg[1], c->GetName())) { - c->Message(0, "%s has been successfully added to the Banned_IPs table by %s", sep->arg[1], c->GetName()); + c->Message(Chat::White, "%s has been successfully added to the Banned_IPs table by %s", sep->arg[1], c->GetName()); } else { - c->Message(0, "IPBan Failed (IP address is possibly already in the table?)"); + c->Message(Chat::White, "IPBan Failed (IP address is possibly already in the table?)"); } } } @@ -7116,7 +7116,7 @@ void command_ipban(Client *c, const Seperator *sep) void command_revoke(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0 || sep->arg[2][0] == 0) { - c->Message(0, "Usage: #revoke [charname] [1/0]"); + c->Message(Chat::White, "Usage: #revoke [charname] [1/0]"); return; } @@ -7134,7 +7134,7 @@ void command_revoke(Client *c, const Seperator *sep) Client* revokee = entity_list.GetClientByAccID(characterID); if(revokee) { - c->Message(0, "Found %s in this zone.", revokee->GetName()); + c->Message(Chat::White, "Found %s in this zone.", revokee->GetName()); revokee->SetRevoked(flag); return; } @@ -7153,7 +7153,7 @@ void command_revoke(Client *c, const Seperator *sep) void command_oocmute(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0 || !(sep->arg[1][0] == '1' || sep->arg[1][0] == '0')) - c->Message(0, "Usage: #oocmute [1/0]"); + c->Message(Chat::White, "Usage: #oocmute [1/0]"); else { auto outapp = new ServerPacket(ServerOP_OOCMute, 1); *(outapp->pBuffer) = atoi(sep->arg[1]); @@ -7168,13 +7168,13 @@ void command_checklos(Client *c, const Seperator *sep) { // if(c->CheckLos(c->GetTarget())) if(c->CheckLosFN(c->GetTarget())) - c->Message(0, "You have LOS to %s", c->GetTarget()->GetName()); + c->Message(Chat::White, "You have LOS to %s", c->GetTarget()->GetName()); else - c->Message(0, "You do not have LOS to %s", c->GetTarget()->GetName()); + c->Message(Chat::White, "You do not have LOS to %s", c->GetTarget()->GetName()); } else { - c->Message(0, "ERROR: Target required"); + c->Message(Chat::White, "ERROR: Target required"); } } @@ -7187,17 +7187,17 @@ void command_set_adventure_points(Client *c, const Seperator *sep) if(!sep->arg[1][0]) { - c->Message(0, "Usage: #setadventurepoints [points] [theme]"); + c->Message(Chat::White, "Usage: #setadventurepoints [points] [theme]"); return; } if(!sep->IsNumber(1) || !sep->IsNumber(2)) { - c->Message(0, "Usage: #setadventurepoints [points] [theme]"); + c->Message(Chat::White, "Usage: #setadventurepoints [points] [theme]"); return; } - c->Message(0, "Updating adventure points for %s", t->GetName()); + c->Message(Chat::White, "Updating adventure points for %s", t->GetName()); t->UpdateLDoNPoints(atoi(sep->arg[1]), atoi(sep->arg[2])); } @@ -7209,7 +7209,7 @@ void command_npcsay(Client *c, const Seperator *sep) } else { - c->Message(0, "Usage: #npcsay message (requires NPC target"); + c->Message(Chat::White, "Usage: #npcsay message (requires NPC target"); } } @@ -7221,13 +7221,13 @@ void command_npcshout(Client *c, const Seperator *sep) } else { - c->Message(0, "Usage: #npcshout message (requires NPC target"); + c->Message(Chat::White, "Usage: #npcshout message (requires NPC target"); } } void command_timers(Client *c, const Seperator *sep) { if(!c->GetTarget() || !c->GetTarget()->IsClient()) { - c->Message(0,"Need a player target for timers."); + c->Message(Chat::White,"Need a player target for timers."); return; } Client *them = c->GetTarget()->CastToClient(); @@ -7235,12 +7235,12 @@ void command_timers(Client *c, const Seperator *sep) { std::vector< std::pair > res; them->GetPTimers().ToVector(res); - c->Message(0,"Timers for target:"); + c->Message(Chat::White,"Timers for target:"); int r; int l = res.size(); for(r = 0; r < l; r++) { - c->Message(0,"Timer %d: %d seconds remain.", res[r].first, res[r].second->GetRemainingTime()); + c->Message(Chat::White,"Timer %d: %d seconds remain.", res[r].first, res[r].second->GetRemainingTime()); } } @@ -7252,7 +7252,7 @@ void command_npcemote(Client *c, const Seperator *sep) } else { - c->Message(0, "Usage: #npcemote message (requires NPC target"); + c->Message(Chat::White, "Usage: #npcemote message (requires NPC target"); } } @@ -7367,93 +7367,93 @@ void command_npceditmass(Client *c, const Seperator *sep) void command_npcedit(Client *c, const Seperator *sep) { if (!c->GetTarget() || !c->GetTarget()->IsNPC()) { - c->Message(0, "Error: Must have NPC targeted"); + c->Message(Chat::White, "Error: Must have NPC targeted"); return; } if (strcasecmp(sep->arg[1], "help") == 0) { - c->Message(0, "Help File for #npcedit. Syntax for commands are:"); - c->Message(0, "#npcedit Name - Sets an NPC's name"); - c->Message(0, "#npcedit Lastname - Sets an NPC's lastname"); - c->Message(0, "#npcedit Level - Sets an NPC's level"); - c->Message(0, "#npcedit Maxlevel - Sets an NPC's maximum level"); - c->Message(0, "#npcedit Race - Sets an NPC's race"); - c->Message(0, "#npcedit Class - Sets an NPC's class"); - c->Message(0, "#npcedit Bodytype - Sets an NPC's bodytype"); - c->Message(0, "#npcedit HP - Sets an NPC's hitpoints"); - c->Message(0, "#npcedit Gender - Sets an NPC's gender"); - c->Message(0, "#npcedit Texture - Sets an NPC's texture"); - c->Message(0, "#npcedit Helmtexture - Sets an NPC's helmet texture"); - c->Message(0, "#npcedit Armtexture - Sets an NPC's arm texture"); - c->Message(0, "#npcedit Bracertexture - Sets an NPC's bracer texture"); - c->Message(0, "#npcedit Handtexture - Sets an NPC's hand texture"); - c->Message(0, "#npcedit Legtexture - Sets an NPC's leg texture"); - c->Message(0, "#npcedit Feettexture - Sets an NPC's feettexture"); - c->Message(0, "#npcedit Herosforgemodel - Sets an NPC's Hero's Forge Model"); - c->Message(0, "#npcedit Size - Sets an NPC's size"); - c->Message(0, "#npcedit Hpregen - Sets an NPC's hitpoint regen rate per tick"); - c->Message(0, "#npcedit Manaregen - Sets an NPC's mana regen rate per tick"); - c->Message(0, "#npcedit Loottable - Sets the loottable ID for an NPC "); - c->Message(0, "#npcedit Merchantid - Sets the merchant ID for an NPC"); - c->Message(0, "#npcedit alt_currency_id - Sets the Alternate Currency ID for an alterative currency Merchant"); - c->Message(0, "#npcedit npc_spells_effects_id - Sets the NPC Spell Effects ID"); - c->Message(0, "#npcedit adventure_template_id - Sets the NPC's Adventure Template ID"); - c->Message(0, "#npcedit trap_template - Sets the NPC's Trap Template ID"); - c->Message(0, "#npcedit special_abilities - Sets the NPC's Special Abilities"); - c->Message(0, "#npcedit Spell - Sets the npc spells list ID for an NPC"); - c->Message(0, "#npcedit Faction - Sets the NPC's faction id"); - c->Message(0, "#npcedit Damage - Sets an NPC's damage"); - c->Message(0, "#npcedit Meleetype - Sets an NPC's melee types"); - c->Message(0, "#npcedit Rangedtype - Sets an NPC's ranged type"); - c->Message(0, "#npcedit Ammoidfile - Sets an NPC's ammo id file"); - c->Message(0, "#npcedit Aggroradius - Sets an NPC's aggro radius"); - c->Message(0, "#npcedit Assistradius - Sets an NPC's assist radius"); - c->Message(0, "#npcedit Social - Set to 1 if an NPC should assist others on its faction"); - c->Message(0, "#npcedit Runspeed - Sets an NPC's run speed"); - c->Message(0, "#npcedit Walkspeed - Sets an NPC's walk speed"); - c->Message(0, "#npcedit AGI - Sets an NPC's Agility"); - c->Message(0, "#npcedit CHA - Sets an NPC's Charisma"); - c->Message(0, "#npcedit DEX - Sets an NPC's Dexterity"); - c->Message(0, "#npcedit INT - Sets an NPC's Intelligence"); - c->Message(0, "#npcedit STA - Sets an NPC's Stamina"); - c->Message(0, "#npcedit STR - Sets an NPC's Strength"); - c->Message(0, "#npcedit WIS - Sets an NPC's Wisdom"); - c->Message(0, "#npcedit MR - Sets an NPC's Magic Resistance"); - c->Message(0, "#npcedit PR - Sets an NPC's Poison Resistance"); - c->Message(0, "#npcedit DR - Sets an NPC's Disease Resistance"); - c->Message(0, "#npcedit FR - Sets an NPC's Fire Resistance"); - c->Message(0, "#npcedit CR - Sets an NPC's Cold Resistance"); - c->Message(0, "#npcedit Corrup - Sets an NPC's Corruption Resistance"); - c->Message(0, "#npcedit PhR - Sets and NPC's Physical Resistance"); - c->Message(0, "#npcedit Seeinvis - Sets an NPC's ability to see invis"); - c->Message(0, "#npcedit Seeinvisundead - Sets an NPC's ability to see through invis vs. undead"); - c->Message(0, "#npcedit Seehide - Sets an NPC's ability to see through hide"); - c->Message(0, "#npcedit Seeimprovedhide - Sets an NPC's ability to see through improved hide"); - c->Message(0, "#npcedit AC - Sets an NPC's Armor Class"); - c->Message(0, "#npcedit ATK - Sets an NPC's Attack"); - c->Message(0, "#npcedit Accuracy - Sets an NPC's Accuracy"); - c->Message(0, "#npcedit Avoidance - Sets an NPC's Avoidance"); - c->Message(0, "#npcedit npcaggro - Sets an NPC's npc_aggro flag"); - c->Message(0, "#npcedit qglobal - Sets an NPC's quest global flag"); - c->Message(0, "#npcedit spawn_limit - Sets an NPC's spawn limit counter"); - c->Message(0, "#npcedit Attackspeed - Sets an NPC's attack speed modifier"); - c->Message(0, "#npcedit Attackdelay - Sets an NPC's attack delay"); - c->Message(0, "#npcedit Attackcount - Sets an NPC's attack count"); - c->Message(0, "#npcedit findable - Sets an NPC's findable flag"); - c->Message(0, "#npcedit trackable - Sets an NPC's trackable flag"); - c->Message(0, "#npcedit weapon - Sets an NPC's primary and secondary weapon model"); - c->Message(0, "#npcedit featuresave - Saves all current facial features to the database"); - c->Message(0, "#npcedit color - Sets an NPC's red, green, and blue armor tint"); - c->Message(0, "#npcedit armortint_id - Set an NPC's Armor tint ID"); - c->Message(0, "#npcedit setanimation - Set an NPC's animation on spawn (Stored in spawn2 table)"); - c->Message(0, "#npcedit scalerate - Set an NPC's scaling rate"); - c->Message(0, "#npcedit healscale - Set an NPC's heal scaling rate"); - c->Message(0, "#npcedit spellscale - Set an NPC's spell scaling rate"); - c->Message(0, "#npcedit no_target - Set an NPC's ability to be targeted with the target hotkey"); - c->Message(0, "#npcedit version - Set an NPC's version"); - c->Message(0, "#npcedit slow_mitigation - Set an NPC's slow mitigation"); - c->Message(0, "#npcedit flymode - Set an NPC's flymode [0 = ground, 1 = flying, 2 = levitate, 3 = water, 4 = floating]"); + c->Message(Chat::White, "Help File for #npcedit. Syntax for commands are:"); + c->Message(Chat::White, "#npcedit Name - Sets an NPC's name"); + c->Message(Chat::White, "#npcedit Lastname - Sets an NPC's lastname"); + c->Message(Chat::White, "#npcedit Level - Sets an NPC's level"); + c->Message(Chat::White, "#npcedit Maxlevel - Sets an NPC's maximum level"); + c->Message(Chat::White, "#npcedit Race - Sets an NPC's race"); + c->Message(Chat::White, "#npcedit Class - Sets an NPC's class"); + c->Message(Chat::White, "#npcedit Bodytype - Sets an NPC's bodytype"); + c->Message(Chat::White, "#npcedit HP - Sets an NPC's hitpoints"); + c->Message(Chat::White, "#npcedit Gender - Sets an NPC's gender"); + c->Message(Chat::White, "#npcedit Texture - Sets an NPC's texture"); + c->Message(Chat::White, "#npcedit Helmtexture - Sets an NPC's helmet texture"); + c->Message(Chat::White, "#npcedit Armtexture - Sets an NPC's arm texture"); + c->Message(Chat::White, "#npcedit Bracertexture - Sets an NPC's bracer texture"); + c->Message(Chat::White, "#npcedit Handtexture - Sets an NPC's hand texture"); + c->Message(Chat::White, "#npcedit Legtexture - Sets an NPC's leg texture"); + c->Message(Chat::White, "#npcedit Feettexture - Sets an NPC's feettexture"); + c->Message(Chat::White, "#npcedit Herosforgemodel - Sets an NPC's Hero's Forge Model"); + c->Message(Chat::White, "#npcedit Size - Sets an NPC's size"); + c->Message(Chat::White, "#npcedit Hpregen - Sets an NPC's hitpoint regen rate per tick"); + c->Message(Chat::White, "#npcedit Manaregen - Sets an NPC's mana regen rate per tick"); + c->Message(Chat::White, "#npcedit Loottable - Sets the loottable ID for an NPC "); + c->Message(Chat::White, "#npcedit Merchantid - Sets the merchant ID for an NPC"); + c->Message(Chat::White, "#npcedit alt_currency_id - Sets the Alternate Currency ID for an alterative currency Merchant"); + c->Message(Chat::White, "#npcedit npc_spells_effects_id - Sets the NPC Spell Effects ID"); + c->Message(Chat::White, "#npcedit adventure_template_id - Sets the NPC's Adventure Template ID"); + c->Message(Chat::White, "#npcedit trap_template - Sets the NPC's Trap Template ID"); + c->Message(Chat::White, "#npcedit special_abilities - Sets the NPC's Special Abilities"); + c->Message(Chat::White, "#npcedit Spell - Sets the npc spells list ID for an NPC"); + c->Message(Chat::White, "#npcedit Faction - Sets the NPC's faction id"); + c->Message(Chat::White, "#npcedit Damage - Sets an NPC's damage"); + c->Message(Chat::White, "#npcedit Meleetype - Sets an NPC's melee types"); + c->Message(Chat::White, "#npcedit Rangedtype - Sets an NPC's ranged type"); + c->Message(Chat::White, "#npcedit Ammoidfile - Sets an NPC's ammo id file"); + c->Message(Chat::White, "#npcedit Aggroradius - Sets an NPC's aggro radius"); + c->Message(Chat::White, "#npcedit Assistradius - Sets an NPC's assist radius"); + c->Message(Chat::White, "#npcedit Social - Set to 1 if an NPC should assist others on its faction"); + c->Message(Chat::White, "#npcedit Runspeed - Sets an NPC's run speed"); + c->Message(Chat::White, "#npcedit Walkspeed - Sets an NPC's walk speed"); + c->Message(Chat::White, "#npcedit AGI - Sets an NPC's Agility"); + c->Message(Chat::White, "#npcedit CHA - Sets an NPC's Charisma"); + c->Message(Chat::White, "#npcedit DEX - Sets an NPC's Dexterity"); + c->Message(Chat::White, "#npcedit INT - Sets an NPC's Intelligence"); + c->Message(Chat::White, "#npcedit STA - Sets an NPC's Stamina"); + c->Message(Chat::White, "#npcedit STR - Sets an NPC's Strength"); + c->Message(Chat::White, "#npcedit WIS - Sets an NPC's Wisdom"); + c->Message(Chat::White, "#npcedit MR - Sets an NPC's Magic Resistance"); + c->Message(Chat::White, "#npcedit PR - Sets an NPC's Poison Resistance"); + c->Message(Chat::White, "#npcedit DR - Sets an NPC's Disease Resistance"); + c->Message(Chat::White, "#npcedit FR - Sets an NPC's Fire Resistance"); + c->Message(Chat::White, "#npcedit CR - Sets an NPC's Cold Resistance"); + c->Message(Chat::White, "#npcedit Corrup - Sets an NPC's Corruption Resistance"); + c->Message(Chat::White, "#npcedit PhR - Sets and NPC's Physical Resistance"); + c->Message(Chat::White, "#npcedit Seeinvis - Sets an NPC's ability to see invis"); + c->Message(Chat::White, "#npcedit Seeinvisundead - Sets an NPC's ability to see through invis vs. undead"); + c->Message(Chat::White, "#npcedit Seehide - Sets an NPC's ability to see through hide"); + c->Message(Chat::White, "#npcedit Seeimprovedhide - Sets an NPC's ability to see through improved hide"); + c->Message(Chat::White, "#npcedit AC - Sets an NPC's Armor Class"); + c->Message(Chat::White, "#npcedit ATK - Sets an NPC's Attack"); + c->Message(Chat::White, "#npcedit Accuracy - Sets an NPC's Accuracy"); + c->Message(Chat::White, "#npcedit Avoidance - Sets an NPC's Avoidance"); + c->Message(Chat::White, "#npcedit npcaggro - Sets an NPC's npc_aggro flag"); + c->Message(Chat::White, "#npcedit qglobal - Sets an NPC's quest global flag"); + c->Message(Chat::White, "#npcedit spawn_limit - Sets an NPC's spawn limit counter"); + c->Message(Chat::White, "#npcedit Attackspeed - Sets an NPC's attack speed modifier"); + c->Message(Chat::White, "#npcedit Attackdelay - Sets an NPC's attack delay"); + c->Message(Chat::White, "#npcedit Attackcount - Sets an NPC's attack count"); + c->Message(Chat::White, "#npcedit findable - Sets an NPC's findable flag"); + c->Message(Chat::White, "#npcedit trackable - Sets an NPC's trackable flag"); + c->Message(Chat::White, "#npcedit weapon - Sets an NPC's primary and secondary weapon model"); + c->Message(Chat::White, "#npcedit featuresave - Saves all current facial features to the database"); + c->Message(Chat::White, "#npcedit color - Sets an NPC's red, green, and blue armor tint"); + c->Message(Chat::White, "#npcedit armortint_id - Set an NPC's Armor tint ID"); + c->Message(Chat::White, "#npcedit setanimation - Set an NPC's animation on spawn (Stored in spawn2 table)"); + c->Message(Chat::White, "#npcedit scalerate - Set an NPC's scaling rate"); + c->Message(Chat::White, "#npcedit healscale - Set an NPC's heal scaling rate"); + c->Message(Chat::White, "#npcedit spellscale - Set an NPC's spell scaling rate"); + c->Message(Chat::White, "#npcedit no_target - Set an NPC's ability to be targeted with the target hotkey"); + c->Message(Chat::White, "#npcedit version - Set an NPC's version"); + c->Message(Chat::White, "#npcedit slow_mitigation - Set an NPC's slow mitigation"); + c->Message(Chat::White, "#npcedit flymode - Set an NPC's flymode [0 = ground, 1 = flying, 2 = levitate, 3 = water, 4 = floating]"); } @@ -7994,9 +7994,9 @@ void command_npcedit(Client *c, const Seperator *sep) if((strcasecmp(sep->arg[2], "loot" ) == 0) || atoi(sep->arg[2]) == 4) animation = 4; //Looting Animation } else { - c->Message(0, "You must specifiy an animation stand, sit, crouch, dead, loot (0-4)"); - c->Message(0, "Example: #npcedit setanimation sit"); - c->Message(0, "Example: #npcedit setanimation 0"); + c->Message(Chat::White, "You must specifiy an animation stand, sit, crouch, dead, loot (0-4)"); + c->Message(Chat::White, "Example: #npcedit setanimation sit"); + c->Message(Chat::White, "Example: #npcedit setanimation 0"); return; } @@ -8051,7 +8051,7 @@ void command_npcedit(Client *c, const Seperator *sep) } if((sep->arg[1][0] == 0 || strcasecmp(sep->arg[1],"*")==0) || ((c->GetTarget()==0) || (c->GetTarget()->IsClient()))) - c->Message(0, "Type #npcedit help for more info"); + c->Message(Chat::White, "Type #npcedit help for more info"); } @@ -8078,14 +8078,14 @@ void command_profilereset(Client *c, const Seperator *sep) { void command_opcode(Client *c, const Seperator *sep) { if(!strcasecmp(sep->arg[1], "reload" )) { ReloadAllPatches(); - c->Message(0, "Opcodes for all patches have been reloaded"); + c->Message(Chat::White, "Opcodes for all patches have been reloaded"); } } void command_qglobal(Client *c, const Seperator *sep) { //In-game switch for qglobal column if(sep->arg[1][0] == 0) { - c->Message(0, "Syntax: #qglobal [on/off/view]. Requires NPC target."); + c->Message(Chat::White, "Syntax: #qglobal [on/off/view]. Requires NPC target."); return; } @@ -8168,7 +8168,7 @@ void command_undye(Client *c, const Seperator *sep) } else { - c->Message(0, "ERROR: Client target required"); + c->Message(Chat::White, "ERROR: Client target required"); } } @@ -8275,23 +8275,23 @@ void command_ginfo(Client *c, const Seperator *sep) Group *g = t->GetGroup(); if(!g) { - c->Message(0, "This client is not in a group"); + c->Message(Chat::White, "This client is not in a group"); return; } - c->Message(0, "Player: %s is in Group #%lu: with %i members", t->GetName(), (unsigned long)g->GetID(), g->GroupCount()); + c->Message(Chat::White, "Player: %s is in Group #%lu: with %i members", t->GetName(), (unsigned long)g->GetID(), g->GroupCount()); uint32 r; for(r = 0; r < MAX_GROUP_MEMBERS; r++) { if(g->members[r] == nullptr) { if(g->membername[r][0] == '\0') continue; - c->Message(0, "...Zoned Member: %s, Roles: %s %s %s", g->membername[r], + c->Message(Chat::White, "...Zoned Member: %s, Roles: %s %s %s", g->membername[r], (g->MemberRoles[r] & RoleAssist) ? "Assist" : "", (g->MemberRoles[r] & RoleTank) ? "Tank" : "", (g->MemberRoles[r] & RolePuller) ? "Puller" : ""); } else { - c->Message(0, "...In-Zone Member: %s (0x%x) Roles: %s %s %s", g->membername[r], g->members[r], + c->Message(Chat::White, "...In-Zone Member: %s (0x%x) Roles: %s %s %s", g->membername[r], g->members[r], (g->MemberRoles[r] & RoleAssist) ? "Assist" : "", (g->MemberRoles[r] & RoleTank) ? "Tank" : "", (g->MemberRoles[r] & RolePuller) ? "Puller" : ""); @@ -8309,7 +8309,7 @@ void command_hp(Client *c, const Seperator *sep) void command_aggro(Client *c, const Seperator *sep) { if(c->GetTarget() == nullptr || !c->GetTarget()->IsNPC()) { - c->Message(0, "Error: you must have an NPC target."); + c->Message(Chat::White, "Error: you must have an NPC target."); return; } float d = atof(sep->arg[1]); @@ -8330,18 +8330,18 @@ void command_pf(Client *c, const Seperator *sep) if(c->GetTarget()) { Mob *who = c->GetTarget(); - c->Message(0, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ()); - c->Message(0, "WP: %s (%d/%d)", to_string(who->GetCurrentWayPoint()).c_str(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1); - c->Message(0, "pause=%d RAspeed=%d", who->GetCWPP(), who->GetRunAnimSpeed()); + c->Message(Chat::White, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ()); + c->Message(Chat::White, "WP: %s (%d/%d)", to_string(who->GetCurrentWayPoint()).c_str(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1); + c->Message(Chat::White, "pause=%d RAspeed=%d", who->GetCWPP(), who->GetRunAnimSpeed()); //who->DumpMovement(c); } else { - c->Message(0, "ERROR: target required"); + c->Message(Chat::White, "ERROR: target required"); } } void command_bestz(Client *c, const Seperator *sep) { if (zone->zonemap == nullptr) { - c->Message(0,"Map not loaded for this zone"); + c->Message(Chat::White,"Map not loaded for this zone"); } else { glm::vec3 me; me.x = c->GetX(); @@ -8355,16 +8355,16 @@ void command_bestz(Client *c, const Seperator *sep) { if (best_z != BEST_Z_INVALID) { - c->Message(0, "Z is %.3f at (%.3f, %.3f).", best_z, me.x, me.y); + c->Message(Chat::White, "Z is %.3f at (%.3f, %.3f).", best_z, me.x, me.y); } else { - c->Message(0, "Found no Z."); + c->Message(Chat::White, "Found no Z."); } } if(zone->watermap == nullptr) { - c->Message(0,"Water Region Map not loaded for this zone"); + c->Message(Chat::White,"Water Region Map not loaded for this zone"); } else { WaterRegionType RegionType; float z; @@ -8373,28 +8373,28 @@ void command_bestz(Client *c, const Seperator *sep) { z=c->GetTarget()->GetZ(); auto position = glm::vec3(c->GetTarget()->GetX(), c->GetTarget()->GetY(), z); RegionType = zone->watermap->ReturnRegionType(position); - c->Message(0,"InWater returns %d", zone->watermap->InWater(position)); - c->Message(0,"InLava returns %d", zone->watermap->InLava(position)); + c->Message(Chat::White,"InWater returns %d", zone->watermap->InWater(position)); + c->Message(Chat::White,"InLava returns %d", zone->watermap->InLava(position)); } else { z=c->GetZ(); auto position = glm::vec3(c->GetX(), c->GetY(), z); RegionType = zone->watermap->ReturnRegionType(position); - c->Message(0,"InWater returns %d", zone->watermap->InWater(position)); - c->Message(0,"InLava returns %d", zone->watermap->InLava(position)); + c->Message(Chat::White,"InWater returns %d", zone->watermap->InWater(position)); + c->Message(Chat::White,"InLava returns %d", zone->watermap->InLava(position)); } switch(RegionType) { - case RegionTypeNormal: { c->Message(0,"There is nothing special about the region you are in!"); break; } - case RegionTypeWater: { c->Message(0,"You/your target are in Water."); break; } - case RegionTypeLava: { c->Message(0,"You/your target are in Lava."); break; } - case RegionTypeVWater: { c->Message(0,"You/your target are in VWater (Icy Water?)."); break; } - case RegionTypePVP: { c->Message(0, "You/your target are in a pvp enabled area."); break; } - case RegionTypeSlime: { c->Message(0, "You/your target are in slime."); break; } - case RegionTypeIce: { c->Message(0, "You/your target are in ice."); break; } - default: c->Message(0,"You/your target are in an unknown region type."); + case RegionTypeNormal: { c->Message(Chat::White,"There is nothing special about the region you are in!"); break; } + case RegionTypeWater: { c->Message(Chat::White,"You/your target are in Water."); break; } + case RegionTypeLava: { c->Message(Chat::White,"You/your target are in Lava."); break; } + case RegionTypeVWater: { c->Message(Chat::White,"You/your target are in VWater (Icy Water?)."); break; } + case RegionTypePVP: { c->Message(Chat::White, "You/your target are in a pvp enabled area."); break; } + case RegionTypeSlime: { c->Message(Chat::White, "You/your target are in slime."); break; } + case RegionTypeIce: { c->Message(Chat::White, "You/your target are in ice."); break; } + default: c->Message(Chat::White,"You/your target are in an unknown region type."); } } @@ -8403,7 +8403,7 @@ void command_bestz(Client *c, const Seperator *sep) { void command_reloadstatic(Client *c, const Seperator *sep) { - c->Message(0, "Reloading zone static data..."); + c->Message(Chat::White, "Reloading zone static data..."); zone->ReloadStaticData(); } @@ -8422,13 +8422,13 @@ void command_flags(Client *c, const Seperator *sep) { void command_flagedit(Client *c, const Seperator *sep) { //super-command for editing zone flags if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "Syntax: #flagedit [lockzone|unlockzone|listzones|give|take]."); - c->Message(0, "...lockzone [zone id/short] [flag name] - Set the specified flag name on the zone, locking the zone"); - c->Message(0, "...unlockzone [zone id/short] - Removes the flag requirement from the specified zone"); - c->Message(0, "...listzones - List all zones which require a flag, and their flag's name"); - c->Message(0, "...give [zone id/short] - Give your target the zone flag for the specified zone."); - c->Message(0, "...take [zone id/short] - Take the zone flag for the specified zone away from your target"); - c->Message(0, "...Note: use #flags to view flags on a person"); + c->Message(Chat::White, "Syntax: #flagedit [lockzone|unlockzone|listzones|give|take]."); + c->Message(Chat::White, "...lockzone [zone id/short] [flag name] - Set the specified flag name on the zone, locking the zone"); + c->Message(Chat::White, "...unlockzone [zone id/short] - Removes the flag requirement from the specified zone"); + c->Message(Chat::White, "...listzones - List all zones which require a flag, and their flag's name"); + c->Message(Chat::White, "...give [zone id/short] - Give your target the zone flag for the specified zone."); + c->Message(Chat::White, "...take [zone id/short] - Take the zone flag for the specified zone away from your target"); + c->Message(Chat::White, "...Note: use #flags to view flags on a person"); return; } @@ -8501,9 +8501,9 @@ void command_flagedit(Client *c, const Seperator *sep) { return; } - c->Message(0, "Zones which require flags:"); + c->Message(Chat::White, "Zones which require flags:"); for (auto row = results.begin(); row != results.end(); ++row) - c->Message(0, "Zone %s (%s,%s) version %s requires key %s", row[2], row[0], row[1], row[3], row[4]); + c->Message(Chat::White, "Zone %s (%s,%s) version %s requires key %s", row[2], row[0], row[1], row[3], row[4]); return; } @@ -8568,7 +8568,7 @@ void command_acceptrules(Client *c, const Seperator *sep) { database.SetAgreementFlag(c->AccountID()); c->SendAppearancePacket(AT_Anim, ANIM_STAND); - c->Message(0,"It is recorded you have agreed to the rules."); + c->Message(Chat::White,"It is recorded you have agreed to the rules."); } } @@ -8580,7 +8580,7 @@ void command_guildcreate(Client *c, const Seperator *sep) } else { - c->Message(0,"Guild name must be more than 4 characters and less than 16."); + c->Message(Chat::White,"Guild name must be more than 4 characters and less than 16."); } } @@ -8597,17 +8597,17 @@ void command_guildlist(Client *c, const Seperator *sep) tmp->ApprovedMembers(c); } else - c->Message(0,"Could not find reference id."); + c->Message(Chat::White,"Could not find reference id."); } void command_hatelist(Client *c, const Seperator *sep) { Mob *target = c->GetTarget(); if(target == nullptr) { - c->Message(0, "Error: you must have a target."); + c->Message(Chat::White, "Error: you must have a target."); return; } - c->Message(0, "Display hate list for %s..", target->GetName()); + c->Message(Chat::White, "Display hate list for %s..", target->GetName()); target->PrintHateListToClient(c); } @@ -8615,29 +8615,29 @@ void command_hatelist(Client *c, const Seperator *sep) { void command_rules(Client *c, const Seperator *sep) { //super-command for managing rules settings if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "Syntax: #rules [subcommand]."); - c->Message(0, "-- Rule Set Manipulation --"); - c->Message(0, "...listsets - List avaliable rule sets"); - c->Message(0, "...current - gives the name of the ruleset currently running in this zone"); - c->Message(0, "...reload - Reload the selected ruleset in this zone"); - c->Message(0, "...switch (ruleset name) - Change the selected ruleset and load it"); - c->Message(0, "...load (ruleset name) - Load a ruleset in just this zone without changing the selected set"); + c->Message(Chat::White, "Syntax: #rules [subcommand]."); + c->Message(Chat::White, "-- Rule Set Manipulation --"); + c->Message(Chat::White, "...listsets - List avaliable rule sets"); + c->Message(Chat::White, "...current - gives the name of the ruleset currently running in this zone"); + c->Message(Chat::White, "...reload - Reload the selected ruleset in this zone"); + c->Message(Chat::White, "...switch (ruleset name) - Change the selected ruleset and load it"); + c->Message(Chat::White, "...load (ruleset name) - Load a ruleset in just this zone without changing the selected set"); //too lazy to write this right now: -// c->Message(0, "...wload (ruleset name) - Load a ruleset in all zones without changing the selected set"); - c->Message(0, "...store [ruleset name] - Store the running ruleset as the specified name"); - c->Message(0, "---------------------"); - c->Message(0, "-- Running Rule Manipulation --"); - c->Message(0, "...reset - Reset all rules to their default values"); - c->Message(0, "...get [rule] - Get the specified rule's local value"); - c->Message(0, "...set (rule) (value) - Set the specified rule to the specified value locally only"); - c->Message(0, "...setdb (rule) (value) - Set the specified rule to the specified value locally and in the DB"); - c->Message(0, "...list [catname] - List all rules in the specified category (or all categiries if omitted)"); - c->Message(0, "...values [catname] - List the value of all rules in the specified category"); +// c->Message(Chat::White, "...wload (ruleset name) - Load a ruleset in all zones without changing the selected set"); + c->Message(Chat::White, "...store [ruleset name] - Store the running ruleset as the specified name"); + c->Message(Chat::White, "---------------------"); + c->Message(Chat::White, "-- Running Rule Manipulation --"); + c->Message(Chat::White, "...reset - Reset all rules to their default values"); + c->Message(Chat::White, "...get [rule] - Get the specified rule's local value"); + c->Message(Chat::White, "...set (rule) (value) - Set the specified rule to the specified value locally only"); + c->Message(Chat::White, "...setdb (rule) (value) - Set the specified rule to the specified value locally and in the DB"); + c->Message(Chat::White, "...list [catname] - List all rules in the specified category (or all categiries if omitted)"); + c->Message(Chat::White, "...values [catname] - List the value of all rules in the specified category"); return; } if(!strcasecmp(sep->arg[1], "current")) { - c->Message(0, "Currently running ruleset '%s' (%d)", RuleManager::Instance()->GetActiveRuleset(), + c->Message(Chat::White, "Currently running ruleset '%s' (%d)", RuleManager::Instance()->GetActiveRuleset(), RuleManager::Instance()->GetActiveRulesetID()); } else if(!strcasecmp(sep->arg[1], "listsets")) { std::map sets; @@ -8646,16 +8646,16 @@ void command_rules(Client *c, const Seperator *sep) { return; } - c->Message(0, "Avaliable rule sets:"); + c->Message(Chat::White, "Avaliable rule sets:"); std::map::iterator cur, end; cur = sets.begin(); end = sets.end(); for(; cur != end; ++cur) { - c->Message(0, "(%d) %s", cur->first, cur->second.c_str()); + c->Message(Chat::White, "(%d) %s", cur->first, cur->second.c_str()); } } else if(!strcasecmp(sep->arg[1], "reload")) { RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true); - c->Message(0, "The active ruleset (%s (%d)) has been reloaded", RuleManager::Instance()->GetActiveRuleset(), + c->Message(Chat::White, "The active ruleset (%s (%d)) has been reloaded", RuleManager::Instance()->GetActiveRuleset(), RuleManager::Instance()->GetActiveRulesetID()); } else if(!strcasecmp(sep->arg[1], "switch")) { //make sure this is a valid rule set.. @@ -8672,7 +8672,7 @@ void command_rules(Client *c, const Seperator *sep) { //TODO: we likely want to reload this ruleset everywhere... RuleManager::Instance()->LoadRules(&database, sep->arg[2], true); - c->Message(0, "The selected ruleset has been changed to (%s (%d)) and reloaded locally", sep->arg[2], rsid); + c->Message(Chat::White, "The selected ruleset has been changed to (%s (%d)) and reloaded locally", sep->arg[2], rsid); } else if(!strcasecmp(sep->arg[1], "load")) { //make sure this is a valid rule set.. int rsid = RuleManager::Instance()->GetRulesetID(&database, sep->arg[2]); @@ -8681,12 +8681,12 @@ void command_rules(Client *c, const Seperator *sep) { return; } RuleManager::Instance()->LoadRules(&database, sep->arg[2], true); - c->Message(0, "Loaded ruleset '%s' (%d) locally", sep->arg[2], rsid); + c->Message(Chat::White, "Loaded ruleset '%s' (%d) locally", sep->arg[2], rsid); } else if(!strcasecmp(sep->arg[1], "store")) { if(sep->argnum == 1) { //store current rule set. RuleManager::Instance()->SaveRules(&database); - c->Message(0, "Rules saved"); + c->Message(Chat::White, "Rules saved"); } else if(sep->argnum == 2) { RuleManager::Instance()->SaveRules(&database, sep->arg[2]); int prersid = RuleManager::Instance()->GetActiveRulesetID(); @@ -8694,9 +8694,9 @@ void command_rules(Client *c, const Seperator *sep) { if(rsid < 0) { c->Message(Chat::Red, "Unable to query ruleset ID after store, it most likely failed."); } else { - c->Message(0, "Stored rules as ruleset '%s' (%d)", sep->arg[2], rsid); + c->Message(Chat::White, "Stored rules as ruleset '%s' (%d)", sep->arg[2], rsid); if(prersid != rsid) { - c->Message(0, "Rule set %s (%d) is now active in this zone", sep->arg[2], rsid); + c->Message(Chat::White, "Rule set %s (%d) is now active in this zone", sep->arg[2], rsid); } } } else { @@ -8705,7 +8705,7 @@ void command_rules(Client *c, const Seperator *sep) { } } else if(!strcasecmp(sep->arg[1], "reset")) { RuleManager::Instance()->ResetRules(true); - c->Message(0, "The running ruleset has been set to defaults"); + c->Message(Chat::White, "The running ruleset has been set to defaults"); } else if(!strcasecmp(sep->arg[1], "get")) { if(sep->argnum != 2) { @@ -8716,7 +8716,7 @@ void command_rules(Client *c, const Seperator *sep) { if(!RuleManager::Instance()->GetRule(sep->arg[2], value)) c->Message(Chat::Red, "Unable to find rule %s", sep->arg[2]); else - c->Message(0, "%s - %s", sep->arg[2], value.c_str()); + c->Message(Chat::White, "%s - %s", sep->arg[2], value.c_str()); } else if(!strcasecmp(sep->arg[1], "set")) { if(sep->argnum != 3) { @@ -8726,7 +8726,7 @@ void command_rules(Client *c, const Seperator *sep) { if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], nullptr, false, true)) { c->Message(Chat::Red, "Failed to modify rule"); } else { - c->Message(0, "Rule modified locally."); + c->Message(Chat::White, "Rule modified locally."); } } else if(!strcasecmp(sep->arg[1], "setdb")) { if(sep->argnum != 3) { @@ -8736,7 +8736,7 @@ void command_rules(Client *c, const Seperator *sep) { if(!RuleManager::Instance()->SetRule(sep->arg[2], sep->arg[3], &database, true, true)) { c->Message(Chat::Red, "Failed to modify rule"); } else { - c->Message(0, "Rule modified locally and in the database."); + c->Message(Chat::White, "Rule modified locally and in the database."); } } else if(!strcasecmp(sep->arg[1], "list")) { if(sep->argnum == 1) { @@ -8745,12 +8745,12 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(Chat::Red, "Failed to list categories!"); return; } - c->Message(0, "Rule Categories:"); + c->Message(Chat::White, "Rule Categories:"); std::vector::iterator cur, end; cur = rule_list.begin(); end = rule_list.end(); for(; cur != end; ++cur) { - c->Message(0, " %s", *cur); + c->Message(Chat::White, " %s", *cur); } } else if(sep->argnum == 2) { const char *catfilt = nullptr; @@ -8761,12 +8761,12 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(Chat::Red, "Failed to list rules!"); return; } - c->Message(0, "Rules in category %s:", sep->arg[2]); + c->Message(Chat::White, "Rules in category %s:", sep->arg[2]); std::vector::iterator cur, end; cur = rule_list.begin(); end = rule_list.end(); for(; cur != end; ++cur) { - c->Message(0, " %s", *cur); + c->Message(Chat::White, " %s", *cur); } } else { c->Message(Chat::Red, "Invalid argument count, see help."); @@ -8784,13 +8784,13 @@ void command_rules(Client *c, const Seperator *sep) { c->Message(Chat::Red, "Failed to list rules!"); return; } - c->Message(0, "Rules & values in category %s:", sep->arg[2]); + c->Message(Chat::White, "Rules & values in category %s:", sep->arg[2]); std::vector::iterator cur, end; cur = rule_list.begin(); end = rule_list.end(); for(std::string tmp_value; cur != end; ++cur) { if (RuleManager::Instance()->GetRule(*cur, tmp_value)) - c->Message(0, " %s - %s", *cur, tmp_value.c_str()); + c->Message(Chat::White, " %s - %s", *cur, tmp_value.c_str()); } } @@ -8803,15 +8803,15 @@ void command_rules(Client *c, const Seperator *sep) { void command_task(Client *c, const Seperator *sep) { //super-command for managing tasks if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "Syntax: #task [subcommand]."); - c->Message(0, "-- Task System Commands --"); - c->Message(0, "...show - List active tasks for a client"); - c->Message(0, "...update [Count]"); - c->Message(0, "...reloadall - Reload all Task information from the database"); - c->Message(0, "...reload task - Reload Task and Activity informnation for a single task"); - c->Message(0, "...reload lists - Reload goal/reward list information"); - c->Message(0, "...reload prox - Reload proximity information"); - c->Message(0, "...reload sets - Reload task set information"); + c->Message(Chat::White, "Syntax: #task [subcommand]."); + c->Message(Chat::White, "-- Task System Commands --"); + c->Message(Chat::White, "...show - List active tasks for a client"); + c->Message(Chat::White, "...update [Count]"); + c->Message(Chat::White, "...reloadall - Reload all Task information from the database"); + c->Message(Chat::White, "...reload task - Reload Task and Activity informnation for a single task"); + c->Message(Chat::White, "...reload lists - Reload goal/reward list information"); + c->Message(Chat::White, "...reload prox - Reload proximity information"); + c->Message(Chat::White, "...reload sets - Reload task set information"); return; } @@ -8879,7 +8879,7 @@ void command_task(Client *c, const Seperator *sep) { } } - c->Message(0, "Unable to interpret command. Type #task help"); + c->Message(Chat::White, "Unable to interpret command. Type #task help"); } void command_reloadtitles(Client *c, const Seperator *sep) @@ -8898,7 +8898,7 @@ void command_traindisc(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); if (sep->argnum < 1 || !sep->IsNumber(1)) { - c->Message(0, "FORMAT: #traindisc "); + c->Message(Chat::White, "FORMAT: #traindisc "); return; } @@ -8911,17 +8911,17 @@ void command_traindisc(Client *c, const Seperator *sep) min_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level if(max_level < 1 || min_level < 1) { - c->Message(0, "ERROR: Level must be greater than 1."); + c->Message(Chat::White, "ERROR: Level must be greater than 1."); return; } if (min_level > max_level) { - c->Message(0, "Error: Min Level must be less than or equal to Max Level."); + c->Message(Chat::White, "Error: Min Level must be less than or equal to Max Level."); return; } - t->Message(0, "Training disciplines"); + t->Message(Chat::White, "Training disciplines"); if(t != c) - c->Message(0, "Training disciplines for %s.", t->GetName()); + c->Message(Chat::White, "Training disciplines for %s.", t->GetName()); Log(Logs::General, Logs::Normal, "Train disciplines request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level); int spell_id = 0; @@ -8963,7 +8963,7 @@ void command_traindisc(Client *c, const Seperator *sep) t->GetPP().disciplines.values[r] = spell_id_; database.SaveCharacterDisc(t->CharacterID(), r, spell_id_); change = true; - t->Message(0, "You have learned a new discipline!"); + t->Message(Chat::White, "You have learned a new discipline!"); ++count; // success counter break; // continue the 1st loop } // if we get to this point, there's already a discipline in this slot, so we continue onto the next slot @@ -8977,13 +8977,13 @@ void command_traindisc(Client *c, const Seperator *sep) t->SendDisciplineUpdate(); if (count > 0) { - t->Message(0, "Successfully trained %u disciplines.", count); + t->Message(Chat::White, "Successfully trained %u disciplines.", count); if (t != c) - c->Message(0, "Successfully trained %u disciplines for %s.", count, t->GetName()); + c->Message(Chat::White, "Successfully trained %u disciplines for %s.", count, t->GetName()); } else { - t->Message(0, "No disciplines trained."); + t->Message(Chat::White, "No disciplines trained."); if (t != c) - c->Message(0, "No disciplines trained for %s.", t->GetName()); + c->Message(Chat::White, "No disciplines trained for %s.", t->GetName()); } } @@ -8997,7 +8997,7 @@ void command_setgraveyard(Client *c, const Seperator *sep) t=c->GetTarget()->CastToClient(); if(!sep->arg[1][0]) { - c->Message(0, "Usage: #setgraveyard [zonename]"); + c->Message(Chat::White, "Usage: #setgraveyard [zonename]"); return; } @@ -9007,21 +9007,21 @@ void command_setgraveyard(Client *c, const Seperator *sep) graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetPosition()); if(graveyard_id > 0) { - c->Message(0, "Successfuly added a new record for this graveyard!"); + c->Message(Chat::White, "Successfuly added a new record for this graveyard!"); if(database.AddGraveyardIDToZone(zoneid, graveyard_id) > 0) { - c->Message(0, "Successfuly added this new graveyard for the zone %s.", sep->arg[1]); + c->Message(Chat::White, "Successfuly added this new graveyard for the zone %s.", sep->arg[1]); // TODO: Set graveyard data to the running zone process. - c->Message(0, "Done!"); + c->Message(Chat::White, "Done!"); } else - c->Message(0, "Unable to add this new graveyard to the zone %s.", sep->arg[1]); + c->Message(Chat::White, "Unable to add this new graveyard to the zone %s.", sep->arg[1]); } else { - c->Message(0, "Unable to create a new graveyard record in the database."); + c->Message(Chat::White, "Unable to create a new graveyard record in the database."); } } else { - c->Message(0, "Unable to retrieve a ZoneID for the zone: %s", sep->arg[1]); + c->Message(Chat::White, "Unable to retrieve a ZoneID for the zone: %s", sep->arg[1]); } return; @@ -9033,7 +9033,7 @@ void command_deletegraveyard(Client *c, const Seperator *sep) uint32 graveyard_id = 0; if(!sep->arg[1][0]) { - c->Message(0, "Usage: #deletegraveyard [zonename]"); + c->Message(Chat::White, "Usage: #deletegraveyard [zonename]"); return; } @@ -9042,15 +9042,15 @@ void command_deletegraveyard(Client *c, const Seperator *sep) if(zoneid > 0 && graveyard_id > 0) { if(database.DeleteGraveyard(zoneid, graveyard_id)) - c->Message(0, "Successfuly deleted graveyard %u for zone %s.", graveyard_id, sep->arg[1]); + c->Message(Chat::White, "Successfuly deleted graveyard %u for zone %s.", graveyard_id, sep->arg[1]); else - c->Message(0, "Unable to delete graveyard %u for zone %s.", graveyard_id, sep->arg[1]); + c->Message(Chat::White, "Unable to delete graveyard %u for zone %s.", graveyard_id, sep->arg[1]); } else { if(zoneid <= 0) - c->Message(0, "Unable to retrieve a ZoneID for the zone: %s", sep->arg[1]); + c->Message(Chat::White, "Unable to retrieve a ZoneID for the zone: %s", sep->arg[1]); else if(graveyard_id <= 0) - c->Message(0, "Unable to retrieve a valid GraveyardID for the zone: %s", sep->arg[1]); + c->Message(Chat::White, "Unable to retrieve a valid GraveyardID for the zone: %s", sep->arg[1]); } return; @@ -9063,14 +9063,14 @@ void command_summonburiedplayercorpse(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) t = c->GetTarget()->CastToClient(); else { - c->Message(0, "You must first select a target!"); + c->Message(Chat::White, "You must first select a target!"); return; } Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetPosition()); if(!PlayerCorpse) - c->Message(0, "Your target doesn't have any buried corpses."); + c->Message(Chat::White, "Your target doesn't have any buried corpses."); return; } @@ -9082,16 +9082,16 @@ void command_getplayerburiedcorpsecount(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) t = c->GetTarget()->CastToClient(); else { - c->Message(0, "You must first select a target!"); + c->Message(Chat::White, "You must first select a target!"); return; } uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID()); if(CorpseCount > 0) - c->Message(0, "Your target has a total of %u buried corpses.", CorpseCount); + c->Message(Chat::White, "Your target has a total of %u buried corpses.", CorpseCount); else - c->Message(0, "Your target doesn't have any buried corpses."); + c->Message(Chat::White, "Your target doesn't have any buried corpses."); return; } @@ -9116,7 +9116,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "maketype") == 0) { if(!target || !target->IsNPC()) { - c->Message(0, "Target Required!"); + c->Message(Chat::White, "Target Required!"); return; } @@ -9126,7 +9126,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "makegroup") == 0) { if(!sep->arg[2]) { - c->Message(0, "Format: #advnpdspawn makegroup [spawn limit] [dist] [max x] [min x] [max y] [min y] [delay]"); + c->Message(Chat::White, "Format: #advnpdspawn makegroup [spawn limit] [dist] [max x] [min x] [max y] [min y] [delay]"); return; } @@ -9143,18 +9143,18 @@ void command_advnpcspawn(Client *c, const Seperator *sep) (sep->arg[9]? atoi(sep->arg[9]): 0)); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); + c->Message(Chat::White, "Invalid Arguments -- MySQL gave the following error:"); c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } - c->Message(0, "Group ID %i created successfully!", results.LastInsertedID()); + c->Message(Chat::White, "Group ID %i created successfully!", results.LastInsertedID()); return; } if (strcasecmp(sep->arg[1], "addgroupentry") == 0) { if(!atoi(sep->arg[2]) || !atoi(sep->arg[3]) || !atoi(sep->arg[4])) { - c->Message(0, "Format: #advnpdspawn addgroupentry "); + c->Message(Chat::White, "Format: #advnpdspawn addgroupentry "); return; } @@ -9163,19 +9163,19 @@ void command_advnpcspawn(Client *c, const Seperator *sep) atoi(sep->arg[2]), atoi(sep->arg[3]), atoi(sep->arg[4])); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); + c->Message(Chat::White, "Invalid Arguments -- MySQL gave the following error:"); c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } - c->Message(0, "NPC %i added to group %i with %i chance!", atoi(sep->arg[3]), atoi(sep->arg[2]), atoi(sep->arg[4]) ); + c->Message(Chat::White, "NPC %i added to group %i with %i chance!", atoi(sep->arg[3]), atoi(sep->arg[2]), atoi(sep->arg[4]) ); return; } if (strcasecmp(sep->arg[1], "editgroupbox") == 0) { if(!atof(sep->arg[2]) || !atof(sep->arg[3]) || !atof(sep->arg[4]) || !atof(sep->arg[5]) || !atof(sep->arg[6]) || !atof(sep->arg[7]) || !atof(sep->arg[8])) { - c->Message(0, "Format: #advnpdspawn editgroupbox "); + c->Message(Chat::White, "Format: #advnpdspawn editgroupbox "); return; } @@ -9186,19 +9186,19 @@ void command_advnpcspawn(Client *c, const Seperator *sep) atoi(sep->arg[2])); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); + c->Message(Chat::White, "Invalid Arguments -- MySQL gave the following error:"); c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } - c->Message(0, "Group ID %i created successfully!", results.LastInsertedID()); + c->Message(Chat::White, "Group ID %i created successfully!", results.LastInsertedID()); return; } if (strcasecmp(sep->arg[1], "cleargroupbox") == 0) { if(!atoi(sep->arg[2])) { - c->Message(0, "Format: #advnpdspawn cleargroupbox "); + c->Message(Chat::White, "Format: #advnpdspawn cleargroupbox "); return; } @@ -9208,32 +9208,32 @@ void command_advnpcspawn(Client *c, const Seperator *sep) "WHERE id = '%i' ", atoi(sep->arg[2])); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Invalid Arguments -- MySQL gave the following error:"); + c->Message(Chat::White, "Invalid Arguments -- MySQL gave the following error:"); c->Message(Chat::Red, results.ErrorMessage().c_str()); return; } - c->Message(0, "Group ID %i created successfully!", results.LastInsertedID()); + c->Message(Chat::White, "Group ID %i created successfully!", results.LastInsertedID()); return; } if (strcasecmp(sep->arg[1], "addgroupspawn") == 0 && atoi(sep->arg[2])!=0) { database.NPCSpawnDB(5, zone->GetShortName(), zone->GetInstanceVersion(), c, 0, atoi(sep->arg[2])); - c->Message(0, "Mob of group %i added successfully!", atoi(sep->arg[2])); + c->Message(Chat::White, "Mob of group %i added successfully!", atoi(sep->arg[2])); return; } if (strcasecmp(sep->arg[1], "removegroupspawn") == 0) { if (!target || !target->IsNPC()) { - c->Message(0, "Error: Need an NPC target."); + c->Message(Chat::White, "Error: Need an NPC target."); return; } Spawn2* s2 = target->CastToNPC()->respawn2; if(!s2) { - c->Message(0, "removegroupspawn FAILED -- cannot determine which spawn entry in the database this mob came from."); + c->Message(Chat::White, "removegroupspawn FAILED -- cannot determine which spawn entry in the database this mob came from."); return; } @@ -9245,7 +9245,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) return; } - c->Message(0, "Spawnpoint Removed successfully."); + c->Message(Chat::White, "Spawnpoint Removed successfully."); target->Depop(false); return; @@ -9253,14 +9253,14 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "movespawn") == 0) { if (!target || !target->IsNPC()) { - c->Message(0, "Error: Need an NPC target."); + c->Message(Chat::White, "Error: Need an NPC target."); return; } Spawn2* s2 = target->CastToNPC()->respawn2; if(!s2) { - c->Message(0, "movespawn FAILED -- cannot determine which spawn entry in the database this mob came from."); + c->Message(Chat::White, "movespawn FAILED -- cannot determine which spawn entry in the database this mob came from."); return; } @@ -9274,7 +9274,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) return; } - c->Message(0, "Updating coordinates successful."); + c->Message(Chat::White, "Updating coordinates successful."); target->GMMove(c->GetX(), c->GetY(), c->GetZ(), c->GetHeading()); return; @@ -9282,7 +9282,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "editrespawn") == 0) { if (!target || !target->IsNPC()) { - c->Message(0, "Error: Need an NPC target."); + c->Message(Chat::White, "Error: Need an NPC target."); return; } @@ -9291,7 +9291,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) uint32 new_rs = 0; uint32 new_var = s2->GetVariance(); if(!sep->IsNumber(2)) { - c->Message(0, "editrespawn FAILED -- cannot set respawn to be 0"); + c->Message(Chat::White, "editrespawn FAILED -- cannot set respawn to be 0"); return; } @@ -9301,7 +9301,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) new_var = atoi(sep->arg[3]); if(!s2) { - c->Message(0, "editrespawn FAILED -- cannot determine which spawn entry in the database this mob came from."); + c->Message(Chat::White, "editrespawn FAILED -- cannot determine which spawn entry in the database this mob came from."); return; } @@ -9314,7 +9314,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) return; } - c->Message(0, "Updating respawn timer successful."); + c->Message(Chat::White, "Updating respawn timer successful."); s2->SetRespawnTimer(new_rs); s2->SetVariance(new_var); @@ -9323,12 +9323,12 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "setversion") == 0) { if (!target || !target->IsNPC()) { - c->Message(0, "Error: Need an NPC target."); + c->Message(Chat::White, "Error: Need an NPC target."); return; } if(!sep->IsNumber(2)) { - c->Message(0, "setversion FAILED -- You must set a version number"); + c->Message(Chat::White, "setversion FAILED -- You must set a version number"); return; } @@ -9343,7 +9343,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) return; } - c->Message(0, "Version change to %i was successful from SpawnGroupID %i", version, c->GetTarget()->CastToNPC()->GetSp2()); + c->Message(Chat::White, "Version change to %i was successful from SpawnGroupID %i", version, c->GetTarget()->CastToNPC()->GetSp2()); c->GetTarget()->Depop(false); return; @@ -9351,13 +9351,13 @@ void command_advnpcspawn(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "testload") == 0 && atoi(sep->arg[2])!=0) { database.LoadSpawnGroupsByID(atoi(sep->arg[2]),&zone->spawn_group_list); - c->Message(0, "Group %i loaded successfully!", atoi(sep->arg[2])); + c->Message(Chat::White, "Group %i loaded successfully!", atoi(sep->arg[2])); return; } - c->Message(0, "Error: #advnpcspawn: Invalid command."); - c->Message(0, "Usage: #advnpcspawn [maketype|makegroup|addgroupentry|addgroupspawn|setversion]"); - c->Message(0, "Usage: #advnpcspawn [removegroupspawn|movespawn|editrespawn|editgroupbox|cleargroupbox]"); + c->Message(Chat::White, "Error: #advnpcspawn: Invalid command."); + c->Message(Chat::White, "Usage: #advnpcspawn [maketype|makegroup|addgroupentry|addgroupspawn|setversion]"); + c->Message(Chat::White, "Usage: #advnpcspawn [removegroupspawn|movespawn|editrespawn|editgroupbox|cleargroupbox]"); } void command_aggrozone(Client *c, const Seperator *sep) { @@ -9371,7 +9371,7 @@ void command_aggrozone(Client *c, const Seperator *sep) { uint32 hate = atoi(sep->arg[1]); //should default to 0 if we don't enter anything entity_list.AggroZone(m, hate); - c->Message(0, "Train to you! Last chance to go invulnerable..."); + c->Message(Chat::White, "Train to you! Last chance to go invulnerable..."); } void command_modifynpcstat(Client *c, const Seperator *sep) @@ -9381,8 +9381,8 @@ void command_modifynpcstat(Client *c, const Seperator *sep) if(sep->arg[1][0] == '\0') { - c->Message(0, "usage #modifynpcstat arg value"); - c->Message(0, "Args: ac, str, sta, agi, dex, wis, _int, cha, max_hp, mr, fr, cr, pr, dr, runspeed, special_attacks, " + c->Message(Chat::White, "usage #modifynpcstat arg value"); + c->Message(Chat::White, "Args: ac, str, sta, agi, dex, wis, _int, cha, max_hp, mr, fr, cr, pr, dr, runspeed, special_attacks, " "attack_speed, atk, accuracy, trackable, min_hit, max_hit, see_invis_undead, see_hide, see_improved_hide, " "hp_regen, mana_regen, aggro, assist, slow_mitigation, loottable_id, healscale, spellscale"); return; @@ -9412,22 +9412,22 @@ void command_instance(Client *c, const Seperator *sep) if(strcasecmp(sep->arg[1], "help") == 0) { - c->Message(0, "#instance usage:"); - c->Message(0, "#instance create zone_id version duration - Creates an instance of version 'version' in the " + c->Message(Chat::White, "#instance usage:"); + c->Message(Chat::White, "#instance create zone_id version duration - Creates an instance of version 'version' in the " "zone with id matching zone_id, will last for duration seconds."); - c->Message(0, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); - c->Message(0, "#instance add instance_id player_name - adds the player 'player_name' to the instance " + c->Message(Chat::White, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); + c->Message(Chat::White, "#instance add instance_id player_name - adds the player 'player_name' to the instance " "with id matching instance_id."); - c->Message(0, "#instance remove instance_id player_name - removes the player 'player_name' from the " + c->Message(Chat::White, "#instance remove instance_id player_name - removes the player 'player_name' from the " "instance with id matching instance_id."); - c->Message(0, "#instance list player_name - lists all the instances 'player_name' is apart of."); + c->Message(Chat::White, "#instance list player_name - lists all the instances 'player_name' is apart of."); return; } else if(strcasecmp(sep->arg[1], "create") == 0) { if(!sep->IsNumber(3) || !sep->IsNumber(4)) { - c->Message(0, "#instance create zone_id version duration - Creates an instance of version 'version' in the " + c->Message(Chat::White, "#instance create zone_id version duration - Creates an instance of version 'version' in the " "zone with id matching zone_id, will last for duration seconds."); return; } @@ -9450,42 +9450,42 @@ void command_instance(Client *c, const Seperator *sep) if(!zn) { - c->Message(0, "Zone with id %lu was not found by the server.", (unsigned long)zone_id); + c->Message(Chat::White, "Zone with id %lu was not found by the server.", (unsigned long)zone_id); return; } uint16 id = 0; if(!database.GetUnusedInstanceID(id)) { - c->Message(0, "Server was unable to find a free instance id."); + c->Message(Chat::White, "Server was unable to find a free instance id."); return; } if(!database.CreateInstance(id, zone_id, version, duration)) { - c->Message(0, "Server was unable to create a new instance."); + c->Message(Chat::White, "Server was unable to create a new instance."); return; } - c->Message(0, "New instance %s was created with id %lu.", zn, (unsigned long)id); + c->Message(Chat::White, "New instance %s was created with id %lu.", zn, (unsigned long)id); } else if(strcasecmp(sep->arg[1], "destroy") == 0) { if(!sep->IsNumber(2)) { - c->Message(0, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); + c->Message(Chat::White, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); return; } uint16 id = atoi(sep->arg[2]); database.DeleteInstance(id); - c->Message(0, "Destroyed instance with id %lu.", (unsigned long)id); + c->Message(Chat::White, "Destroyed instance with id %lu.", (unsigned long)id); } else if(strcasecmp(sep->arg[1], "add") == 0) { if(!sep->IsNumber(2)) { - c->Message(0, "#instance add instance_id player_name - adds the player 'player_name' to the instance " + c->Message(Chat::White, "#instance add instance_id player_name - adds the player 'player_name' to the instance " "with id matching instance_id."); return; } @@ -9495,13 +9495,13 @@ void command_instance(Client *c, const Seperator *sep) if(id <= 0 || charid <= 0) { - c->Message(0, "Must enter a valid instance id and player name."); + c->Message(Chat::White, "Must enter a valid instance id and player name."); return; } if(!database.CheckInstanceExists(id)) { - c->Message(0, "Instance does not exist."); + c->Message(Chat::White, "Instance does not exist."); return; } @@ -9512,23 +9512,23 @@ void command_instance(Client *c, const Seperator *sep) { if(database.AddClientToInstance(id, charid)) { - c->Message(0, "Added client to instance."); + c->Message(Chat::White, "Added client to instance."); } else { - c->Message(0, "Failed to add client to instance."); + c->Message(Chat::White, "Failed to add client to instance."); } } else { - c->Message(0, "Client was already saved to %u which has uses the same zone and version as that instance.", cur_id); + c->Message(Chat::White, "Client was already saved to %u which has uses the same zone and version as that instance.", cur_id); } } else if(strcasecmp(sep->arg[1], "remove") == 0) { if(!sep->IsNumber(2)) { - c->Message(0, "#instance remove instance_id player_name - removes the player 'player_name' from the " + c->Message(Chat::White, "#instance remove instance_id player_name - removes the player 'player_name' from the " "instance with id matching instance_id."); return; } @@ -9538,16 +9538,16 @@ void command_instance(Client *c, const Seperator *sep) if(id <= 0 || charid <= 0) { - c->Message(0, "Must enter a valid instance id and player name."); + c->Message(Chat::White, "Must enter a valid instance id and player name."); } if(database.RemoveClientFromInstance(id, charid)) { - c->Message(0, "Removed client from instance."); + c->Message(Chat::White, "Removed client from instance."); } else { - c->Message(0, "Failed to remove client from instance."); + c->Message(Chat::White, "Failed to remove client from instance."); } } else if(strcasecmp(sep->arg[1], "list") == 0) @@ -9557,7 +9557,7 @@ void command_instance(Client *c, const Seperator *sep) { if(c->GetTarget() == nullptr || (c->GetTarget() && !c->GetTarget()->IsClient())) { - c->Message(0, "Character not found."); + c->Message(Chat::White, "Character not found."); return; } else @@ -9568,16 +9568,16 @@ void command_instance(Client *c, const Seperator *sep) } else { - c->Message(0, "Invalid Argument."); - c->Message(0, "#instance usage:"); - c->Message(0, "#instance create zone_id version duration - Creates an instance of version 'version' in the " + c->Message(Chat::White, "Invalid Argument."); + c->Message(Chat::White, "#instance usage:"); + c->Message(Chat::White, "#instance create zone_id version duration - Creates an instance of version 'version' in the " "zone with id matching zone_id, will last for duration seconds."); - c->Message(0, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); - c->Message(0, "#instance add instance_id player_name - adds the player 'player_name' to the instance " + c->Message(Chat::White, "#instance destroy instance_id - Destroys the instance with id matching instance_id."); + c->Message(Chat::White, "#instance add instance_id player_name - adds the player 'player_name' to the instance " "with id matching instance_id."); - c->Message(0, "#instance remove instance_id player_name - removes the player 'player_name' from the " + c->Message(Chat::White, "#instance remove instance_id player_name - removes the player 'player_name' from the " "instance with id matching instance_id."); - c->Message(0, "#instance list player_name - lists all the instances 'player_name' is apart of."); + c->Message(Chat::White, "#instance list player_name - lists all the instances 'player_name' is apart of."); return; } } @@ -9589,8 +9589,8 @@ void command_setstartzone(Client *c, const Seperator *sep) if(c->GetTarget() && c->GetTarget()->IsClient() && sep->arg[1][0] != 0) target = c->GetTarget()->CastToClient(); else { - c->Message(0, "Usage: (needs PC target) #setstartzone zonename"); - c->Message(0, "Optional Usage: Use '#setstartzone reset' or '#setstartzone 0' to clear a starting zone. Player can select a starting zone using /setstartcity"); + c->Message(Chat::White, "Usage: (needs PC target) #setstartzone zonename"); + c->Message(Chat::White, "Optional Usage: Use '#setstartzone reset' or '#setstartzone 0' to clear a starting zone. Player can select a starting zone using /setstartcity"); return; } @@ -9603,7 +9603,7 @@ void command_setstartzone(Client *c, const Seperator *sep) else { startzone = database.GetZoneID(sep->arg[1]); if(startzone == 0) { - c->Message(0, "Unable to locate zone '%s'", sep->arg[1]); + c->Message(Chat::White, "Unable to locate zone '%s'", sep->arg[1]); return; } } @@ -9622,7 +9622,7 @@ void command_netstats(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "reset") == 0) { auto connection = c->Connection(); - c->Message(0, "Resetting client stats (packet loss will not read correctly after reset)."); + c->Message(Chat::White, "Resetting client stats (packet loss will not read correctly after reset)."); connection->ResetStats(); return; } @@ -9634,58 +9634,58 @@ void command_netstats(Client *c, const Seperator *sep) auto now = EQ::Net::Clock::now(); auto sec_since_stats_reset = std::chrono::duration_cast>(now - stats.created).count(); - c->Message(0, "Netstats:"); - c->Message(0, "--------------------------------------------------------------------"); - c->Message(0, "Sent Bytes: %u (%.2f/sec)", stats.sent_bytes, stats.sent_bytes / sec_since_stats_reset); - c->Message(0, "Recv Bytes: %u (%.2f/sec)", stats.recv_bytes, stats.recv_bytes / sec_since_stats_reset); - c->Message(0, "Bytes Before Encode (Sent): %u, Compression Rate: %.2f%%", stats.bytes_before_encode, + c->Message(Chat::White, "Netstats:"); + c->Message(Chat::White, "--------------------------------------------------------------------"); + c->Message(Chat::White, "Sent Bytes: %u (%.2f/sec)", stats.sent_bytes, stats.sent_bytes / sec_since_stats_reset); + c->Message(Chat::White, "Recv Bytes: %u (%.2f/sec)", stats.recv_bytes, stats.recv_bytes / sec_since_stats_reset); + c->Message(Chat::White, "Bytes Before Encode (Sent): %u, Compression Rate: %.2f%%", stats.bytes_before_encode, static_cast(stats.bytes_before_encode - stats.sent_bytes) / static_cast(stats.bytes_before_encode) * 100.0); - c->Message(0, "Bytes After Decode (Recv): %u, Compression Rate: %.2f%%", stats.bytes_after_decode, + c->Message(Chat::White, "Bytes After Decode (Recv): %u, Compression Rate: %.2f%%", stats.bytes_after_decode, static_cast(stats.bytes_after_decode - stats.recv_bytes) / static_cast(stats.bytes_after_decode) * 100.0); - c->Message(0, "Min Ping: %u", stats.min_ping); - c->Message(0, "Max Ping: %u", stats.max_ping); - c->Message(0, "Last Ping: %u", stats.last_ping); - c->Message(0, "Average Ping: %u", stats.avg_ping); - c->Message(0, "--------------------------------------------------------------------"); - c->Message(0, "(Realtime) Recv Packets: %u (%.2f/sec)", stats.recv_packets, stats.recv_packets / sec_since_stats_reset); - c->Message(0, "(Realtime) Sent Packets: %u (%.2f/sec)", stats.sent_packets, stats.sent_packets / sec_since_stats_reset); - c->Message(0, "(Sync) Recv Packets: %u", stats.sync_recv_packets); - c->Message(0, "(Sync) Sent Packets: %u", stats.sync_sent_packets); - c->Message(0, "(Sync) Remote Recv Packets: %u", stats.sync_remote_recv_packets); - c->Message(0, "(Sync) Remote Sent Packets: %u", stats.sync_remote_sent_packets); - c->Message(0, "Packet Loss In: %.2f%%", 100.0 * (1.0 - static_cast(stats.sync_recv_packets) / static_cast(stats.sync_remote_sent_packets))); - c->Message(0, "Packet Loss Out: %.2f%%", 100.0 * (1.0 - static_cast(stats.sync_remote_recv_packets) / static_cast(stats.sync_sent_packets))); - c->Message(0, "--------------------------------------------------------------------"); - c->Message(0, "Resent Packets: %u (%.2f/sec)", stats.resent_packets, stats.resent_packets / sec_since_stats_reset); - c->Message(0, "Resent Fragments: %u (%.2f/sec)", stats.resent_fragments, stats.resent_fragments / sec_since_stats_reset); - c->Message(0, "Resent Non-Fragments: %u (%.2f/sec)", stats.resent_full, stats.resent_full / sec_since_stats_reset); - c->Message(0, "Dropped Datarate Packets: %u (%.2f/sec)", stats.dropped_datarate_packets, stats.dropped_datarate_packets / sec_since_stats_reset); + c->Message(Chat::White, "Min Ping: %u", stats.min_ping); + c->Message(Chat::White, "Max Ping: %u", stats.max_ping); + c->Message(Chat::White, "Last Ping: %u", stats.last_ping); + c->Message(Chat::White, "Average Ping: %u", stats.avg_ping); + c->Message(Chat::White, "--------------------------------------------------------------------"); + c->Message(Chat::White, "(Realtime) Recv Packets: %u (%.2f/sec)", stats.recv_packets, stats.recv_packets / sec_since_stats_reset); + c->Message(Chat::White, "(Realtime) Sent Packets: %u (%.2f/sec)", stats.sent_packets, stats.sent_packets / sec_since_stats_reset); + c->Message(Chat::White, "(Sync) Recv Packets: %u", stats.sync_recv_packets); + c->Message(Chat::White, "(Sync) Sent Packets: %u", stats.sync_sent_packets); + c->Message(Chat::White, "(Sync) Remote Recv Packets: %u", stats.sync_remote_recv_packets); + c->Message(Chat::White, "(Sync) Remote Sent Packets: %u", stats.sync_remote_sent_packets); + c->Message(Chat::White, "Packet Loss In: %.2f%%", 100.0 * (1.0 - static_cast(stats.sync_recv_packets) / static_cast(stats.sync_remote_sent_packets))); + c->Message(Chat::White, "Packet Loss Out: %.2f%%", 100.0 * (1.0 - static_cast(stats.sync_remote_recv_packets) / static_cast(stats.sync_sent_packets))); + c->Message(Chat::White, "--------------------------------------------------------------------"); + c->Message(Chat::White, "Resent Packets: %u (%.2f/sec)", stats.resent_packets, stats.resent_packets / sec_since_stats_reset); + c->Message(Chat::White, "Resent Fragments: %u (%.2f/sec)", stats.resent_fragments, stats.resent_fragments / sec_since_stats_reset); + c->Message(Chat::White, "Resent Non-Fragments: %u (%.2f/sec)", stats.resent_full, stats.resent_full / sec_since_stats_reset); + c->Message(Chat::White, "Dropped Datarate Packets: %u (%.2f/sec)", stats.dropped_datarate_packets, stats.dropped_datarate_packets / sec_since_stats_reset); if (opts.daybreak_options.outgoing_data_rate > 0.0) { - c->Message(0, "Outgoing Link Saturation %.2f%% (%.2fkb/sec)", 100.0 * (1.0 - ((opts.daybreak_options.outgoing_data_rate - stats.datarate_remaining) / opts.daybreak_options.outgoing_data_rate)), opts.daybreak_options.outgoing_data_rate); + c->Message(Chat::White, "Outgoing Link Saturation %.2f%% (%.2fkb/sec)", 100.0 * (1.0 - ((opts.daybreak_options.outgoing_data_rate - stats.datarate_remaining) / opts.daybreak_options.outgoing_data_rate)), opts.daybreak_options.outgoing_data_rate); } if (strcasecmp(sep->arg[1], "full") == 0) { - c->Message(0, "--------------------------------------------------------------------"); - c->Message(0, "Sent Packet Types"); + c->Message(Chat::White, "--------------------------------------------------------------------"); + c->Message(Chat::White, "Sent Packet Types"); for (auto i = 0; i < _maxEmuOpcode; ++i) { auto cnt = eqs_stats.SentCount[i]; if (cnt > 0) { - c->Message(0, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset); + c->Message(Chat::White, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset); } } - c->Message(0, "--------------------------------------------------------------------"); - c->Message(0, "Recv Packet Types"); + c->Message(Chat::White, "--------------------------------------------------------------------"); + c->Message(Chat::White, "Recv Packet Types"); for (auto i = 0; i < _maxEmuOpcode; ++i) { auto cnt = eqs_stats.RecvCount[i]; if (cnt > 0) { - c->Message(0, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset); + c->Message(Chat::White, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset); } } } - c->Message(0, "--------------------------------------------------------------------"); + c->Message(Chat::White, "--------------------------------------------------------------------"); } } @@ -9698,7 +9698,7 @@ void command_object(Client *c, const Seperator *sep) const char *usage_string = "Usage: #object List|Add|Edit|Move|Rotate|Save|Copy|Delete|Undo"; if ((!sep) || (sep->argnum == 0)) { - c->Message(0, usage_string); + c->Message(Chat::White, usage_string); return; } @@ -9731,7 +9731,7 @@ void command_object(Client *c, const Seperator *sep) // Insufficient or invalid args if ((sep->argnum < 2) || (sep->arg[2][0] < '0') || ((sep->arg[2][0] > '9') && ((sep->arg[2][0] & 0xDF) != 'A'))) { - c->Message(0, "Usage: #object List All|(radius)"); + c->Message(Chat::White, "Usage: #object List All|(radius)"); return; } @@ -9741,9 +9741,9 @@ void command_object(Client *c, const Seperator *sep) radius = 500; // Invalid radius. Default to 500 units. if (radius == 0) - c->Message(0, "Objects within this zone:"); + c->Message(Chat::White, "Objects within this zone:"); else - c->Message(0, "Objects within %u units of your current location:", radius); + c->Message(Chat::White, "Objects within %u units of your current location:", radius); std::string query; if (radius) @@ -9768,7 +9768,7 @@ void command_object(Client *c, const Seperator *sep) auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Error in objects query"); + c->Message(Chat::White, "Error in objects query"); return; } @@ -9795,27 +9795,27 @@ void command_object(Client *c, const Seperator *sep) if (od.size == 0) // Unknown08 field is optional Size parameter for static objects od.size = 100; // Static object default Size is 100% - c->Message(0, "- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " + c->Message(Chat::White, "- STATIC Object (%s): id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " "size %u, solidtype %u, incline %u", (od.object_type == 0) ? "locked" : "unlocked", id, od.x, od.y, od.z, od.heading, od.object_name, od.size, od.solidtype, od.unknown020); break; case OT_DROPPEDITEM: // Ground Spawn - c->Message(0, "- TEMPORARY Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, itemid %u, " + c->Message(Chat::White, "- TEMPORARY Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, itemid %u, " "model %s, icon %u", id, od.x, od.y, od.z, od.heading, itemid, od.object_name, icon); break; default: // All others == Tradeskill Objects - c->Message(0, "- TRADESKILL Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " + c->Message(Chat::White, "- TRADESKILL Object: id %u, x %.1f, y %.1f, z %.1f, h %.1f, model %s, " "type %u, icon %u", id, od.x, od.y, od.z, od.heading, od.object_name, od.object_type, icon); break; } } - c->Message(0, "%u object%s found", results.RowCount(), (results.RowCount() == 1) ? "" : "s"); + c->Message(Chat::White, "%u object%s found", results.RowCount(), (results.RowCount() == 1) ? "" : "s"); return; } @@ -9823,10 +9823,10 @@ void command_object(Client *c, const Seperator *sep) // Insufficient or invalid arguments if ((sep->argnum < 3) || ((sep->arg[3][0] == '\0') && (sep->arg[4][0] < '0') && (sep->arg[4][0] > '9'))) { - c->Message(0, "Usage: (Static Object): #object Add [ObjectID] 0 Model [SizePercent] " + c->Message(Chat::White, "Usage: (Static Object): #object Add [ObjectID] 0 Model [SizePercent] " "[SolidType] [Incline]"); - c->Message(0, "Usage: (Tradeskill Object): #object Add [ObjectID] TypeNum Model Icon"); - c->Message(0, "- Notes: Model must start with a letter, max length 16. SolidTypes = 0 (Solid), " + c->Message(Chat::White, "Usage: (Tradeskill Object): #object Add [ObjectID] TypeNum Model Icon"); + c->Message(Chat::White, "- Notes: Model must start with a letter, max length 16. SolidTypes = 0 (Solid), " "1 (Sometimes Non-Solid)"); return; } @@ -9868,7 +9868,7 @@ void command_object(Client *c, const Seperator *sep) break; case 1: // Ground Spawn - c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and dropped " + c->Message(Chat::White, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and dropped " "items, which are not supported with #object. See the 'ground_spawns' table in " "the database."); return; @@ -9877,7 +9877,7 @@ void command_object(Client *c, const Seperator *sep) icon = ((sep->argnum - col) > 3) ? atoi(sep->arg[4 + col]) : 0; if (icon == 0) { - c->Message(0, "ERROR: Required property 'Icon' not specified for Tradeskill Object"); + c->Message(Chat::White, "ERROR: Required property 'Icon' not specified for Tradeskill Object"); return; } @@ -9906,7 +9906,7 @@ void command_object(Client *c, const Seperator *sep) id = 0; if (id == 0) { - c->Message(0, "ERROR: An object already exists with the id %u", atoi(sep->arg[2])); + c->Message(Chat::White, "ERROR: An object already exists with the id %u", atoi(sep->arg[2])); return; } } @@ -9934,7 +9934,7 @@ void command_object(Client *c, const Seperator *sep) objectsFound = 1; if (objectsFound) { - c->Message(0, "ERROR: Object already at this location."); + c->Message(Chat::White, "ERROR: Object already at this location."); return; } @@ -9955,7 +9955,7 @@ void command_object(Client *c, const Seperator *sep) strupr(od.object_name); // Model names are always upper-case. if ((od.object_name[0] < 'A') || (od.object_name[0] > 'Z')) { - c->Message(0, "ERROR: Model name must start with a letter."); + c->Message(Chat::White, "ERROR: Model name must start with a letter."); return; } @@ -9996,13 +9996,13 @@ void command_object(Client *c, const Seperator *sep) y2 = 10.0f * cos(c->GetHeading() / 256.0f * 3.14159265f); c->MovePC(c->GetX() - x2, c->GetY() - y2, c->GetZ(), c->GetHeading()); - c->Message(0, "Spawning object with tentative id %u at location (%.1f, %.1f, %.1f heading %.1f). Use " + c->Message(Chat::White, "Spawning object with tentative id %u at location (%.1f, %.1f, %.1f heading %.1f). Use " "'#object Save' to save to database when satisfied with placement.", id, od.x, od.y, od.z, od.heading); // Temporary Static Object if (od.object_type == staticType) - c->Message(0, "- Note: Static Object will act like a tradeskill container and will not reflect " + c->Message(Chat::White, "- Note: Static Object will act like a tradeskill container and will not reflect " "size, solidtype, or incline values until you commit with '#object Save', after " "which it will be unchangeable until you use '#object Edit' and zone back in."); @@ -10012,9 +10012,9 @@ void command_object(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "edit") == 0) { if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) < 1)) { - c->Message(0, "Usage: #object Edit (ObjectID) [PropertyName] [NewValue]"); - c->Message(0, "- Static Object (Type 0) Properties: model, type, size, solidtype, incline"); - c->Message(0, "- Tradeskill Object (Type 2+) Properties: model, type, icon"); + c->Message(Chat::White, "Usage: #object Edit (ObjectID) [PropertyName] [NewValue]"); + c->Message(Chat::White, "- Static Object (Type 0) Properties: model, type, size, solidtype, incline"); + c->Message(Chat::White, "- Tradeskill Object (Type 2+) Properties: model, type, icon"); return; } @@ -10026,7 +10026,7 @@ void command_object(Client *c, const Seperator *sep) // Yep, looks like we can make real-time changes. if (sep->argnum < 4) { // Or not. '#object Edit (ObjectID)' called without PropertyName and NewValue - c->Message(0, "Note: Object %u already unlocked and ready for changes", id); + c->Message(Chat::White, "Note: Object %u already unlocked and ready for changes", id); return; } } else { @@ -10034,7 +10034,7 @@ void command_object(Client *c, const Seperator *sep) std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); + c->Message(Chat::White, "ERROR: Object %u not found", id); return; } @@ -10046,13 +10046,13 @@ void command_object(Client *c, const Seperator *sep) // Object not in this zone? if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u not in this zone.", id); + c->Message(Chat::White, "ERROR: Object %u not in this zone.", id); return; } // Object not in this instance? if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u not part of this instance version.", id); + c->Message(Chat::White, "ERROR: Object %u not part of this instance version.", id); return; } @@ -10063,23 +10063,23 @@ void command_object(Client *c, const Seperator *sep) database.QueryDatabase(query); - c->Message(0, "Static Object %u unlocked for editing. You must zone out and back in to " + c->Message(Chat::White, "Static Object %u unlocked for editing. You must zone out and back in to " "make your changes, then commit them with '#object Save'.", id); if (sep->argnum >= 4) - c->Message(0, "NOTE: The change you specified has not been applied, since the " + c->Message(Chat::White, "NOTE: The change you specified has not been applied, since the " "static object had not been unlocked for editing yet."); return; case OT_DROPPEDITEM: - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " + c->Message(Chat::White, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " "which cannot be manipulated with #object. See the 'ground_spawns' table " "in the database.", id); return; case staticType: - c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out " + c->Message(Chat::White, "ERROR: Object %u has been unlocked for editing, but you must zone out " "and back in for your client to refresh its object table before you can " "make changes to it.", id); @@ -10087,7 +10087,7 @@ void command_object(Client *c, const Seperator *sep) default: // Unknown error preventing us from seeing the object in the zone. - c->Message(0, "ERROR: Unknown problem attempting to manipulate object %u", id); + c->Message(Chat::White, "ERROR: Unknown problem attempting to manipulate object %u", id); return; } } @@ -10104,7 +10104,7 @@ void command_object(Client *c, const Seperator *sep) if (strcmp(sep->arg[3], "model") == 0) { if ((sep->arg[4][0] < 'A') || (sep->arg[4][0] > 'Z')) { - c->Message(0, "ERROR: Model names must begin with a letter."); + c->Message(Chat::White, "ERROR: Model names must begin with a letter."); return; } @@ -10112,10 +10112,10 @@ void command_object(Client *c, const Seperator *sep) o->SetObjectData(&od); - c->Message(0, "Object %u now being rendered with model '%s'", id, od.object_name); + c->Message(Chat::White, "Object %u now being rendered with model '%s'", id, od.object_name); } else if (strcmp(sep->arg[3], "type") == 0) { if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid type number"); + c->Message(Chat::White, "ERROR: Invalid type number"); return; } @@ -10125,20 +10125,20 @@ void command_object(Client *c, const Seperator *sep) case 0: // Convert Static Object to temporary changeable type od.object_type = staticType; - c->Message(0, "Note: Static Object will still act like tradeskill object and will not " + c->Message(Chat::White, "Note: Static Object will still act like tradeskill object and will not " "reflect size, solidtype, or incline settings until committed to the " "database with '#object Save', after which it will be unchangeable until " "it is unlocked again with '#object Edit'."); break; case OT_DROPPEDITEM: - c->Message(0, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and " + c->Message(Chat::White, "ERROR: Object Type 1 is used for temporarily spawned ground spawns and " "dropped items, which are not supported with #object. See the " "'ground_spawns' table in the database."); return; default: - c->Message(0, "Object %u changed to Tradeskill Object Type %u", id, od.object_type); + c->Message(Chat::White, "Object %u changed to Tradeskill Object Type %u", id, od.object_type); break; } @@ -10152,7 +10152,7 @@ void command_object(Client *c, const Seperator *sep) } if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid size specified. Please enter a number."); + c->Message(Chat::White, "ERROR: Invalid size specified. Please enter a number."); return; } @@ -10162,47 +10162,47 @@ void command_object(Client *c, const Seperator *sep) if (od.size == 0) // 0 == unspecified == 100% od.size = 100; - c->Message(0, "Static Object %u set to %u%% size. Size will take effect when you commit to the " + c->Message(Chat::White, "Static Object %u set to %u%% size. Size will take effect when you commit to the " "database with '#object Save', after which the object will be unchangeable until " "you unlock it again with '#object Edit' and zone out and back in.", id, od.size); } else if (strcmp(sep->arg[3], "solidtype") == 0) { if (od.object_type != staticType) { - c->Message(0, "ERROR: Object %u is not a Static Object and does not support the " + c->Message(Chat::White, "ERROR: Object %u is not a Static Object and does not support the " "SolidType property", id); return; } if ((sep->arg[4][0] < '0') || (sep->arg[4][0] > '9')) { - c->Message(0, "ERROR: Invalid solidtype specified. Please enter a number."); + c->Message(Chat::White, "ERROR: Invalid solidtype specified. Please enter a number."); return; } od.solidtype = atoi(sep->arg[4]); o->SetObjectData(&od); - c->Message(0, "Static Object %u set to SolidType %u. Change will take effect when you commit " + c->Message(Chat::White, "Static Object %u set to SolidType %u. Change will take effect when you commit " "to the database with '#object Save'. Support for this property is on a " "per-model basis, mostly seen in smaller objects such as chests and tables.", id, od.solidtype); } else if (strcmp(sep->arg[3], "icon") == 0) { if ((od.object_type < 2) || (od.object_type == staticType)) { - c->Message(0, "ERROR: Object %u is not a Tradeskill Object and does not support the " + c->Message(Chat::White, "ERROR: Object %u is not a Tradeskill Object and does not support the " "Icon property", id); return; } if ((icon = atoi(sep->arg[4])) == 0) { - c->Message(0, "ERROR: Invalid Icon specified. Please enter an icon number."); + c->Message(Chat::White, "ERROR: Invalid Icon specified. Please enter an icon number."); return; } o->SetIcon(icon); - c->Message(0, "Tradeskill Object %u icon set to %u", id, icon); + c->Message(Chat::White, "Tradeskill Object %u icon set to %u", id, icon); } else if (strcmp(sep->arg[3], "incline") == 0) { if (od.object_type != staticType) { c->Message( @@ -10222,12 +10222,12 @@ void command_object(Client *c, const Seperator *sep) od.unknown020 = atoi(sep->arg[4]); o->SetObjectData(&od); - c->Message(0, "Static Object %u set to %u incline. Incline will take effect when you commit to " + c->Message(Chat::White, "Static Object %u set to %u incline. Incline will take effect when you commit to " "the database with '#object Save', after which the object will be unchangeable " "until you unlock it again with '#object Edit' and zone out and back in.", id, od.unknown020); } else { - c->Message(0, "ERROR: Unrecognized property name: %s", sep->arg[3]); + c->Message(Chat::White, "ERROR: Unrecognized property name: %s", sep->arg[3]); return; } @@ -10250,7 +10250,7 @@ void command_object(Client *c, const Seperator *sep) ((id = atoi(sep->arg[2])) == 0) || // ID not specified (((sep->arg[3][0] < '0') || (sep->arg[3][0] > '9')) && ((sep->arg[3][0] & 0xDF) != 'T') && (sep->arg[3][0] != '-') && (sep->arg[3][0] != '.'))) { // Location argument not specified correctly - c->Message(0, "Usage: #object Move (ObjectID) ToMe|(x y z [h])"); + c->Message(Chat::White, "Usage: #object Move (ObjectID) ToMe|(x y z [h])"); return; } @@ -10258,7 +10258,7 @@ void command_object(Client *c, const Seperator *sep) std::string query = StringFormat("SELECT zoneid, version, type FROM object WHERE id = %u", id); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); + c->Message(Chat::White, "ERROR: Object %u not found", id); return; } @@ -10268,38 +10268,38 @@ void command_object(Client *c, const Seperator *sep) od.object_type = atoi(row[2]); if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u is not in this zone", id); + c->Message(Chat::White, "ERROR: Object %u is not in this zone", id); return; } if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u is not in this instance version", id); + c->Message(Chat::White, "ERROR: Object %u is not in this instance version", id); return; } switch (od.object_type) { case 0: - c->Message(0, "ERROR: Object %u is not yet unlocked for editing. Use '#object Edit' " + c->Message(Chat::White, "ERROR: Object %u is not yet unlocked for editing. Use '#object Edit' " "then zone out and back in to move it.", id); return; case staticType: - c->Message(0, "ERROR: Object %u has been unlocked for editing, but you must zone out " + c->Message(Chat::White, "ERROR: Object %u has been unlocked for editing, but you must zone out " "and back in before your client sees the change and will allow you to " "move it.", id); return; case 1: - c->Message(0, "ERROR: Object %u is a temporary spawned object and cannot be " + c->Message(Chat::White, "ERROR: Object %u is a temporary spawned object and cannot be " "manipulated with #object. See the 'ground_spawns' table in the " "database.", id); return; default: - c->Message(0, "ERROR: Object %u not located in zone.", id); + c->Message(Chat::White, "ERROR: Object %u not located in zone.", id); return; } } @@ -10354,12 +10354,12 @@ void command_object(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "rotate") == 0) { // Insufficient or invalid arguments if ((sep->argnum < 3) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Rotate (ObjectID) (Heading, 0-512)"); + c->Message(Chat::White, "Usage: #object Rotate (ObjectID) (Heading, 0-512)"); return; } if ((o = entity_list.FindObject(id)) == nullptr) { - c->Message(0, "ERROR: Object %u not found in zone, or is a static object not yet unlocked with " + c->Message(Chat::White, "ERROR: Object %u not found in zone, or is a static object not yet unlocked with " "'#object Edit' for editing.", id); return; @@ -10383,7 +10383,7 @@ void command_object(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "save") == 0) { // Insufficient or invalid arguments if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Save (ObjectID)"); + c->Message(Chat::White, "Usage: #object Save (ObjectID)"); return; } @@ -10411,36 +10411,36 @@ void command_object(Client *c, const Seperator *sep) // Object not found in zone. Can't save an object we can't see. if (bNewObject) { - c->Message(0, "ERROR: Object %u not found", id); + c->Message(Chat::White, "ERROR: Object %u not found", id); return; } if (od.zone_id != zone->GetZoneID()) { - c->Message(0, "ERROR: Wrong Object ID. %u is not part of this zone.", id); + c->Message(Chat::White, "ERROR: Wrong Object ID. %u is not part of this zone.", id); return; } if (od.zone_instance != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Wrong Object ID. %u is not part of this instance version.", id); + c->Message(Chat::White, "ERROR: Wrong Object ID. %u is not part of this instance version.", id); return; } if (od.object_type == 0) { - c->Message(0, "ERROR: Static Object %u has already been committed. Use '#object Edit " + c->Message(Chat::White, "ERROR: Static Object %u has already been committed. Use '#object Edit " "%u' and zone out and back in to make changes.", id, id); return; } if (od.object_type == 1) { - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " + c->Message(Chat::White, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, " "which is not supported with #object. See the 'ground_spawns' table in " "the database.", id); return; } - c->Message(0, "ERROR: Object %u not found.", id); + c->Message(Chat::White, "ERROR: Object %u not found.", id); return; } @@ -10493,28 +10493,28 @@ void command_object(Client *c, const Seperator *sep) results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + c->Message(Chat::White, "Database Error: %s", results.ErrorMessage().c_str()); return; } if (results.RowsAffected() == 0) { // No change made, but no error message given - c->Message(0, "Database Error: Could not save change to Object %u", id); + c->Message(Chat::White, "Database Error: Could not save change to Object %u", id); return; } if (bNewObject) { if (newid == results.LastInsertedID()) { - c->Message(0, "Saved new Object %u to database", id); + c->Message(Chat::White, "Saved new Object %u to database", id); return; } - c->Message(0, "Saved Object. NOTE: Database returned a new ID number for object: %u", newid); + c->Message(Chat::White, "Saved Object. NOTE: Database returned a new ID number for object: %u", newid); id = newid; return; } - c->Message(0, "Saved changes to Object %u", id); + c->Message(Chat::White, "Saved changes to Object %u", id); newid = id; if (od.object_type == 0) { @@ -10588,7 +10588,7 @@ void command_object(Client *c, const Seperator *sep) entity_list.QueueClients(0, app); safe_delete(app); - c->Message(0, "NOTE: Object %u is now a static object, and is unchangeable. To make future " + c->Message(Chat::White, "NOTE: Object %u is now a static object, and is unchangeable. To make future " "changes, use '#object Edit' to convert it to a changeable form, then zone out " "and back in.", id); @@ -10600,15 +10600,15 @@ void command_object(Client *c, const Seperator *sep) // Insufficient or invalid arguments if ((sep->argnum < 3) || (((sep->arg[2][0] & 0xDF) != 'A') && ((sep->arg[2][0] < '0') || (sep->arg[2][0] > '9')))) { - c->Message(0, "Usage: #object Copy All|(ObjectID) (InstanceVersion)"); - c->Message(0, "- Note: Only objects saved in the database can be copied to another instance."); + c->Message(Chat::White, "Usage: #object Copy All|(ObjectID) (InstanceVersion)"); + c->Message(Chat::White, "- Note: Only objects saved in the database can be copied to another instance."); return; } od.zone_instance = atoi(sep->arg[3]); if (od.zone_instance == zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Source and destination instance versions are the same."); + c->Message(Chat::White, "ERROR: Source and destination instance versions are the same."); return; } @@ -10625,11 +10625,11 @@ void command_object(Client *c, const Seperator *sep) od.zone_instance, zone->GetZoneID(), zone->GetInstanceVersion()); auto results = database.QueryDatabase(query); if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + c->Message(Chat::White, "Database Error: %s", results.ErrorMessage().c_str()); return; } - c->Message(0, "Copied %u object%s into instance version %u", results.RowCount(), + c->Message(Chat::White, "Copied %u object%s into instance version %u", results.RowCount(), (results.RowCount() == 1) ? "" : "s", od.zone_instance); return; } @@ -10645,7 +10645,7 @@ void command_object(Client *c, const Seperator *sep) od.zone_instance, id, zone->GetZoneID(), zone->GetInstanceVersion()); auto results = database.QueryDatabase(query); if (results.Success() && results.RowsAffected() > 0) { - c->Message(0, "Copied Object %u into instance version %u", id, od.zone_instance); + c->Message(Chat::White, "Copied Object %u into instance version %u", id, od.zone_instance); return; } @@ -10653,7 +10653,7 @@ void command_object(Client *c, const Seperator *sep) // got an error message if (!results.Success()) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + c->Message(Chat::White, "Database Error: %s", results.ErrorMessage().c_str()); return; } @@ -10665,25 +10665,25 @@ void command_object(Client *c, const Seperator *sep) return; if (results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found", id); + c->Message(Chat::White, "ERROR: Object %u not found", id); return; } auto row = results.begin(); // Wrong ZoneID? if (atoi(row[0]) != zone->GetZoneID()) { - c->Message(0, "ERROR: Object %u is not part of this zone.", id); + c->Message(Chat::White, "ERROR: Object %u is not part of this zone.", id); return; } // Wrong Instance Version? if (atoi(row[1]) != zone->GetInstanceVersion()) { - c->Message(0, "ERROR: Object %u is not part of this instance version.", id); + c->Message(Chat::White, "ERROR: Object %u is not part of this instance version.", id); return; } // Well, NO clue at this point. Just let 'em know something screwed up. - c->Message(0, "ERROR: Unknown database error copying Object %u to instance version %u", id, + c->Message(Chat::White, "ERROR: Unknown database error copying Object %u to instance version %u", id, od.zone_instance); return; } @@ -10691,7 +10691,7 @@ void command_object(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "delete") == 0) { if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) <= 0)) { - c->Message(0, "Usage: #object Delete (ObjectID) -- NOTE: Object deletions are permanent and " + c->Message(Chat::White, "Usage: #object Delete (ObjectID) -- NOTE: Object deletions are permanent and " "cannot be undone!"); return; } @@ -10715,7 +10715,7 @@ void command_object(Client *c, const Seperator *sep) id, zone->GetZoneID(), zone->GetInstanceVersion()); auto results = database.QueryDatabase(query); - c->Message(0, "Object %u deleted", id); + c->Message(Chat::White, "Object %u deleted", id); return; } @@ -10729,7 +10729,7 @@ void command_object(Client *c, const Seperator *sep) return; if (results.RowCount() == 0) { - c->Message(0, "ERROR: Object %u not found in this zone or instance!", id); + c->Message(Chat::White, "ERROR: Object %u not found in this zone or instance!", id); return; } @@ -10742,13 +10742,13 @@ void command_object(Client *c, const Seperator *sep) id, zone->GetZoneID(), zone->GetInstanceVersion()); results = database.QueryDatabase(query); - c->Message(0, "Object %u deleted. NOTE: This static object will remain for anyone currently in " + c->Message(Chat::White, "Object %u deleted. NOTE: This static object will remain for anyone currently in " "the zone until they next zone out and in.", id); return; case 1: // Temporary Spawn - c->Message(0, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which " + c->Message(Chat::White, "ERROR: Object %u is a temporarily spawned ground spawn or dropped item, which " "is not supported with #object. See the 'ground_spawns' table in the database.", id); return; @@ -10760,7 +10760,7 @@ void command_object(Client *c, const Seperator *sep) if (strcasecmp(sep->arg[1], "undo") == 0) { // Insufficient or invalid arguments if ((sep->argnum < 2) || ((id = atoi(sep->arg[2])) == 0)) { - c->Message(0, "Usage: #object Undo (ObjectID) -- Reload object from database, undoing any " + c->Message(Chat::White, "Usage: #object Undo (ObjectID) -- Reload object from database, undoing any " "changes you have made"); return; } @@ -10768,13 +10768,13 @@ void command_object(Client *c, const Seperator *sep) o = entity_list.FindObject(id); if (!o) { - c->Message(0, "ERROR: Object %u not found in zone in a manipulable form. No changes to undo.", + c->Message(Chat::White, "ERROR: Object %u not found in zone in a manipulable form. No changes to undo.", id); return; } if (o->GetType() == OT_DROPPEDITEM) { - c->Message(0, "ERROR: Object %u is a temporary spawned item and cannot be manipulated with " + c->Message(Chat::White, "ERROR: Object %u is a temporary spawned item and cannot be manipulated with " "#object. See the 'ground_spawns' table in the database.", id); return; @@ -10794,7 +10794,7 @@ void command_object(Client *c, const Seperator *sep) id); auto results = database.QueryDatabase(query); if (!results.Success() || results.RowCount() == 0) { - c->Message(0, "Database Error: %s", results.ErrorMessage().c_str()); + c->Message(Chat::White, "Database Error: %s", results.ErrorMessage().c_str()); return; } @@ -10819,11 +10819,11 @@ void command_object(Client *c, const Seperator *sep) o = new Object(id, od.object_type, icon, od, nullptr); entity_list.AddObject(o, true); - c->Message(0, "Object %u reloaded from database.", id); + c->Message(Chat::White, "Object %u reloaded from database.", id); return; } - c->Message(0, usage_string); + c->Message(Chat::White, usage_string); } void command_showspellslist(Client *c, const Seperator *sep) @@ -10831,12 +10831,12 @@ void command_showspellslist(Client *c, const Seperator *sep) Mob *target = c->GetTarget(); if (!target) { - c->Message(0, "Must target an NPC."); + c->Message(Chat::White, "Must target an NPC."); return; } if (!target->IsNPC()) { - c->Message(0, "%s is not an NPC.", target->GetName()); + c->Message(Chat::White, "%s is not an NPC.", target->GetName()); return; } @@ -10848,7 +10848,7 @@ void command_showspellslist(Client *c, const Seperator *sep) void command_raidloot(Client *c, const Seperator *sep) { if(!sep->arg[1][0]) { - c->Message(0, "Usage: #raidloot [LEADER/GROUPLEADER/SELECTED/ALL]"); + c->Message(Chat::White, "Usage: #raidloot [LEADER/GROUPLEADER/SELECTED/ALL]"); return; } @@ -10861,7 +10861,7 @@ void command_raidloot(Client *c, const Seperator *sep) { if(r->members[x].IsRaidLeader == 0) { - c->Message(0, "You must be the raid leader to use this command."); + c->Message(Chat::White, "You must be the raid leader to use this command."); } else { @@ -10892,12 +10892,12 @@ void command_raidloot(Client *c, const Seperator *sep) } else { - c->Message(0, "Usage: #raidloot [LEADER/GROUPLEADER/SELECTED/ALL]"); + c->Message(Chat::White, "Usage: #raidloot [LEADER/GROUPLEADER/SELECTED/ALL]"); } } else { - c->Message(0, "You must be in a raid to use that command."); + c->Message(Chat::White, "You must be in a raid to use that command."); } } @@ -10905,7 +10905,7 @@ void command_emoteview(Client *c, const Seperator *sep) { if(!c->GetTarget() || !c->GetTarget()->IsNPC()) { - c->Message(0, "You must target a NPC to view their emotes."); + c->Message(Chat::White, "You must target a NPC to view their emotes."); return; } @@ -10921,22 +10921,22 @@ void command_emoteview(Client *c, const Seperator *sep) NPC_Emote_Struct* nes = iterator.GetData(); if(emoteid == nes->emoteid) { - c->Message(0, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); + c->Message(Chat::White, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); count++; } iterator.Advance(); } if (count == 0) - c->Message(0, "No emotes found."); + c->Message(Chat::White, "No emotes found."); else - c->Message(0, "%i emote(s) found", count); + c->Message(Chat::White, "%i emote(s) found", count); } } void command_emotesearch(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) - c->Message(0, "Usage: #emotesearch [search string or emoteid]"); + c->Message(Chat::White, "Usage: #emotesearch [search string or emoteid]"); else { const char *search_criteria=sep->argplus[1]; @@ -10952,15 +10952,15 @@ void command_emotesearch(Client *c, const Seperator *sep) NPC_Emote_Struct* nes = iterator.GetData(); if(emoteid == nes->emoteid) { - c->Message(0, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); + c->Message(Chat::White, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); count++; } iterator.Advance(); } if (count == 0) - c->Message(0, "No emotes found."); + c->Message(Chat::White, "No emotes found."); else - c->Message(0, "%i emote(s) found", count); + c->Message(Chat::White, "%i emote(s) found", count); } else { @@ -10980,7 +10980,7 @@ void command_emotesearch(Client *c, const Seperator *sep) pdest = strstr(sText, sCriteria); if (pdest != nullptr) { - c->Message(0, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); + c->Message(Chat::White, "EmoteID: %i Event: %i Type: %i Text: %s", nes->emoteid, nes->event_, nes->type, nes->text); count++; } if (count == 50) @@ -10989,9 +10989,9 @@ void command_emotesearch(Client *c, const Seperator *sep) iterator.Advance(); } if (count == 50) - c->Message(0, "50 emotes shown...too many results."); + c->Message(Chat::White, "50 emotes shown...too many results."); else - c->Message(0, "%i emote(s) found", count); + c->Message(Chat::White, "%i emote(s) found", count); } } } @@ -11000,7 +11000,7 @@ void command_reloademote(Client *c, const Seperator *sep) { zone->NPCEmoteList.Clear(); zone->LoadNPCEmotes(&zone->NPCEmoteList); - c->Message(0, "NPC emotes reloaded."); + c->Message(Chat::White, "NPC emotes reloaded."); } void command_globalview(Client *c, const Seperator *sep) @@ -11044,14 +11044,14 @@ void command_globalview(Client *c, const Seperator *sep) auto iter = globalMap.begin(); uint32 gcount = 0; - c->Message(0, "Name, Value"); + c->Message(Chat::White, "Name, Value"); while(iter != globalMap.end()) { - c->Message(0, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); + c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); ++iter; ++gcount; } - c->Message(0, "%u globals loaded.", gcount); + c->Message(Chat::White, "%u globals loaded.", gcount); } else { @@ -11077,14 +11077,14 @@ void command_globalview(Client *c, const Seperator *sep) auto iter = globalMap.begin(); uint32 gcount = 0; - c->Message(0, "Name, Value"); + c->Message(Chat::White, "Name, Value"); while(iter != globalMap.end()) { - c->Message(0, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); + c->Message(Chat::White, "%s %s", (*iter).name.c_str(), (*iter).value.c_str()); ++iter; ++gcount; } - c->Message(0, "%u globals loaded.", gcount); + c->Message(Chat::White, "%u globals loaded.", gcount); } } @@ -11092,7 +11092,7 @@ void command_distance(Client *c, const Seperator *sep) { if(c && c->GetTarget()) { Mob* target = c->GetTarget(); - c->Message(0, "Your target, %s, is %1.1f units from you.", c->GetTarget()->GetName(), Distance(c->GetPosition(), target->GetPosition())); + c->Message(Chat::White, "Your target, %s, is %1.1f units from you.", c->GetTarget()->GetName(), Distance(c->GetPosition(), target->GetPosition())); } } @@ -11136,24 +11136,24 @@ void command_max_all_skills(Client *c, const Seperator *sep) void command_showbonusstats(Client *c, const Seperator *sep) { if (c->GetTarget() == 0) - c->Message(0, "ERROR: No target!"); + c->Message(Chat::White, "ERROR: No target!"); else if (!c->GetTarget()->IsMob() && !c->GetTarget()->IsClient()) - c->Message(0, "ERROR: Target is not a Mob or Player!"); + c->Message(Chat::White, "ERROR: Target is not a Mob or Player!"); else { bool bAll = false; if(sep->arg[1][0] == '\0' || strcasecmp(sep->arg[1], "all") == 0) bAll = true; if (bAll || (strcasecmp(sep->arg[1], "item")==0)) { - c->Message(0, "Target Item Bonuses:"); - c->Message(0, " Accuracy: %i%% Divine Save: %i%%", c->GetTarget()->GetItemBonuses().Accuracy, c->GetTarget()->GetItemBonuses().DivineSaveChance); - c->Message(0, " Flurry: %i%% HitChance: %i%%", c->GetTarget()->GetItemBonuses().FlurryChance, c->GetTarget()->GetItemBonuses().HitChance / 15); + c->Message(Chat::White, "Target Item Bonuses:"); + c->Message(Chat::White, " Accuracy: %i%% Divine Save: %i%%", c->GetTarget()->GetItemBonuses().Accuracy, c->GetTarget()->GetItemBonuses().DivineSaveChance); + c->Message(Chat::White, " Flurry: %i%% HitChance: %i%%", c->GetTarget()->GetItemBonuses().FlurryChance, c->GetTarget()->GetItemBonuses().HitChance / 15); } if (bAll || (strcasecmp(sep->arg[1], "spell")==0)) { - c->Message(0, " Target Spell Bonuses:"); - c->Message(0, " Accuracy: %i%% Divine Save: %i%%", c->GetTarget()->GetSpellBonuses().Accuracy, c->GetTarget()->GetSpellBonuses().DivineSaveChance); - c->Message(0, " Flurry: %i%% HitChance: %i%% ", c->GetTarget()->GetSpellBonuses().FlurryChance, c->GetTarget()->GetSpellBonuses().HitChance / 15); + c->Message(Chat::White, " Target Spell Bonuses:"); + c->Message(Chat::White, " Accuracy: %i%% Divine Save: %i%%", c->GetTarget()->GetSpellBonuses().Accuracy, c->GetTarget()->GetSpellBonuses().DivineSaveChance); + c->Message(Chat::White, " Flurry: %i%% HitChance: %i%% ", c->GetTarget()->GetSpellBonuses().FlurryChance, c->GetTarget()->GetSpellBonuses().HitChance / 15); } - c->Message(0, " Effective Casting Level: %i", c->GetTarget()->GetCasterLevel(0)); + c->Message(Chat::White, " Effective Casting Level: %i", c->GetTarget()->GetCasterLevel(0)); } } @@ -11332,27 +11332,27 @@ void command_profanity(Client *c, const Seperator *sep) return; } - c->Message(0, "Usage: #profanity [list] - shows profanity list"); - c->Message(0, "Usage: #profanity [clear] - deletes all entries"); - c->Message(0, "Usage: #profanity [add] [] - adds entry"); - c->Message(0, "Usage: #profanity [del] [] - deletes entry"); - c->Message(0, "Usage: #profanity [reload] - reloads profanity list"); + c->Message(Chat::White, "Usage: #profanity [list] - shows profanity list"); + c->Message(Chat::White, "Usage: #profanity [clear] - deletes all entries"); + c->Message(Chat::White, "Usage: #profanity [add] [] - adds entry"); + c->Message(Chat::White, "Usage: #profanity [del] [] - deletes entry"); + c->Message(Chat::White, "Usage: #profanity [reload] - reloads profanity list"); } void command_mysql(Client *c, const Seperator *sep) { if(!sep->arg[1][0] || !sep->arg[2][0]) { - c->Message(0, "Usage: #mysql query \"Query here\""); + c->Message(Chat::White, "Usage: #mysql query \"Query here\""); return; } if (strcasecmp(sep->arg[1], "help") == 0) { - c->Message(0, "MYSQL In-Game CLI Interface:"); - c->Message(0, "Example: #mysql query \"Query goes here quoted\" -s -h"); - c->Message(0, "To use 'like \"%%something%%\" replace the %% with #"); - c->Message(0, "Example: #mysql query \"select * from table where name like \"#something#\""); - c->Message(0, "-s - Spaces select entries apart"); - c->Message(0, "-h - Colors every other select result"); + c->Message(Chat::White, "MYSQL In-Game CLI Interface:"); + c->Message(Chat::White, "Example: #mysql query \"Query goes here quoted\" -s -h"); + c->Message(Chat::White, "To use 'like \"%%something%%\" replace the %% with #"); + c->Message(Chat::White, "Example: #mysql query \"select * from table where name like \"#something#\""); + c->Message(Chat::White, "-s - Spaces select entries apart"); + c->Message(Chat::White, "-h - Colors every other select result"); return; } @@ -11408,7 +11408,7 @@ void command_mysql(Client *c, const Seperator *sep) lineVec.push_back(lineText.str()); if(optionS) //This provides spacing for the space switch - c->Message(0, " "); + c->Message(Chat::White, " "); if(optionH) //This option will highlight every other row highlightTextIndex = 1 - highlightTextIndex; @@ -11437,7 +11437,7 @@ void command_xtargets(Client *c, const Seperator *sep) return; } t->SetMaxXTargets(NewMax); - c->Message(0, "Max number of XTargets set to %i", NewMax); + c->Message(Chat::White, "Max number of XTargets set to %i", NewMax); } else t->ShowXTargets(c); @@ -11448,11 +11448,11 @@ void command_zopp(Client *c, const Seperator *sep) if (!c) return; else if (sep->argnum < 3 || sep->argnum > 4) - c->Message(0, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); + c->Message(Chat::White, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); else if (!strcasecmp(sep->arg[1], "trade") == 0 && !strcasecmp(sep->arg[1], "t") == 0 && !strcasecmp(sep->arg[1], "summon") == 0 && !strcasecmp(sep->arg[1], "s") == 0) - c->Message(0, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); + c->Message(Chat::White, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); else if (!sep->IsNumber(2) || !sep->IsNumber(3) || (sep->argnum == 4 && !sep->IsNumber(4))) - c->Message(0, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); + c->Message(Chat::White, "Usage: #zopp [trade/summon] [slot id] [item id] [*charges]"); else { ItemPacketType packettype; @@ -11486,12 +11486,12 @@ void command_zopp(Client *c, const Seperator *sep) if (charges < 0 || charges > FakeItem->StackSize) { c->Message(Chat::Red, "Warning: The specified charge count does not meet expected criteria!"); - c->Message(0, "Processing request..results may cause unpredictable behavior."); + c->Message(Chat::White, "Processing request..results may cause unpredictable behavior."); } EQEmu::ItemInstance* FakeItemInst = database.CreateItem(FakeItem, charges); c->SendItemPacket(slotid, FakeItemInst, packettype); - c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.", + c->Message(Chat::White, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.", packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges, std::abs(charges == 1) ? "charge" : "charges", slotid); safe_delete(FakeItemInst); @@ -11515,17 +11515,17 @@ void command_questerrors(Client *c, const Seperator *sep) { std::list err; parse->GetErrors(err); - c->Message(0, "Current Quest Errors:"); + c->Message(Chat::White, "Current Quest Errors:"); auto iter = err.begin(); int i = 0; while(iter != err.end()) { if(i >= 30) { - c->Message(0, "Maximum of 30 Errors shown..."); + c->Message(Chat::White, "Maximum of 30 Errors shown..."); break; } - c->Message(0, iter->c_str()); + c->Message(Chat::White, iter->c_str()); ++i; ++iter; } @@ -11540,20 +11540,20 @@ void command_enablerecipe(Client *c, const Seperator *sep) recipe_id = atoi(sep->arg[1]); } else { - c->Message(0, "Invalid number of arguments.\nUsage: #enablerecipe recipe_id"); + c->Message(Chat::White, "Invalid number of arguments.\nUsage: #enablerecipe recipe_id"); return; } if (recipe_id > 0) { success = database.EnableRecipe(recipe_id); if (success) { - c->Message(0, "Recipe enabled."); + c->Message(Chat::White, "Recipe enabled."); } else { - c->Message(0, "Recipe not enabled."); + c->Message(Chat::White, "Recipe not enabled."); } } else { - c->Message(0, "Invalid recipe id.\nUsage: #enablerecipe recipe_id"); + c->Message(Chat::White, "Invalid recipe id.\nUsage: #enablerecipe recipe_id"); } } } @@ -11567,20 +11567,20 @@ void command_disablerecipe(Client *c, const Seperator *sep) recipe_id = atoi(sep->arg[1]); } else { - c->Message(0, "Invalid number of arguments.\nUsage: #disablerecipe recipe_id"); + c->Message(Chat::White, "Invalid number of arguments.\nUsage: #disablerecipe recipe_id"); return; } if (recipe_id > 0) { success = database.DisableRecipe(recipe_id); if (success) { - c->Message(0, "Recipe disabled."); + c->Message(Chat::White, "Recipe disabled."); } else { - c->Message(0, "Recipe not disabled."); + c->Message(Chat::White, "Recipe not disabled."); } } else { - c->Message(0, "Invalid recipe id.\nUsage: #disablerecipe recipe_id"); + c->Message(Chat::White, "Invalid recipe id.\nUsage: #disablerecipe recipe_id"); } } } @@ -11590,13 +11590,13 @@ void command_npctype_cache(Client *c, const Seperator *sep) if (sep->argnum > 0) { for (int i = 0; i < sep->argnum; ++i) { if (strcasecmp(sep->arg[i + 1], "all") == 0) { - c->Message(0, "Clearing all npc types from the cache."); + c->Message(Chat::White, "Clearing all npc types from the cache."); zone->ClearNPCTypeCache(-1); } else { int id = atoi(sep->arg[i + 1]); if (id > 0) { - c->Message(0, "Clearing npc type %d from the cache.", id); + c->Message(Chat::White, "Clearing npc type %d from the cache.", id); zone->ClearNPCTypeCache(id); return; } @@ -11604,9 +11604,9 @@ void command_npctype_cache(Client *c, const Seperator *sep) } } else { - c->Message(0, "Usage:"); - c->Message(0, "#npctype_cache [npctype_id] ..."); - c->Message(0, "#npctype_cache all"); + c->Message(Chat::White, "Usage:"); + c->Message(Chat::White, "#npctype_cache [npctype_id] ..."); + c->Message(Chat::White, "#npctype_cache all"); } } @@ -11614,7 +11614,7 @@ void command_merchantopenshop(Client *c, const Seperator *sep) { Mob *merchant = c->GetTarget(); if (!merchant || merchant->GetClass() != MERCHANT) { - c->Message(0, "You must target a merchant to open their shop."); + c->Message(Chat::White, "You must target a merchant to open their shop."); return; } @@ -11625,7 +11625,7 @@ void command_merchantcloseshop(Client *c, const Seperator *sep) { Mob *merchant = c->GetTarget(); if (!merchant || merchant->GetClass() != MERCHANT) { - c->Message(0, "You must target a merchant to close their shop."); + c->Message(Chat::White, "You must target a merchant to close their shop."); return; } @@ -11643,12 +11643,12 @@ void command_shownpcgloballoot(Client *c, const Seperator *sep) auto tar = c->GetTarget(); if (!tar || !tar->IsNPC()) { - c->Message(0, "You must target an NPC to use this command."); + c->Message(Chat::White, "You must target an NPC to use this command."); return; } auto npc = tar->CastToNPC(); - c->Message(0, "GlobalLoot for %s (%d)", npc->GetName(), npc->GetNPCTypeID()); + c->Message(Chat::White, "GlobalLoot for %s (%d)", npc->GetName(), npc->GetNPCTypeID()); zone->ShowNPCGlobalLoot(c, npc); } @@ -11657,33 +11657,33 @@ void command_tune(Client *c, const Seperator *sep) //Work in progress - Kayen if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "Syntax: #tune [subcommand]."); - c->Message(0, "-- Tune System Commands --"); - c->Message(0, "-- Usage: Returning recommended combat statistical values based on a desired outcome."); - c->Message(0, "-- Note: If targeted mob does not have a target (ie not engaged in combat), YOU will be considered the target."); - c->Message(0, "-- Warning: The calculations done in this process are intense and can potentially cause zone crashes depending on parameters set, use with caution!"); - c->Message(0, "-- Below are OPTIONAL parameters."); - c->Message(0, "-- Note: [interval] Determines how fast the stat being checked increases/decreases till it finds the best result. Default [ATK/AC 50][Acc/Avoid 10] "); - c->Message(0, "-- Note: [loop_max] Determines how many iterations are done to increases/decreases the stat till it finds the best result. Default [ATK/AC 100][Acc/Avoid 1000]"); - c->Message(0, "-- Note: [Stat Override] Will override that stat on mob being checkd with the specified value. Default=0"); - c->Message(0, "-- Note: [Info Level] How much statistical detail is displayed[0 - 3]. Default=0 "); - c->Message(0, "-- Note: Results are only approximations usually accurate to +/- 2 intervals."); + c->Message(Chat::White, "Syntax: #tune [subcommand]."); + c->Message(Chat::White, "-- Tune System Commands --"); + c->Message(Chat::White, "-- Usage: Returning recommended combat statistical values based on a desired outcome."); + c->Message(Chat::White, "-- Note: If targeted mob does not have a target (ie not engaged in combat), YOU will be considered the target."); + c->Message(Chat::White, "-- Warning: The calculations done in this process are intense and can potentially cause zone crashes depending on parameters set, use with caution!"); + c->Message(Chat::White, "-- Below are OPTIONAL parameters."); + c->Message(Chat::White, "-- Note: [interval] Determines how fast the stat being checked increases/decreases till it finds the best result. Default [ATK/AC 50][Acc/Avoid 10] "); + c->Message(Chat::White, "-- Note: [loop_max] Determines how many iterations are done to increases/decreases the stat till it finds the best result. Default [ATK/AC 100][Acc/Avoid 1000]"); + c->Message(Chat::White, "-- Note: [Stat Override] Will override that stat on mob being checkd with the specified value. Default=0"); + c->Message(Chat::White, "-- Note: [Info Level] How much statistical detail is displayed[0 - 3]. Default=0 "); + c->Message(Chat::White, "-- Note: Results are only approximations usually accurate to +/- 2 intervals."); - c->Message(0, "... "); - c->Message(0, "...### Category A ### Target = ATTACKER ### YOU or Target's Target = DEFENDER ###"); - c->Message(0, "...### Category B ### Target = DEFENDER ### YOU or Target's Target = ATTACKER ###"); - c->Message(0, "... "); - c->Message(0, "...#Returns recommended ATK adjustment +/- on ATTACKER that will result in an average mitigation pct on DEFENDER. "); - c->Message(0, "...tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level]"); - c->Message(0, "... "); - c->Message(0, "...#Returns recommended AC adjustment +/- on DEFENDER for an average mitigation pct from ATTACKER. "); - c->Message(0, "...tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] "); - c->Message(0, "... "); - c->Message(0, "...#Returns recommended Accuracy adjustment +/- on ATTACKER that will result in a hit chance pct on DEFENDER. "); - c->Message(0, "...tune FindAccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]"); - c->Message(0, "... "); - c->Message(0, "...#Returns recommended Avoidance adjustment +/- on DEFENDER for in a hit chance pct from ATTACKER. "); - c->Message(0, "...tune FindAvoidance [A/B] [pct mitigation] [interval][loop_max][Accuracy Overwride][Info Level] "); + c->Message(Chat::White, "... "); + c->Message(Chat::White, "...### Category A ### Target = ATTACKER ### YOU or Target's Target = DEFENDER ###"); + c->Message(Chat::White, "...### Category B ### Target = DEFENDER ### YOU or Target's Target = ATTACKER ###"); + c->Message(Chat::White, "... "); + c->Message(Chat::White, "...#Returns recommended ATK adjustment +/- on ATTACKER that will result in an average mitigation pct on DEFENDER. "); + c->Message(Chat::White, "...tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level]"); + c->Message(Chat::White, "... "); + c->Message(Chat::White, "...#Returns recommended AC adjustment +/- on DEFENDER for an average mitigation pct from ATTACKER. "); + c->Message(Chat::White, "...tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] "); + c->Message(Chat::White, "... "); + c->Message(Chat::White, "...#Returns recommended Accuracy adjustment +/- on ATTACKER that will result in a hit chance pct on DEFENDER. "); + c->Message(Chat::White, "...tune FindAccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]"); + c->Message(Chat::White, "... "); + c->Message(Chat::White, "...#Returns recommended Avoidance adjustment +/- on DEFENDER for in a hit chance pct from ATTACKER. "); + c->Message(Chat::White, "...tune FindAvoidance [A/B] [pct mitigation] [interval][loop_max][Accuracy Overwride][Info Level] "); return; } @@ -11693,7 +11693,7 @@ void command_tune(Client *c, const Seperator *sep) if (!attacker) { - c->Message(0, "#Tune - Error no target selected. [#Tune help]"); + c->Message(Chat::White, "#Tune - Error no target selected. [#Tune help]"); return; } @@ -11730,9 +11730,9 @@ void command_tune(Client *c, const Seperator *sep) else if(!strcasecmp(sep->arg[2], "B")) c->Tune_FindATKByPctMitigation(attacker,defender, pct_mitigation, interval, max_loop,ac_override,info_level); else { - c->Message(0, "#Tune - Error no category selcted. [#Tune help]"); - c->Message(0, "Usage #tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level] "); - c->Message(0, "Example #tune FindATK A 60"); + c->Message(Chat::White, "#Tune - Error no category selcted. [#Tune help]"); + c->Message(Chat::White, "Usage #tune FindATK [A/B] [pct mitigation] [interval][loop_max][AC Overwride][Info Level] "); + c->Message(Chat::White, "Example #tune FindATK A 60"); } return; } @@ -11765,9 +11765,9 @@ void command_tune(Client *c, const Seperator *sep) else if(!strcasecmp(sep->arg[2], "B")) c->Tune_FindACByPctMitigation(attacker, defender, pct_mitigation, interval, max_loop,atk_override,info_level); else { - c->Message(0, "#Tune - Error no category selcted. [#Tune help]"); - c->Message(0, "Usage #tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] "); - c->Message(0, "Example #tune FindAC A 60"); + c->Message(Chat::White, "#Tune - Error no category selcted. [#Tune help]"); + c->Message(Chat::White, "Usage #tune FindAC [A/B] [pct mitigation] [interval][loop_max][ATK Overwride][Info Level] "); + c->Message(Chat::White, "Example #tune FindAC A 60"); } return; @@ -11807,9 +11807,9 @@ void command_tune(Client *c, const Seperator *sep) else if(!strcasecmp(sep->arg[2], "B")) c->Tune_FindAccuaryByHitChance(attacker, defender, hit_chance, interval, max_loop,avoid_override,info_level); else { - c->Message(0, "#Tune - Error no category selcted. [#Tune help]"); - c->Message(0, "Usage #tune FindAcccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]"); - c->Message(0, "Exampled #tune FindAccuracy B 30"); + c->Message(Chat::White, "#Tune - Error no category selcted. [#Tune help]"); + c->Message(Chat::White, "Usage #tune FindAcccuracy [A/B] [hit chance] [interval][loop_max][Avoidance Overwride][Info Level]"); + c->Message(Chat::White, "Exampled #tune FindAccuracy B 30"); } return; @@ -11825,7 +11825,7 @@ void command_tune(Client *c, const Seperator *sep) if (!hit_chance) { - c->Message(0, "#Tune - Error must enter the desired hit chance on defender. Ie. Defender to have hit chance of 40 pct."); + c->Message(Chat::White, "#Tune - Error must enter the desired hit chance on defender. Ie. Defender to have hit chance of 40 pct."); return; } @@ -11849,9 +11849,9 @@ void command_tune(Client *c, const Seperator *sep) else if(!strcasecmp(sep->arg[2], "B")) c->Tune_FindAvoidanceByHitChance(attacker, defender, hit_chance, interval, max_loop,acc_override, info_level); else { - c->Message(0, "#Tune - Error no category selcted. [#Tune help]"); - c->Message(0, "Usage #tune FindAvoidance [A/B] [hit chance] [interval][loop_max][Accuracy Overwride][Info Level]"); - c->Message(0, "Exampled #tune FindAvoidance B 30"); + c->Message(Chat::White, "#Tune - Error no category selcted. [#Tune help]"); + c->Message(Chat::White, "Usage #tune FindAvoidance [A/B] [hit chance] [interval][loop_max][Accuracy Overwride][Info Level]"); + c->Message(Chat::White, "Exampled #tune FindAvoidance B 30"); } return; @@ -11875,7 +11875,7 @@ void command_logtest(Client *c, const Seperator *sep){ void command_crashtest(Client *c, const Seperator *sep) { - c->Message(0, "Alright, now we get an GPF ;) "); + c->Message(Chat::White, "Alright, now we get an GPF ;) "); char* gpf = 0; memcpy(gpf, "Ready to crash", 30); } @@ -11893,11 +11893,11 @@ void command_logs(Client *c, const Seperator *sep){ /* #logs list_settings */ if (strcasecmp(sep->arg[1], "list_settings") == 0 || (strcasecmp(sep->arg[1], "set") == 0 && strcasecmp(sep->arg[3], "") == 0)) { - c->Message(0, "[Category ID | console | file | gmsay | Category Description]"); + c->Message(Chat::White, "[Category ID | console | file | gmsay | Category Description]"); int redisplay_columns = 0; for (int i = 0; i < Logs::LogCategory::MaxCategoryID; i++) { if (redisplay_columns == 10) { - c->Message(0, "[Category ID | console | file | gmsay | Category Description]"); + c->Message(Chat::White, "[Category ID | console | file | gmsay | Category Description]"); redisplay_columns = 0; } c->Message( @@ -11928,8 +11928,8 @@ void command_logs(Client *c, const Seperator *sep){ logs_set = 1; } else{ - c->Message(0, "--- #logs set [console|file|gmsay] - Sets log settings during the lifetime of the zone"); - c->Message(0, "--- #logs set gmsay 20 1 - Would output Quest errors to gmsay"); + c->Message(Chat::White, "--- #logs set [console|file|gmsay] - Sets log settings during the lifetime of the zone"); + c->Message(Chat::White, "--- #logs set gmsay 20 1 - Would output Quest errors to gmsay"); } if (logs_set == 1){ c->Message(Chat::Yellow, "Your Log Settings have been applied"); @@ -11947,10 +11947,10 @@ void command_logs(Client *c, const Seperator *sep){ } } else { - c->Message(0, "#logs usage:"); - c->Message(0, "--- #logs reload_all - Reload all settings in world and all zone processes with what is defined in the database"); - c->Message(0, "--- #logs list_settings - Shows current log settings and categories loaded into the current process' memory"); - c->Message(0, "--- #logs set [console|file|gmsay] - Sets log settings during the lifetime of the zone"); + c->Message(Chat::White, "#logs usage:"); + c->Message(Chat::White, "--- #logs reload_all - Reload all settings in world and all zone processes with what is defined in the database"); + c->Message(Chat::White, "--- #logs list_settings - Shows current log settings and categories loaded into the current process' memory"); + c->Message(Chat::White, "--- #logs set [console|file|gmsay] - Sets log settings during the lifetime of the zone"); } } @@ -11979,24 +11979,24 @@ void command_resetaa_timer(Client *c, const Seperator *sep) { if(sep->IsNumber(1)) { int timer_id = atoi(sep->arg[1]); - c->Message(0, "Reset of timer %i for %s", timer_id, c->GetName()); + c->Message(Chat::White, "Reset of timer %i for %s", timer_id, c->GetName()); c->ResetAlternateAdvancementTimer(timer_id); } else if(!strcasecmp(sep->arg[1], "all")) { - c->Message(0, "Reset all timers for %s", c->GetName()); + c->Message(Chat::White, "Reset all timers for %s", c->GetName()); c->ResetAlternateAdvancementTimers(); } else { - c->Message(0, "usage: #resetaa_timer [all | timer_id]"); + c->Message(Chat::White, "usage: #resetaa_timer [all | timer_id]"); } } void command_reloadaa(Client *c, const Seperator *sep) { - c->Message(0, "Reloading Alternate Advancement Data..."); + c->Message(Chat::White, "Reloading Alternate Advancement Data..."); zone->LoadAlternateAdvancement(); - c->Message(0, "Alternate Advancement Data Reloaded"); + c->Message(Chat::White, "Alternate Advancement Data Reloaded"); entity_list.SendAlternateAdvancementStats(); } @@ -12011,7 +12011,7 @@ void command_hotfix(Client *c, const Seperator *sep) { hotfix_name = "hotfix_"; } - c->Message(0, "Creating and applying hotfix"); + c->Message(Chat::White, "Creating and applying hotfix"); std::thread t1( [c, hotfix_name]() { #ifdef WIN32 @@ -12036,7 +12036,7 @@ void command_hotfix(Client *c, const Seperator *sep) { } worldserver.SendPacket(&pack); - if (c) c->Message(0, "Hotfix applied"); + if (c) c->Message(Chat::White, "Hotfix applied"); }); t1.detach(); @@ -12048,12 +12048,12 @@ void command_load_shared_memory(Client *c, const Seperator *sep) { std::string hotfix_name; if(strcasecmp(hotfix.c_str(), sep->arg[1]) == 0) { - c->Message(0, "Cannot attempt to load this shared memory segment as it is already loaded."); + c->Message(Chat::White, "Cannot attempt to load this shared memory segment as it is already loaded."); return; } hotfix_name = sep->arg[1]; - c->Message(0, "Loading shared memory segment %s", hotfix_name.c_str()); + c->Message(Chat::White, "Loading shared memory segment %s", hotfix_name.c_str()); std::thread t1([c,hotfix_name]() { #ifdef WIN32 if(hotfix_name.length() > 0) { @@ -12069,7 +12069,7 @@ void command_load_shared_memory(Client *c, const Seperator *sep) { if(system(StringFormat("./shared_memory").c_str())); } #endif - c->Message(0, "Shared memory segment finished loading."); + c->Message(Chat::White, "Shared memory segment finished loading."); }); t1.detach(); @@ -12080,7 +12080,7 @@ void command_apply_shared_memory(Client *c, const Seperator *sep) { database.GetVariable("hotfix_name", hotfix); std::string hotfix_name = sep->arg[1]; - c->Message(0, "Applying shared memory segment %s", hotfix_name.c_str()); + c->Message(Chat::White, "Applying shared memory segment %s", hotfix_name.c_str()); database.SetVariable("hotfix_name", hotfix_name); ServerPacket pack(ServerOP_ChangeSharedMem, hotfix_name.length() + 1); @@ -12370,54 +12370,54 @@ void command_network(Client *c, const Seperator *sep) if (!strcasecmp(sep->arg[2], "all")) { - c->Message(0, "max_packet_size: %llu", (uint64_t)opts.daybreak_options.max_packet_size); - c->Message(0, "max_connection_count: %llu", (uint64_t)opts.daybreak_options.max_connection_count); - c->Message(0, "keepalive_delay_ms: %llu", (uint64_t)opts.daybreak_options.keepalive_delay_ms); - c->Message(0, "resend_delay_factor: %.2f", opts.daybreak_options.resend_delay_factor); - c->Message(0, "resend_delay_ms: %llu", (uint64_t)opts.daybreak_options.resend_delay_ms); - c->Message(0, "resend_delay_min: %llu", (uint64_t)opts.daybreak_options.resend_delay_min); - c->Message(0, "resend_delay_max: %llu", (uint64_t)opts.daybreak_options.resend_delay_max); - c->Message(0, "connect_delay_ms: %llu", (uint64_t)opts.daybreak_options.connect_delay_ms); - c->Message(0, "connect_stale_ms: %llu", (uint64_t)opts.daybreak_options.connect_stale_ms); - c->Message(0, "stale_connection_ms: %llu", (uint64_t)opts.daybreak_options.stale_connection_ms); - c->Message(0, "crc_length: %llu", (uint64_t)opts.daybreak_options.crc_length); - c->Message(0, "hold_size: %llu", (uint64_t)opts.daybreak_options.hold_size); - c->Message(0, "hold_length_ms: %llu", (uint64_t)opts.daybreak_options.hold_length_ms); - c->Message(0, "simulated_in_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_in_packet_loss); - c->Message(0, "simulated_out_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_out_packet_loss); - c->Message(0, "tic_rate_hertz: %.2f", opts.daybreak_options.tic_rate_hertz); - c->Message(0, "resend_timeout: %llu", (uint64_t)opts.daybreak_options.resend_timeout); - c->Message(0, "connection_close_time: %llu", (uint64_t)opts.daybreak_options.connection_close_time); - c->Message(0, "encode_passes[0]: %llu", (uint64_t)opts.daybreak_options.encode_passes[0]); - c->Message(0, "encode_passes[1]: %llu", (uint64_t)opts.daybreak_options.encode_passes[1]); - c->Message(0, "port: %llu", (uint64_t)opts.daybreak_options.port); + c->Message(Chat::White, "max_packet_size: %llu", (uint64_t)opts.daybreak_options.max_packet_size); + c->Message(Chat::White, "max_connection_count: %llu", (uint64_t)opts.daybreak_options.max_connection_count); + c->Message(Chat::White, "keepalive_delay_ms: %llu", (uint64_t)opts.daybreak_options.keepalive_delay_ms); + c->Message(Chat::White, "resend_delay_factor: %.2f", opts.daybreak_options.resend_delay_factor); + c->Message(Chat::White, "resend_delay_ms: %llu", (uint64_t)opts.daybreak_options.resend_delay_ms); + c->Message(Chat::White, "resend_delay_min: %llu", (uint64_t)opts.daybreak_options.resend_delay_min); + c->Message(Chat::White, "resend_delay_max: %llu", (uint64_t)opts.daybreak_options.resend_delay_max); + c->Message(Chat::White, "connect_delay_ms: %llu", (uint64_t)opts.daybreak_options.connect_delay_ms); + c->Message(Chat::White, "connect_stale_ms: %llu", (uint64_t)opts.daybreak_options.connect_stale_ms); + c->Message(Chat::White, "stale_connection_ms: %llu", (uint64_t)opts.daybreak_options.stale_connection_ms); + c->Message(Chat::White, "crc_length: %llu", (uint64_t)opts.daybreak_options.crc_length); + c->Message(Chat::White, "hold_size: %llu", (uint64_t)opts.daybreak_options.hold_size); + c->Message(Chat::White, "hold_length_ms: %llu", (uint64_t)opts.daybreak_options.hold_length_ms); + c->Message(Chat::White, "simulated_in_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_in_packet_loss); + c->Message(Chat::White, "simulated_out_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_out_packet_loss); + c->Message(Chat::White, "tic_rate_hertz: %.2f", opts.daybreak_options.tic_rate_hertz); + c->Message(Chat::White, "resend_timeout: %llu", (uint64_t)opts.daybreak_options.resend_timeout); + c->Message(Chat::White, "connection_close_time: %llu", (uint64_t)opts.daybreak_options.connection_close_time); + c->Message(Chat::White, "encode_passes[0]: %llu", (uint64_t)opts.daybreak_options.encode_passes[0]); + c->Message(Chat::White, "encode_passes[1]: %llu", (uint64_t)opts.daybreak_options.encode_passes[1]); + c->Message(Chat::White, "port: %llu", (uint64_t)opts.daybreak_options.port); } else { - c->Message(0, "Unknown get option: %s", sep->arg[2]); - c->Message(0, "Available options:"); + c->Message(Chat::White, "Unknown get option: %s", sep->arg[2]); + c->Message(Chat::White, "Available options:"); //Todo the rest of these when im less lazy. - //c->Message(0, "max_packet_size"); - //c->Message(0, "max_connection_count"); - //c->Message(0, "keepalive_delay_ms"); - //c->Message(0, "resend_delay_factor"); - //c->Message(0, "resend_delay_ms"); - //c->Message(0, "resend_delay_min"); - //c->Message(0, "resend_delay_max"); - //c->Message(0, "connect_delay_ms"); - //c->Message(0, "connect_stale_ms"); - //c->Message(0, "stale_connection_ms"); - //c->Message(0, "crc_length"); - //c->Message(0, "hold_size"); - //c->Message(0, "hold_length_ms"); - //c->Message(0, "simulated_in_packet_loss"); - //c->Message(0, "simulated_out_packet_loss"); - //c->Message(0, "tic_rate_hertz"); - //c->Message(0, "resend_timeout"); - //c->Message(0, "connection_close_time"); - //c->Message(0, "encode_passes[0]"); - //c->Message(0, "encode_passes[1]"); - //c->Message(0, "port"); - c->Message(0, "all"); + //c->Message(Chat::White, "max_packet_size"); + //c->Message(Chat::White, "max_connection_count"); + //c->Message(Chat::White, "keepalive_delay_ms"); + //c->Message(Chat::White, "resend_delay_factor"); + //c->Message(Chat::White, "resend_delay_ms"); + //c->Message(Chat::White, "resend_delay_min"); + //c->Message(Chat::White, "resend_delay_max"); + //c->Message(Chat::White, "connect_delay_ms"); + //c->Message(Chat::White, "connect_stale_ms"); + //c->Message(Chat::White, "stale_connection_ms"); + //c->Message(Chat::White, "crc_length"); + //c->Message(Chat::White, "hold_size"); + //c->Message(Chat::White, "hold_length_ms"); + //c->Message(Chat::White, "simulated_in_packet_loss"); + //c->Message(Chat::White, "simulated_out_packet_loss"); + //c->Message(Chat::White, "tic_rate_hertz"); + //c->Message(Chat::White, "resend_timeout"); + //c->Message(Chat::White, "connection_close_time"); + //c->Message(Chat::White, "encode_passes[0]"); + //c->Message(Chat::White, "encode_passes[1]"); + //c->Message(Chat::White, "port"); + c->Message(Chat::White, "all"); } } else if (!strcasecmp(sep->arg[1], "setopt")) @@ -12428,7 +12428,7 @@ void command_network(Client *c, const Seperator *sep) if (!strcasecmp(sep->arg[3], "")) { - c->Message(0, "Missing value for set"); + c->Message(Chat::White, "Missing value for set"); return; } @@ -12509,30 +12509,30 @@ void command_network(Client *c, const Seperator *sep) manager->SetOptions(opts); } else { - c->Message(0, "Unknown set option: %s", sep->arg[2]); - c->Message(0, "Available options:"); - c->Message(0, "max_connection_count"); - c->Message(0, "keepalive_delay_ms"); - c->Message(0, "resend_delay_factor"); - c->Message(0, "resend_delay_ms"); - c->Message(0, "resend_delay_min"); - c->Message(0, "resend_delay_max"); - c->Message(0, "connect_delay_ms"); - c->Message(0, "connect_stale_ms"); - c->Message(0, "stale_connection_ms"); - c->Message(0, "hold_size"); - c->Message(0, "hold_length_ms"); - c->Message(0, "simulated_in_packet_loss"); - c->Message(0, "simulated_out_packet_loss"); - c->Message(0, "resend_timeout"); - c->Message(0, "connection_close_time"); + c->Message(Chat::White, "Unknown set option: %s", sep->arg[2]); + c->Message(Chat::White, "Available options:"); + c->Message(Chat::White, "max_connection_count"); + c->Message(Chat::White, "keepalive_delay_ms"); + c->Message(Chat::White, "resend_delay_factor"); + c->Message(Chat::White, "resend_delay_ms"); + c->Message(Chat::White, "resend_delay_min"); + c->Message(Chat::White, "resend_delay_max"); + c->Message(Chat::White, "connect_delay_ms"); + c->Message(Chat::White, "connect_stale_ms"); + c->Message(Chat::White, "stale_connection_ms"); + c->Message(Chat::White, "hold_size"); + c->Message(Chat::White, "hold_length_ms"); + c->Message(Chat::White, "simulated_in_packet_loss"); + c->Message(Chat::White, "simulated_out_packet_loss"); + c->Message(Chat::White, "resend_timeout"); + c->Message(Chat::White, "connection_close_time"); } } else { - c->Message(0, "Unknown command: %s", sep->arg[1]); - c->Message(0, "Network commands avail:"); - c->Message(0, "getopt optname - Retrieve the current option value set."); - c->Message(0, "setopt optname - Set the current option allowed."); + c->Message(Chat::White, "Unknown command: %s", sep->arg[1]); + c->Message(Chat::White, "Network commands avail:"); + c->Message(Chat::White, "getopt optname - Retrieve the current option value set."); + c->Message(Chat::White, "setopt optname - Set the current option allowed."); } } diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 2dc2872ec..e3a5eb80e 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -1371,7 +1371,7 @@ void Corpse::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) { void Corpse::QueryLoot(Client* to) { int x = 0, y = 0; // x = visible items, y = total items - to->Message(0, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper); + to->Message(Chat::White, "Coin: %ip, %ig, %is, %ic", platinum, gold, silver, copper); ItemList::iterator cur,end; cur = itemlist.begin(); @@ -1405,19 +1405,19 @@ void Corpse::QueryLoot(Client* to) { const EQEmu::ItemData* item = database.GetItem(sitem->item_id); if (item) - to->Message(0, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges); + to->Message(Chat::White, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges); else - to->Message(0, "Error: 0x%04x", sitem->item_id); + to->Message(Chat::White, "Error: 0x%04x", sitem->item_id); y++; } } if (IsPlayerCorpse()) { - to->Message(0, "%i visible %s (%i total) on %s (DBID: %i).", x, x==1?"item":"items", y, this->GetName(), this->GetCorpseDBID()); + to->Message(Chat::White, "%i visible %s (%i total) on %s (DBID: %i).", x, x==1?"item":"items", y, this->GetName(), this->GetCorpseDBID()); } else { - to->Message(0, "%i %s on %s.", y, y==1?"item":"items", this->GetName()); + to->Message(Chat::White, "%i %s on %s.", y, y==1?"item":"items", this->GetName()); } } @@ -1434,7 +1434,7 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) { is_corpse_changed = true; } else { - client->Message(0, "Corpse is too far away."); + client->Message(Chat::White, "Corpse is too far away."); return false; } } @@ -1449,14 +1449,14 @@ bool Corpse::Summon(Client* client, bool spell, bool CheckDistance) { is_corpse_changed = true; } else { - client->Message(0, "Corpse is too far away."); + client->Message(Chat::White, "Corpse is too far away."); return false; } consented = true; } } if(!consented) { - client->Message(0, "You do not have permission to move this corpse."); + client->Message(Chat::White, "You do not have permission to move this corpse."); return false; } } diff --git a/zone/entity.cpp b/zone/entity.cpp index e52935ded..9003dc7f6 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2902,15 +2902,15 @@ void EntityList::ListNPCCorpses(Client *client) uint32 x = 0; auto it = corpse_list.begin(); - client->Message(0, "NPC Corpses in the zone:"); + client->Message(Chat::White, "NPC Corpses in the zone:"); while (it != corpse_list.end()) { if (it->second->IsNPCCorpse()) { - client->Message(0, " %5d: %s", it->first, it->second->GetName()); + client->Message(Chat::White, " %5d: %s", it->first, it->second->GetName()); x++; } ++it; } - client->Message(0, "%d npc corpses listed.", x); + client->Message(Chat::White, "%d npc corpses listed.", x); } void EntityList::ListPlayerCorpses(Client *client) @@ -2918,15 +2918,15 @@ void EntityList::ListPlayerCorpses(Client *client) uint32 x = 0; auto it = corpse_list.begin(); - client->Message(0, "Player Corpses in the zone:"); + client->Message(Chat::White, "Player Corpses in the zone:"); while (it != corpse_list.end()) { if (it->second->IsPlayerCorpse()) { - client->Message(0, " %5d: %s", it->first, it->second->GetName()); + client->Message(Chat::White, " %5d: %s", it->first, it->second->GetName()); x++; } ++it; } - client->Message(0, "%d player corpses listed.", x); + client->Message(Chat::White, "%d player corpses listed.", x); } // returns the number of corpses deleted. A negative number indicates an error code. diff --git a/zone/global_loot_manager.cpp b/zone/global_loot_manager.cpp index 8e990c0ac..ccdf88840 100644 --- a/zone/global_loot_manager.cpp +++ b/zone/global_loot_manager.cpp @@ -21,14 +21,14 @@ std::vector GlobalLootManager::GetGlobalLootTables(NPC *mob) const void GlobalLootManager::ShowZoneGlobalLoot(Client *to) const { for (auto &e : m_entries) - to->Message(0, " %s : %d table %d", e.GetDescription().c_str(), e.GetID(), e.GetLootTableID()); + to->Message(Chat::White, " %s : %d table %d", e.GetDescription().c_str(), e.GetID(), e.GetLootTableID()); } void GlobalLootManager::ShowNPCGlobalLoot(Client *to, NPC *who) const { for (auto &e : m_entries) { if (e.PassesRules(who)) - to->Message(0, " %s : %d table %d", e.GetDescription().c_str(), e.GetID(), e.GetLootTableID()); + to->Message(Chat::White, " %s : %d table %d", e.GetDescription().c_str(), e.GetID(), e.GetLootTableID()); } } diff --git a/zone/groups.cpp b/zone/groups.cpp index a4104b26a..cef37fbda 100644 --- a/zone/groups.cpp +++ b/zone/groups.cpp @@ -199,7 +199,7 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu Client *c = members[i]->CastToClient(); //I could not get MoneyOnCorpse to work, so we use this c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true); - c->Message(2, msg.c_str()); + c->Message(Chat::Green, msg.c_str()); } } } @@ -1680,9 +1680,9 @@ void Group::NotifyMainTank(Client *c, uint8 toggle) if (c->ClientVersion() < EQEmu::versions::ClientVersion::SoD) { if(toggle) - c->Message(0, "%s is now Main Tank.", MainTankName.c_str()); + c->Message(Chat::White, "%s is now Main Tank.", MainTankName.c_str()); else - c->Message(0, "%s is no longer Main Tank.", MainTankName.c_str()); + c->Message(Chat::White, "%s is no longer Main Tank.", MainTankName.c_str()); } else { @@ -1775,9 +1775,9 @@ void Group::NotifyPuller(Client *c, uint8 toggle) if (c->ClientVersion() < EQEmu::versions::ClientVersion::SoD) { if(toggle) - c->Message(0, "%s is now Puller.", PullerName.c_str()); + c->Message(Chat::White, "%s is now Puller.", PullerName.c_str()); else - c->Message(0, "%s is no longer Puller.", PullerName.c_str()); + c->Message(Chat::White, "%s is no longer Puller.", PullerName.c_str()); } else { diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 43157ed2d..eacfcb474 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -189,7 +189,7 @@ uint8 *ZoneGuildManager::MakeGuildMembers(uint32 guild_id, const char *prefix_na } void ZoneGuildManager::ListGuilds(Client *c) const { - c->Message(0, "Listing guilds on the server:"); + c->Message(Chat::White, "Listing guilds on the server:"); char leadername[64]; std::map::const_iterator cur, end; cur = m_guilds.begin(); @@ -199,12 +199,12 @@ void ZoneGuildManager::ListGuilds(Client *c) const { leadername[0] = '\0'; database.GetCharName(cur->second->leader_char_id, leadername); if (leadername[0] == '\0') - c->Message(0, " Guild #%i <%s>", cur->first, cur->second->name.c_str()); + c->Message(Chat::White, " Guild #%i <%s>", cur->first, cur->second->name.c_str()); else - c->Message(0, " Guild #%i <%s> Leader: %s", cur->first, cur->second->name.c_str(), leadername); + c->Message(Chat::White, " Guild #%i <%s> Leader: %s", cur->first, cur->second->name.c_str(), leadername); r++; } - c->Message(0, "%i guilds listed.", r); + c->Message(Chat::White, "%i guilds listed.", r); } @@ -212,17 +212,17 @@ void ZoneGuildManager::DescribeGuild(Client *c, uint32 guild_id) const { std::map::const_iterator res; res = m_guilds.find(guild_id); if(res == m_guilds.end()) { - c->Message(0, "Guild %d not found.", guild_id); + c->Message(Chat::White, "Guild %d not found.", guild_id); return; } const GuildInfo *info = res->second; - c->Message(0, "Guild info DB# %i <%s>", guild_id, info->name.c_str()); + c->Message(Chat::White, "Guild info DB# %i <%s>", guild_id, info->name.c_str()); char leadername[64]; database.GetCharName(info->leader_char_id, leadername); - c->Message(0, "Guild Leader: %s", leadername); + c->Message(Chat::White, "Guild Leader: %s", leadername); char permbuffer[256]; uint8 i; @@ -232,8 +232,8 @@ void ZoneGuildManager::DescribeGuild(Client *c, uint32 guild_id) const { for(r = 0; r < _MaxGuildAction; r++) permptr += sprintf(permptr, " %s: %c", GuildActionNames[r], info->ranks[i].permissions[r]?'Y':'N'); - c->Message(0, "Rank %i: %s", i, info->ranks[i].name.c_str()); - c->Message(0, "Permissions: %s", permbuffer); + c->Message(Chat::White, "Rank %i: %s", i, info->ranks[i].name.c_str()); + c->Message(Chat::White, "Permissions: %s", permbuffer); } } @@ -537,14 +537,14 @@ void ZoneGuildManager::AddMemberApproval(uint32 refid,Client* name) if(tmp != 0) { if(!tmp->AddMemberApproval(name)) - name->Message(0,"Unable to add to list."); + name->Message(Chat::White,"Unable to add to list."); else { - name->Message(0,"Added to list."); + name->Message(Chat::White,"Added to list."); } } else - name->Message(0,"Unable to find guild reference id."); + name->Message(Chat::White,"Unable to find guild reference id."); } ZoneGuildManager::~ZoneGuildManager() @@ -1397,7 +1397,7 @@ bool GuildApproval::ProcessApproval() if(deletion_timer->Check() || !owner) { if(owner) - owner->Message(0,"You took too long! Your guild request has been deleted."); + owner->Message(Chat::White,"You took too long! Your guild request has been deleted."); return false; } @@ -1414,7 +1414,7 @@ GuildApproval::GuildApproval(const char* guildname, Client* owner,uint32 id) this->owner = owner; this->refid = id; if(owner) - owner->Message(0,"You can now start getting your guild approved, tell your %i members to #guildapprove %i, you have 30 minutes to create your guild.",tmp,GetID()); + owner->Message(Chat::White,"You can now start getting your guild approved, tell your %i members to #guildapprove %i, you have 30 minutes to create your guild.",tmp,GetID()); for(int i=0;iMessage(0,"%i: %s",i,members[i]->GetName()); + requestee->Message(Chat::White,"%i: %s",i,members[i]->GetName()); } } @@ -1484,8 +1484,8 @@ void GuildApproval::GuildApproved() { if(members[i]) { - owner->Message(0, "%s",members[i]->GetName()); - owner->Message(0, "%i",members[i]->CharacterID()); + owner->Message(Chat::White, "%s",members[i]->GetName()); + owner->Message(Chat::White, "%i",members[i]->CharacterID()); guild_mgr.SetGuild(members[i]->CharacterID(),tmpeq,0); size_t len = MBUFFER - strlen(gmembers)+1; strncat(gmembers," ",len); @@ -1521,7 +1521,7 @@ void GuildApproval::GuildApproved() memcpy(pack->pBuffer, &tmpeq, 4); worldserver.SendPacket(pack); safe_delete(pack); - owner->Message(0, "Your guild was created."); + owner->Message(Chat::White, "Your guild was created."); owner = 0; } diff --git a/zone/hate_list.cpp b/zone/hate_list.cpp index 242a4c8e3..478c9ac50 100644 --- a/zone/hate_list.cpp +++ b/zone/hate_list.cpp @@ -608,7 +608,7 @@ void HateList::PrintHateListToClient(Client *c) while (iterator != list.end()) { struct_HateList *e = (*iterator); - c->Message(0, "- name: %s, damage: %d, hate: %d", + c->Message(Chat::White, "- name: %s, damage: %d, hate: %d", (e->entity_on_hatelist && e->entity_on_hatelist->GetName()) ? e->entity_on_hatelist->GetName() : "(null)", e->hatelist_damage, e->stored_hate_amount); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 94ca78007..500663491 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -3397,7 +3397,7 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool Log(Logs::General, Logs::Error, "Client::InterrogateInventory() called for %s by %s with an error state of %s", GetName(), requester->GetName(), (error ? "TRUE" : "FALSE")); } if (!silent) { - requester->Message(1, "--- Inventory Interrogation Report for %s (requested by: %s, error state: %s) ---", GetName(), requester->GetName(), (error ? "TRUE" : "FALSE")); + requester->Message(Chat::Default, "--- Inventory Interrogation Report for %s (requested by: %s, error state: %s) ---", GetName(), requester->GetName(), (error ? "TRUE" : "FALSE")); } // call InterrogateInventory_ for report @@ -3419,8 +3419,8 @@ bool Client::InterrogateInventory(Client* requester, bool log, bool silent, bool Log(Logs::Detail, Logs::None, "[CLIENT] Client::InterrogateInventory() -- End"); } if (!silent) { - requester->Message(1, "Target interrogation flag: %s", (GetInterrogateInvState() ? "TRUE" : "FALSE")); - requester->Message(1, "--- End of Interrogation Report ---"); + requester->Message(Chat::Default, "Target interrogation flag: %s", (GetInterrogateInvState() ? "TRUE" : "FALSE")); + requester->Message(Chat::Default, "--- End of Interrogation Report ---"); } instmap.clear(); diff --git a/zone/mob.cpp b/zone/mob.cpp index a5d7ae261..f9665af32 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1551,39 +1551,39 @@ void Mob::ShowStats(Client* client) } else if (IsCorpse()) { if (IsPlayerCorpse()) { - client->Message(0, " CharID: %i PlayerCorpse: %i", CastToCorpse()->GetCharID(), CastToCorpse()->GetCorpseDBID()); + client->Message(Chat::White, " CharID: %i PlayerCorpse: %i", CastToCorpse()->GetCharID(), CastToCorpse()->GetCorpseDBID()); } else { - client->Message(0, " NPCCorpse", GetID()); + client->Message(Chat::White, " NPCCorpse", GetID()); } } else { - client->Message(0, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), ACSum(), GetClass(), GetSize(), GetHaste()); - client->Message(0, " HP: %i Max HP: %i",GetHP(), GetMaxHP()); - client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana()); - client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus()); - client->Message(0, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); - client->Message(0, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR()); - client->Message(0, " Race: %i BaseRace: %i Texture: %i HelmTexture: %i Gender: %i BaseGender: %i", GetRace(), GetBaseRace(), GetTexture(), GetHelmTexture(), GetGender(), GetBaseGender()); + client->Message(Chat::White, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), ACSum(), GetClass(), GetSize(), GetHaste()); + client->Message(Chat::White, " HP: %i Max HP: %i",GetHP(), GetMaxHP()); + client->Message(Chat::White, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana()); + client->Message(Chat::White, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus()); + client->Message(Chat::White, " STR: %i STA: %i DEX: %i AGI: %i INT: %i WIS: %i CHA: %i", GetSTR(), GetSTA(), GetDEX(), GetAGI(), GetINT(), GetWIS(), GetCHA()); + client->Message(Chat::White, " MR: %i PR: %i FR: %i CR: %i DR: %i Corruption: %i PhR: %i", GetMR(), GetPR(), GetFR(), GetCR(), GetDR(), GetCorrup(), GetPhR()); + client->Message(Chat::White, " Race: %i BaseRace: %i Texture: %i HelmTexture: %i Gender: %i BaseGender: %i", GetRace(), GetBaseRace(), GetTexture(), GetHelmTexture(), GetGender(), GetBaseGender()); if (client->Admin() >= 100) - client->Message(0, " EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); + client->Message(Chat::White, " EntityID: %i PetID: %i OwnerID: %i AIControlled: %i Targetted: %i", GetID(), GetPetID(), GetOwnerID(), IsAIControlled(), targeted); if (IsNPC()) { NPC *n = CastToNPC(); uint32 spawngroupid = 0; if(n->respawn2 != 0) spawngroupid = n->respawn2->SpawnGroupID(); - client->Message(0, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID()); - client->Message(0, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %.3f Walkspeed: %.3f", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), static_cast(0.025f * n->GetRunspeed()), static_cast(0.025f * n->GetWalkspeed())); + client->Message(Chat::White, " NPCID: %u SpawnGroupID: %u Grid: %i LootTable: %u FactionID: %i SpellsID: %u ", GetNPCTypeID(),spawngroupid, n->GetGrid(), n->GetLoottableID(), n->GetNPCFactionID(), n->GetNPCSpellsID()); + client->Message(Chat::White, " Accuracy: %i MerchantID: %i EmoteID: %i Runspeed: %.3f Walkspeed: %.3f", n->GetAccuracyRating(), n->MerchantType, n->GetEmoteID(), static_cast(0.025f * n->GetRunspeed()), static_cast(0.025f * n->GetWalkspeed())); n->QueryLoot(client); } if (IsAIControlled()) { - client->Message(0, " AggroRange: %1.0f AssistRange: %1.0f", GetAggroRange(), GetAssistRange()); + client->Message(Chat::White, " AggroRange: %1.0f AssistRange: %1.0f", GetAggroRange(), GetAssistRange()); } - client->Message(0, " compute_tohit: %i TotalToHit: %i", compute_tohit(EQEmu::skills::SkillHandtoHand), GetTotalToHit(EQEmu::skills::SkillHandtoHand, 0)); - client->Message(0, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense()); - client->Message(0, " offense: %i mitigation ac: %i", offense(EQEmu::skills::SkillHandtoHand), GetMitigationAC()); + client->Message(Chat::White, " compute_tohit: %i TotalToHit: %i", compute_tohit(EQEmu::skills::SkillHandtoHand), GetTotalToHit(EQEmu::skills::SkillHandtoHand, 0)); + client->Message(Chat::White, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense()); + client->Message(Chat::White, " offense: %i mitigation ac: %i", offense(EQEmu::skills::SkillHandtoHand), GetMitigationAC()); } } @@ -1620,33 +1620,33 @@ void Mob::DoAnim(const int animnum, int type, bool ackreq, eqFilterType filter) void Mob::ShowBuffs(Client* client) { if(SPDAT_RECORDS <= 0) return; - client->Message(0, "Buffs on: %s", this->GetName()); + client->Message(Chat::White, "Buffs on: %s", this->GetName()); uint32 i; uint32 buff_count = GetMaxTotalSlots(); for (i=0; i < buff_count; i++) { if (buffs[i].spellid != SPELL_UNKNOWN) { if (spells[buffs[i].spellid].buffdurationformula == DF_Permanent) - client->Message(0, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); + client->Message(Chat::White, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); else - client->Message(0, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); + client->Message(Chat::White, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); } } if (IsClient()){ - client->Message(0, "itembonuses:"); - client->Message(0, "Atk:%i Ac:%i HP(%i):%i Mana:%i", itembonuses.ATK, itembonuses.AC, itembonuses.HPRegen, itembonuses.HP, itembonuses.Mana); - client->Message(0, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", + client->Message(Chat::White, "itembonuses:"); + client->Message(Chat::White, "Atk:%i Ac:%i HP(%i):%i Mana:%i", itembonuses.ATK, itembonuses.AC, itembonuses.HPRegen, itembonuses.HP, itembonuses.Mana); + client->Message(Chat::White, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", itembonuses.STR,itembonuses.STA,itembonuses.DEX,itembonuses.AGI,itembonuses.INT,itembonuses.WIS,itembonuses.CHA); - client->Message(0, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", + client->Message(Chat::White, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", itembonuses.MR,itembonuses.FR,itembonuses.CR,itembonuses.PR,itembonuses.DR); - client->Message(0, "DmgShield:%i Haste:%i", itembonuses.DamageShield, itembonuses.haste ); - client->Message(0, "spellbonuses:"); - client->Message(0, "Atk:%i Ac:%i HP(%i):%i Mana:%i", spellbonuses.ATK, spellbonuses.AC, spellbonuses.HPRegen, spellbonuses.HP, spellbonuses.Mana); - client->Message(0, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", + client->Message(Chat::White, "DmgShield:%i Haste:%i", itembonuses.DamageShield, itembonuses.haste ); + client->Message(Chat::White, "spellbonuses:"); + client->Message(Chat::White, "Atk:%i Ac:%i HP(%i):%i Mana:%i", spellbonuses.ATK, spellbonuses.AC, spellbonuses.HPRegen, spellbonuses.HP, spellbonuses.Mana); + client->Message(Chat::White, "Str:%i Sta:%i Dex:%i Agi:%i Int:%i Wis:%i Cha:%i", spellbonuses.STR,spellbonuses.STA,spellbonuses.DEX,spellbonuses.AGI,spellbonuses.INT,spellbonuses.WIS,spellbonuses.CHA); - client->Message(0, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", + client->Message(Chat::White, "SvMagic:%i SvFire:%i SvCold:%i SvPoison:%i SvDisease:%i", spellbonuses.MR,spellbonuses.FR,spellbonuses.CR,spellbonuses.PR,spellbonuses.DR); - client->Message(0, "DmgShield:%i Haste:%i", spellbonuses.DamageShield, spellbonuses.haste ); + client->Message(Chat::White, "DmgShield:%i Haste:%i", spellbonuses.DamageShield, spellbonuses.haste ); } } @@ -1654,15 +1654,15 @@ void Mob::ShowBuffList(Client* client) { if(SPDAT_RECORDS <= 0) return; - client->Message(0, "Buffs on: %s", this->GetCleanName()); + client->Message(Chat::White, "Buffs on: %s", this->GetCleanName()); uint32 i; uint32 buff_count = GetMaxTotalSlots(); for (i = 0; i < buff_count; i++) { if (buffs[i].spellid != SPELL_UNKNOWN) { if (spells[buffs[i].spellid].buffdurationformula == DF_Permanent) - client->Message(0, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); + client->Message(Chat::White, " %i: %s: Permanent", i, spells[buffs[i].spellid].name); else - client->Message(0, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); + client->Message(Chat::White, " %i: %s: %i tics left", i, spells[buffs[i].spellid].name, buffs[i].ticsremaining); } } } diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 6b7218417..31a0fcb40 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -2758,7 +2758,7 @@ void NPC::AISpellsList(Client *c) return; for (auto it = AIspells.begin(); it != AIspells.end(); ++it) - c->Message(0, "%s (%d): Type %d, Priority %d, Recast Delay %d, Resist Adjust %d, Min HP %d, Max HP %d", + c->Message(Chat::White, "%s (%d): Type %d, Priority %d, Recast Delay %d, Resist Adjust %d, Min HP %d, Max HP %d", spells[it->spellid].name, it->spellid, it->type, it->priority, it->recast_delay, it->resist_adjust, it->min_hp, it->max_hp); return; diff --git a/zone/mob_info.cpp b/zone/mob_info.cpp index 174a00330..8cf486dea 100644 --- a/zone/mob_info.cpp +++ b/zone/mob_info.cpp @@ -624,7 +624,7 @@ inline void NPCCommandsMenu(Client* client, NPC* npc) if (menu_commands.length() > 0) { std::string dev_menu = "[" + EQEmu::SayLinkEngine::GenerateQuestSaylink("#devtools", false, "DevTools") + "] ";; - client->Message(0, "| %s [Show Commands] %s", dev_menu.c_str(), menu_commands.c_str()); + client->Message(Chat::White, "| %s [Show Commands] %s", dev_menu.c_str(), menu_commands.c_str()); } } diff --git a/zone/npc.cpp b/zone/npc.cpp index 30bf0b614..ebbf5397f 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -611,7 +611,7 @@ void NPC::ClearItemList() { void NPC::QueryLoot(Client* to) { - to->Message(0, "| # Current Loot (%s) LootTableID: %i", GetName(), GetLoottableID()); + to->Message(Chat::White, "| # Current Loot (%s) LootTableID: %i", GetName(), GetLoottableID()); int item_count = 0; for (auto cur = itemlist.begin(); cur != itemlist.end(); ++cur, ++item_count) { @@ -639,7 +639,7 @@ void NPC::QueryLoot(Client* to) ); } - to->Message(0, "| %i Platinum %i Gold %i Silver %i Copper", platinum, gold, silver, copper); + to->Message(Chat::White, "| %i Platinum %i Gold %i Silver %i Copper", platinum, gold, silver, copper); } void NPC::AddCash(uint16 in_copper, uint16 in_silver, uint16 in_gold, uint16 in_platinum) { @@ -1190,17 +1190,17 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* if (client) { // Notify client of spawn data - client->Message(0, "New spawn:"); - client->Message(0, "Name: %s", npc->name); - client->Message(0, "Race: %u", npc->race); - client->Message(0, "Level: %u", npc->level); - client->Message(0, "Material: %u", npc->texture); - client->Message(0, "Current/Max HP: %i", npc->max_hp); - client->Message(0, "Gender: %u", npc->gender); - client->Message(0, "Class: %u", npc->class_); - client->Message(0, "Weapon Item Number: %u/%u", npc->d_melee_texture1, npc->d_melee_texture2); - client->Message(0, "MerchantID: %u", npc->MerchantType); - client->Message(0, "Bodytype: %u", npc->bodytype); + client->Message(Chat::White, "New spawn:"); + client->Message(Chat::White, "Name: %s", npc->name); + client->Message(Chat::White, "Race: %u", npc->race); + client->Message(Chat::White, "Level: %u", npc->level); + client->Message(Chat::White, "Material: %u", npc->texture); + client->Message(Chat::White, "Current/Max HP: %i", npc->max_hp); + client->Message(Chat::White, "Gender: %u", npc->gender); + client->Message(Chat::White, "Class: %u", npc->class_); + client->Message(Chat::White, "Weapon Item Number: %u/%u", npc->d_melee_texture1, npc->d_melee_texture2); + client->Message(Chat::White, "MerchantID: %u", npc->MerchantType); + client->Message(Chat::White, "Bodytype: %u", npc->bodytype); } return npc; @@ -1471,7 +1471,7 @@ uint32 ZoneDatabase::AddNPCTypes(const char *zone, uint32 zone_version, Client * npc_type_id = results.LastInsertedID(); if (client) - client->Message(0, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id); + client->Message(Chat::White, "%s npc_type ID %i created successfully!", numberlessName, npc_type_id); return 1; } @@ -1694,7 +1694,7 @@ void NPC::PickPocket(Client* thief) return; } - thief->Message(0, "This target's pockets are empty"); + thief->Message(Chat::White, "This target's pockets are empty"); thief->SendPickPocketResponse(this, 0, PickPocketFailed); } diff --git a/zone/object.cpp b/zone/object.cpp index 4306c6642..241d3a3f1 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -572,7 +572,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object) if (sender->ClientVersion() >= EQEmu::versions::ClientVersion::RoF) { coa->drop_id = 0xFFFFFFFF; - sender->Message(0, "Someone else is using that. Try again later."); + sender->Message(Chat::White, "Someone else is using that. Try again later."); } } diff --git a/zone/pathfinder_nav_mesh.cpp b/zone/pathfinder_nav_mesh.cpp index 090afa920..262d7a923 100644 --- a/zone/pathfinder_nav_mesh.cpp +++ b/zone/pathfinder_nav_mesh.cpp @@ -355,7 +355,7 @@ void PathfinderNavmesh::DebugCommand(Client *c, const Seperator *sep) { if (sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "#path show: Plots a path from the user to their target."); + c->Message(Chat::White, "#path show: Plots a path from the user to their target."); return; } diff --git a/zone/pathfinder_waypoint.cpp b/zone/pathfinder_waypoint.cpp index 58ad5afea..83d924499 100644 --- a/zone/pathfinder_waypoint.cpp +++ b/zone/pathfinder_waypoint.cpp @@ -200,9 +200,9 @@ void PathfinderWaypoint::DebugCommand(Client *c, const Seperator *sep) { if(sep->arg[1][0] == '\0' || !strcasecmp(sep->arg[1], "help")) { - c->Message(0, "Syntax: #path shownodes: Spawns a npc to represent every npc node."); - c->Message(0, "#path show: Plots a path from the user to their target."); - c->Message(0, "#path info node_id: Gives information about node info (requires shownode target)."); + c->Message(Chat::White, "Syntax: #path shownodes: Spawns a npc to represent every npc node."); + c->Message(Chat::White, "#path show: Plots a path from the user to their target."); + c->Message(Chat::White, "#path info node_id: Gives information about node info (requires shownode target)."); return; } @@ -425,11 +425,11 @@ void PathfinderWaypoint::NodeInfo(Client *c) return; } - c->Message(0, "Pathing node: %i at (%.2f, %.2f, %.2f) with bestz %.2f", + c->Message(Chat::White, "Pathing node: %i at (%.2f, %.2f, %.2f) with bestz %.2f", node->id, node->v.x, node->v.y, node->v.z, node->bestz); for (auto &edge : node->edges) { - c->Message(0, "id: %i, distance: %.2f, door id: %i, is teleport: %i", + c->Message(Chat::White, "id: %i, distance: %.2f, door id: %i, is teleport: %i", edge.first, edge.second.distance, edge.second.door_id, diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index cc19c59fd..9c8898b2e 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1097,7 +1097,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { initiator->GetPP().disciplines.values[r] = spell_id_; database.SaveCharacterDisc(char_id, r, spell_id_); change = true; - initiator->Message(0, "You have learned a new discipline!"); + initiator->Message(Chat::White, "You have learned a new discipline!"); ++count; // success counter } break; // continue the 1st loop @@ -1109,7 +1109,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { initiator->GetPP().disciplines.values[r] = spell_id_; database.SaveCharacterDisc(char_id, r, spell_id_); change = true; - initiator->Message(0, "You have learned a new discipline!"); + initiator->Message(Chat::White, "You have learned a new discipline!"); ++count; } break; @@ -1118,7 +1118,7 @@ uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) { initiator->GetPP().disciplines.values[r] = spell_id_; database.SaveCharacterDisc(char_id, r, spell_id_); change = true;; - initiator->Message(0, "You have learned a new discipline!"); + initiator->Message(Chat::White, "You have learned a new discipline!"); ++count; // success counter break; // continue the 1st loop } @@ -1411,7 +1411,7 @@ void QuestManager::itemlink(int item_id) { linker.SetLinkType(EQEmu::saylink::SayLinkItemData); linker.SetItemData(item); - initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), linker.GenerateLink().c_str()); + initiator->Message(Chat::White, "%s tells you, %s", owner->GetCleanName(), linker.GenerateLink().c_str()); } } @@ -2171,11 +2171,11 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level std::string test_name = name; bool available_flag = false; if(!database.botdb.QueryNameAvailablity(test_name, available_flag)) { - initiator->Message(0, "%s for '%s'", BotDatabase::fail::QueryNameAvailablity(), (char*)name); + initiator->Message(Chat::White, "%s for '%s'", BotDatabase::fail::QueryNameAvailablity(), (char*)name); return false; } if (!available_flag) { - initiator->Message(0, "The name %s is already being used or is invalid. Please choose a different name.", (char*)name); + initiator->Message(Chat::White, "The name %s is already being used or is invalid. Please choose a different name.", (char*)name); return false; } @@ -2184,23 +2184,23 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level if(NewBot) { if(!NewBot->IsValidRaceClassCombo()) { - initiator->Message(0, "That Race/Class combination cannot be created."); + initiator->Message(Chat::White, "That Race/Class combination cannot be created."); return false; } if(!NewBot->IsValidName()) { - initiator->Message(0, "%s has invalid characters. You can use only the A-Z, a-z and _ characters in a bot name.", NewBot->GetCleanName()); + initiator->Message(Chat::White, "%s has invalid characters. You can use only the A-Z, a-z and _ characters in a bot name.", NewBot->GetCleanName()); return false; } // Now that all validation is complete, we can save our newly created bot if(!NewBot->Save()) { - initiator->Message(0, "Unable to save %s as a bot.", NewBot->GetCleanName()); + initiator->Message(Chat::White, "Unable to save %s as a bot.", NewBot->GetCleanName()); } else { - initiator->Message(0, "%s saved as bot %u.", NewBot->GetCleanName(), NewBot->GetBotID()); + initiator->Message(Chat::White, "%s saved as bot %u.", NewBot->GetCleanName(), NewBot->GetBotID()); return true; } } diff --git a/zone/raids.cpp b/zone/raids.cpp index 51fd2296f..9b5485f40 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -813,7 +813,7 @@ void Raid::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum //I could not get MoneyOnCorpse to work, so we use this members[i].member->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true); - members[i].member->Message(2, msg.c_str()); + members[i].member->Message(Chat::Green, msg.c_str()); } } } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 3940834b8..cc0ea1b3b 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -551,7 +551,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) { if (bIsBehind || bCanFrontalBS || (IsNPC() && CanFacestab())) { // Player is behind other OR can do Frontal Backstab if (bCanFrontalBS && IsClient()) // I don't think there is any message ... - CastToClient()->Message(0,"Your fierce attack is executed with such grace, your target did not see it coming!"); + CastToClient()->Message(Chat::White,"Your fierce attack is executed with such grace, your target did not see it coming!"); RogueBackstab(other,false,ReuseTime); if (level > 54) { diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 1f8acfa2f..6286f9c51 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -387,7 +387,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove TryTriggerOnValueAmount(false, true); #ifdef SPELL_EFFECT_SPAM if (caster) - caster->Message(0, "You have gained %+i mana!", effect_value); + caster->Message(Chat::White, "You have gained %+i mana!", effect_value); #endif } } @@ -745,19 +745,19 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove WipeHateList(); if (IsClient() && caster->IsClient()) { - caster->Message(0, "Unable to cast charm on a fellow player."); + caster->Message(Chat::White, "Unable to cast charm on a fellow player."); BuffFadeByEffect(SE_Charm); break; } else if(IsCorpse()) { - caster->Message(0, "Unable to cast charm on a corpse."); + caster->Message(Chat::White, "Unable to cast charm on a corpse."); BuffFadeByEffect(SE_Charm); break; } else if(caster->GetPet() != nullptr && caster->IsClient()) { - caster->Message(0, "You cannot charm something when you already have a pet."); + caster->Message(Chat::White, "You cannot charm something when you already have a pet."); BuffFadeByEffect(SE_Charm); break; } else if(GetOwner()) { - caster->Message(0, "You cannot charm someone else's pet!"); + caster->Message(Chat::White, "You cannot charm someone else's pet!"); BuffFadeByEffect(SE_Charm); break; } diff --git a/zone/spells.cpp b/zone/spells.cpp index f6cf829c5..e0ade3798 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1211,7 +1211,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if(!HasInstrument) { // if the instrument is missing, log it and interrupt the song Log(Logs::Detail, Logs::Spells, "Song %d: Canceled. Missing required instrument %d", spell_id, component); if(c->GetGM()) - c->Message(0, "Your GM status allows you to finish casting even though you're missing a required instrument."); + c->Message(Chat::White, "Your GM status allows you to finish casting even though you're missing a required instrument."); else { InterruptSpell(); return; @@ -1248,7 +1248,7 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo if (missingreags) { if(c->GetGM()) - c->Message(0, "Your GM status allows you to finish casting even though you're missing required components."); + c->Message(Chat::White, "Your GM status allows you to finish casting even though you're missing required components."); else { InterruptSpell(); return; diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 40d301e7d..895e01e90 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -1266,18 +1266,18 @@ void TaskManager::ExplainTask(Client*c, int TaskID) { if(!c) return; if((TaskID<=0) || (TaskID>=MAXTASKS)) { - c->Message(0, "TaskID out-of-range."); + c->Message(Chat::White, "TaskID out-of-range."); return; } if(Tasks[TaskID] == nullptr) { - c->Message(0, "Task does not exist."); + c->Message(Chat::White, "Task does not exist."); return; } char Explanation[1000], *ptr; - c->Message(0, "Task %4i: Title: %s", TaskID, Tasks[TaskID]->Description.c_str()); - c->Message(0, "%3i Activities", Tasks[TaskID]->ActivityCount); + c->Message(Chat::White, "Task %4i: Title: %s", TaskID, Tasks[TaskID]->Description.c_str()); + c->Message(Chat::White, "%3i Activities", Tasks[TaskID]->ActivityCount); ptr = Explanation; for(int i=0; iActivityCount; i++) { @@ -1936,7 +1936,7 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation *Task, int T // Send the updated task/activity list to the client taskmanager->SendSingleActiveTaskToClient(c, *info, TaskComplete, false); // Inform the client the task has been updated, both by a chat message - c->Message(0, "Your task '%s' has been updated.", Task->Title.c_str()); + c->Message(Chat::White, "Your task '%s' has been updated.", Task->Title.c_str()); if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) { if (!ignore_quest_update){ @@ -2306,12 +2306,12 @@ void ClientTaskState::ResetTaskActivity(Client *c, int TaskID, int ActivityID) void ClientTaskState::ShowClientTasks(Client *c) { - c->Message(0, "Task Information:"); + c->Message(Chat::White, "Task Information:"); if (ActiveTask.TaskID != TASKSLOTEMPTY) { - c->Message(0, "Task: %i %s", ActiveTask.TaskID, taskmanager->Tasks[ActiveTask.TaskID]->Title.c_str()); - c->Message(0, " Description: [%s]\n", taskmanager->Tasks[ActiveTask.TaskID]->Description.c_str()); + c->Message(Chat::White, "Task: %i %s", ActiveTask.TaskID, taskmanager->Tasks[ActiveTask.TaskID]->Title.c_str()); + c->Message(Chat::White, " Description: [%s]\n", taskmanager->Tasks[ActiveTask.TaskID]->Description.c_str()); for (int j = 0; j < taskmanager->GetActivityCount(ActiveTask.TaskID); j++) { - c->Message(0, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", + c->Message(Chat::White, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", ActiveTask.Activity[j].ActivityID, ActiveTask.Activity[j].DoneCount, ActiveTask.Activity[j].State); } @@ -2321,11 +2321,11 @@ void ClientTaskState::ShowClientTasks(Client *c) if (ActiveQuests[i].TaskID == TASKSLOTEMPTY) continue; - c->Message(0, "Quest: %i %s", ActiveQuests[i].TaskID, + c->Message(Chat::White, "Quest: %i %s", ActiveQuests[i].TaskID, taskmanager->Tasks[ActiveQuests[i].TaskID]->Title.c_str()); - c->Message(0, " Description: [%s]\n", taskmanager->Tasks[ActiveQuests[i].TaskID]->Description.c_str()); + c->Message(Chat::White, " Description: [%s]\n", taskmanager->Tasks[ActiveQuests[i].TaskID]->Description.c_str()); for (int j = 0; j < taskmanager->GetActivityCount(ActiveQuests[i].TaskID); j++) { - c->Message(0, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", + c->Message(Chat::White, " Activity: %2d, DoneCount: %2d, Status: %d (0=Hidden, 1=Active, 2=Complete)", ActiveQuests[i].Activity[j].ActivityID, ActiveQuests[i].Activity[j].DoneCount, ActiveQuests[i].Activity[j].State); } @@ -3309,7 +3309,7 @@ void ClientTaskState::AcceptNewTask(Client *c, int TaskID, int NPCID, bool enfor ActiveTaskCount++; taskmanager->SendSingleActiveTaskToClient(c, *active_slot, false, true); - c->Message(0, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str()); + c->Message(Chat::White, "You have been assigned the task '%s'.", taskmanager->Tasks[TaskID]->Title.c_str()); std::string buf = std::to_string(TaskID); diff --git a/zone/tune.cpp b/zone/tune.cpp index e4d730abc..22ca90375 100644 --- a/zone/tune.cpp +++ b/zone/tune.cpp @@ -249,9 +249,9 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh if (Msg){ - GM->Message(0, "######### Melee Mitigation Report: Start [Detail Level %i]#########", Msg); - GM->Message(0, "#ATTACKER: %s", attacker->GetCleanName()); - GM->Message(0, "#DEFENDER: %s", defender->GetCleanName()); + GM->Message(Chat::White, "######### Melee Mitigation Report: Start [Detail Level %i]#########", Msg); + GM->Message(Chat::White, "#ATTACKER: %s", attacker->GetCleanName()); + GM->Message(Chat::White, "#DEFENDER: %s", defender->GetCleanName()); } if (RuleB(Combat, UseIntervalAC)) { @@ -264,16 +264,16 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh float weight = 0.0; if (Msg >= 2){ - GM->Message(0, " "); - GM->Message(0, "### Calculate Mitigation Rating ###"); + GM->Message(Chat::White, " "); + GM->Message(Chat::White, "### Calculate Mitigation Rating ###"); if (aabonuses.CombatStability) - GM->Message(0, "# %i #### DEFENDER SE_CombatStability(259) AA Bonus", aabonuses.CombatStability); + GM->Message(Chat::White, "# %i #### DEFENDER SE_CombatStability(259) AA Bonus", aabonuses.CombatStability); if (spellbonuses.CombatStability) - GM->Message(0, "# %i #### DEFENDER SE_CombatStability(259) Spell Bonus", spellbonuses.CombatStability); + GM->Message(Chat::White, "# %i #### DEFENDER SE_CombatStability(259) Spell Bonus", spellbonuses.CombatStability); if (itembonuses.CombatStability) - GM->Message(0, "# %i #### DEFENDER SE_CombatStability(259) Worn Bonus", itembonuses.CombatStability); + GM->Message(Chat::White, "# %i #### DEFENDER SE_CombatStability(259) Worn Bonus", itembonuses.CombatStability); - GM->Message(0, "# %.2f #### DEFENDER Base Soft Cap", softcap); + GM->Message(Chat::White, "# %.2f #### DEFENDER Base Soft Cap", softcap); } float monkweight = RuleI(Combat, MonkACBonusWeight); @@ -287,11 +287,11 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh armor = ac_override; if (Msg >=2 ){ - GM->Message(0, "# %i #### DEFENDER AC Equiped/Worn Bonus", itembonuses.AC); - GM->Message(0, "# %i #### DEFENDER SE_ArmorClass(1) AA Bonus", aabonuses.AC); - GM->Message(0, "# %i #### DEFENDER SE_ArmorClass(1) Spell Bonus", spellbonuses.AC); - GM->Message(0, "# %i #### DEFENDER Shield AC", shield_ac); - GM->Message(0, "# %i #### DEFENDER Total Client Armor - NO shield", armor); + GM->Message(Chat::White, "# %i #### DEFENDER AC Equiped/Worn Bonus", itembonuses.AC); + GM->Message(Chat::White, "# %i #### DEFENDER SE_ArmorClass(1) AA Bonus", aabonuses.AC); + GM->Message(Chat::White, "# %i #### DEFENDER SE_ArmorClass(1) Spell Bonus", spellbonuses.AC); + GM->Message(Chat::White, "# %i #### DEFENDER Shield AC", shield_ac); + GM->Message(Chat::White, "# %i #### DEFENDER Total Client Armor - NO shield", armor); } } else if (IsNPC()) { @@ -301,9 +301,9 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh armor = ac_override; if (Msg >=2 ){ - GM->Message(0, "# %i #### DEFENDER AC Equiped/Worn Bonus", itembonuses.AC); - GM->Message(0, "# %i #### DEFENDER SE_ArmorClass(1) Spell Bonus", spellbonuses.AC); - GM->Message(0, "# %i #### DEFENDER NPC AC Stat", CastToNPC()->GetRawAC()); + GM->Message(Chat::White, "# %i #### DEFENDER AC Equiped/Worn Bonus", itembonuses.AC); + GM->Message(Chat::White, "# %i #### DEFENDER SE_ArmorClass(1) Spell Bonus", spellbonuses.AC); + GM->Message(Chat::White, "# %i #### DEFENDER NPC AC Stat", CastToNPC()->GetRawAC()); } int PetACBonus = 0; @@ -311,7 +311,7 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh if (!IsPet()){ armor = (armor / RuleR(Combat, NPCACFactor)); if (Msg >=2 ) - GM->Message(0, "# %i #### DEFENDER NPC Armor after RuleR(Combat, NPCACFactor) %.2f", armor, RuleR(Combat, NPCACFactor)); + GM->Message(Chat::White, "# %i #### DEFENDER NPC Armor after RuleR(Combat, NPCACFactor) %.2f", armor, RuleR(Combat, NPCACFactor)); } Mob *owner = nullptr; @@ -325,18 +325,18 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh if (Msg >=2 ){ if (owner->aabonuses.PetMeleeMitigation) - GM->Message(0, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) AA Bonus", owner->aabonuses.PetMeleeMitigation); + GM->Message(Chat::White, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) AA Bonus", owner->aabonuses.PetMeleeMitigation); if (owner->spellbonuses.PetMeleeMitigation) - GM->Message(0, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) Spell Bonus",owner->spellbonuses.PetMeleeMitigation); + GM->Message(Chat::White, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) Spell Bonus",owner->spellbonuses.PetMeleeMitigation); if (owner->itembonuses.PetMeleeMitigation) - GM->Message(0, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) Worn Bonus", owner->itembonuses.PetMeleeMitigation); + GM->Message(Chat::White, "# %i #### DEFENDER Pet Owner SE_PetMeleeMitigation(379) Worn Bonus", owner->itembonuses.PetMeleeMitigation); } } armor += spellbonuses.AC + itembonuses.AC + PetACBonus + 1; if (Msg >= 2) - GM->Message(0, "# %i #### DEFENDER NPC Total Base Armor",armor); + GM->Message(Chat::White, "# %i #### DEFENDER NPC Total Base Armor",armor); } if (opts) { @@ -405,38 +405,38 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh armor = softcap + softcap_armor; if (Msg >= 2) - GM->Message(0, "# %i #### DEFENDER Final Armor [Soft Cap %i Soft Cap Armor %i]",armor, softcap,softcap_armor); + GM->Message(Chat::White, "# %i #### DEFENDER Final Armor [Soft Cap %i Soft Cap Armor %i]",armor, softcap,softcap_armor); } int tmp_armor = armor; if (GetClass() == WIZARD || GetClass() == MAGICIAN || GetClass() == NECROMANCER || GetClass() == ENCHANTER){ mitigation_rating = ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 4.0) + armor + 1; if (Msg >= 2) - GM->Message(0, "# + %.2f #### DEFENDER Armor Bonus [Defense Skill %i Heroic Agi %i]", mitigation_rating - tmp_armor, GetSkill(EQEmu::skills::SkillDefense), itembonuses.HeroicAGI); + GM->Message(Chat::White, "# + %.2f #### DEFENDER Armor Bonus [Defense Skill %i Heroic Agi %i]", mitigation_rating - tmp_armor, GetSkill(EQEmu::skills::SkillDefense), itembonuses.HeroicAGI); } else{ mitigation_rating = ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 3.0) + (armor * 1.333333) + 1; if (Msg >= 2) - GM->Message(0, "# + %.2f #### DEFENDER Armor Bonus [Defense Skill %i Heroic Agi %i]", mitigation_rating - tmp_armor, GetSkill(EQEmu::skills::SkillDefense), itembonuses.HeroicAGI); + GM->Message(Chat::White, "# + %.2f #### DEFENDER Armor Bonus [Defense Skill %i Heroic Agi %i]", mitigation_rating - tmp_armor, GetSkill(EQEmu::skills::SkillDefense), itembonuses.HeroicAGI); } mitigation_rating *= 0.847; if (Msg >= 1) - GM->Message(0, "# %.2f #### DEFENDER Final Mitigation Rating", mitigation_rating); + GM->Message(Chat::White, "# %.2f #### DEFENDER Final Mitigation Rating", mitigation_rating); if (Msg >= 2){ - GM->Message(0, " "); - GM->Message(0, "### Mitigation Bonus Effects ###"); + GM->Message(Chat::White, " "); + GM->Message(Chat::White, "### Mitigation Bonus Effects ###"); if (itembonuses.MeleeMitigation) - GM->Message(0, "# %i #### DEFENDER Item Mod2 Shielding", itembonuses.MeleeMitigation); + GM->Message(Chat::White, "# %i #### DEFENDER Item Mod2 Shielding", itembonuses.MeleeMitigation); if (aabonuses.MeleeMitigationEffect) - GM->Message(0, "# %i #### DEFENDER SE_MeleeMitigation(168) AA Bonus", aabonuses.MeleeMitigationEffect); + GM->Message(Chat::White, "# %i #### DEFENDER SE_MeleeMitigation(168) AA Bonus", aabonuses.MeleeMitigationEffect); if (spellbonuses.MeleeMitigationEffect) - GM->Message(0, "# %i #### DEFENDER SE_MeleeMitigation(168) Spell Bonus", spellbonuses.MeleeMitigationEffect); + GM->Message(Chat::White, "# %i #### DEFENDER SE_MeleeMitigation(168) Spell Bonus", spellbonuses.MeleeMitigationEffect); if (itembonuses.MeleeMitigationEffect) - GM->Message(0, "# %i #### DEFENDER SE_MeleeMitigation(168) Worn Bonus", itembonuses.MeleeMitigationEffect); + GM->Message(Chat::White, "# %i #### DEFENDER SE_MeleeMitigation(168) Worn Bonus", itembonuses.MeleeMitigationEffect); } mitigation_rating = mod_mitigation_rating(mitigation_rating, attacker); @@ -458,31 +458,31 @@ int32 Mob::Tune_MeleeMitigation(Mob* GM, Mob *attacker, int32 damage, int32 minh attack_rating = attacker->mod_attack_rating(attack_rating, this); if (Msg >= 2){ - GM->Message(0, " "); - GM->Message(0, "### Calculate Attack Rating ###"); + GM->Message(Chat::White, " "); + GM->Message(Chat::White, "### Calculate Attack Rating ###"); if (attacker->IsClient()){ - GM->Message(0, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); - GM->Message(0, "# %i #### ATTACKER SE_ATK(2) AA Bonus", attacker->aabonuses.ATK); - GM->Message(0, "# %i #### ATTACKER SE_ATK(2) spell Bonus", attacker->spellbonuses.ATK); - GM->Message(0, "# %i #### ATTACKER Leadership Bonus", attacker->CastToClient()->GroupLeadershipAAOffenseEnhancement()); - GM->Message(0, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); - GM->Message(0, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); - GM->Message(0, "# %.2f #### ATTACKER Strength Stat ATK Bonus [Stat Amt: %i]", ((attacker->GetSTR()-66) * 0.9),attacker->GetSTR()); - GM->Message(0, "# %.2f #### ATTACKER Offensive Skill ATK Bonus [Stat Amt: %i]", (attacker->GetSkill(EQEmu::skills::SkillOffense)*1.345), attacker->GetSkill(EQEmu::skills::SkillOffense)); + GM->Message(Chat::White, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER SE_ATK(2) AA Bonus", attacker->aabonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER SE_ATK(2) spell Bonus", attacker->spellbonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER Leadership Bonus", attacker->CastToClient()->GroupLeadershipAAOffenseEnhancement()); + GM->Message(Chat::White, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); + GM->Message(Chat::White, "# %.2f #### ATTACKER Strength Stat ATK Bonus [Stat Amt: %i]", ((attacker->GetSTR()-66) * 0.9),attacker->GetSTR()); + GM->Message(Chat::White, "# %.2f #### ATTACKER Offensive Skill ATK Bonus [Stat Amt: %i]", (attacker->GetSkill(EQEmu::skills::SkillOffense)*1.345), attacker->GetSkill(EQEmu::skills::SkillOffense)); } else{ - GM->Message(0, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); - GM->Message(0, "# %i #### ATTACKER SE_ATK(2) spell Bonus", attacker->spellbonuses.ATK); - GM->Message(0, "# %i #### ATTACKER NPC ATK Stat", attacker->CastToNPC()->ATK); - GM->Message(0, "# %.2f #### ATTACKER Strength Stat ATK Bonus [Stat Amt: %i]", ((attacker->GetSTR()-66) * 0.9),attacker->GetSTR()); - GM->Message(0, "# %.2f #### ATTACKER Offensive Skill ATK Bonus [Stat Amt: %i]", (attacker->GetSkill(EQEmu::skills::SkillOffense)*1.345), attacker->GetSkill(EQEmu::skills::SkillOffense)); + GM->Message(Chat::White, "# %i #### ATTACKER Worn/Equip ATK Bonus", attacker->itembonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER SE_ATK(2) spell Bonus", attacker->spellbonuses.ATK); + GM->Message(Chat::White, "# %i #### ATTACKER NPC ATK Stat", attacker->CastToNPC()->ATK); + GM->Message(Chat::White, "# %.2f #### ATTACKER Strength Stat ATK Bonus [Stat Amt: %i]", ((attacker->GetSTR()-66) * 0.9),attacker->GetSTR()); + GM->Message(Chat::White, "# %.2f #### ATTACKER Offensive Skill ATK Bonus [Stat Amt: %i]", (attacker->GetSkill(EQEmu::skills::SkillOffense)*1.345), attacker->GetSkill(EQEmu::skills::SkillOffense)); } } if (Msg >= 1){ - GM->Message(0, "# %.2f #### ATTACKER Final Attack Rating", attack_rating); - GM->Message(0, "######### Melee Mitigation Report: Complete #########", Msg); + GM->Message(Chat::White, "# %.2f #### ATTACKER Final Attack Rating", attack_rating); + GM->Message(Chat::White, "######### Melee Mitigation Report: Complete #########", Msg); } diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index fb0a85490..bc9e3870d 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -70,7 +70,7 @@ void NPC::AI_SetRoambox(float distance, float max_x, float min_x, float max_y, f void NPC::DisplayWaypointInfo(Client *c) { - c->Message(0, "Mob is on grid %d, in spawn group %d, on waypoint %d/%d", + c->Message(Chat::White, "Mob is on grid %d, in spawn group %d, on waypoint %d/%d", GetGrid(), GetSp2(), GetCurWp(), @@ -81,7 +81,7 @@ void NPC::DisplayWaypointInfo(Client *c) { cur = Waypoints.begin(); end = Waypoints.end(); for (; cur != end; ++cur) { - c->Message(0, "Waypoint %d: (%.2f,%.2f,%.2f,%.2f) pause %d", + c->Message(Chat::White, "Waypoint %d: (%.2f,%.2f,%.2f,%.2f) pause %d", cur->index, cur->x, cur->y, @@ -895,7 +895,7 @@ void ZoneDatabase::AssignGrid(Client *client, int grid, int spawn2id) { return; } - client->Message(0, "Grid assign: spawn2 id = %d updated", spawn2id); + client->Message(Chat::White, "Grid assign: spawn2 id = %d updated", spawn2id); } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 4d1399f68..2fc29e3b6 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -578,7 +578,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) printf("Zoning %s to %s(%u) - %u\n", client != nullptr ? client->GetCleanName() : "Unknown", szp->zone, database.GetZoneID(szp->zone), szp->instance_id); if (client != 0) { if (strcasecmp(szp->adminname, szp->name) == 0) - client->Message(0, "Zoning to: %s", szp->zone); + client->Message(Chat::White, "Zoning to: %s", szp->zone); else if (client->GetAnon() == 1 && client->Admin() > szp->adminrank) break; else { diff --git a/zone/zone.cpp b/zone/zone.cpp index d20b2934e..f364ab298 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1770,14 +1770,14 @@ void Zone::SpawnStatus(Mob* client) { while(iterator.MoreElements()) { if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); else - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); x++; iterator.Advance(); } - client->Message(0, "%i spawns listed.", x); + client->Message(Chat::White, "%i spawns listed.", x); } void Zone::ShowEnabledSpawnStatus(Mob* client) @@ -1792,7 +1792,7 @@ void Zone::ShowEnabledSpawnStatus(Mob* client) { if (iterator.GetData()->timer.GetRemainingTime() != 0xFFFFFFFF) { - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); iEnabledCount++; } @@ -1800,7 +1800,7 @@ void Zone::ShowEnabledSpawnStatus(Mob* client) iterator.Advance(); } - client->Message(0, "%i of %i spawns listed.", iEnabledCount, x); + client->Message(Chat::White, "%i of %i spawns listed.", iEnabledCount, x); } void Zone::ShowDisabledSpawnStatus(Mob* client) @@ -1815,7 +1815,7 @@ void Zone::ShowDisabledSpawnStatus(Mob* client) { if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) { - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); iDisabledCount++; } @@ -1823,7 +1823,7 @@ void Zone::ShowDisabledSpawnStatus(Mob* client) iterator.Advance(); } - client->Message(0, "%i of %i spawns listed.", iDisabledCount, x); + client->Message(Chat::White, "%i of %i spawns listed.", iDisabledCount, x); } void Zone::ShowSpawnStatusByID(Mob* client, uint32 spawnid) @@ -1839,9 +1839,9 @@ void Zone::ShowSpawnStatusByID(Mob* client, uint32 spawnid) if (iterator.GetData()->GetID() == spawnid) { if (iterator.GetData()->timer.GetRemainingTime() == 0xFFFFFFFF) - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: disabled", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ()); else - client->Message(0, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); + client->Message(Chat::White, " %d: %1.1f, %1.1f, %1.1f: %1.2f", iterator.GetData()->GetID(), iterator.GetData()->GetX(), iterator.GetData()->GetY(), iterator.GetData()->GetZ(), (float)iterator.GetData()->timer.GetRemainingTime() / 1000); iSpawnIDCount++; @@ -1853,9 +1853,9 @@ void Zone::ShowSpawnStatusByID(Mob* client, uint32 spawnid) } if(iSpawnIDCount > 0) - client->Message(0, "%i of %i spawns listed.", iSpawnIDCount, x); + client->Message(Chat::White, "%i of %i spawns listed.", iSpawnIDCount, x); else - client->Message(0, "No matching spawn id was found in this zone."); + client->Message(Chat::White, "No matching spawn id was found in this zone."); } bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes) diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 7c90bcc11..91f456768 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -3544,10 +3544,10 @@ void ZoneDatabase::ListAllInstances(Client* client, uint32 charid) char name[64]; database.GetCharName(charid, name); - client->Message(0, "%s is part of the following instances:", name); + client->Message(Chat::White, "%s is part of the following instances:", name); for (auto row = results.begin(); row != results.end(); ++row) { - client->Message(0, "%s - id: %lu, version: %lu", database.GetZoneName(atoi(row[1])), + client->Message(Chat::White, "%s - id: %lu, version: %lu", database.GetZoneName(atoi(row[1])), (unsigned long)atoi(row[0]), (unsigned long)atoi(row[2])); } } diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 5950d4025..800ee8cd2 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -814,7 +814,7 @@ bool Client::HasZoneFlag(uint32 zone_id) const { void Client::SendZoneFlagInfo(Client *to) const { if(zone_flags.empty()) { - to->Message(0, "%s has no zone flags.", GetName()); + to->Message(Chat::White, "%s has no zone flags.", GetName()); return; } @@ -823,7 +823,7 @@ void Client::SendZoneFlagInfo(Client *to) const { end = zone_flags.end(); char empty[1] = { '\0' }; - to->Message(0, "Flags for %s:", GetName()); + to->Message(Chat::White, "Flags for %s:", GetName()); for(; cur != end; ++cur) { uint32 zoneid = *cur; @@ -843,7 +843,7 @@ void Client::SendZoneFlagInfo(Client *to) const { strcpy(flag_name, "(ERROR GETTING NAME)"); } - to->Message(0, "Has Flag %s for zone %s (%d,%s)", flag_name, long_name, zoneid, short_name); + to->Message(Chat::White, "Has Flag %s for zone %s (%d,%s)", flag_name, long_name, zoneid, short_name); if(long_name != empty) delete[] long_name; } From 20bd37dde70dfbe5a091fcd0552ac3802ac6056c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 01:09:11 -0500 Subject: [PATCH 150/491] More function name refactoring --- common/eq_constants.h | 2 +- zone/attack.cpp | 2 +- zone/bot.cpp | 8 ++--- zone/bot_command.cpp | 4 +-- zone/client.cpp | 10 +++---- zone/client_packet.cpp | 64 ++++++++++++++++++++-------------------- zone/client_process.cpp | 4 +-- zone/merc.cpp | 4 +-- zone/mob.cpp | 8 ++--- zone/mob.h | 8 ++--- zone/oldcode.cpp | 2 +- zone/special_attacks.cpp | 2 +- zone/tasks.cpp | 6 ++-- 13 files changed, 62 insertions(+), 62 deletions(-) diff --git a/common/eq_constants.h b/common/eq_constants.h index bf65f2bfb..6c3e28da0 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -71,7 +71,7 @@ //#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2) // animations for AT_Anim -#define ANIM_FREEZE 102 +#define ANIM_FREEZE 102 #define ANIM_STAND 0x64 #define ANIM_SIT 0x6e #define ANIM_CROUCH 0x6f diff --git a/zone/attack.cpp b/zone/attack.cpp index 58a661969..780a8fba4 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1914,7 +1914,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool //Check that we can attack before we calc heading and face our target if (!IsAttackAllowed(other)) { if (this->GetOwnerID()) - this->Say_StringID(NOT_LEGAL_TARGET); + this->SayString(NOT_LEGAL_TARGET); if (other) { if (other->IsClient()) other->CastToClient()->RemoveXTarget(this, false); diff --git a/zone/bot.cpp b/zone/bot.cpp index 4398f2fd5..cd525022a 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -2276,12 +2276,12 @@ void Bot::AI_Process() { // Berserk updates should occur if primary AI criteria are met if (GetClass() == WARRIOR || GetClass() == BERSERKER) { if (!berserk && GetHP() > 0 && GetHPRatio() < 30.0f) { - entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName()); + entity_list.MessageCloseString(this, false, 200, 0, BERSERK_START, GetName()); berserk = true; } if (berserk && GetHPRatio() >= 30.0f) { - entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName()); + entity_list.MessageCloseString(this, false, 200, 0, BERSERK_END, GetName()); berserk = false; } } @@ -5364,7 +5364,7 @@ bool Bot::TryFinishingBlow(Mob *defender, int &damage) if (defender->GetLevel() <= levelreq && (chance >= zone->random.Int(1, 1000))) { Log(Logs::Detail, Logs::Combat, "Landed a finishing blow: levelreq at %d, other level %d", levelreq, defender->GetLevel()); - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, FINISHING_BLOW, GetName()); + entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, FINISHING_BLOW, GetName()); damage = fb_damage; return true; } else { @@ -5572,7 +5572,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) { if (bIsBehind || bCanFrontalBS) { int chance = (10 + (GetDEX() / 10) + (itembonuses.HeroicDEX / 10)); if(level >= 60 && other->GetLevel() <= 45 && !other->CastToNPC()->IsEngaged() && other->GetHP()<= 32000 && other->IsNPC() && zone->random.Real(0, 99) < chance) { - entity_list.MessageClose_StringID(this, false, 200, Chat::MeleeCrit, ASSASSINATES, GetName()); + entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, ASSASSINATES, GetName()); RogueAssassinate(other); } else { RogueBackstab(other); diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 90d694004..fc5b78ff1 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -7454,7 +7454,7 @@ void bot_subcommand_pet_get_lost(Client *c, const Seperator *sep) if (!bot_iter->GetPet() || bot_iter->GetPet()->IsCharmed()) continue; - bot_iter->GetPet()->Say_StringID(PET_GETLOST_STRING); + bot_iter->GetPet()->SayString(PET_GETLOST_STRING); bot_iter->GetPet()->Depop(false); bot_iter->SetPetID(0); database.botdb.DeletePetItems(bot_iter->GetBotID()); @@ -7500,7 +7500,7 @@ void bot_subcommand_pet_remove(Client *c, const Seperator *sep) } if (bot_iter->GetPet()) { - bot_iter->GetPet()->Say_StringID(PET_GETLOST_STRING); + bot_iter->GetPet()->SayString(PET_GETLOST_STRING); bot_iter->GetPet()->Depop(false); bot_iter->SetPetID(0); } diff --git a/zone/client.cpp b/zone/client.cpp index bf2fb3a0d..c1293be3f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -7948,7 +7948,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) } // If no primary faction or biggest influence is your faction hit if (primaryfaction <= 0 || lowestvalue == tmpFactionValue) { - merchant->Say_StringID(zone->random.Int(WONT_SELL_DEEDS1, WONT_SELL_DEEDS6)); + merchant->SayString(zone->random.Int(WONT_SELL_DEEDS1, WONT_SELL_DEEDS6)); } else if (lowestvalue == fmod.race_mod) { // race biggest // Non-standard race (ex. illusioned to wolf) if (GetRace() > PLAYER_RACE_COUNT) { @@ -7967,7 +7967,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) messageid = WONT_SELL_NONSTDRACE1; break; } - merchant->Say_StringID(messageid); + merchant->SayString(messageid); } else { // normal player races messageid = zone->random.Int(1, 4); switch (messageid) { @@ -7987,15 +7987,15 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction) messageid = WONT_SELL_RACE1; break; } - merchant->Say_StringID(messageid, itoa(GetRace())); + merchant->SayString(messageid, itoa(GetRace())); } } else if (lowestvalue == fmod.class_mod) { - merchant->Say_StringID(zone->random.Int(WONT_SELL_CLASS1, WONT_SELL_CLASS5), itoa(GetClass())); + merchant->SayString(zone->random.Int(WONT_SELL_CLASS1, WONT_SELL_CLASS5), itoa(GetClass())); } else { // Must be deity - these two sound the best for that. // Can't use a message with a field, GUI wants class/race names. // for those message IDs. These are straight text. - merchant->Say_StringID(zone->random.Int(WONT_SELL_DEEDS1, WONT_SELL_DEEDS2)); + merchant->SayString(zone->random.Int(WONT_SELL_DEEDS1, WONT_SELL_DEEDS2)); } return; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 67c766597..e0ae5562e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -8727,7 +8727,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app) #endif // This Seems to be handled in OP_DeleteItem handling //DeleteItemInInventory(slot_id, 1, false); - //entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name); + //entity_list.MessageCloseString(this, true, 50, 0, DRINKING_MESSAGE, GetName(), item->Name); //Should add intoxication level to the PP at some point //CheckIncreaseSkill(ALCOHOL_TOLERANCE, nullptr, 25); } @@ -9953,11 +9953,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (target) { auto owner = target->GetOwner(); if (owner) - target->Say_StringID(PET_LEADERIS, owner->GetCleanName()); + target->SayString(PET_LEADERIS, owner->GetCleanName()); else - target->Say_StringID(I_FOLLOW_NOONE); + target->SayString(I_FOLLOW_NOONE); } else if (mypet) { - mypet->Say_StringID(PET_LEADERIS, GetName()); + mypet->SayString(PET_LEADERIS, GetName()); } } @@ -9996,7 +9996,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) break; //prevent pet from attacking stuff while feared if (!mypet->IsAttackAllowed(target)) { - mypet->SayTo_StringID(this, NOT_LEGAL_TARGET); + mypet->SayString(this, NOT_LEGAL_TARGET); break; } @@ -10045,7 +10045,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) } if (!mypet->IsAttackAllowed(GetTarget())) { - mypet->SayTo_StringID(this, NOT_LEGAL_TARGET); + mypet->SayString(this, NOT_LEGAL_TARGET); break; } @@ -10070,7 +10070,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //keeps pet running while feared if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_CALMING); + mypet->SayString(this, Chat::PetResponse, PET_CALMING); mypet->WipeHateList(); mypet->SetTarget(nullptr); if (mypet->IsPetStop()) { @@ -10101,13 +10101,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) SetPet(nullptr); } - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); + mypet->SayString(this, Chat::PetResponse, PET_GETLOST_STRING); mypet->CastToNPC()->Depop(); //Oddly, the client (Titanium) will still allow "/pet get lost" command despite me adding the code below. If someone can figure that out, you can uncomment this code and use it. /* if((mypet->GetPetType() == petAnimation && GetAA(aaAnimationEmpathy) >= 2) || mypet->GetPetType() != petAnimation) { - mypet->Say_StringID(PET_GETLOST_STRING); + mypet->SayString(PET_GETLOST_STRING); mypet->CastToNPC()->Depop(); } */ @@ -10119,7 +10119,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->IsNPC()) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GUARDINGLIFE); + mypet->SayString(this, Chat::PetResponse, PET_GUARDINGLIFE); mypet->SetPetOrder(SPO_Guard); mypet->CastToNPC()->SaveGuardSpot(mypet->GetPosition()); if (!mypet->GetTarget()) // want them to not twitch if they're chasing something down @@ -10136,7 +10136,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_FOLLOWING); + mypet->SayString(this, Chat::PetResponse, PET_FOLLOWING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); if (mypet->IsPetStop()) { @@ -10179,7 +10179,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GUARDME_STRING); + mypet->SayString(this, Chat::PetResponse, PET_GUARDME_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); if (mypet->IsPetStop()) { @@ -10195,13 +10195,13 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { if (mypet->GetPetOrder() == SPO_Sit) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); + mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); } else { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); + mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Sit); mypet->SetRunAnimSpeed(0); if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet @@ -10215,7 +10215,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); + mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Follow); mypet->SendAppearancePacket(AT_Anim, ANIM_STAND); } @@ -10225,7 +10225,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (mypet->IsFeared()) break; //could be exploited like PET_BACKOFF if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_SIT_STRING); + mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING); mypet->SetPetOrder(SPO_Sit); mypet->SetRunAnimSpeed(0); if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet @@ -10248,9 +10248,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) MessageString(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); + mypet->SayString(this, Chat::PetResponse, PET_NOW_HOLDING); else - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); + mypet->SayString(this, Chat::PetResponse, PET_ON_HOLD); mypet->SetHeld(true); } @@ -10265,9 +10265,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) MessageString(Chat::PetResponse, PET_HOLD_SET_ON); if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) - mypet->SayTo_StringID(this, Chat::PetResponse, PET_NOW_HOLDING); + mypet->SayString(this, Chat::PetResponse, PET_NOW_HOLDING); else - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); + mypet->SayString(this, Chat::PetResponse, PET_ON_HOLD); mypet->SetHeld(true); mypet->SetGHeld(false); SetPetCommandState(PET_BUTTON_GHOLD, 0); @@ -10294,9 +10294,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { MessageString(Chat::PetResponse, PET_ON_GHOLD); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); + mypet->SayString(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); + mypet->SayString(this, Chat::PetResponse, PET_ON_HOLD); } mypet->SetGHeld(true); } @@ -10309,9 +10309,9 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand] && mypet->IsNPC()) { if (m_ClientVersionBit & EQEmu::versions::maskUFAndLater) { MessageString(Chat::PetResponse, PET_ON_GHOLD); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GHOLD_ON_MSG); + mypet->SayString(this, Chat::PetResponse, PET_GHOLD_ON_MSG); } else { - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_HOLD); + mypet->SayString(this, Chat::PetResponse, PET_ON_HOLD); } mypet->SetGHeld(true); mypet->SetHeld(false); @@ -10432,7 +10432,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) SetPetCommandState(PET_BUTTON_REGROUP, 0); } } - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); + mypet->SayString(this, Chat::PetResponse, PET_GETLOST_STRING); } break; } @@ -10443,7 +10443,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) mypet->SetPetStop(true); mypet->StopNavigation(); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); + mypet->SayString(this, Chat::PetResponse, PET_GETLOST_STRING); if (mypet->IsPetRegroup()) { mypet->SetPetRegroup(false); SetPetCommandState(PET_BUTTON_REGROUP, 0); @@ -10456,7 +10456,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) { mypet->SetPetStop(false); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_GETLOST_STRING); + mypet->SayString(this, Chat::PetResponse, PET_GETLOST_STRING); } break; } @@ -10466,11 +10466,11 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { if (mypet->IsPetRegroup()) { mypet->SetPetRegroup(false); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_OFF_REGROUPING); + mypet->SayString(this, Chat::PetResponse, PET_OFF_REGROUPING); } else { mypet->SetPetRegroup(true); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_REGROUPING); + mypet->SayString(this, Chat::PetResponse, PET_ON_REGROUPING); if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10485,7 +10485,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { mypet->SetPetRegroup(true); mypet->SetTarget(nullptr); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_ON_REGROUPING); + mypet->SayString(this, Chat::PetResponse, PET_ON_REGROUPING); if (mypet->IsPetStop()) { mypet->SetPetStop(false); SetPetCommandState(PET_BUTTON_STOP, 0); @@ -10498,7 +10498,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app) if (aabonuses.PetCommands[PetCommand]) { mypet->SetPetRegroup(false); - mypet->SayTo_StringID(this, Chat::PetResponse, PET_OFF_REGROUPING); + mypet->SayString(this, Chat::PetResponse, PET_OFF_REGROUPING); } break; } @@ -13043,7 +13043,7 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app) // 1199 I don't have time for that now. etc if (!tmp->CastToNPC()->IsMerchantOpen()) { - tmp->Say_StringID(zone->random.Int(1199, 1202)); + tmp->SayString(zone->random.Int(1199, 1202)); action = 0; } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 7e08054d8..7465ac925 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1527,7 +1527,7 @@ void Client::OPGMTraining(const EQApplicationPacket *app) // welcome message if (pTrainer && pTrainer->IsNPC()) { - pTrainer->Say_StringID(zone->random.Int(1204, 1207), GetCleanName()); + pTrainer->SayString(zone->random.Int(1204, 1207), GetCleanName()); } } @@ -1556,7 +1556,7 @@ void Client::OPGMEndTraining(const EQApplicationPacket *app) // goodbye message if (pTrainer->IsNPC()) { - pTrainer->Say_StringID(zone->random.Int(1208, 1211), GetCleanName()); + pTrainer->SayString(zone->random.Int(1208, 1211), GetCleanName()); } } diff --git a/zone/merc.cpp b/zone/merc.cpp index c2b433d52..c48c3fb66 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1637,11 +1637,11 @@ void Merc::AI_Process() { // TODO: Do mercs berserk? Find this out on live... //if (GetClass() == WARRIOR || GetClass() == BERSERKER) { // if(GetHP() > 0 && !berserk && this->GetHPRatio() < 30) { - // entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_START, GetName()); + // entity_list.MessageCloseString(this, false, 200, 0, BERSERK_START, GetName()); // this->berserk = true; // } // if (berserk && this->GetHPRatio() > 30) { - // entity_list.MessageClose_StringID(this, false, 200, 0, BERSERK_END, GetName()); + // entity_list.MessageCloseString(this, false, 200, 0, BERSERK_END, GetName()); // this->berserk = false; // } //} diff --git a/zone/mob.cpp b/zone/mob.cpp index f9665af32..108749f0b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2844,7 +2844,7 @@ void Mob::Say(const char *format, ...) // // this is like the above, but the first parameter is a string id // -void Mob::Say_StringID(uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) +void Mob::SayString(uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) { char string_id_str[10]; @@ -2857,7 +2857,7 @@ void Mob::Say_StringID(uint32 string_id, const char *message3, const char *messa ); } -void Mob::Say_StringID(uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) +void Mob::SayString(uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) { char string_id_str[10]; @@ -2870,7 +2870,7 @@ void Mob::Say_StringID(uint32 type, uint32 string_id, const char *message3, cons ); } -void Mob::SayTo_StringID(Client *to, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) +void Mob::SayString(Client *to, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) { if (!to) return; @@ -2880,7 +2880,7 @@ void Mob::SayTo_StringID(Client *to, uint32 string_id, const char *message3, con to->MessageString(Chat::NPCQuestSay, GENERIC_STRINGID_SAY, GetCleanName(), string_id_str.c_str(), message3, message4, message5, message6, message7, message8, message9); } -void Mob::SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) +void Mob::SayString(Client *to, uint32 type, uint32 string_id, const char *message3, const char *message4, const char *message5, const char *message6, const char *message7, const char *message8, const char *message9) { if (!to) return; diff --git a/zone/mob.h b/zone/mob.h index 5134f1ace..1a19eb9fb 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -734,13 +734,13 @@ public: const char *message7 = nullptr, const char *message8 = nullptr, const char *message9 = nullptr) { } void Say(const char *format, ...); - void Say_StringID(uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, + void SayString(uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0); - void Say_StringID(uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, + void SayString(uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0); - void SayTo_StringID(Client *to, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, + void SayString(Client *to, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0); - void SayTo_StringID(Client *to, uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, + void SayString(Client *to, uint32 type, uint32 string_id, const char *message3 = 0, const char *message4 = 0, const char *message5 = 0, const char *message6 = 0, const char *message7 = 0, const char *message8 = 0, const char *message9 = 0); void Shout(const char *format, ...); void Emote(const char *format, ...); diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp index 059504328..9f20f686c 100644 --- a/zone/oldcode.cpp +++ b/zone/oldcode.cpp @@ -1233,7 +1233,7 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0] return; duration = 11; reuse = 60*60; - entity_list.MessageClose_StringID(this, false, 100, 0, DISCIPLINE_FEARLESS, GetName()); + entity_list.MessageCloseString(this, false, 100, 0, DISCIPLINE_FEARLESS, GetName()); //entity_list.MessageClose(this, false, 100, 0, "%s becomes fearless!", GetName()); break; } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index cc0ea1b3b..d9666efc6 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -1953,7 +1953,7 @@ void Mob::Taunt(NPC *who, bool always_succeed, int chance_bonus, bool FromSpell, } if (who->CanTalk()) - who->Say_StringID(SUCCESSFUL_TAUNT, GetCleanName()); + who->SayString(SUCCESSFUL_TAUNT, GetCleanName()); } else { MessageString(Chat::SpellFailure, FAILED_TAUNT); } diff --git a/zone/tasks.cpp b/zone/tasks.cpp index 895e01e90..9137898c3 100644 --- a/zone/tasks.cpp +++ b/zone/tasks.cpp @@ -1001,7 +1001,7 @@ void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, i return; if (TaskSets[TaskSetID].empty()) { - mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // I think this is suppose to be yellow + mob->SayString(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // I think this is suppose to be yellow return; } @@ -1033,7 +1033,7 @@ void TaskManager::TaskSetSelector(Client *c, ClientTaskState *state, Mob *mob, i if (TaskListIndex > 0) { SendTaskSelector(c, mob, TaskListIndex, TaskList); } else { - mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + mob->SayString(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow } return; @@ -1065,7 +1065,7 @@ void TaskManager::TaskQuestSetSelector(Client *c, ClientTaskState *state, Mob *m if (TaskListIndex > 0) { SendTaskSelector(c, mob, TaskListIndex, TaskList); } else { - mob->SayTo_StringID(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow + mob->SayString(c, Chat::Yellow, MAX_ACTIVE_TASKS, c->GetName()); // check color, I think this might be only for (Shared) Tasks, w/e -- think should be yellow } return; From 04a18786f99bd4522daf7a32bb9cafb1599ef401 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 01:21:55 -0500 Subject: [PATCH 151/491] Bot compile fixes --- zone/bot.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/zone/bot.cpp b/zone/bot.cpp index cd525022a..9cce41c2f 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3838,32 +3838,32 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli } if (client != GetOwner()) { - client->Message(CC_Red, "You are not the owner of this bot - Trade Canceled."); + client->Message(Chat::Red, "You are not the owner of this bot - Trade Canceled."); client->ResetTrade(); return; } if ((beginSlotID != invslot::TRADE_BEGIN) && (beginSlotID != invslot::slotCursor)) { - client->Message(CC_Red, "Trade request processing from illegal 'begin' slot - Trade Canceled."); + client->Message(Chat::Red, "Trade request processing from illegal 'begin' slot - Trade Canceled."); client->ResetTrade(); return; } if ((endSlotID != invslot::TRADE_END) && (endSlotID != invslot::slotCursor)) { - client->Message(CC_Red, "Trade request processing from illegal 'end' slot - Trade Canceled."); + client->Message(Chat::Red, "Trade request processing from illegal 'end' slot - Trade Canceled."); client->ResetTrade(); return; } if (((beginSlotID == invslot::slotCursor) && (endSlotID != invslot::slotCursor)) || ((beginSlotID != invslot::slotCursor) && (endSlotID == invslot::slotCursor))) { - client->Message(CC_Red, "Trade request processing illegal slot range - Trade Canceled."); + client->Message(Chat::Red, "Trade request processing illegal slot range - Trade Canceled."); client->ResetTrade(); return; } if (endSlotID < beginSlotID) { - client->Message(CC_Red, "Trade request processing in reverse slot order - Trade Canceled."); + client->Message(Chat::Red, "Trade request processing in reverse slot order - Trade Canceled."); client->ResetTrade(); return; } if (client->IsEngaged() || IsEngaged()) { - client->Message(CC_Yellow, "You may not perform a trade while engaged - Trade Canceled!"); + client->Message(Chat::Yellow, "You may not perform a trade while engaged - Trade Canceled!"); client->ResetTrade(); return; } @@ -3879,23 +3879,23 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli if (!trade_instance->GetItem()) { // TODO: add logging - client->Message(CC_Red, "A server error was encountered while processing client slot %i - Trade Canceled.", trade_index); + client->Message(Chat::Red, "A server error was encountered while processing client slot %i - Trade Canceled.", trade_index); client->ResetTrade(); return; } if ((trade_index != invslot::slotCursor) && !trade_instance->IsDroppable()) { // TODO: add logging - client->Message(CC_Red, "Trade hack detected - Trade Canceled."); + client->Message(Chat::Red, "Trade hack detected - Trade Canceled."); client->ResetTrade(); return; } if (trade_instance->IsStackable() && (trade_instance->GetCharges() < trade_instance->GetItem()->StackSize)) { // temp until partial stacks are implemented - client->Message(CC_Yellow, "'%s' is only a partially stacked item - Trade Canceled!", trade_instance->GetItem()->Name); + client->Message(Chat::Yellow, "'%s' is only a partially stacked item - Trade Canceled!", trade_instance->GetItem()->Name); client->ResetTrade(); return; } if (CheckLoreConflict(trade_instance->GetItem())) { - client->Message(CC_Yellow, "This bot already has lore equipment matching the item '%s' - Trade Canceled!", trade_instance->GetItem()->Name); + client->Message(Chat::Yellow, "This bot already has lore equipment matching the item '%s' - Trade Canceled!", trade_instance->GetItem()->Name); client->ResetTrade(); return; } @@ -3925,13 +3925,13 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli if ((trade_iterator.tradeItemInstance->GetItem()->LoreGroup == -1) && (check_iterator.tradeItemInstance->GetItem()->ID == trade_iterator.tradeItemInstance->GetItem()->ID)) { // TODO: add logging - client->Message(CC_Red, "Trade hack detected - Trade Canceled."); + client->Message(Chat::Red, "Trade hack detected - Trade Canceled."); client->ResetTrade(); return; } if ((trade_iterator.tradeItemInstance->GetItem()->LoreGroup > 0) && (check_iterator.tradeItemInstance->GetItem()->LoreGroup == trade_iterator.tradeItemInstance->GetItem()->LoreGroup)) { // TODO: add logging - client->Message(CC_Red, "Trade hack detected - Trade Canceled."); + client->Message(Chat::Red, "Trade hack detected - Trade Canceled."); client->ResetTrade(); return; } @@ -4040,14 +4040,14 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli if (!return_instance->GetItem()) { // TODO: add logging - client->Message(CC_Red, "A server error was encountered while processing bot slot %i - Trade Canceled.", return_iterator.fromBotSlot); + client->Message(Chat::Red, "A server error was encountered while processing bot slot %i - Trade Canceled.", return_iterator.fromBotSlot); client->ResetTrade(); return; } // non-failing checks above are causing this to trigger (i.e., !ItemClassCommon and !IsEquipable{race, class, min_level}) // this process is hindered by not having bots use the inventory trade method (TODO: implement bot inventory use) if (client->CheckLoreConflict(return_instance->GetItem())) { - client->Message(CC_Yellow, "You already have lore equipment matching the item '%s' - Trade Canceled!", return_instance->GetItem()->Name); + client->Message(Chat::Yellow, "You already have lore equipment matching the item '%s' - Trade Canceled!", return_instance->GetItem()->Name); client->ResetTrade(); return; } @@ -4104,7 +4104,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli } if (return_iterator.toClientSlot == invslot::SLOT_INVALID) { - client->Message(CC_Yellow, "You do not have room to complete this trade - Trade Canceled!"); + client->Message(Chat::Yellow, "You do not have room to complete this trade - Trade Canceled!"); client->ResetTrade(); return; } @@ -4130,7 +4130,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli //} if (!database.botdb.DeleteItemBySlot(GetBotID(), return_iterator.fromBotSlot)) - client->Message(CC_Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::DeleteItemBySlot(), return_iterator.fromBotSlot, (return_instance ? return_instance->GetItem()->Name : "nullptr")); + client->Message(Chat::Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::DeleteItemBySlot(), return_iterator.fromBotSlot, (return_instance ? return_instance->GetItem()->Name : "nullptr")); BotRemoveEquipItem(return_iterator.fromBotSlot); if (return_instance) @@ -4145,7 +4145,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli // TODO: code for stackables if (!database.botdb.SaveItemBySlot(this, trade_iterator.toBotSlot, trade_iterator.tradeItemInstance)) - client->Message(CC_Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::SaveItemBySlot(), trade_iterator.toBotSlot, (trade_iterator.tradeItemInstance ? trade_iterator.tradeItemInstance->GetItem()->Name : "nullptr")); + client->Message(Chat::Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::SaveItemBySlot(), trade_iterator.toBotSlot, (trade_iterator.tradeItemInstance ? trade_iterator.tradeItemInstance->GetItem()->Name : "nullptr")); m_inv.PutItem(trade_iterator.toBotSlot, *trade_iterator.tradeItemInstance); this->BotAddEquipItem(trade_iterator.toBotSlot, (trade_iterator.tradeItemInstance ? trade_iterator.tradeItemInstance->GetID() : 0)); @@ -4190,9 +4190,9 @@ bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::Sk Mob *my_owner = GetBotOwner(); if (my_owner && my_owner->IsClient() && my_owner->CastToClient()->GetBotOptionDeathMarquee()) { if (killerMob) - my_owner->CastToClient()->SendMarqueeMessage(CC_Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain by %s", GetCleanName(), killerMob->GetCleanName())); + my_owner->CastToClient()->SendMarqueeMessage(Chat::Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain by %s", GetCleanName(), killerMob->GetCleanName())); else - my_owner->CastToClient()->SendMarqueeMessage(CC_Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain", GetCleanName())); + my_owner->CastToClient()->SendMarqueeMessage(Chat::Yellow, 510, 0, 1000, 3000, StringFormat("%s has been slain", GetCleanName())); } Mob *give_exp = hate_list.GetDamageTopOnHateList(this); From e9cb8781bfeb30e4625a8d020d3d1a6276f128f2 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 01:32:51 -0500 Subject: [PATCH 152/491] More build fixes for bot --- zone/bot_command.cpp | 6 +++--- zone/client_packet.cpp | 2 +- zone/effects.cpp | 2 +- zone/forage.cpp | 2 +- zone/oldcode.cpp | 2 +- zone/spells.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index fc5b78ff1..749553de1 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -84,7 +84,7 @@ namespace { //#define BCSTSPELLDUMP // only needed if you're adding/tailoring bot command spells and need a file dump -#define m_message Chat::WhiteSmoke +#define m_message Chat::White #define m_action Chat::Yellow #define m_note Chat::Gray #define m_usage Chat::Cyan @@ -7310,7 +7310,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) itm = itminst->GetItem(); if (itminst && itm && c->CheckLoreConflict(itm)) { - c->MessageString(Chat::WhiteSmoke, PICK_LORE); + c->MessageString(Chat::White, PICK_LORE); return; } @@ -7324,7 +7324,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep) if (!c->CheckLoreConflict(itma->GetItem())) continue; - c->MessageString(Chat::WhiteSmoke, PICK_LORE); + c->MessageString(Chat::White, PICK_LORE); return; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index e0ae5562e..38e7aaff4 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4825,7 +4825,7 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) Message(0, "This corpse can be resurrected for %i minutes and %i seconds.", min, sec); } else { - MessageString(Chat::WhiteSmoke, CORPSE_TOO_OLD); + MessageString(Chat::White, CORPSE_TOO_OLD); } */ } diff --git a/zone/effects.cpp b/zone/effects.cpp index f6996c030..25923b35f 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -623,7 +623,7 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) { /*char val1[20]={0};*/ //unused /*char val2[20]={0};*/ //unused uint32 remain = p_timers.GetRemainingTime(DiscTimer); - //MessageString(Chat::WhiteSmoke, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); + //MessageString(Chat::White, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2)); Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60)); return(false); } diff --git a/zone/forage.cpp b/zone/forage.cpp index c3310a0d3..12d2f61a1 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -223,7 +223,7 @@ void Client::GoFish() //TODO: generate a message if we're already fishing /*if (!fishing_timer.Check()) { //this isn't the right check, may need to add something to the Client class like 'bool is_fishing' - MessageString(Chat::WhiteSmoke, ALREADY_FISHING); //You are already fishing! + MessageString(Chat::White, ALREADY_FISHING); //You are already fishing! return; }*/ diff --git a/zone/oldcode.cpp b/zone/oldcode.cpp index 9f20f686c..7329c73f3 100644 --- a/zone/oldcode.cpp +++ b/zone/oldcode.cpp @@ -1198,7 +1198,7 @@ Message(0, "Disc packet id=%d, %x,%x,%x", disc_in->disc_id, disc_in->unknown3[0] char val1[20]={0}; char val2[20]={0}; uint32 remain = p_timers.GetRemainingTime(pTimerDisciplineReuse); - MessageString(Chat::WhiteSmoke,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); + MessageString(Chat::White,DISCIPLINE_CANUSEIN,ConvertArray((remain)/60,val1),ConvertArray(remain%60,val2)); //Message(0,"You can use a new discipline in %i minutes %i seconds.", (disc_timer.GetRemainingTime()/1000)/60, disc_timer.GetRemainingTime()/1000%60); return; } diff --git a/zone/spells.cpp b/zone/spells.cpp index e0ade3798..9392ab7af 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -4004,7 +4004,7 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) /* if(!can_rez) { if(Caster && Caster->IsClient()) - Caster->MessageString(Chat::WhiteSmoke, CORPSE_TOO_OLD); + Caster->MessageString(Chat::White, CORPSE_TOO_OLD); return; } */ From 1c6a76246f14c9738d22fac2e62642fed5d9fd52 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 02:40:23 -0500 Subject: [PATCH 153/491] Added bulk edit command #npceditmass --- changelog.txt | 3 +++ common/string_util.cpp | 22 +++++++++++----- common/string_util.h | 2 +- zone/command.cpp | 59 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/changelog.txt b/changelog.txt index 3f69bf570..43451a7ea 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 8/11/2019 == +Akkadius: Added bulk edit command #npceditmass + == 8/6/2019 == Akkadius: Optimizations to movement updates to eliminate ghosting possibilities in larger zones diff --git a/common/string_util.cpp b/common/string_util.cpp index b12811159..ec53663cc 100644 --- a/common/string_util.cpp +++ b/common/string_util.cpp @@ -27,6 +27,8 @@ #else #include #include +#include + #endif #ifndef va_copy @@ -119,19 +121,27 @@ std::vector SplitString(const std::string &str, char delim) { while(std::getline(ss, item, delim)) { ret.push_back(item); } - + return ret; } -static std::string implode(char *sep, std::vector src) +std::string implode(std::string glue, std::vector src) { - std::ostringstream output; + if (src.empty()) { + return {}; + } + + std::ostringstream output; std::vector::iterator src_iter; - for (src_iter = src.begin(); src_iter != src.end(); src_iter++) - output << *src_iter << sep; + for (src_iter = src.begin(); src_iter != src.end(); src_iter++) { + output << *src_iter << glue; + } - return output.str(); + std::string final_output = output.str(); + final_output.resize (output.str().size () - glue.size()); + + return final_output; } std::string EscapeString(const std::string &s) { diff --git a/common/string_util.h b/common/string_util.h index cf1dbc761..23a8af05b 100644 --- a/common/string_util.h +++ b/common/string_util.h @@ -30,7 +30,7 @@ const std::string ucfirst(std::string s); std::vector split(std::string str_to_split, char delimiter); const std::string StringFormat(const char* format, ...); const std::string vStringFormat(const char* format, va_list args); -static std::string implode(char *sep, std::vector src); +std::string implode(std::string glue, std::vector src); std::vector SplitString(const std::string &s, char delim); std::string EscapeString(const char *src, size_t sz); std::string EscapeString(const std::string &s); diff --git a/zone/command.cpp b/zone/command.cpp index 5ee0f1b1c..725f40ea5 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -7337,6 +7337,15 @@ void command_npceditmass(Client *c, const Seperator *sep) zone->GetInstanceVersion() ); + std::string status = "(Searching)"; + + if (strcasecmp(sep->arg[5], "apply") == 0) { + status = "(Applying)"; + } + + std::vector npc_ids; + + int found_count = 0; results = database.QueryDatabase(query); for (auto row = results.begin(); row != results.end(); ++row) { @@ -7352,16 +7361,60 @@ void command_npceditmass(Client *c, const Seperator *sep) c->Message( 15, fmt::format( - "NPC ({0}) [{1}] ({2}) [{3}] Current ({4}) [{5}] New [{6}]", + "NPC ({0}) [{1}] ({2}) [{3}] Current ({4}) [{5}] New [{6}] {7}", npc_id, npc_name, search_column, search_column_value, change_column, change_column_current_value, - change_value + change_value, + status ).c_str() ); + + npc_ids.push_back(npc_id); + + found_count++; + } + + std::string saylink = fmt::format( + "#npceditmass {} {} {} {} apply", + search_column, + search_value, + change_column, + change_value + ); + + if (strcasecmp(sep->arg[5], "apply") == 0) { + std::string npc_ids_string = implode(",", npc_ids); + if (npc_ids_string.empty()) { + c->Message(Chat::Red, "Error: Ran into an unknown error compiling NPC IDs"); + return; + } + + database.QueryDatabase( + fmt::format( + "UPDATE `npc_types` SET {} = {} WHERE id IN ({})", + change_column, + change_value, + npc_ids_string + ) + ); + + c->Message(Chat::Yellow, "Changes applied to (%i) NPC's", found_count); + zone->Repop(); + } + else { + c->Message(Chat::Yellow, "Found (%i) NPC's that match this search...", found_count); + + if (found_count > 0) { + c->Message( + Chat::Yellow, "To apply these changes, click <%s> or type [%s]", + EQEmu::SayLinkEngine::GenerateQuestSaylink(saylink, false, "Apply").c_str(), + saylink.c_str() + ); + } } } @@ -12232,7 +12285,7 @@ void command_scale(Client *c, const Seperator *sep) c->Message(Chat::Yellow, "Found (%i) NPC's that match this search...", found_count); c->Message( - 15, "To apply these changes, click <%s> or type %s", + Chat::Yellow, "To apply these changes, click <%s> or type %s", EQEmu::SayLinkEngine::GenerateQuestSaylink(saylink, false, "Apply").c_str(), saylink.c_str() ); From 1ef577bc2576912fd691f0efd26bc295d5c45175 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Sun, 11 Aug 2019 03:20:38 -0500 Subject: [PATCH 154/491] Modifications to findzone --- changelog.txt | 2 + zone/command.cpp | 114 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 81 insertions(+), 35 deletions(-) diff --git a/changelog.txt b/changelog.txt index 43451a7ea..afef68a37 100644 --- a/changelog.txt +++ b/changelog.txt @@ -2,6 +2,8 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- == 8/11/2019 == Akkadius: Added bulk edit command #npceditmass +Akkadius: Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances +Akkadius: Added #findzone expansion to show zones via expansion == 8/6/2019 == Akkadius: Optimizations to movement updates to eliminate ghosting possibilities in larger zones diff --git a/zone/command.cpp b/zone/command.cpp index 725f40ea5..1dff2cd9e 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -3720,49 +3720,93 @@ void command_findnpctype(Client *c, const Seperator *sep) void command_findzone(Client *c, const Seperator *sep) { - if(sep->arg[1][0] == 0) { + if (sep->arg[1][0] == 0) { c->Message(Chat::White, "Usage: #findzone [search criteria]"); - return; - } + c->Message(Chat::White, "Usage: #findzone expansion [expansion number]"); + return; + } - std::string query; - int id = atoi((const char *)sep->arg[1]); - if (id == 0) { // If id evaluates to 0, then search as if user entered a string. - auto escName = new char[strlen(sep->arg[1]) * 2 + 1]; - database.DoEscapeString(escName, sep->arg[1], strlen(sep->arg[1])); + std::string query; + int id = atoi((const char *) sep->arg[1]); - query = StringFormat("SELECT zoneidnumber, short_name, long_name FROM zone " - "WHERE long_name RLIKE '%s' AND version = 0", - escName); - safe_delete_array(escName); - } - else // Otherwise, look for just that zoneidnumber. - query = StringFormat("SELECT zoneidnumber, short_name, long_name FROM zone " - "WHERE zoneidnumber = %i AND version = 0", id); + std::string arg1 = sep->arg[1]; - auto results = database.QueryDatabase(query); - if (!results.Success()) { - c->Message (0, "Error querying database."); - c->Message (0, query.c_str()); - return; - } + if (arg1 == "expansion") { + query = fmt::format( + "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE expansion = {}", + sep->arg[2] + ); + } + else { - int count = 0; - const int maxrows = 20; + /** + * If id evaluates to 0, then search as if user entered a string + */ + if (id == 0) { + query = fmt::format( + "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE long_name LIKE '%{}%'", + EscapeString(sep->arg[1]) + ); + } + else { + query = fmt::format( + "SELECT zoneidnumber, short_name, long_name, version FROM zone WHERE zoneidnumber = {}", + id + ); + } + } - for(auto row = results.begin(); row != results.end(); ++row) { - if (++count > maxrows) { - c->Message (0, "%i zones shown. Too many results.", maxrows); - break; - } + auto results = database.QueryDatabase(query); + if (!results.Success()) { + c->Message(Chat::White, "Error querying database."); + c->Message(Chat::White, query.c_str()); + return; + } - c->Message (0, " %s: %s, %s", row[0], row[1], row[2]); - } + int count = 0; + const int maxrows = 100; - if (count <= maxrows) - c->Message (0, "Query complete. %i rows shown.", count); - else if (count == 0) - c->Message (0, "No matches found for %s.", sep->arg[1]); + for (auto row = results.begin(); row != results.end(); ++row) { + std::string zone_id = row[0]; + std::string short_name = row[1]; + std::string long_name = row[2]; + int version = atoi(row[3]); + + if (++count > maxrows) { + c->Message(Chat::White, "%i zones shown. Too many results.", maxrows); + break; + } + + std::string command_zone = EQEmu::SayLinkEngine::GenerateQuestSaylink("#zone " + short_name, false, "zone"); + std::string command_gmzone = EQEmu::SayLinkEngine::GenerateQuestSaylink( + fmt::format("#gmzone {} {}", short_name, version), + false, + "gmzone" + ); + + c->Message( + Chat::White, + fmt::format( + "[{}] [{}] [{}] Version ({}) [{}]", + (version == 0 ? command_zone : "zone"), + command_gmzone, + short_name, + version, + long_name + ).c_str() + ); + } + + if (count <= maxrows) { + c->Message( + Chat::White, + "Query complete. %i rows shown. %s", + count, + (arg1 == "expansion" ? "(expansion search)" : "")); + } + else if (count == 0) { + c->Message(Chat::White, "No matches found for %s.", sep->arg[1]); + } } void command_viewnpctype(Client *c, const Seperator *sep) From 963da7050602be1173328e3b1350fcd432c6905c Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 13 Aug 2019 15:11:37 -0400 Subject: [PATCH 155/491] Change how we handle null quest initiator in QuestManager::say Timers etc triggered say's don't have an initiator but should still work. The target ID is set in QuestJournalledSay for us so not needed here --- zone/questmgr.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 9c8898b2e..19c779d87 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -161,12 +161,10 @@ void QuestManager::say(const char *str, Journal::Options &opts) { return; } else { - if (!RuleB(NPC, EnableNPCQuestJournal)) + // if there is no initiator we still want stuff to work (timers, signals, waypoints, etc) + if (!RuleB(NPC, EnableNPCQuestJournal) || initiator == nullptr) opts.journal_mode = Journal::Mode::None; - if (initiator) { - opts.target_spawn_id = initiator->GetID(); - owner->QuestJournalledSay(initiator, str, opts); - } + owner->QuestJournalledSay(initiator, str, opts); } } From 7b4908957d7f9aee02e1e2095160b768bc505100 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 13 Aug 2019 15:19:20 -0400 Subject: [PATCH 156/491] Clean up EntityList::QuestJournalledSayClose --- zone/entity.cpp | 4 ++-- zone/entity.h | 2 +- zone/mob.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zone/entity.cpp b/zone/entity.cpp index 9003dc7f6..be5f249bc 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3923,8 +3923,8 @@ bool Entity::CheckCoordLosNoZLeaps(float cur_x, float cur_y, float cur_z, return false; } -void EntityList::QuestJournalledSayClose(Mob *sender, Client *QuestInitiator, - float dist, const char* mobname, const char* message, Journal::Options &opts) +void EntityList::QuestJournalledSayClose(Mob *sender, float dist, const char *mobname, const char *message, + Journal::Options &opts) { SerializeBuffer buf(sizeof(SpecialMesgHeader_Struct) + 12 + 64 + 64); diff --git a/zone/entity.h b/zone/entity.h index 3f6581ca6..339bbfd8a 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -368,7 +368,7 @@ public: void SendNimbusEffects(Client *c); void SendUntargetable(Client *c); void DuelMessage(Mob* winner, Mob* loser, bool flee); - void QuestJournalledSayClose(Mob *sender, Client *QuestIntiator, float dist, const char* mobname, const char* message, Journal::Options &opts); + void QuestJournalledSayClose(Mob *sender, float dist, const char* mobname, const char* message, Journal::Options &opts); void GroupMessage(uint32 gid, const char *from, const char *message); void ExpeditionWarning(uint32 minutes_left); diff --git a/zone/mob.cpp b/zone/mob.cpp index 108749f0b..b8bedc994 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2924,7 +2924,7 @@ void Mob::QuestJournalledSay(Client *QuestInitiator, const char *str, Journal::O if (opts.target_spawn_id == 0 && QuestInitiator) opts.target_spawn_id = QuestInitiator->GetID(); - entity_list.QuestJournalledSayClose(this, QuestInitiator, 200, GetCleanName(), str, opts); + entity_list.QuestJournalledSayClose(this, 200, GetCleanName(), str, opts); } const char *Mob::GetCleanName() From ef6b2976a36f3daec28abf5324a3c5218bd8e70e Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Wed, 14 Aug 2019 23:06:34 -0400 Subject: [PATCH 157/491] Make SE_SummonPC only clear aggro for beneficial spells --- zone/spell_effects.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 6286f9c51..cc9ead157 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -2116,7 +2116,10 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove caster->GetY(), caster->GetZ(), caster->GetHeading(), 2, SummonPC); Message(Chat::Yellow, "You have been summoned!"); - entity_list.ClearAggro(this); + // only for beneficial spells like Call of the Hero + // This clear probably isn't actually needed, but need to investigate more + if (IsBeneficialSpell(spell_id)) + entity_list.ClearAggro(this); } else caster->Message(Chat::Red, "This spell can only be cast on players."); From 65c05f227b97e43fae6f70b8bbb64d8654021b9a Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 15 Aug 2019 21:10:51 -0400 Subject: [PATCH 158/491] Added zlib1.dll debug symbols to eqemu_server.pl download [skip ci] --- utils/scripts/eqemu_server.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index b2a53b864..d3a6936c5 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -454,6 +454,8 @@ sub do_installer_routines { fetch_latest_windows_appveyor(); get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); + get_remote_file($install_repository_request_url . "zlib1.ilk", "zlib1.ilk", 1); + get_remote_file($install_repository_request_url . "zlib1.pdb", "zlib1.pdb", 1); get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); } @@ -1642,9 +1644,11 @@ sub check_windows_firewall_rules { } sub fetch_server_dlls { - print "[Download] Fetching lua51.dll, zlib1.dll, libmysql.dll...\n"; + print "[Download] Fetching lua51.dll, zlib1.dll, zlib1.ilk, zlib1.pdb, libmysql.dll...\n"; get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); + get_remote_file($install_repository_request_url . "zlib1.ilk", "zlib1.ilk", 1); + get_remote_file($install_repository_request_url . "zlib1.pdb", "zlib1.pdb", 1); get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); } From 1f4753b71931bfdb4bd4eb76d807e8c1abd73a0e Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Thu, 15 Aug 2019 20:20:33 -0500 Subject: [PATCH 159/491] Create SECURITY.md --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..8cacbe80e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution From 9476f9e4172fa52ab97b8dccec742ede916aedbb Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Thu, 15 Aug 2019 20:21:09 -0500 Subject: [PATCH 160/491] Update SECURITY.md --- SECURITY.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 8cacbe80e..0a653b06f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,3 @@ -# Security Policy - -## Reporting a Vulnerability +# Security Policy - Reporting Vulnerabilities When reporting active hacks, exploits and other vulnerabilities, please describe how to reproduce said report and if you can provide context into a possible solution From 537e3931efa26bb8a55638db1ae2d745bb7a43ee Mon Sep 17 00:00:00 2001 From: Uleat Date: Thu, 15 Aug 2019 22:20:58 -0400 Subject: [PATCH 161/491] Don't need the zlib1.ilk file... [skip ci] --- utils/scripts/eqemu_server.pl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/utils/scripts/eqemu_server.pl b/utils/scripts/eqemu_server.pl index d3a6936c5..ef8b0babd 100644 --- a/utils/scripts/eqemu_server.pl +++ b/utils/scripts/eqemu_server.pl @@ -454,7 +454,6 @@ sub do_installer_routines { fetch_latest_windows_appveyor(); get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); - get_remote_file($install_repository_request_url . "zlib1.ilk", "zlib1.ilk", 1); get_remote_file($install_repository_request_url . "zlib1.pdb", "zlib1.pdb", 1); get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); } @@ -1644,10 +1643,9 @@ sub check_windows_firewall_rules { } sub fetch_server_dlls { - print "[Download] Fetching lua51.dll, zlib1.dll, zlib1.ilk, zlib1.pdb, libmysql.dll...\n"; + print "[Download] Fetching lua51.dll, zlib1.dll, zlib1.pdb, libmysql.dll...\n"; get_remote_file($install_repository_request_url . "lua51.dll", "lua51.dll", 1); get_remote_file($install_repository_request_url . "zlib1.dll", "zlib1.dll", 1); - get_remote_file($install_repository_request_url . "zlib1.ilk", "zlib1.ilk", 1); get_remote_file($install_repository_request_url . "zlib1.pdb", "zlib1.pdb", 1); get_remote_file($install_repository_request_url . "libmysql.dll", "libmysql.dll", 1); } From c149e6ca5f99da517143ef0fe8b6c3449e0020ae Mon Sep 17 00:00:00 2001 From: Akkadius Date: Thu, 15 Aug 2019 22:56:03 -0500 Subject: [PATCH 162/491] Add a heading option to #goto --- zone/command.cpp | 91 +++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/zone/command.cpp b/zone/command.cpp index 1dff2cd9e..1640994c6 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -223,7 +223,7 @@ int command_init(void) command_add("gm", "- Turn player target's or your GM flag on or off", 80, command_gm) || command_add("gmspeed", "[on/off] - Turn GM speed hack on/off for you or your player target", 100, command_gmspeed) || command_add("gmzone", "[zone_short_name] [zone_version=0] [identifier=gmzone] - Zones to a private GM instance", 100, command_gmzone) || - command_add("goto", "[x] [y] [z] - Teleport to the provided coordinates or to your target", 10, command_goto) || + command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", 10, command_goto) || command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", 170, command_grid) || command_add("guild", "- Guild manipulation commands. Use argument help for more info.", 10, command_guild) || command_add("guildapprove", "[guildapproveid] - Approve a guild with specified ID (guild creator receives the id)", 0, command_guildapprove) || @@ -5501,23 +5501,23 @@ void command_loc(Client *c, const Seperator *sep) void command_goto(Client *c, const Seperator *sep) { - /** - * Goto via target and no args - */ - if (sep->arg[1][0] == '\0' && c->GetTarget()) { + std::string arg1 = sep->arg[1]; + + bool goto_via_target_no_args = sep->arg[1][0] == '\0' && c->GetTarget(); + bool goto_via_player_name = !sep->IsNumber(1) && !arg1.empty(); + bool goto_via_x_y_z = sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3); + + if (goto_via_target_no_args) { c->MovePC( zone->GetZoneID(), zone->GetInstanceID(), c->GetTarget()->GetX(), c->GetTarget()->GetY(), c->GetTarget()->GetZ(), - c->GetTarget()->GetHeading()); + c->GetTarget()->GetHeading() + ); } - - /** - * Goto via player name - */ - else if (!sep->IsNumber(1) && sep->arg[1]) { + else if (goto_via_player_name) { /** * Find them in zone first @@ -5532,7 +5532,8 @@ void command_goto(Client *c, const Seperator *sep) client->GetX(), client->GetY(), client->GetZ(), - client->GetHeading()); + client->GetHeading() + ); c->Message(Chat::Yellow, "Goto player '%s' same zone", player_name_string.c_str()); } @@ -5543,21 +5544,18 @@ void command_goto(Client *c, const Seperator *sep) c->Message(Chat::Yellow, "Player '%s' not found", player_name_string.c_str()); } } - - /** - * Goto via x y z - */ - else if (sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3)) { + else if (goto_via_x_y_z) { c->MovePC( zone->GetZoneID(), zone->GetInstanceID(), atof(sep->arg[1]), atof(sep->arg[2]), atof(sep->arg[3]), - c->GetHeading()); + (sep->arg[4] ? atof(sep->arg[4]) : c->GetHeading()) + ); } else { - c->Message(Chat::White, "Usage: #goto [x y z]"); + c->Message(Chat::White, "Usage: #goto [x y z] [h]"); c->Message(Chat::White, "Usage: #goto [player_name]"); } } @@ -6696,47 +6694,54 @@ void command_wpinfo(Client *c, const Seperator *sep) void command_wpadd(Client *c, const Seperator *sep) { - int type1=0, - type2=0, - pause=0; // Defaults for a new grid + int type1 = 0, + type2 = 0, + pause = 0; // Defaults for a new grid - Mob *t=c->GetTarget(); - if (t && t->IsNPC()) - { - Spawn2* s2info = t->CastToNPC()->respawn2; + Mob *target = c->GetTarget(); + if (target && target->IsNPC()) { + Spawn2 *s2info = target->CastToNPC()->respawn2; - if(s2info == nullptr) // Can't figure out where this mob's spawn came from... maybe a dynamic mob created by #spawn + if (s2info == + nullptr) // Can't figure out where this mob's spawn came from... maybe a dynamic mob created by #spawn { - c->Message(Chat::White,"#wpadd FAILED -- Can't determine which spawn record in the database this mob came from!"); + c->Message( + Chat::White, + "#wpadd FAILED -- Can't determine which spawn record in the database this mob came from!" + ); return; } - if (sep->arg[1][0]) - { - if (atoi(sep->arg[1]) >= 0) - pause=atoi(sep->arg[1]); - else - { - c->Message(Chat::White,"Usage: #wpadd [pause] [-h]"); + if (sep->arg[1][0]) { + if (atoi(sep->arg[1]) >= 0) { + pause = atoi(sep->arg[1]); + } + else { + c->Message(Chat::White, "Usage: #wpadd [pause] [-h]"); return; } } auto position = c->GetPosition(); - if (strcmp("-h",sep->arg[2]) != 0) + if (strcmp("-h", sep->arg[2]) != 0) { position.w = -1; + } uint32 tmp_grid = database.AddWPForSpawn(c, s2info->GetID(), position, pause, type1, type2, zone->GetZoneID()); - if (tmp_grid) - t->CastToNPC()->SetGrid(tmp_grid); + if (tmp_grid) { + target->CastToNPC()->SetGrid(tmp_grid); + } - t->CastToNPC()->AssignWaypoints(t->CastToNPC()->GetGrid()); - c->Message(Chat::White,"Waypoint added. Use #wpinfo to see waypoints for this NPC (may need to #repop first)."); + target->CastToNPC()->AssignWaypoints(target->CastToNPC()->GetGrid()); + c->Message( + Chat::White, + "Waypoint added. Use #wpinfo to see waypoints for this NPC (may need to #repop first)." + ); + } + else { + c->Message(Chat::White, "You must target an NPC to use this."); } - else - c->Message(Chat::White,"You must target an NPC to use this."); } - void command_interrupt(Client *c, const Seperator *sep) { uint16 ci_message=0x01b7, ci_color=0x0121; From 05e7c473df4c8e8246603938766e14692197187e Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 16 Aug 2019 03:25:34 -0500 Subject: [PATCH 163/491] Simplified the use of roamboxes and improved the AI for roambox pathing --- changelog.txt | 8 + zone/aggro.cpp | 6 +- zone/api_service.cpp | 2 +- zone/attack.cpp | 1 + zone/command.cpp | 121 +++++++++++++-- zone/command.h | 1 + zone/entity.cpp | 2 +- zone/lua_npc.cpp | 25 +++- zone/lua_npc.h | 3 + zone/mob.cpp | 6 +- zone/mob_ai.cpp | 68 +++++++-- zone/mob_info.cpp | 2 +- zone/npc.cpp | 72 +++++---- zone/npc.h | 20 +-- zone/perl_npc.cpp | 41 +++++- zone/questmgr.cpp | 77 +++++----- zone/spawn2.cpp | 9 +- zone/spawngroup.cpp | 341 ++++++++++++++++++++++++++++++------------- zone/spawngroup.h | 55 ++++--- zone/waypoints.cpp | 19 ++- zone/zone.cpp | 2 + zone/zonedb.h | 2 +- 22 files changed, 638 insertions(+), 245 deletions(-) diff --git a/changelog.txt b/changelog.txt index afef68a37..b62f810be 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,13 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 8/16/2019 == +Akkadius: Simplified the use of roamboxes and improved the AI for roambox pathing https://i.imgur.com/z33u7y9.gif +Akkadius: Implemented command #roambox set [move_delay] +Akkadius: Implemented command #roambox remove +Akkadius: Implemented LUA NPC:SetSimpleRoamBox(box_size, [move_distance], [move_delay]); +Akkadius: Implemented Perl $npc->SetSimpleRoamBox(box_size, [move_distance], [move_delay]); +Akkadius: Spawngroup data now hot reloads on #repop + == 8/11/2019 == Akkadius: Added bulk edit command #npceditmass Akkadius: Modified #findzone to include clickable saylinks to both regular zone (if able) and private gmzone instances diff --git a/zone/aggro.cpp b/zone/aggro.cpp index ca565e0b9..490bf7bbf 100644 --- a/zone/aggro.cpp +++ b/zone/aggro.cpp @@ -973,11 +973,13 @@ bool Mob::CombatRange(Mob* other) } //Father Nitwit's LOS code -bool Mob::CheckLosFN(Mob* other) { +bool Mob::CheckLosFN(Mob *other) +{ bool Result = false; - if(other) + if (other) { Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize()); + } SetLastLosState(Result); diff --git a/zone/api_service.cpp b/zone/api_service.cpp index 957d2b012..b8ae1149e 100644 --- a/zone/api_service.cpp +++ b/zone/api_service.cpp @@ -225,7 +225,7 @@ Json::Value ApiGetNpcListDetail(EQ::Net::WebsocketServerConnection *connection, row["sec_skill"] = npc->GetSecSkill(); row["silver"] = npc->GetSilver(); row["slow_mitigation"] = npc->GetSlowMitigation(); - row["sp2"] = npc->GetSp2(); + row["spawn_group_id"] = npc->GetSpawnGroupId(); row["swarm_owner"] = npc->GetSwarmOwner(); row["swarm_target"] = npc->GetSwarmTarget(); row["waypoint_max"] = npc->GetWaypointMax(); diff --git a/zone/attack.cpp b/zone/attack.cpp index 780a8fba4..3dca5f8c3 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "lua_parser.h" #include "fastmath.h" #include "mob.h" +#include "npc.h" #include diff --git a/zone/command.cpp b/zone/command.cpp index 1640994c6..babe3ec24 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -346,6 +346,7 @@ int command_init(void) command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) || command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) || command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) || + command_add("roambox", "Manages roambox settings for an NPC", 200, command_roambox) || command_add("rules", "(subcommand) - Manage server rules", 250, command_rules) || command_add("save", "- Force your player or player corpse target to be saved to the database", 50, command_save) || command_add("scale", "- Handles npc scaling", 150, command_scale) || @@ -1820,7 +1821,7 @@ void command_npcstats(Client *c, const Seperator *sep) //c->Message(Chat::White, "Weapon Item Number: %s", target_npc->GetWeapNo()); c->Message(Chat::White, "- Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType()); c->Message(Chat::White, "- Runspeed: %.3f Walkspeed: %.3f", static_cast(0.025f * target_npc->GetRunspeed()), static_cast(0.025f * target_npc->GetWalkspeed())); - c->Message(Chat::White, "- Spawn Group: %i Grid: %i", target_npc->GetSp2(), target_npc->GetGrid()); + c->Message(Chat::White, "- Spawn Group: %i Grid: %i", target_npc->GetSpawnGroupId(), target_npc->GetGrid()); if (target_npc->proximity) { c->Message(Chat::White, "- Proximity: Enabled"); c->Message(Chat::White, "-- Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ()); @@ -7199,6 +7200,96 @@ void command_revoke(Client *c, const Seperator *sep) safe_delete(outapp); } +void command_roambox(Client *c, const Seperator *sep) +{ + std::string arg1 = sep->arg[1]; + + Mob *target = c->GetTarget(); + if (!target || !target->IsNPC()) { + c->Message(Chat::Red, "You need a valid NPC target for this command"); + return; + } + + NPC *npc = dynamic_cast(target); + int spawn_group_id = npc->GetSpawnGroupId(); + if (spawn_group_id <= 0) { + c->Message(Chat::Red, "NPC needs a valid SpawnGroup!"); + return; + } + + if (arg1 == "set") { + int box_size = (sep->arg[2] ? atoi(sep->arg[2]) : 0); + int delay = (sep->arg[3] ? atoi(sep->arg[3]) : 15000); + if (box_size > 0) { + std::string query = fmt::format( + SQL( + UPDATE spawngroup SET + dist = {}, + min_x = {}, + max_x = {}, + min_y = {}, + max_y = {}, + delay = {} + WHERE id = {} + ), + box_size, + npc->GetX() - 100, + npc->GetX() + 100, + npc->GetY() - 100, + npc->GetY() + 100, + delay, + spawn_group_id + ); + + database.QueryDatabase(query); + + c->Message( + Chat::Yellow, + "NPC (%s) Roam Box set to box size of [%i] SpawnGroupId [%i] delay [%i]", + npc->GetCleanName(), + box_size, + spawn_group_id, + delay + ); + + return; + } + + c->Message(Chat::Red, "Box size must be set!"); + } + + if (arg1 == "remove") { + std::string query = fmt::format( + SQL( + UPDATE spawngroup SET + dist = 0, + min_x = 0, + max_x = 0, + min_y = 0, + max_y = 0, + delay = 0 + WHERE id = {} + ), + spawn_group_id + ); + + database.QueryDatabase(query); + + c->Message( + Chat::Yellow, + "NPC (%s) Roam Box has been removed from SpawnGroupID [%i]", + npc->GetCleanName(), + spawn_group_id + ); + + return; + } + + c->Message(Chat::Yellow, "> Command Usage"); + c->Message(Chat::Yellow, "#roambox set box_size [delay = 0]"); + c->Message(Chat::Yellow, "#roambox remove"); +} + void command_oocmute(Client *c, const Seperator *sep) { if(sep->arg[1][0] == 0 || !(sep->arg[1][0] == '1' || sep->arg[1][0] == '0')) @@ -7213,16 +7304,15 @@ void command_oocmute(Client *c, const Seperator *sep) void command_checklos(Client *c, const Seperator *sep) { - if(c->GetTarget()) - { -// if(c->CheckLos(c->GetTarget())) - if(c->CheckLosFN(c->GetTarget())) - c->Message(Chat::White, "You have LOS to %s", c->GetTarget()->GetName()); - else - c->Message(Chat::White, "You do not have LOS to %s", c->GetTarget()->GetName()); + if (c->GetTarget()) { + if (c->CheckLosFN(c->GetTarget())) { + c->Message(Chat::White, "You have LOS to %s", c->GetTarget()->GetName()); + } + else { + c->Message(Chat::White, "You do not have LOS to %s", c->GetTarget()->GetName()); + } } - else - { + else { c->Message(Chat::White, "ERROR: Target required"); } } @@ -8102,8 +8192,10 @@ void command_npcedit(Client *c, const Seperator *sep) return; } - c->Message(Chat::Yellow,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, c->GetTarget()->CastToNPC()->GetSp2() ); - std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation, c->GetTarget()->CastToNPC()->GetSp2()); + c->Message(Chat::Yellow,"NPCID %u now has the animation set to %i on spawn with spawngroup %i", npcTypeID, animation, + c->GetTarget()->CastToNPC()->GetSpawnGroupId() ); + std::string query = StringFormat("UPDATE spawn2 SET animation = %i " "WHERE spawngroupID = %i", animation, + c->GetTarget()->CastToNPC()->GetSpawnGroupId()); database.QueryDatabase(query); c->GetTarget()->SetAppearance(EmuAppearance(animation)); @@ -9437,7 +9529,7 @@ void command_advnpcspawn(Client *c, const Seperator *sep) int16 version = atoi(sep->arg[2]); std::string query = StringFormat("UPDATE spawn2 SET version = %i " "WHERE spawngroupID = '%i'", - version, c->GetTarget()->CastToNPC()->GetSp2()); + version, c->GetTarget()->CastToNPC()->GetSpawnGroupId()); auto results = database.QueryDatabase(query); if (!results.Success()) { c->Message(Chat::Red, "Update failed! MySQL gave the following error:"); @@ -9445,7 +9537,8 @@ void command_advnpcspawn(Client *c, const Seperator *sep) return; } - c->Message(Chat::White, "Version change to %i was successful from SpawnGroupID %i", version, c->GetTarget()->CastToNPC()->GetSp2()); + c->Message(Chat::White, "Version change to %i was successful from SpawnGroupID %i", version, + c->GetTarget()->CastToNPC()->GetSpawnGroupId()); c->GetTarget()->Depop(false); return; diff --git a/zone/command.h b/zone/command.h index d6ce90a23..422c61ec0 100644 --- a/zone/command.h +++ b/zone/command.h @@ -248,6 +248,7 @@ void command_repopclose(Client *c, const Seperator *sep); void command_resetaa(Client* c,const Seperator *sep); void command_resetaa_timer(Client *c, const Seperator *sep); void command_revoke(Client *c, const Seperator *sep); +void command_roambox(Client *c, const Seperator *sep); void command_rules(Client *c, const Seperator *sep); void command_save(Client *c, const Seperator *sep); void command_scale(Client *c, const Seperator *sep); diff --git a/zone/entity.cpp b/zone/entity.cpp index be5f249bc..2a1c76101 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -3728,7 +3728,7 @@ void EntityList::LimitAddNPC(NPC *npc) SpawnLimitRecord r; uint16 eid = npc->GetID(); - r.spawngroup_id = npc->GetSp2(); + r.spawngroup_id = npc->GetSpawnGroupId(); r.npc_type = npc->GetNPCTypeID(); npc_limit_list[eid] = r; diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index cb12bce23..4a8bd12a9 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -159,7 +159,7 @@ void Lua_NPC::SetSaveWaypoint(int wp) { void Lua_NPC::SetSp2(int sg2) { Lua_Safe_Call_Void(); - self->SetSp2(sg2); + self->SetSpawnGroupId(sg2); } int Lua_NPC::GetWaypointMax() { @@ -174,7 +174,7 @@ int Lua_NPC::GetGrid() { uint32 Lua_NPC::GetSp2() { Lua_Safe_Call_Int(); - return self->GetSp2(); + return self->GetSpawnGroupId(); } int Lua_NPC::GetNPCFactionID() { @@ -529,6 +529,24 @@ int Lua_NPC::GetAvoidanceRating() return self->GetAvoidanceRating(); } +void Lua_NPC::SetSimpleRoamBox(float box_size) +{ + Lua_Safe_Call_Void(); + self->SetSimpleRoamBox(box_size); +} + +void Lua_NPC::SetSimpleRoamBox(float box_size, float move_distance) +{ + Lua_Safe_Call_Void(); + self->SetSimpleRoamBox(box_size, move_distance); +} + +void Lua_NPC::SetSimpleRoamBox(float box_size, float move_distance, int move_delay) +{ + Lua_Safe_Call_Void(); + self->SetSimpleRoamBox(box_size, move_distance, move_delay); +} + luabind::scope lua_register_npc() { return luabind::class_("NPC") .def(luabind::constructor<>()) @@ -614,6 +632,9 @@ luabind::scope lua_register_npc() { .def("GetGuardPointZ", (float(Lua_NPC::*)(void))&Lua_NPC::GetGuardPointZ) .def("SetPrimSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetPrimSkill) .def("SetSecSkill", (void(Lua_NPC::*)(int))&Lua_NPC::SetSecSkill) + .def("SetSimpleRoamBox", (void(Lua_NPC::*)(float))&Lua_NPC::SetSimpleRoamBox) + .def("SetSimpleRoamBox", (void(Lua_NPC::*)(float, float))&Lua_NPC::SetSimpleRoamBox) + .def("SetSimpleRoamBox", (void(Lua_NPC::*)(float, float, int))&Lua_NPC::SetSimpleRoamBox) .def("GetPrimSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimSkill) .def("GetSecSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetSecSkill) .def("GetSwarmOwner", (int(Lua_NPC::*)(void))&Lua_NPC::GetSwarmOwner) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 4c407b3fa..92ad73cd7 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -131,6 +131,9 @@ public: void MerchantCloseShop(); int GetRawAC(); int GetAvoidanceRating(); + void SetSimpleRoamBox(float box_size); + void SetSimpleRoamBox(float box_size, float move_distance); + void SetSimpleRoamBox(float box_size, float move_distance, int move_delay); }; #endif diff --git a/zone/mob.cpp b/zone/mob.cpp index b8bedc994..46a5c2fc6 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2789,10 +2789,10 @@ void Mob::WipeHateList() } } -uint32 Mob::RandomTimer(int min,int max) { +uint32 Mob::RandomTimer(int min, int max) +{ int r = 14000; - if(min != 0 && max != 0 && min < max) - { + if (min != 0 && max != 0 && min < max) { r = zone->random.Int(min, max); } return r; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 31a0fcb40..de7cc68dd 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1579,7 +1579,25 @@ void NPC::AI_DoMovement() { if (GetCWP() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) { // We have arrived - time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay); + + int roambox_move_delay = EQEmu::ClampLower(GetRoamboxDelay(), GetRoamboxMinDelay()); + int move_delay_max = (roambox_move_delay > 0 ? roambox_move_delay : (int) GetRoamboxMinDelay() * 4); + int random_timer = RandomTimer( + GetRoamboxMinDelay(), + move_delay_max + ); + + Log( + Logs::Detail, + Logs::NPCRoamBox, "(%s) Timer calc | random_timer [%i] roambox_move_delay [%i] move_min [%i] move_max [%i]", + this->GetCleanName(), + random_timer, + roambox_move_delay, + (int) GetRoamboxMinDelay(), + move_delay_max + ); + + time_until_can_move = Timer::GetCurrentTime() + random_timer; SetCurrentWP(0); return; } @@ -1636,25 +1654,51 @@ void NPC::AI_DoMovement() { } } - roambox_destination_z = 0; - /* - if (zone->zonemap) { - roambox_destination_z = FindGroundZ(roambox_destination_x, roambox_destination_y, this->GetZOffset()); - } - */ + PathfinderOptions opts; + opts.smooth_path = true; + opts.step_size = RuleR(Pathing, NavmeshStepSize); + opts.offset = GetZOffset(); + opts.flags = PathingNotDisabled ^ PathingZoneLine; - Log(Logs::Detail, + auto partial = false; + auto stuck = false; + auto route = zone->pathing->FindPath( + glm::vec3(GetX(), GetY(), GetZ()), + glm::vec3( + roambox_destination_x, + roambox_destination_y, + GetGroundZ(roambox_destination_x, roambox_destination_y) + ), + partial, + stuck, + opts + ); + + if (route.empty()) { + Log( + Logs::Detail, + Logs::NPCRoamBox, "(%s) We don't have a path route... exiting...", + this->GetCleanName() + ); + return; + } + + roambox_destination_z = 0; + + Log( + Logs::General, Logs::NPCRoamBox, - "Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f", + "NPC (%s) distance [%.0f] X (min/max) [%.0f / %.0f] Y (min/max) [%.0f / %.0f] | Dest x/y/z [%.0f / %.0f / %.0f]", this->GetCleanName(), roambox_distance, roambox_min_x, roambox_max_x, - roambox_destination_x, roambox_min_y, roambox_max_y, - roambox_destination_y); - Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z); + roambox_destination_x, + roambox_destination_y, + roambox_destination_z + ); SetCurrentWP(EQEmu::WaypointStatus::RoamBoxPauseInProgress); NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z); diff --git a/zone/mob_info.cpp b/zone/mob_info.cpp index 8cf486dea..edac37768 100644 --- a/zone/mob_info.cpp +++ b/zone/mob_info.cpp @@ -278,7 +278,7 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut return std::to_string((int)npc->GetWalkspeed()); } if (attribute == "spawngroup") { - return std::to_string(npc->GetSp2()); + return std::to_string(npc->GetSpawnGroupId()); } if (attribute == "grid") { return std::to_string(npc->GetGrid()); diff --git a/zone/npc.cpp b/zone/npc.cpp index ebbf5397f..755664f49 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -146,33 +146,33 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi size = GetRaceGenderDefaultHeight(race, gender); } - taunting = false; - proximity = nullptr; - copper = 0; - silver = 0; - gold = 0; - platinum = 0; - max_dmg = npc_type_data->max_dmg; - min_dmg = npc_type_data->min_dmg; - attack_count = npc_type_data->attack_count; - grid = 0; - wp_m = 0; - max_wp = 0; - save_wp = 0; - spawn_group = 0; - swarmInfoPtr = nullptr; - spellscale = npc_type_data->spellscale; - healscale = npc_type_data->healscale; - pAggroRange = npc_type_data->aggroradius; - pAssistRange = npc_type_data->assistradius; - findable = npc_type_data->findable; - trackable = npc_type_data->trackable; - MR = npc_type_data->MR; - CR = npc_type_data->CR; - DR = npc_type_data->DR; - FR = npc_type_data->FR; - PR = npc_type_data->PR; - Corrup = npc_type_data->Corrup; + taunting = false; + proximity = nullptr; + copper = 0; + silver = 0; + gold = 0; + platinum = 0; + max_dmg = npc_type_data->max_dmg; + min_dmg = npc_type_data->min_dmg; + attack_count = npc_type_data->attack_count; + grid = 0; + wp_m = 0; + max_wp = 0; + save_wp = 0; + spawn_group_id = 0; + swarmInfoPtr = nullptr; + spellscale = npc_type_data->spellscale; + healscale = npc_type_data->healscale; + pAggroRange = npc_type_data->aggroradius; + pAssistRange = npc_type_data->assistradius; + findable = npc_type_data->findable; + trackable = npc_type_data->trackable; + MR = npc_type_data->MR; + CR = npc_type_data->CR; + DR = npc_type_data->DR; + FR = npc_type_data->FR; + PR = npc_type_data->PR; + Corrup = npc_type_data->Corrup; PhR = npc_type_data->PhR; STR = npc_type_data->STR; STA = npc_type_data->STA; @@ -1270,7 +1270,7 @@ uint32 ZoneDatabase::CreateNewNPCCommand(const char *zone, uint32 zone_version, } uint32 spawngroupid = results.LastInsertedID(); - spawn->SetSp2(spawngroupid); + spawn->SetSpawnGroupId(spawngroupid); spawn->SetNPCTypeID(npc_type_id); query = StringFormat("INSERT INTO spawn2 (zone, version, x, y, z, respawntime, heading, spawngroupID) " @@ -1355,7 +1355,7 @@ uint32 ZoneDatabase::DeleteSpawnLeaveInNPCTypeTable(const char *zone, Client *cl std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE " "zone='%s' AND spawngroupID=%i", - zone, spawn->GetSp2()); + zone, spawn->GetSpawnGroupId()); auto results = QueryDatabase(query); if (!results.Success()) return 0; @@ -1396,7 +1396,7 @@ uint32 ZoneDatabase::DeleteSpawnRemoveFromNPCTypeTable(const char *zone, uint32 std::string query = StringFormat("SELECT id, spawngroupID FROM spawn2 WHERE zone = '%s' " "AND (version = %u OR version = -1) AND spawngroupID = %i", - zone, zone_version, spawn->GetSp2()); + zone, zone_version, spawn->GetSpawnGroupId()); auto results = QueryDatabase(query); if (!results.Success()) return 0; @@ -2924,3 +2924,15 @@ bool NPC::IsProximitySet() return false; } + +void NPC::SetSimpleRoamBox(float box_size, float move_distance, int move_delay) +{ + AI_SetRoambox( + (move_distance != 0 ? move_distance : box_size / 2), + GetX() + box_size, + GetX() - box_size, + GetY() + box_size, + GetY() - box_size, + move_delay + ); +} \ No newline at end of file diff --git a/zone/npc.h b/zone/npc.h index 1957b8e63..4c913f70d 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -214,13 +214,13 @@ public: virtual int32 CalcMaxMana(); void SetGrid(int32 grid_){ grid=grid_; } - void SetSp2(uint32 sg2){ spawn_group=sg2; } + void SetSpawnGroupId(uint32 sg2){ spawn_group_id =sg2; } void SetWaypointMax(uint16 wp_){ wp_m=wp_; } void SetSaveWaypoint(uint16 wp_){ save_wp=wp_; } uint16 GetWaypointMax() const { return wp_m; } int32 GetGrid() const { return grid; } - uint32 GetSp2() const { return spawn_group; } + uint32 GetSpawnGroupId() const { return spawn_group_id; } uint32 GetSpawnPointID() const; glm::vec4 const GetSpawnPoint() const { return m_SpawnPoint; } @@ -453,6 +453,8 @@ public: bool IgnoreDespawn() { return ignore_despawn; } + void SetSimpleRoamBox(float box_size, float move_distance = 0, int move_delay = 0); + float GetRoamboxMaxX() const; float GetRoamboxMaxY() const; float GetRoamboxMinX() const; @@ -478,13 +480,13 @@ protected: friend class EntityList; friend class Aura; std::list faction_list; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 platinum; - int32 grid; - uint32 spawn_group; - uint16 wp_m; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 platinum; + int32 grid; + uint32 spawn_group_id; + uint16 wp_m; int32 npc_faction_id; int32 primary_faction; diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 8c68af734..366aad2ec 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -571,7 +571,7 @@ XS(XS_NPC_SetSp2) { if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - THIS->SetSp2(sg2); + THIS->SetSpawnGroupId(sg2); } XSRETURN_EMPTY; } @@ -644,7 +644,7 @@ XS(XS_NPC_GetSp2) { if (THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->GetSp2(); + RETVAL = THIS->GetSpawnGroupId(); XSprePUSH; PUSHu((UV) RETVAL); } @@ -2377,6 +2377,42 @@ XS(XS_NPC_GetCombatState) { XSRETURN(1); } +XS(XS_NPC_SetSimpleRoamBox); /* prototype to pass -Wmissing-prototypes */ +XS(XS_NPC_SetSimpleRoamBox) { + dXSARGS; + if (items < 2) + Perl_croak(aTHX_ "Usage: NPC::SetSimpleRoamBox(THIS, box_size, move_distance, move_delay)"); + { + NPC *THIS; + + auto box_size = (float) SvNV(ST(1)); + float move_distance = 0; + int move_delay = 0; + + if (items >= 3) { + move_distance = (float) SvNV(ST(2)); + } + + if (items >= 4) { + move_delay = (int) SvIV(ST(3)); + } + + if (sv_derived_from(ST(0), "NPC")) { + IV tmp = SvIV((SV *) SvRV(ST(0))); + THIS = INT2PTR(NPC *, tmp); + } + else { + Perl_croak(aTHX_ "THIS is not of type NPC"); + } + if (THIS == nullptr) { + Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); + } + + THIS->SetSimpleRoamBox(box_size, move_distance, move_delay); + } + XSRETURN_EMPTY; +} + #ifdef __cplusplus extern "C" #endif @@ -2488,6 +2524,7 @@ XS(boot_NPC) { newXSproto(strcpy(buf, "ChangeLastName"), XS_NPC_ChangeLastName, file, "$:$"); newXSproto(strcpy(buf, "ClearLastName"), XS_NPC_ClearLastName, file, "$"); newXSproto(strcpy(buf, "GetCombatState"), XS_NPC_GetCombatState, file, "$"); + newXSproto(strcpy(buf, "SetSimpleRoamBox"), XS_NPC_SetSimpleRoamBox, file, "$$;$$"); XSRETURN_YES; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 19c779d87..64e5bd008 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -234,59 +234,48 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v return nullptr; } -Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id) +Mob *QuestManager::spawn_from_spawn2(uint32 spawn2_id) { - LinkedListIterator iterator(zone->spawn2_list); + LinkedListIterator iterator(zone->spawn2_list); iterator.Reset(); Spawn2 *found_spawn = nullptr; - while(iterator.MoreElements()) - { - Spawn2* cur = iterator.GetData(); + while (iterator.MoreElements()) { + Spawn2 *cur = iterator.GetData(); iterator.Advance(); - if(cur->GetID() == spawn2_id) - { + if (cur->GetID() == spawn2_id) { found_spawn = cur; break; } } - if(found_spawn) - { - SpawnGroup* sg = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID()); - if(!sg) - { - database.LoadSpawnGroupsByID(found_spawn->SpawnGroupID(),&zone->spawn_group_list); - sg = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID()); - if(!sg) - { + if (found_spawn) { + SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID()); + if (!spawn_group) { + database.LoadSpawnGroupsByID(found_spawn->SpawnGroupID(), &zone->spawn_group_list); + spawn_group = zone->spawn_group_list.GetSpawnGroup(found_spawn->SpawnGroupID()); + if (!spawn_group) { return nullptr; } } - uint32 npcid = sg->GetNPCType(); - if(npcid == 0) - { + uint32 npcid = spawn_group->GetNPCType(); + if (npcid == 0) { return nullptr; } - const NPCType* tmp = database.LoadNPCTypesData(npcid); - if(!tmp) - { + const NPCType *tmp = database.LoadNPCTypesData(npcid); + if (!tmp) { return nullptr; } - if(tmp->unique_spawn_by_name) - { - if(!entity_list.LimitCheckName(tmp->name)) - { + if (tmp->unique_spawn_by_name) { + if (!entity_list.LimitCheckName(tmp->name)) { return nullptr; } } - if(tmp->spawn_limit > 0) - { - if(!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) - { + if (tmp->spawn_limit > 0) { + if (!entity_list.LimitCheckType(npcid, tmp->spawn_limit)) { return nullptr; } } @@ -294,21 +283,35 @@ Mob* QuestManager::spawn_from_spawn2(uint32 spawn2_id) database.UpdateRespawnTime(spawn2_id, zone->GetInstanceID(), 0); found_spawn->SetCurrentNPCID(npcid); - auto position = glm::vec4(found_spawn->GetX(), found_spawn->GetY(), found_spawn->GetZ(), found_spawn->GetHeading()); + auto position = glm::vec4( + found_spawn->GetX(), + found_spawn->GetY(), + found_spawn->GetZ(), + found_spawn->GetHeading() + ); + auto npc = new NPC(tmp, found_spawn, position, GravityBehavior::Water); found_spawn->SetNPCPointer(npc); npc->AddLootTable(); - if (npc->DropsGlobalLoot()) + if (npc->DropsGlobalLoot()) { npc->CheckGlobalLootTables(); - npc->SetSp2(found_spawn->SpawnGroupID()); + } + npc->SetSpawnGroupId(found_spawn->SpawnGroupID()); entity_list.AddNPC(npc); entity_list.LimitAddNPC(npc); - if (sg->roamdist && sg->roambox[0] && sg->roambox[1] && sg->roambox[2] && sg->roambox[3] && sg->delay && - sg->min_delay) - npc->AI_SetRoambox(sg->roamdist, sg->roambox[0], sg->roambox[1], sg->roambox[2], sg->roambox[3], - sg->delay, sg->min_delay); + if (spawn_group->roamdist > 0) { + npc->AI_SetRoambox( + spawn_group->roamdist, + spawn_group->roambox[0], + spawn_group->roambox[1], + spawn_group->roambox[2], + spawn_group->roambox[3], + spawn_group->delay, + spawn_group->min_delay + ); + } if (zone->InstantGrids()) { found_spawn->LoadGrid(); } diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index e004faa4a..93c955d4e 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -264,7 +264,7 @@ bool Spawn2::Process() { if (npc->DropsGlobalLoot()) { npc->CheckGlobalLootTables(); } - npc->SetSp2(spawngroup_id_); + npc->SetSpawnGroupId(spawngroup_id_); npc->SaveGuardPointAnim(anim); npc->SetAppearance((EmuAppearance) anim); entity_list.AddNPC(npc); @@ -274,9 +274,7 @@ bool Spawn2::Process() { /** * Roambox init */ - if (spawn_group->roamdist && spawn_group->roambox[0] && spawn_group->roambox[1] && spawn_group->roambox[2] && - spawn_group->roambox[3] && spawn_group->delay && spawn_group->min_delay) { - + if (spawn_group->roamdist > 0) { npc->AI_SetRoambox( spawn_group->roamdist, spawn_group->roambox[0], @@ -298,7 +296,8 @@ bool Spawn2::Process() { npcid, x, y, - z); + z + ); LoadGrid(); } diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index 7cb5cd803..41cd14060 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -16,8 +16,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include "../common/global_define.h" -#include "../common/string_util.h" #include "../common/types.h" #include "entity.h" @@ -26,209 +26,352 @@ #include "zonedb.h" extern EntityList entity_list; -extern Zone* zone; +extern Zone *zone; -SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit ) { - NPCType = in_NPCType; - chance = in_chance; +SpawnEntry::SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit) +{ + NPCType = in_NPCType; + chance = in_chance; npc_spawn_limit = in_npc_spawn_limit; } -SpawnGroup::SpawnGroup( uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in ) { +SpawnGroup::SpawnGroup( + uint32 in_id, + char *name, + int in_group_spawn_limit, + float dist, + float maxx, + float minx, + float maxy, + float miny, + int delay_in, + int despawn_in, + uint32 despawn_timer_in, + int min_delay_in +) +{ id = in_id; - strn0cpy( name_, name, 120); + strn0cpy(name_, name, 120); group_spawn_limit = in_group_spawn_limit; - roambox[0]=maxx; - roambox[1]=minx; - roambox[2]=maxy; - roambox[3]=miny; - roamdist=dist; - min_delay=min_delay_in; - delay=delay_in; - despawn=despawn_in; - despawn_timer=despawn_timer_in; + roambox[0] = maxx; + roambox[1] = minx; + roambox[2] = maxy; + roambox[3] = miny; + roamdist = dist; + min_delay = min_delay_in; + delay = delay_in; + despawn = despawn_in; + despawn_timer = despawn_timer_in; } -uint32 SpawnGroup::GetNPCType() { +uint32 SpawnGroup::GetNPCType() +{ #if EQDEBUG >= 10 Log(Logs::General, Logs::None, "SpawnGroup[%08x]::GetNPCType()", (uint32) this); #endif - int npcType = 0; + int npcType = 0; int totalchance = 0; - if(!entity_list.LimitCheckGroup(id, group_spawn_limit)) - return(0); + if (!entity_list.LimitCheckGroup(id, group_spawn_limit)) { + return (0); + } - std::list::iterator cur,end; - std::list possible; + std::list::iterator cur, end; + std::list possible; cur = list_.begin(); end = list_.end(); - for(; cur != end; ++cur) { + for (; cur != end; ++cur) { SpawnEntry *se = *cur; - if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit)) + if (!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit)) { continue; + } totalchance += se->chance; possible.push_back(se); } - if(totalchance == 0) + if (totalchance == 0) { return 0; + } int32 roll = 0; - roll = zone->random.Int(0, totalchance-1); + roll = zone->random.Int(0, totalchance - 1); cur = possible.begin(); end = possible.end(); - for(; cur != end; ++cur) { + for (; cur != end; ++cur) { SpawnEntry *se = *cur; if (roll < se->chance) { npcType = se->NPCType; break; - } else { + } + else { roll -= se->chance; } } return npcType; } -void SpawnGroup::AddSpawnEntry( SpawnEntry* newEntry ) { - list_.push_back( newEntry ); +void SpawnGroup::AddSpawnEntry(SpawnEntry *newEntry) +{ + list_.push_back(newEntry); } -SpawnGroup::~SpawnGroup() { - std::list::iterator cur,end; +SpawnGroup::~SpawnGroup() +{ + std::list::iterator cur, end; cur = list_.begin(); end = list_.end(); - for(; cur != end; ++cur) { - SpawnEntry* tmp = *cur; + for (; cur != end; ++cur) { + SpawnEntry *tmp = *cur; safe_delete(tmp); } list_.clear(); } -SpawnGroupList::~SpawnGroupList() { - std::map::iterator cur,end; - cur = groups.begin(); - end = groups.end(); - for(; cur != end; ++cur) { - SpawnGroup* tmp = cur->second; +SpawnGroupList::~SpawnGroupList() +{ + std::map::iterator cur, end; + cur = m_spawn_groups.begin(); + end = m_spawn_groups.end(); + for (; cur != end; ++cur) { + SpawnGroup *tmp = cur->second; safe_delete(tmp); } - groups.clear(); + m_spawn_groups.clear(); } -void SpawnGroupList::AddSpawnGroup(SpawnGroup* newGroup) { - if(newGroup == nullptr) +void SpawnGroupList::AddSpawnGroup(SpawnGroup *new_group) +{ + if (new_group == nullptr) { return; - groups[newGroup->id] = newGroup; + } + + m_spawn_groups[new_group->id] = new_group; } -SpawnGroup* SpawnGroupList::GetSpawnGroup(uint32 in_id) { - if(groups.count(in_id) != 1) +SpawnGroup *SpawnGroupList::GetSpawnGroup(uint32 in_id) +{ + if (m_spawn_groups.count(in_id) != 1) { return nullptr; - return(groups[in_id]); + } + + return (m_spawn_groups[in_id]); } -bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) { - if(groups.count(in_id) != 1) - return(false); +bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) +{ + if (m_spawn_groups.count(in_id) != 1) { + return (false); + } - groups.erase(in_id); - return(true); + m_spawn_groups.erase(in_id); + + return (true); +} + +void SpawnGroupList::ReloadSpawnGroups() +{ + ClearSpawnGroups(); + database.LoadSpawnGroups(zone->GetShortName(), zone->GetInstanceVersion(), &zone->spawn_group_list); +} + +void SpawnGroupList::ClearSpawnGroups() +{ + m_spawn_groups.clear(); } bool ZoneDatabase::LoadSpawnGroups(const char *zone_name, uint16 version, SpawnGroupList *spawn_group_list) { - std::string query = StringFormat("SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, " - "spawngroup.dist, spawngroup.max_x, spawngroup.min_x, " - "spawngroup.max_y, spawngroup.min_y, spawngroup.delay, " - "spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay " - "FROM spawn2, spawngroup WHERE spawn2.spawngroupID = spawngroup.ID " - "AND spawn2.version = %u and zone = '%s'", - version, zone_name); + std::string query = fmt::format( + SQL( + SELECT + DISTINCT(spawngroupID), + spawngroup.name, + spawngroup.spawn_limit, + spawngroup.dist, + spawngroup.max_x, + spawngroup.min_x, + spawngroup.max_y, + spawngroup.min_y, + spawngroup.delay, + spawngroup.despawn, + spawngroup.despawn_timer, + spawngroup.mindelay + FROM + spawn2, + spawngroup + WHERE + spawn2.spawngroupID = spawngroup.ID + AND + spawn2.version = {} and zone = '{}' + ), + version, + zone_name + ); + auto results = QueryDatabase(query); if (!results.Success()) { return false; } for (auto row = results.begin(); row != results.end(); ++row) { - auto newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), - atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), - atoi(row[9]), atoi(row[10]), atoi(row[11])); - spawn_group_list->AddSpawnGroup(newSpawnGroup); + auto new_spawn_group = new SpawnGroup( + atoi(row[0]), + row[1], + atoi(row[2]), + atof(row[3]), + atof(row[4]), + atof(row[5]), + atof(row[6]), + atof(row[7]), + atoi(row[8]), + atoi(row[9]), + atoi(row[10]), + atoi(row[11]) + ); + + spawn_group_list->AddSpawnGroup(new_spawn_group); } - query = StringFormat("SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, " - "npc_types.spawn_limit AS sl " - "FROM spawnentry, spawn2, npc_types " - "WHERE spawnentry.npcID=npc_types.id " - "AND spawnentry.spawngroupID = spawn2.spawngroupID " - "AND zone = '%s'", - zone_name); + query = fmt::format( + SQL( + SELECT + DISTINCT + spawnentry.spawngroupID, + npcid, + chance, + npc_types.spawn_limit + AS sl + FROM + spawnentry, + spawn2, + npc_types + WHERE + spawnentry.npcID = npc_types.id + AND + spawnentry.spawngroupID = spawn2.spawngroupID + AND + zone = '{}'), + zone_name + ); + results = QueryDatabase(query); if (!results.Success()) { - Log(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query '%'", query.c_str()); return false; } for (auto row = results.begin(); row != results.end(); ++row) { - auto newSpawnEntry = new SpawnEntry(atoi(row[1]), atoi(row[2]), row[3] ? atoi(row[3]) : 0); - SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); + auto new_spawn_entry = new SpawnEntry( + atoi(row[1]), + atoi(row[2]), + (row[3] ? atoi(row[3]) : 0) + ); - if (!sg) { - safe_delete(newSpawnEntry); + SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0])); + + if (!spawn_group) { + safe_delete(new_spawn_entry); continue; } - sg->AddSpawnEntry(newSpawnEntry); + spawn_group->AddSpawnEntry(new_spawn_entry); } return true; } -bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList *spawn_group_list) +/** + * @param spawn_group_id + * @param spawn_group_list + * @return + */ +bool ZoneDatabase::LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList *spawn_group_list) { - std::string query = StringFormat("SELECT DISTINCT(spawngroup.id), spawngroup.name, spawngroup.spawn_limit, " - "spawngroup.dist, spawngroup.max_x, spawngroup.min_x, " - "spawngroup.max_y, spawngroup.min_y, spawngroup.delay, " - "spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay " - "FROM spawngroup WHERE spawngroup.ID = '%i'", - spawngroupid); + std::string query = fmt::format( + SQL( + SELECT DISTINCT + (spawngroup.id), + spawngroup.name, + spawngroup.spawn_limit, + spawngroup.dist, + spawngroup.max_x, + spawngroup.min_x, + spawngroup.max_y, + spawngroup.min_y, + spawngroup.delay, + spawngroup.despawn, + spawngroup.despawn_timer, + spawngroup.mindelay + FROM + spawngroup + WHERE + spawngroup.ID = '{}' + ), + spawn_group_id + ); + auto results = QueryDatabase(query); if (!results.Success()) { - Log(Logs::General, Logs::Error, "Error2 in PopulateZoneLists query %s", query.c_str()); return false; } for (auto row = results.begin(); row != results.end(); ++row) { - auto newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), - atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), - atoi(row[9]), atoi(row[10]), atoi(row[11])); - spawn_group_list->AddSpawnGroup(newSpawnGroup); + auto new_spawn_group = new SpawnGroup( + atoi(row[0]), + row[1], + atoi(row[2]), + atof(row[3]), + atof(row[4]), + atof(row[5]), + atof(row[6]), + atof(row[7]), + atoi(row[8]), + atoi(row[9]), + atoi(row[10]), + atoi(row[11]) + ); + + spawn_group_list->AddSpawnGroup(new_spawn_group); } - query = StringFormat("SELECT DISTINCT(spawnentry.spawngroupID), spawnentry.npcid, " - "spawnentry.chance, spawngroup.spawn_limit FROM spawnentry, spawngroup " - "WHERE spawnentry.spawngroupID = '%i' AND spawngroup.spawn_limit = '0' " - "ORDER BY chance", - spawngroupid); + query = fmt::format( + SQL( + SELECT DISTINCT + (spawnentry.spawngroupID), + spawnentry.npcid, + spawnentry.chance, + spawngroup.spawn_limit + FROM + spawnentry, + spawngroup + WHERE + spawnentry.spawngroupID = '{}' + AND spawngroup.spawn_limit = '0' + ORDER BY chance), + spawn_group_id + ); + results = QueryDatabase(query); if (!results.Success()) { - Log(Logs::General, Logs::Error, "Error3 in PopulateZoneLists query '%s'", query.c_str()); return false; } for (auto row = results.begin(); row != results.end(); ++row) { - auto newSpawnEntry = new SpawnEntry(atoi(row[1]), atoi(row[2]), row[3] ? atoi(row[3]) : 0); - SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0])); - if (!sg) { - safe_delete(newSpawnEntry); + auto new_spawn_entry = new SpawnEntry( + atoi(row[1]), + atoi(row[2]), + (row[3] ? atoi(row[3]) : 0) + ); + + SpawnGroup *spawn_group = spawn_group_list->GetSpawnGroup(atoi(row[0])); + if (!spawn_group) { + safe_delete(new_spawn_entry); continue; } - sg->AddSpawnEntry(newSpawnEntry); + spawn_group->AddSpawnEntry(new_spawn_entry); } return true; diff --git a/zone/spawngroup.h b/zone/spawngroup.h index b5f6d18cf..4b68a35eb 100644 --- a/zone/spawngroup.h +++ b/zone/spawngroup.h @@ -23,50 +23,63 @@ #include #include -class SpawnEntry -{ +class SpawnEntry { public: - SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit ); - ~SpawnEntry() { } + SpawnEntry(uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit); + ~SpawnEntry() {} uint32 NPCType; - int chance; + int chance; //this is a cached value from npc_types, for speed uint8 npc_spawn_limit; //max # of this entry which can be spawned in this zone }; -class SpawnGroup -{ +class SpawnGroup { public: - SpawnGroup(uint32 in_id, char* name, int in_group_spawn_limit, float dist, float maxx, float minx, float maxy, float miny, int delay_in, int despawn_in, uint32 despawn_timer_in, int min_delay_in ); + SpawnGroup( + uint32 in_id, + char *name, + int in_group_spawn_limit, + float dist, + float maxx, + float minx, + float maxy, + float miny, + int delay_in, + int despawn_in, + uint32 despawn_timer_in, + int min_delay_in + ); + ~SpawnGroup(); uint32 GetNPCType(); - void AddSpawnEntry( SpawnEntry* newEntry ); + void AddSpawnEntry(SpawnEntry *newEntry); uint32 id; - float roamdist; - float roambox[4]; - int min_delay; - int delay; - int despawn; + float roamdist; + float roambox[4]; + int min_delay; + int delay; + int despawn; uint32 despawn_timer; private: char name_[120]; - std::list list_; + std::list list_; uint8 group_spawn_limit; //max # of this entry which can be spawned by this group }; -class SpawnGroupList -{ +class SpawnGroupList { public: - SpawnGroupList() { } + SpawnGroupList() {} ~SpawnGroupList(); - void AddSpawnGroup(SpawnGroup* newGroup); - SpawnGroup* GetSpawnGroup(uint32 id); + void AddSpawnGroup(SpawnGroup *new_group); + SpawnGroup *GetSpawnGroup(uint32 id); bool RemoveSpawnGroup(uint32 in_id); + void ClearSpawnGroups(); + void ReloadSpawnGroups(); private: //LinkedList list_; - std::map groups; + std::map m_spawn_groups; }; #endif diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index bc9e3870d..ebbf5fda5 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -57,7 +57,16 @@ void NPC::AI_SetRoambox(float max_distance, float roam_distance_variance, uint32 ); } -void NPC::AI_SetRoambox(float distance, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 min_delay) { +void NPC::AI_SetRoambox( + float distance, + float max_x, + float min_x, + float max_y, + float min_y, + uint32 delay, + uint32 min_delay +) +{ roambox_distance = distance; roambox_max_x = max_x; roambox_min_x = min_x; @@ -71,10 +80,10 @@ void NPC::AI_SetRoambox(float distance, float max_x, float min_x, float max_y, f void NPC::DisplayWaypointInfo(Client *c) { c->Message(Chat::White, "Mob is on grid %d, in spawn group %d, on waypoint %d/%d", - GetGrid(), - GetSp2(), - GetCurWp(), - GetMaxWp()); + GetGrid(), + GetSpawnGroupId(), + GetCurWp(), + GetMaxWp()); std::vector::iterator cur, end; diff --git a/zone/zone.cpp b/zone/zone.cpp index f364ab298..8ca78735f 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1485,6 +1485,8 @@ bool Zone::Depop(bool StartSpawnTimer) { // clear spell cache database.ClearNPCSpells(); + zone->spawn_group_list.ReloadSpawnGroups(); + return true; } diff --git a/zone/zonedb.h b/zone/zonedb.h index f2103715a..e93a40713 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -409,7 +409,7 @@ public: /* Spawns and Spawn Points */ bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); - bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); + bool LoadSpawnGroupsByID(int spawn_group_id, SpawnGroupList* spawn_group_list); bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance); Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); From bf25937ee00938f988df595e621cd62d6327e1d3 Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 16 Aug 2019 03:39:15 -0500 Subject: [PATCH 164/491] Command #npceditmass now lists column options when one isn't properly specified --- changelog.txt | 1 + zone/command.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/changelog.txt b/changelog.txt index b62f810be..dff7d4e76 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,6 +7,7 @@ Akkadius: Implemented command #roambox remove Akkadius: Implemented LUA NPC:SetSimpleRoamBox(box_size, [move_distance], [move_delay]); Akkadius: Implemented Perl $npc->SetSimpleRoamBox(box_size, [move_distance], [move_delay]); Akkadius: Spawngroup data now hot reloads on #repop +Akkadius: Command #npceditmass now lists column options when one isn't properly specified == 8/11/2019 == Akkadius: Added bulk edit command #npceditmass diff --git a/zone/command.cpp b/zone/command.cpp index babe3ec24..f143c9070 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -7426,6 +7426,8 @@ void command_npceditmass(Client *c, const Seperator *sep) bool valid_search_column = false; auto results = database.QueryDatabase(query); + std::vector possible_column_options; + for (auto row = results.begin(); row != results.end(); ++row) { if (row[0] == change_column) { valid_change_column = true; @@ -7433,15 +7435,21 @@ void command_npceditmass(Client *c, const Seperator *sep) if (row[0] == search_column) { valid_search_column = true; } + + possible_column_options.push_back(row[0]); } + std::string options_glue = ", "; + if (!valid_search_column) { c->Message(Chat::Red, "You must specify a valid search column. [%s] is not valid", search_column.c_str()); + c->Message(Chat::Yellow, "Possible columns [%s]", implode(options_glue, possible_column_options).c_str()); return; } if (!valid_change_column) { c->Message(Chat::Red, "You must specify a valid change column. [%s] is not valid", change_column.c_str()); + c->Message(Chat::Yellow, "Possible columns [%s]", implode(options_glue, possible_column_options).c_str()); return; } From 6fb1d95518ac5cd02d96d94eaf9de5681066272c Mon Sep 17 00:00:00 2001 From: Akkadius Date: Fri, 16 Aug 2019 04:33:51 -0500 Subject: [PATCH 165/491] Implemented command #spawneditmass