diff --git a/zone/client.cpp b/zone/client.cpp index 6324db2a0..16c28e20b 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -2020,20 +2020,22 @@ void Client::Sit() { SetAppearance(eaSitting, false); } -void Client::ChangeLastName(const char* in_lastname) { +void Client::ChangeLastName(std::string last_name) { memset(m_pp.last_name, 0, sizeof(m_pp.last_name)); - strn0cpy(m_pp.last_name, in_lastname, sizeof(m_pp.last_name)); + strn0cpy(m_pp.last_name, last_name.c_str(), sizeof(m_pp.last_name)); auto outapp = new EQApplicationPacket(OP_GMLastName, sizeof(GMLastName_Struct)); - GMLastName_Struct* gmn = (GMLastName_Struct*)outapp->pBuffer; - strcpy(gmn->name, name); - strcpy(gmn->gmname, name); - strcpy(gmn->lastname, in_lastname); - gmn->unknown[0]=1; - gmn->unknown[1]=1; - gmn->unknown[2]=1; - gmn->unknown[3]=1; + auto gmn = (GMLastName_Struct*) outapp->pBuffer; + strn0cpy(gmn->name, name, sizeof(gmn->name)); + strn0cpy(gmn->gmname, name, sizeof(gmn->gmname)); + strn0cpy(gmn->lastname, last_name.c_str(), sizeof(gmn->lastname)); + + gmn->unknown[0] = 1; + gmn->unknown[1] = 1; + gmn->unknown[2] = 1; + gmn->unknown[3] = 1; + entity_list.QueueClients(this, outapp, false); - // Send name update packet here... once know what it is + safe_delete(outapp); } diff --git a/zone/client.h b/zone/client.h index f039966eb..f755ef432 100644 --- a/zone/client.h +++ b/zone/client.h @@ -668,7 +668,7 @@ public: void RemoveFromInstance(uint16 instance_id); void WhoAll(); bool CheckLoreConflict(const EQ::ItemData* item); - void ChangeLastName(const char* in_lastname); + void ChangeLastName(std::string last_name); void GetGroupAAs(GroupLeadershipAA_Struct *into) const; void GetRaidAAs(RaidLeadershipAA_Struct *into) const; void ClearGroupAAs(); @@ -912,8 +912,8 @@ public: inline uint32 GetAAXP() const { return m_pp.expAA; } inline uint32 GetAAPercent() const { return m_epp.perAA; } int64 CalcAAFocus(focusType type, const AA::Rank &rank, uint16 spell_id); - void SetAATitle(const char *Title); - void SetTitleSuffix(const char *txt); + void SetAATitle(std::string title); + void SetTitleSuffix(std::string suffix); void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing, uint32 reduction = 0); // Item methods diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 655613943..c97c60031 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12875,7 +12875,7 @@ void Client::Handle_OP_SetTitle(const EQApplicationPacket *app) return; } - SetTitle_Struct *sts = (SetTitle_Struct *)app->pBuffer; + auto sts = (SetTitle_Struct *) app->pBuffer; if (sts->title_id && !title_manager.HasTitle(this, sts->title_id)) { return; @@ -12892,9 +12892,9 @@ void Client::Handle_OP_SetTitle(const EQApplicationPacket *app) ); if (!sts->is_suffix) { - SetAATitle(title.c_str()); + SetAATitle(title); } else { - SetTitleSuffix(title.c_str()); + SetTitleSuffix(title); } } diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index f2c24e0f6..e1164b760 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -1041,11 +1041,11 @@ XS(XS__surname); XS(XS__surname) { dXSARGS; if (items != 1) - Perl_croak(aTHX_ "Usage: quest::surname(string name)"); + Perl_croak(aTHX_ "Usage: quest::surname(string last_name)"); - char *name = (char *) SvPV_nolen(ST(0)); + std::string last_name = (std::string) SvPV_nolen(ST(0)); - quest_manager.surname(name); + quest_manager.surname(last_name); XSRETURN_EMPTY; } diff --git a/zone/gm_commands/lastname.cpp b/zone/gm_commands/lastname.cpp index 8dd3c7dd0..81b3c2b85 100755 --- a/zone/gm_commands/lastname.cpp +++ b/zone/gm_commands/lastname.cpp @@ -15,7 +15,7 @@ void command_lastname(Client *c, const Seperator *sep) return; } - target->ChangeLastName(last_name.c_str()); + target->ChangeLastName(last_name); c->Message( Chat::White, fmt::format( diff --git a/zone/gm_commands/title.cpp b/zone/gm_commands/title.cpp index bd0503008..dff5a3ec4 100755 --- a/zone/gm_commands/title.cpp +++ b/zone/gm_commands/title.cpp @@ -31,9 +31,9 @@ void command_title(Client *c, const Seperator *sep) } if (!save_title || is_remove) { - target->SetAATitle(title.c_str()); + target->SetAATitle(title); } else if (save_title) { - title_manager.CreateNewPlayerTitle(target, title.c_str()); + title_manager.CreateNewPlayerTitle(target, title); } target->Save(); diff --git a/zone/gm_commands/titlesuffix.cpp b/zone/gm_commands/titlesuffix.cpp index b2e6cb4bf..34c971f64 100755 --- a/zone/gm_commands/titlesuffix.cpp +++ b/zone/gm_commands/titlesuffix.cpp @@ -31,9 +31,9 @@ void command_titlesuffix(Client *c, const Seperator *sep) } if (!save_suffix || is_remove) { - target->SetTitleSuffix(suffix.c_str()); + target->SetTitleSuffix(suffix); } else if (save_suffix) { - title_manager.CreateNewPlayerSuffix(target, suffix.c_str()); + title_manager.CreateNewPlayerSuffix(target, suffix); } target->Save(); diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 68b55ba8c..4fba59888 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -16,6 +16,7 @@ #include "lua_raid.h" #include "lua_packet.h" #include "dialogue_window.h" +#include "titles.h" #include "../common/expedition_lockout_timer.h" struct InventoryWhere { }; @@ -415,9 +416,9 @@ void Lua_Client::MoveZoneInstanceRaid(uint16 instance_id) { self->MoveZoneInstanceRaid(instance_id); } -void Lua_Client::ChangeLastName(const char *in) { +void Lua_Client::ChangeLastName(std::string last_name) { Lua_Safe_Call_Void(); - self->ChangeLastName(in); + self->ChangeLastName(last_name); } int Lua_Client::GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc) { @@ -1120,11 +1121,20 @@ void Lua_Client::SendZoneFlagInfo(Lua_Client to) { self->SendZoneFlagInfo(to); } -void Lua_Client::SetAATitle(const char *title) { +void Lua_Client::SetAATitle(std::string title) { Lua_Safe_Call_Void(); self->SetAATitle(title); } +void Lua_Client::SetAATitle(std::string title, bool save_to_database) { + Lua_Safe_Call_Void(); + if (!save_to_database) { + self->SetAATitle(title); + } else { + title_manager.CreateNewPlayerTitle(self, title); + } +} + int Lua_Client::GetClientVersion() { Lua_Safe_Call_Int(); return static_cast(self->ClientVersion()); @@ -2558,7 +2568,7 @@ luabind::scope lua_register_client() { .def("CalcCurrentWeight", &Lua_Client::CalcCurrentWeight) .def("CalcPriceMod", (float(Lua_Client::*)(Lua_Mob,bool))&Lua_Client::CalcPriceMod) .def("CanHaveSkill", (bool(Lua_Client::*)(int))&Lua_Client::CanHaveSkill) - .def("ChangeLastName", (void(Lua_Client::*)(const char *in))&Lua_Client::ChangeLastName) + .def("ChangeLastName", (void(Lua_Client::*)(std::string))&Lua_Client::ChangeLastName) .def("CharacterID", (uint32(Lua_Client::*)(void))&Lua_Client::CharacterID) .def("CheckIncreaseSkill", (void(Lua_Client::*)(int,Lua_Mob))&Lua_Client::CheckIncreaseSkill) .def("CheckIncreaseSkill", (void(Lua_Client::*)(int,Lua_Mob,int))&Lua_Client::CheckIncreaseSkill) @@ -2838,7 +2848,8 @@ luabind::scope lua_register_client() { .def("SendZoneFlagInfo", (void(Lua_Client::*)(Lua_Client))&Lua_Client::SendZoneFlagInfo) .def("SetAAEXPModifier", (void(Lua_Client::*)(uint32,double))&Lua_Client::SetAAEXPModifier) .def("SetAAPoints", (void(Lua_Client::*)(int))&Lua_Client::SetAAPoints) - .def("SetAATitle", (void(Lua_Client::*)(const char *))&Lua_Client::SetAATitle) + .def("SetAATitle", (void(Lua_Client::*)(std::string))&Lua_Client::SetAATitle) + .def("SetAATitle", (void(Lua_Client::*)(std::string,bool))&Lua_Client::SetAATitle) .def("SetAFK", (void(Lua_Client::*)(uint8))&Lua_Client::SetAFK) .def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag) .def("SetAccountFlag", (void(Lua_Client::*)(std::string,std::string))&Lua_Client::SetAccountFlag) diff --git a/zone/lua_client.h b/zone/lua_client.h index 0060631b8..5bb841c57 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -118,7 +118,7 @@ public: void MoveZoneInstance(uint16 instance_id); void MoveZoneInstanceGroup(uint16 instance_id); void MoveZoneInstanceRaid(uint16 instance_id); - void ChangeLastName(const char *in); + void ChangeLastName(std::string last_name); int GetFactionLevel(uint32 char_id, uint32 npc_id, uint32 race, uint32 class_, uint32 deity, uint32 faction, Lua_NPC npc); void SetFactionLevel(uint32 char_id, uint32 npc_id, int char_class, int char_race, int char_deity); void SetFactionLevel2(uint32 char_id, int faction_id, int char_class, int char_race, int char_deity, int value, int temp); @@ -265,7 +265,8 @@ public: void LoadPEQZoneFlags(); void SendPEQZoneFlagInfo(Lua_Client to); void SetPEQZoneFlag(uint32 zone_id); - void SetAATitle(const char *title); + void SetAATitle(std::string title); + void SetAATitle(std::string title, bool save_to_database); int GetClientVersion(); uint32 GetClientVersionBit(); void SetTitleSuffix(const char *text); diff --git a/zone/lua_npc.cpp b/zone/lua_npc.cpp index c84cfe82e..edc0caa8a 100644 --- a/zone/lua_npc.cpp +++ b/zone/lua_npc.cpp @@ -575,10 +575,10 @@ bool Lua_NPC::IsRaidTarget() return self->IsRaidTarget(); } -void Lua_NPC::ChangeLastName(const char *lastname) +void Lua_NPC::ChangeLastName(std::string last_name) { Lua_Safe_Call_Void(); - self->ChangeLastName(lastname); + self->ChangeLastName(last_name); } void Lua_NPC::ClearLastName() @@ -680,7 +680,7 @@ luabind::scope lua_register_npc() { .def("AddLootTable", (void(Lua_NPC::*)(void))&Lua_NPC::AddLootTable) .def("AssignWaypoints", (void(Lua_NPC::*)(int))&Lua_NPC::AssignWaypoints) .def("CalculateNewWaypoint", (void(Lua_NPC::*)(void))&Lua_NPC::CalculateNewWaypoint) - .def("ChangeLastName", (void(Lua_NPC::*)(const char*))&Lua_NPC::ChangeLastName) + .def("ChangeLastName", (void(Lua_NPC::*)(std::string))&Lua_NPC::ChangeLastName) .def("CheckNPCFactionAlly", (int(Lua_NPC::*)(int))&Lua_NPC::CheckNPCFactionAlly) .def("ClearItemList", (void(Lua_NPC::*)(void))&Lua_NPC::ClearItemList) .def("ClearLastName", (void(Lua_NPC::*)(void))&Lua_NPC::ClearLastName) diff --git a/zone/lua_npc.h b/zone/lua_npc.h index 6b1e71363..90a91e3aa 100644 --- a/zone/lua_npc.h +++ b/zone/lua_npc.h @@ -140,7 +140,7 @@ public: void RecalculateSkills(); void ScaleNPC(uint8 npc_level); bool IsRaidTarget(); - void ChangeLastName(const char *lastname); + void ChangeLastName(std::string last_name); void ClearLastName(); bool HasItem(uint32 item_id); uint16 CountItem(uint32 item_id); diff --git a/zone/npc.cpp b/zone/npc.cpp index faaf29ea2..52f7348da 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -3231,27 +3231,29 @@ void NPC::DoQuestPause(Mob *other) { } -void NPC::ChangeLastName(const char* in_lastname) +void NPC::ChangeLastName(std::string last_name) { - auto outapp = new EQApplicationPacket(OP_GMLastName, sizeof(GMLastName_Struct)); - GMLastName_Struct* gmn = (GMLastName_Struct*)outapp->pBuffer; - strcpy(gmn->name, GetName()); - strcpy(gmn->gmname, GetName()); - strcpy(gmn->lastname, in_lastname); - gmn->unknown[0]=1; - gmn->unknown[1]=1; - gmn->unknown[2]=1; - gmn->unknown[3]=1; + auto gmn = (GMLastName_Struct*) outapp->pBuffer; + + strn0cpy(gmn->name, GetName(), sizeof(gmn->name)); + strn0cpy(gmn->gmname, GetName(), sizeof(gmn->gmname)); + strn0cpy(gmn->lastname, last_name.c_str(), sizeof(gmn->lastname)); + + gmn->unknown[0] = 1; + gmn->unknown[1] = 1; + gmn->unknown[2] = 1; + gmn->unknown[3] = 1; + entity_list.QueueClients(this, outapp, false); + safe_delete(outapp); } void NPC::ClearLastName() { - std::string WT; - WT = '\0'; //Clear Last Name - ChangeLastName( WT.c_str()); + std::string empty; + ChangeLastName(empty); } void NPC::DepopSwarmPets() diff --git a/zone/npc.h b/zone/npc.h index bb47093d2..76ff091ef 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -441,7 +441,7 @@ public: virtual int GetKillExpMod() const { return NPCTypedata_ours ? NPCTypedata_ours->exp_mod : NPCTypedata->exp_mod; } - void ChangeLastName(const char* in_lastname); + void ChangeLastName(std::string last_name); void ClearLastName(); bool GetDepop() { return p_depop; } diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index 1a82f34ec..732d6cf55 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1163,9 +1163,9 @@ XS(XS_Client_ChangeLastName) { Perl_croak(aTHX_ "Usage: Client::ChangeLastName(THIS, string last_name)"); // @categories Account and Character { Client *THIS; - char *in_lastname = (char *) SvPV_nolen(ST(1)); + std::string last_name = (std::string) SvPV_nolen(ST(1)); VALIDATE_THIS_IS_CLIENT; - THIS->ChangeLastName(in_lastname); + THIS->ChangeLastName(last_name); } XSRETURN_EMPTY; } @@ -2965,23 +2965,27 @@ XS(XS_Client_LoadZoneFlags) { XS(XS_Client_SetAATitle); /* prototype to pass -Wmissing-prototypes */ XS(XS_Client_SetAATitle) { dXSARGS; - if ((items < 2) || (items > 3)) + if (items < 2 || items > 3) Perl_croak(aTHX_ "Usage: Client::SetAATitle(THIS, string text, [bool save = false])"); // @categories Alternative Advancement { Client *THIS; - char *txt = (char *) SvPV_nolen(ST(1)); - bool SaveTitle = false; + std::string title = (std::string) SvPV_nolen(ST(1)); + bool save = false; VALIDATE_THIS_IS_CLIENT; - if (strlen(txt) > 31) - Perl_croak(aTHX_ "Title must be 31 characters or less"); - if (items == 3) - SaveTitle = (SvIV(ST(2)) != 0); + if (title.size() > 31) { + Perl_croak(aTHX_ "Title must be 31 characters or less."); + } - if (!SaveTitle) - THIS->SetAATitle(txt); - else - title_manager.CreateNewPlayerTitle(THIS, txt); + if (items == 3) { + save = (bool) SvTRUE(ST(2)); + } + + if (!save) { + THIS->SetAATitle(title); + } else { + title_manager.CreateNewPlayerTitle(THIS, title); + } } XSRETURN_EMPTY; } @@ -3023,23 +3027,27 @@ XS(XS_Client_GetClientVersionBit) { XS(XS_Client_SetTitleSuffix); XS(XS_Client_SetTitleSuffix) { dXSARGS; - if ((items < 2) || (items > 3)) - Perl_croak(aTHX_ "Usage: Client::SetTitleSuffix(THIS, string text, [bool save = false])"); // @categories Account and Character + if (items < 2 || items > 3) + Perl_croak(aTHX_ "Usage: Client::SetTitleSuffix(THIS, string suffix, [bool save = false])"); // @categories Account and Character { Client *THIS; - char *txt = (char *) SvPV_nolen(ST(1)); - bool SaveSuffix = false; + std::string suffix = (std::string) SvPV_nolen(ST(1)); + bool save = false; VALIDATE_THIS_IS_CLIENT; - if (strlen(txt) > 31) - Perl_croak(aTHX_ "Title must be 31 characters or less"); - if (items == 3) - SaveSuffix = (SvIV(ST(2)) != 0); + if (suffix.size() > 31) { + Perl_croak(aTHX_ "Suffix must be 31 characters or less."); + } - if (!SaveSuffix) - THIS->SetTitleSuffix(txt); - else - title_manager.CreateNewPlayerSuffix(THIS, txt); + if (items == 3) { + save = (bool) SvTRUE(ST(2)); + } + + if (!save) { + THIS->SetTitleSuffix(suffix); + } else { + title_manager.CreateNewPlayerSuffix(THIS, suffix); + } } XSRETURN_EMPTY; } diff --git a/zone/perl_npc.cpp b/zone/perl_npc.cpp index 78a9f7402..a0cb935f3 100644 --- a/zone/perl_npc.cpp +++ b/zone/perl_npc.cpp @@ -1625,15 +1625,13 @@ XS(XS_NPC_RemoveDefensiveProc) { XS(XS_NPC_ChangeLastName); /* prototype to pass -Wmissing-prototypes */ XS(XS_NPC_ChangeLastName) { dXSARGS; - if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: NPC::ChangeLastName(THIS, string name)"); // @categories Script Utility + if (items != 2) + Perl_croak(aTHX_ "Usage: NPC::ChangeLastName(THIS, string last_name)"); // @categories Script Utility { NPC *THIS; - char *name = nullptr; + std::string last_name = (std::string) SvPV_nolen(ST(1)); VALIDATE_THIS_IS_NPC; - if (items > 1) { name = (char *) SvPV_nolen(ST(1)); } - - THIS->ChangeLastName(name); + THIS->ChangeLastName(last_name); } XSRETURN_EMPTY; } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index a083233ba..faf58eaa9 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1111,20 +1111,18 @@ void QuestManager::rename(std::string name) { } } -void QuestManager::surname(const char *name) { +void QuestManager::surname(std::string last_name) { QuestManagerCurrentQuestVars(); //Changes the last name. - if(initiator) - { - if(initiator->IsClient()) - { - initiator->ChangeLastName(name); - initiator->Message(Chat::Yellow,"Your surname has been changed/set to: %s", name); - } - else - { - initiator->Message(Chat::Yellow,"Error changing/setting surname"); - } + if (initiator && initiator->IsClient()) { + initiator->ChangeLastName(last_name); + initiator->Message( + Chat::White, + fmt::format( + "Your last name has been set to \"{}\".", + last_name + ).c_str() + ); } } diff --git a/zone/questmgr.h b/zone/questmgr.h index d5b93b83a..96d8a51e6 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -127,7 +127,7 @@ public: void rain(int weather); void snow(int weather); void rename(std::string name); - void surname(const char *name); + void surname(std::string last_name); void permaclass(int class_id); void permarace(int race_id); void permagender(int gender_id); diff --git a/zone/titles.cpp b/zone/titles.cpp index 8bdabc678..14230c4bd 100644 --- a/zone/titles.cpp +++ b/zone/titles.cpp @@ -225,9 +225,9 @@ bool TitleManager::IsNewTradeSkillTitleAvailable(int skill_id, int skill_value) return false; } -void TitleManager::CreateNewPlayerTitle(Client *client, const char *title) +void TitleManager::CreateNewPlayerTitle(Client *client, std::string title) { - if (!client || !title) { + if (!client || title.empty()) { return; } @@ -258,15 +258,15 @@ void TitleManager::CreateNewPlayerTitle(Client *client, const char *title) safe_delete(pack); } -void TitleManager::CreateNewPlayerSuffix(Client *client, const char *suffix) +void TitleManager::CreateNewPlayerSuffix(Client *client, std::string suffix) { - if (!client || !suffix) { + if (!client || suffix.empty()) { return; } client->SetTitleSuffix(suffix); - std::string query = fmt::format( + auto query = fmt::format( "SELECT `id` FROM titles WHERE `suffix` = '{}' AND char_id = {}", EscapeString(suffix), client->CharacterID() @@ -291,24 +291,24 @@ void TitleManager::CreateNewPlayerSuffix(Client *client, const char *suffix) safe_delete(pack); } -void Client::SetAATitle(const char *title) +void Client::SetAATitle(std::string title) { - strn0cpy(m_pp.title, title, sizeof(m_pp.title)); + strn0cpy(m_pp.title, title.c_str(), sizeof(m_pp.title)); auto outapp = new EQApplicationPacket(OP_SetTitleReply, sizeof(SetTitleReply_Struct)); - SetTitleReply_Struct *strs = (SetTitleReply_Struct *)outapp->pBuffer; - strn0cpy(strs->title, title, sizeof(strs->title)); + auto strs = (SetTitleReply_Struct *) outapp->pBuffer; + strn0cpy(strs->title, title.c_str(), sizeof(strs->title)); strs->entity_id = GetID(); entity_list.QueueClients(this, outapp, false); safe_delete(outapp); } -void Client::SetTitleSuffix(const char *suffix) +void Client::SetTitleSuffix(std::string suffix) { - strn0cpy(m_pp.suffix, suffix, sizeof(m_pp.suffix)); + strn0cpy(m_pp.suffix, suffix.c_str(), sizeof(m_pp.suffix)); auto outapp = new EQApplicationPacket(OP_SetTitleReply, sizeof(SetTitleReply_Struct)); - SetTitleReply_Struct *strs = (SetTitleReply_Struct *)outapp->pBuffer; + auto strs = (SetTitleReply_Struct *) outapp->pBuffer; strs->is_suffix = 1; - strn0cpy(strs->title, suffix, sizeof(strs->title)); + strn0cpy(strs->title, suffix.c_str(), sizeof(strs->title)); strs->entity_id = GetID(); entity_list.QueueClients(this, outapp, false); safe_delete(outapp); diff --git a/zone/titles.h b/zone/titles.h index 640d4d29a..5e29e512c 100644 --- a/zone/titles.h +++ b/zone/titles.h @@ -55,8 +55,8 @@ public: bool IsClientEligibleForTitle(Client *client, TitleEntry title); bool IsNewAATitleAvailable(int aa_points, int class_id); bool IsNewTradeSkillTitleAvailable(int skill_id, int skill_value); - void CreateNewPlayerTitle(Client *client, const char *title); - void CreateNewPlayerSuffix(Client *client, const char *suffix); + void CreateNewPlayerTitle(Client *client, std::string title); + void CreateNewPlayerSuffix(Client *client, std::string suffix); bool HasTitle(Client* client, uint32 title_id); protected: