Knightly 7ab909ee47 Standardize Licensing
- License was intended to be GPLv3 per earlier commit of GPLv3 LICENSE FILE
- This is confirmed by the inclusion of libraries that are incompatible with GPLv2
- This is also confirmed by KLS and the agreement of KLS's predecessors
- Added GPLv3 license headers to the compilable source files
- Removed Folly licensing in strings.h since the string functions do not match the Folly functions and are standard functions - this must have been left over from previous implementations
- Removed individual contributor license headers since the project has been under the "developer" mantle for many years
- Removed comments on files that were previously automatically generated since they've been manually modified multiple times and there are no automatic scripts referencing them (removed in 2023)
2026-04-01 17:09:57 -07:00

343 lines
7.5 KiB
C++
Executable File

/* EQEmu: EQEmulator
Copyright (C) 2001-2026 EQEmu Development Team
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; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>.
*/
#include "zone/client.h"
#include "zone/command.h"
#include "zone/corpse.h"
#include "zone/doors.h"
#include "zone/object.h"
struct UniqueEntity {
uint16 entity_id;
std::string entity_name;
uint32 unique_id;
glm::vec4 position;
};
void command_list(Client *c, const Seperator *sep)
{
const uint16 arguments = sep->argnum;
if (!arguments) {
c->Message(Chat::White, "Usage: #list [bots|corpses|doors|npcs|objects|players] [search]");
c->Message(Chat::White, "Example: #list npcs (Blank for all)");
return;
}
const bool can_kill = c->Admin() >= GetCommandStatus("kill");
const bool is_bots = !strcasecmp(sep->arg[1], "bots");
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_bots &&
!is_corpses &&
!is_doors &&
!is_npcs &&
!is_objects &&
!is_players
) {
c->Message(Chat::White, "Usage: #list [bots|corpses|doors|npcs|objects|players] [search]");
c->Message(Chat::White, "Example: #list npcs (Blank for all)");
return;
}
std::string search_type;
std::string unique_type;
if (is_bots) {
search_type = "bot";
unique_type = "Bot ID";
} else 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";
}
uint32 entity_count = 0;
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_bots) {
const auto& l = entity_list.GetBotList();
for (const auto& e : l) {
Bot* entity = e.second;
entity_count++;
const std::string& entity_name = Strings::ToLower(entity->GetName());
if (!search_string.empty() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetName(),
.unique_id = entity->GetBotID(),
.position = entity->GetPosition()
}
);
found_count++;
}
} else 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() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
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() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetDoorName(),
.unique_id = entity->GetDoorID(),
.position = entity->GetPosition()
}
);
found_count++;
}
} else if (is_npcs) {
const auto& l = entity_list.GetMobList();
for (const auto& e: l) {
Mob* entity = e.second;
if (!entity->IsNPC()) {
continue;
}
entity_count++;
const std::string& entity_name = Strings::ToLower(entity->GetName());
if (!search_string.empty() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetName(),
.unique_id = entity->GetNPCTypeID(),
.position = entity->GetPosition()
}
);
found_count++;
}
} else if (is_objects) {
const auto& l = entity_list.GetObjectList();
for (const auto& e: l) {
Object* entity = e.second;
entity_count++;
const std::string& entity_name = Strings::ToLower(entity->GetModelName());
if (!search_string.empty() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetModelName(),
.unique_id = entity->GetDBID(),
.position = glm::vec4(entity->GetX(), entity->GetY(), entity->GetZ(), 0.0f)
}
);
found_count++;
}
} else if (is_players) {
const auto& l = entity_list.GetClientList();
for (const auto& e: l) {
Client* entity = e.second;
entity_count++;
const std::string& entity_name = Strings::ToLower(entity->GetName());
if (!search_string.empty() && !Strings::Contains(entity_name, search_string)) {
continue;
}
unique_entities.emplace_back(
UniqueEntity{
.entity_id = entity->GetID(),
.entity_name = entity->GetName(),
.unique_id = entity->CharacterID(),
.position = entity->GetPosition()
}
);
found_count++;
}
}
if (!found_count) {
c->Message(
Chat::White,
fmt::format(
"Could not find any {}{}.",
search_type,
(
!search_string.empty() ?
fmt::format(
" matching '{}'",
search_string
) :
""
)
).c_str()
);
return;
}
std::sort(
unique_entities.begin(),
unique_entities.end(),
[](UniqueEntity a, UniqueEntity b) {
if (a.entity_id && b.entity_id) {
return a.entity_id < b.entity_id;
} else {
return a.unique_id < b.unique_id;
}
}
);
for (const auto& e : unique_entities) {
const std::string& saylink = Saylink::Silent(
fmt::format(
"#goto {:.2f} {:.2f} {:.2f}",
e.position.x,
e.position.y,
e.position.z
),
"Goto"
);
c->Message(
Chat::White,
fmt::format(
"| {}{}{} | {} |{}",
saylink,
(
e.entity_id ?
fmt::format(
" | ID {}",
e.entity_id
) :
""
),
(
e.unique_id ?
fmt::format(
" | {} {}",
unique_type,
e.unique_id
) :
""
),
e.entity_name,
(
(can_kill && (is_bots || is_npcs || is_players)) ?
fmt::format(
" {} |",
Saylink::Silent(
fmt::format(
"#kill {}",
e.entity_id
),
"Kill"
)
) :
""
)
).c_str()
);
}
c->Message(
Chat::White,
fmt::format(
"Found {} {}{}{}, {} total.",
found_count,
search_type,
found_count != 1 ? "s" : "",
(
!search_string.empty() ?
fmt::format(
" matching '{}'",
search_string
) :
""
),
entity_count
).c_str()
);
}