[Feature] Implement /changename & related script bindings. Clean up #set name (#4770)

* initial work, need to clean up gm commands still

* cleaned up command, works without kicking char select now

* remove thj-specific methods

* add script hooks

* actually clear flag

* rework questmgr::rename

* remove unnecessary logging

* revert

* added missing binding to perl api and updated some text

* don't return a value

* Fix some bad argument types.

* adjust case

* alpha order

* refactor some old string stuff

* don't quote integers, bob

---------

Co-authored-by: Zimp <zimp@zenryo.xyz>
Co-authored-by: Chris Miles <akkadius1@gmail.com>
This commit is contained in:
catapultam-habeo
2025-03-19 19:00:45 -07:00
committed by GitHub
parent be6a5d5f50
commit 213fe6a9e9
14 changed files with 223 additions and 39 deletions
+86 -16
View File
@@ -2549,40 +2549,59 @@ void Client::ChangeLastName(std::string last_name) {
safe_delete(outapp);
}
bool Client::ChangeFirstName(const char* in_firstname, const char* gmname)
// Deprecated, this packet does not actually work in ROF2
bool Client::ChangeFirstName(const std::string in_firstname, const std::string gmname)
{
// check duplicate name
bool used_name = database.IsNameUsed((const char*) in_firstname);
if (used_name) {
if (!ChangeFirstName(in_firstname)) {
return false;
}
// update character_
if(!database.UpdateName(GetName(), in_firstname))
return false;
// update pp
memset(m_pp.name, 0, sizeof(m_pp.name));
snprintf(m_pp.name, sizeof(m_pp.name), "%s", in_firstname);
strcpy(name, m_pp.name);
Save();
// send name update packet
auto outapp = new EQApplicationPacket(OP_GMNameChange, sizeof(GMName_Struct));
GMName_Struct* gmn=(GMName_Struct*)outapp->pBuffer;
strn0cpy(gmn->gmname,gmname,64);
strn0cpy(gmn->gmname,gmname.c_str(),64);
strn0cpy(gmn->oldname,GetName(),64);
strn0cpy(gmn->newname,in_firstname,64);
strn0cpy(gmn->newname,in_firstname.c_str(),64);
gmn->unknown[0] = 1;
gmn->unknown[1] = 1;
gmn->unknown[2] = 1;
entity_list.QueueClients(this, outapp, false);
safe_delete(outapp);
// success
return true;
}
bool Client::ChangeFirstName(const std::string in_firstname)
{
// check duplicate name
bool used_name = database.IsNameUsed(in_firstname) || database.IsPetNameUsed(in_firstname);
if (used_name || !database.CheckNameFilter(in_firstname, false)) {
return false;
}
// update character_
if(!database.UpdateNameByID(CharacterID(), in_firstname))
return false;
// Send Name Update to Clients
SendRename(this, GetName(), in_firstname.c_str());
SetName(in_firstname.c_str());
// update pp
memset(m_pp.name, 0, sizeof(m_pp.name));
snprintf(m_pp.name, sizeof(m_pp.name), "%s", in_firstname.c_str());
strcpy(name, m_pp.name);
Save();
// Update the active char in account table
database.UpdateLiveChar(in_firstname, AccountID());
// finally, update the /who list
UpdateWho();
// success
ClearNameChange();
return true;
}
@@ -4737,6 +4756,57 @@ bool Client::KeyRingRemove(uint32 item_id)
);
}
bool Client::IsNameChangeAllowed() {
if (RuleB(Character, AlwaysAllowNameChange)) {
return true;
}
auto k = GetScopedBucketKeys();
k.key = "name_change_allowed";
auto b = DataBucket::GetData(k);
if (!b.value.empty()) {
return true;
}
return false;
}
bool Client::ClearNameChange() {
if (!IsNameChangeAllowed()) {
return false;
}
auto k = GetScopedBucketKeys();
k.key = "name_change_allowed";
DataBucket::DeleteData(k);
return true;
}
void Client::InvokeChangeNameWindow(bool immediate) {
if (!IsNameChangeAllowed()) {
return;
}
auto packet_op = immediate ? OP_InvokeNameChangeImmediate : OP_InvokeNameChangeLazy;
auto outapp = new EQApplicationPacket(packet_op, 0);
QueuePacket(outapp);
safe_delete(outapp);
}
void Client::GrantNameChange() {
auto k = GetScopedBucketKeys();
k.key = "name_change_allowed";
k.value = "allowed"; // potentially put a timestamp here
DataBucket::SetData(k);
InvokeChangeNameWindow(true);
}
bool Client::IsPetNameChangeAllowed() {
if (RuleB(Pets, AlwaysAllowPetRename)) {
return true;