[Commands] Cleanup #list Command (#3714)

* [Commands] Cleanup #list Command

# Notes
- Cleanup messages and logic.
- Introduce a struct so we don't have to duplicate so much code.

* Update list.cpp
This commit is contained in:
Alex King 2023-11-26 01:12:58 -05:00 committed by GitHub
parent aa0fbb8b45
commit c9993fb698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,237 +3,273 @@
#include "../object.h" #include "../object.h"
#include "../doors.h" #include "../doors.h"
struct UniqueEntity {
uint16 entity_id;
std::string entity_name;
uint32 unique_id;
glm::vec4 position;
};
void command_list(Client *c, const Seperator *sep) void command_list(Client *c, const Seperator *sep)
{ {
const int arguments = sep->argnum;
if (!arguments) {
c->Message(Chat::White, "Usage: #list [corpses|doors|npcs|objects|players] [search]");
c->Message(Chat::White, "Example: #list npcs (Blank for all)");
return;
}
const bool is_corpses = !strcasecmp(sep->arg[1], "corpses");
const bool is_doors = !strcasecmp(sep->arg[1], "doors");
const bool is_npcs = !strcasecmp(sep->arg[1], "npcs");
const bool is_objects = !strcasecmp(sep->arg[1], "objects");
const bool is_players = !strcasecmp(sep->arg[1], "players");
if (
!is_corpses &&
!is_doors &&
!is_npcs &&
!is_objects &&
!is_players
) {
c->Message(Chat::White, "Usage: #list [npcs|players|corpses|doors|objects] [search]");
c->Message(Chat::White, "Example: #list npcs (Blank for all)");
return;
}
std::string search_type; std::string search_type;
if (strcasecmp(sep->arg[1], "npcs") == 0) { std::string unique_type;
search_type = "npcs";
if (is_corpses) {
search_type = "corpse";
unique_type = "Corpse ID";
} else if (is_doors) {
search_type = "door";
unique_type = "Door ID";
} else if (is_npcs) {
search_type = "NPC";
unique_type = "NPC ID";
} else if (is_objects) {
search_type = "object";
unique_type = "Object ID";
} else if (is_players) {
search_type = "player";
unique_type = "Character ID";
} }
if (strcasecmp(sep->arg[1], "players") == 0) { uint32 entity_count = 0;
search_type = "players"; uint32 found_count = 0;
const std::string &search_string = sep->arg[2] ? Strings::ToLower(sep->arg[2]) : std::string();
std::vector<UniqueEntity> unique_entities;
if (is_corpses) {
const auto &l = entity_list.GetCorpseList();
for (const auto &e : l) {
Corpse *entity = e.second;
entity_count++;
const std::string &entity_name = Strings::ToLower(entity->GetName());
if (!search_string.empty() && entity_name.find(search_string) == std::string::npos) {
continue;
} }
if (strcasecmp(sep->arg[1], "corpses") == 0) { unique_entities.emplace_back(
search_type = "corpses"; UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetName(),
.unique_id = entity->GetCorpseDBID(),
.position = entity->GetPosition()
}
);
found_count++;
}
} else if (is_doors) {
const auto &l = entity_list.GetDoorsList();
for (const auto &e : l) {
Doors *entity = e.second;
entity_count++;
const std::string &entity_name = Strings::ToLower(entity->GetDoorName());
if (!search_string.empty() && entity_name.find(search_string) == std::string::npos) {
continue;
} }
if (strcasecmp(sep->arg[1], "doors") == 0) { unique_entities.emplace_back(
search_type = "doors"; UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetDoorName(),
.unique_id = entity->GetDoorID(),
.position = entity->GetPosition()
} }
);
if (strcasecmp(sep->arg[1], "objects") == 0) { found_count++;
search_type = "objects";
} }
} else if (is_npcs) {
const auto &l = entity_list.GetMobList();
if (search_type.length() > 0) { for (const auto &e : l) {
Mob *entity = e.second;
int entity_count = 0;
int found_count = 0;
std::string search_string;
if (sep->arg[2]) {
search_string = Strings::ToLower(sep->arg[2]);
}
// NPC
if (search_type.find("npcs") != std::string::npos) {
auto &entity_list_search = entity_list.GetMobList();
for (auto &itr : entity_list_search) {
Mob *entity = itr.second;
if (!entity->IsNPC()) { if (!entity->IsNPC()) {
continue; continue;
} }
entity_count++; entity_count++;
std::string entity_name = Strings::ToLower(entity->GetName()); const std::string &entity_name = Strings::ToLower(entity->GetName());
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) { if (!search_string.empty() && entity_name.find(search_string) == std::string::npos) {
continue; continue;
} }
std::string saylink = StringFormat( unique_entities.emplace_back(
"#goto %.0f %0.f %.0f", UniqueEntity{
entity->GetX(), .entity_id = entity->GetID(),
entity->GetY(), .entity_name = entity->GetName(),
entity->GetZ() + (entity->IsBoat() ? 50 : 0)); .unique_id = entity->GetNPCTypeID(),
.position = entity->GetPosition()
c->Message( }
0,
"| %s | ID %5d | %s | x %.0f | y %0.f | z %.0f",
Saylink::Silent(saylink, "Goto").c_str(),
entity->GetID(),
entity->GetName(),
entity->GetX(),
entity->GetY(),
entity->GetZ()
); );
found_count++; found_count++;
} }
} } else if (is_objects) {
const auto &l = entity_list.GetObjectList();
// Client for (const auto &e : l) {
if (search_type.find("players") != std::string::npos) { Object *entity = e.second;
auto &entity_list_search = entity_list.GetClientList();
for (auto &itr : entity_list_search) {
Client *entity = itr.second;
entity_count++; entity_count++;
std::string entity_name = Strings::ToLower(entity->GetName()); const std::string &entity_name = Strings::ToLower(entity->GetModelName());
if (!search_string.empty() && entity_name.find(search_string) == std::string::npos) {
/**
* Filter by name
*/
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
continue; continue;
} }
std::string saylink = StringFormat( unique_entities.emplace_back(
"#goto %.0f %0.f %.0f", UniqueEntity{
entity->GetX(), .entity_id = entity->GetID(),
entity->GetY(), .entity_name = entity->GetModelName(),
entity->GetZ()); .unique_id = entity->GetDBID(),
.position = glm::vec4(entity->GetX(), entity->GetY(), entity->GetZ(), 0.0f)
c->Message( }
0,
"| %s | ID %5d | %s | x %.0f | y %0.f | z %.0f",
Saylink::Silent(saylink, "Goto").c_str(),
entity->GetID(),
entity->GetName(),
entity->GetX(),
entity->GetY(),
entity->GetZ()
); );
found_count++; found_count++;
} }
} } else if (is_players) {
const auto &l = entity_list.GetClientList();
// Corpse for (const auto &e : l) {
if (search_type.find("corpses") != std::string::npos) { Client *entity = e.second;
auto &entity_list_search = entity_list.GetCorpseList();
for (auto &itr : entity_list_search) {
Corpse *entity = itr.second;
entity_count++; entity_count++;
std::string entity_name = Strings::ToLower(entity->GetName()); const std::string &entity_name = Strings::ToLower(entity->GetName());
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) { if (!search_string.empty() && entity_name.find(search_string) == std::string::npos) {
continue; continue;
} }
std::string saylink = StringFormat( unique_entities.emplace_back(
"#goto %.0f %0.f %.0f", UniqueEntity{
entity->GetX(), .entity_id = entity->GetID(),
entity->GetY(), .entity_name = entity->GetName(),
entity->GetZ()); .unique_id = entity->CharacterID(),
.position = entity->GetPosition()
c->Message( }
0,
"| %s | ID %5d | %s | x %.0f | y %0.f | z %.0f",
Saylink::Silent(saylink, "Goto").c_str(),
entity->GetID(),
entity->GetName(),
entity->GetX(),
entity->GetY(),
entity->GetZ()
); );
found_count++; found_count++;
} }
} }
// Doors if (!found_count) {
if (search_type.find("doors") != std::string::npos) { c->Message(
auto &entity_list_search = entity_list.GetDoorsList(); Chat::White,
fmt::format(
for (auto &itr : entity_list_search) { "Could not find any {}{}.",
Doors *entity = itr.second; search_type,
(
entity_count++; !search_string.empty() ?
fmt::format(
std::string entity_name = Strings::ToLower(entity->GetDoorName()); " matching '{}'",
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) { search_string
continue; ) :
""
)
).c_str()
);
return;
} }
std::string saylink = StringFormat( std::sort(unique_entities.begin(), unique_entities.end(), [](UniqueEntity a, UniqueEntity b) {
"#goto %.0f %0.f %.0f", if (a.entity_id && b.entity_id) {
entity->GetX(), return a.entity_id < b.entity_id;
entity->GetY(), } else {
entity->GetZ()); return a.unique_id < b.unique_id;
}
});
c->Message( for (const auto& e : unique_entities) {
0, const std::string &saylink = Saylink::Silent(
"| %s | Entity ID %5d | Door ID %i | %s | x %.0f | y %0.f | z %.0f", fmt::format(
Saylink::Silent(saylink, "Goto").c_str(), "#goto {:.2f} {:.2f} {:.2f}",
entity->GetID(), e.position.x,
entity->GetDoorID(), e.position.y,
entity->GetDoorName(), e.position.z
entity->GetX(), ),
entity->GetY(), "Goto"
entity->GetZ()
); );
found_count++;
}
}
// Objects
if (search_type.find("objects") != std::string::npos) {
auto &entity_list_search = entity_list.GetObjectList();
for (auto &itr : entity_list_search) {
Object *entity = itr.second;
entity_count++;
std::string entity_name = Strings::ToLower(entity->GetModelName());
if (search_string.length() > 0 && entity_name.find(search_string) == std::string::npos) {
continue;
}
std::string saylink = StringFormat(
"#goto %.0f %0.f %.0f",
entity->GetX(),
entity->GetY(),
entity->GetZ());
c->Message( c->Message(
0, Chat::White,
"| %s | Entity ID %5d | Object DBID %i | %s | x %.0f | y %0.f | z %.0f", fmt::format(
Saylink::Silent(saylink, "Goto").c_str(), "| {}{}{} | {} |",
entity->GetID(), saylink,
entity->GetDBID(), (
entity->GetModelName(), e.entity_id ?
entity->GetX(), fmt::format(
entity->GetY(), " | ID {}",
entity->GetZ() e.entity_id
) :
""
),
(
e.unique_id ?
fmt::format(
" | {} {}",
unique_type,
e.unique_id
) :
""
),
e.entity_name
).c_str()
); );
found_count++;
}
} }
if (found_count) {
c->Message( c->Message(
0, "Found (%i) of type (%s) in zone (%i) total", Chat::White,
fmt::format(
"Found {} {}{}{}, {} total.",
found_count, found_count,
search_type.c_str(), search_type,
found_count != 1 ? "s" : "",
(
!search_string.empty() ?
fmt::format(
" matching '{}'",
search_string
) :
""
),
entity_count entity_count
).c_str()
); );
}
}
else {
c->Message(Chat::White, "Usage of #list");
c->Message(Chat::White, "- #list [npcs|players|corpses|doors|objects] [search]");
c->Message(Chat::White, "- Example: #list npcs (Blank for all)");
}
} }