aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Server/Console/ServerCliRegistry.cpp
diff options
context:
space:
mode:
authorqwasdrizzel <145519042+qwasdrizzel@users.noreply.github.com>2026-03-16 21:44:26 -0500
committerGitHub <noreply@github.com>2026-03-16 21:44:26 -0500
commitce739f6045ec72127491286ea3f3f21e537c1b55 (patch)
treef33bd42a47c1b4a7b2153a7fb77127ee3b407db9 /Minecraft.Server/Console/ServerCliRegistry.cpp
parent255a18fe8e9b57377975f82e2b227afe2a12eda0 (diff)
parent5a59f5d146b43811dde6a5a0245ee9875d7b5cd1 (diff)
Merge branch 'smartcmd:main' into main
Diffstat (limited to 'Minecraft.Server/Console/ServerCliRegistry.cpp')
-rw-r--r--Minecraft.Server/Console/ServerCliRegistry.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Minecraft.Server/Console/ServerCliRegistry.cpp b/Minecraft.Server/Console/ServerCliRegistry.cpp
new file mode 100644
index 00000000..432907b2
--- /dev/null
+++ b/Minecraft.Server/Console/ServerCliRegistry.cpp
@@ -0,0 +1,99 @@
+#include "stdafx.h"
+
+#include "ServerCliRegistry.h"
+
+#include "commands\IServerCliCommand.h"
+#include "..\Common\StringUtils.h"
+
+namespace ServerRuntime
+{
+ bool ServerCliRegistry::Register(std::unique_ptr<IServerCliCommand> command)
+ {
+ if (!command)
+ {
+ return false;
+ }
+
+ IServerCliCommand *raw = command.get();
+ std::string baseName = StringUtils::ToLowerAscii(raw->Name());
+ // Reject empty/duplicate primary command names.
+ if (baseName.empty() || m_lookup.find(baseName) != m_lookup.end())
+ {
+ return false;
+ }
+ std::vector<std::string> aliases = raw->Aliases();
+ std::vector<std::string> normalizedAliases;
+ normalizedAliases.reserve(aliases.size());
+ for (size_t i = 0; i < aliases.size(); ++i)
+ {
+ std::string alias = StringUtils::ToLowerAscii(aliases[i]);
+ // Alias must also be unique across all names and aliases.
+ if (alias.empty() || m_lookup.find(alias) != m_lookup.end())
+ {
+ return false;
+ }
+ normalizedAliases.push_back(alias);
+ }
+
+ m_lookup[baseName] = raw;
+ for (size_t i = 0; i < normalizedAliases.size(); ++i)
+ {
+ m_lookup[normalizedAliases[i]] = raw;
+ }
+
+ // Command objects are owned here; lookup stores non-owning pointers.
+ m_commands.push_back(std::move(command));
+ return true;
+ }
+
+ const IServerCliCommand *ServerCliRegistry::Find(const std::string &name) const
+ {
+ std::string key = StringUtils::ToLowerAscii(name);
+ auto it = m_lookup.find(key);
+ if (it == m_lookup.end())
+ {
+ return NULL;
+ }
+ return it->second;
+ }
+
+ IServerCliCommand *ServerCliRegistry::FindMutable(const std::string &name)
+ {
+ std::string key = StringUtils::ToLowerAscii(name);
+ auto it = m_lookup.find(key);
+ if (it == m_lookup.end())
+ {
+ return NULL;
+ }
+ return it->second;
+ }
+
+ void ServerCliRegistry::SuggestCommandNames(const std::string &prefix, const std::string &linePrefix, std::vector<std::string> *out) const
+ {
+ for (size_t i = 0; i < m_commands.size(); ++i)
+ {
+ const IServerCliCommand *command = m_commands[i].get();
+ std::string name = command->Name();
+ if (StringUtils::StartsWithIgnoreCase(name, prefix))
+ {
+ out->push_back(linePrefix + name);
+ }
+
+ // Include aliases so users can discover shorthand commands.
+ std::vector<std::string> aliases = command->Aliases();
+ for (size_t aliasIndex = 0; aliasIndex < aliases.size(); ++aliasIndex)
+ {
+ if (StringUtils::StartsWithIgnoreCase(aliases[aliasIndex], prefix))
+ {
+ out->push_back(linePrefix + aliases[aliasIndex]);
+ }
+ }
+ }
+ }
+
+ const std::vector<std::unique_ptr<IServerCliCommand>> &ServerCliRegistry::Commands() const
+ {
+ return m_commands;
+ }
+}
+