Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Help command alphabetization #1575

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 41 additions & 60 deletions dGame/dUtilities/SlashCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,31 @@
#include "dServer.h"

namespace {
std::vector<Command> CommandInfos;
std::map<std::string, Command> CommandInfos;
std::map<std::string, Command> RegisteredCommands;
}

void SlashCommandHandler::RegisterCommand(Command command) {
if (command.aliases.empty()) {
LOG("Command %s has no aliases! Skipping!", command.help.c_str());
return;
}

for (const auto& alias : command.aliases) {
LOG_DEBUG("Registering command %s", alias.c_str());
auto [_, success] = RegisteredCommands.try_emplace(alias, command);
// Don't allow duplicate commands
if (!success) {
LOG_DEBUG("Command alias %s is already registered! Skipping!", alias.c_str());
continue;
}
}

CommandInfos.push_back(command);
};
if (command.aliases.empty()) {
LOG("Command %s has no aliases! Skipping!", command.help.c_str());
return;
}

for (const auto& alias : command.aliases) {
LOG_DEBUG("Registering command %s", alias.c_str());
auto [_, success] = RegisteredCommands.try_emplace(alias, command);
// Don't allow duplicate commands
if (!success) {
LOG_DEBUG("Command alias %s is already registered! Skipping!", alias.c_str());
continue;
}
}

// Inserting into CommandInfos using the first alias as the key
if (!command.aliases.empty()) {
CommandInfos.insert(std::make_pair(command.aliases[0], command));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CommandInfos.insert(std::make_pair(command.aliases[0], command));
CommandInfos[command.aliases[0]] = command;

}
}

void SlashCommandHandler::HandleChatCommand(const std::u16string& chat, Entity* entity, const SystemAddress& sysAddr) {
auto input = GeneralUtils::UTF16ToWTF8(chat);
Expand Down Expand Up @@ -74,43 +77,6 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& chat, Entity*
}
}

// This commands in here so we can access the CommandInfos to display info
void GMZeroCommands::Help(Entity* entity, const SystemAddress& sysAddr, const std::string args) {
std::ostringstream feedback;
if (args.empty()) {
feedback << "----- Commands -----";
for (const auto& command : CommandInfos) {
// TODO: Limit displaying commands based on GM level they require
if (command.requiredLevel > entity->GetGMLevel()) continue;
LOG("Help command: %s", command.aliases[0].c_str());
feedback << "\n/" << command.aliases[0] << ": " << command.help;
}
} else {
bool foundCommand = false;
for (const auto& command : CommandInfos) {
if (std::ranges::find(command.aliases, args) == command.aliases.end()) continue;

if (entity->GetGMLevel() < command.requiredLevel) break;
foundCommand = true;
feedback << "----- " << command.aliases.at(0) << " -----\n";
// info can be a localizable string
feedback << command.info;
if (command.aliases.size() == 1) break;

feedback << "\nAliases: ";
for (size_t i = 0; i < command.aliases.size(); i++) {
if (i > 0) feedback << ", ";
feedback << command.aliases[i];
}
}

// Let GameMasters know if the command doesn't exist
if (!foundCommand && entity->GetGMLevel() > eGameMasterLevel::CIVILIAN) feedback << "Command " << std::quoted(args) << " does not exist!";
}
const auto feedbackStr = feedback.str();
if (!feedbackStr.empty()) GameMessages::SendSlashCommandFeedbackText(entity, GeneralUtils::ASCIIToUTF16(feedbackStr));
}

void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::string& message) {
AMFArrayValue args;

Expand Down Expand Up @@ -899,11 +865,26 @@ void SlashCommandHandler::Startup() {
// Register GM Zero Commands

Command HelpCommand{
.help = "Display command info",
.info = "If a command is given, display detailed info on that command. Otherwise display a list of commands with short desctiptions.",
.aliases = { "help", "h"},
.handle = GMZeroCommands::Help,
.requiredLevel = eGameMasterLevel::CIVILIAN
.help = "Display command info",
.info = "If a command is given, display detailed info on that command. Otherwise display a list of commands with short descriptions.",
.aliases = { "help", "h"},
.handle = [](Entity* entity, const SystemAddress& sysAddr, const std::string& args) {
std::ostringstream feedback;
feedback << "----- Commands -----";

// Loop through CommandInfos and display commands the player can access
for (const auto& [alias, command] : CommandInfos) {
if (command.requiredLevel <= entity->GetGMLevel()) {
LOG("Help command: %s", alias.c_str());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOG("Help command: %s", alias.c_str());

feedback << "\n/" << alias << ": " << command.help;
}
}

// Send feedback text
const auto feedbackStr = feedback.str();
if (!feedbackStr.empty()) GameMessages::SendSlashCommandFeedbackText(entity, GeneralUtils::ASCIIToUTF16(feedbackStr));
},
Comment on lines +871 to +886
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this back to being its own function

.requiredLevel = eGameMasterLevel::CIVILIAN
};
RegisterCommand(HelpCommand);

Expand Down
Loading