Class SensitiveCommandRegistry
A command such as /login <password> carries a secret in its arguments. Anything the
framework sends to UltiCloud (the panel's console log stream, including the start-up lines
replayed once the stream opens; error reports; chat events) is passed through
redactText(String) on its way out, which keeps a registered command's name and replaces
everything after it with ***. A player-command event never carries arguments at all,
registered or not: it carries commandName(String) only.
Only data sent to UltiCloud is redacted. The server's own console, its log files and the
LogRecord objects other handlers see keep the original text: the
operator who can read the local console can already read what the players typed.
Matching. A command line matches when its first word, with one leading / and a
namespace: prefix removed, equals a registered name, compared case-insensitively
(Locale.ROOT, so a Turkish or other default locale does not change the result). With
login registered, all of /login, /LOGIN, ultilogin:login and
/ultilogin:Login match. Names are stored in that normalised form, so registering
ultilogin:login registers login.
The table starts empty. The framework registers nothing on its own; a module that owns a secret-carrying command registers it, and every alias, from its enable hook:
public boolean registerSelf() {
UltiTools.getInstance().getSensitiveCommandRegistry()
.register("login", "l", "register", "reg", "changepassword");
return true;
}
Registration is safe from any thread, takes effect immediately whether or not the server is
linked to UltiCloud, and is idempotent, so registering again after a module reload is harmless.
There is deliberately no way to unregister: a name stays redacted until the server restarts,
which errs on the side of redacting too much rather than too little, and means one module cannot
weaken another module's redaction.
Unlike the rest of this package, this class is a stable, public extension point for modules.
- Since:
- 6.3.1
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic StringcommandName(String commandLine) The normalised name of a command line's command: its first whitespace-delimited token, passed throughnormalize(String).private intfindRedactionPoint(String text, int lineStart, int lineEnd) Finds where one line must be cut: the end of the first registered command that is followed by an argument, or-1when the line needs no redaction.private static booleanhasArgument(String text, int from, int to) Whether an argument lies in[from, to): any character other than whitespace and quote characters, so a closing quote alone is not an argument.private static booleanisBoundary(char c) Whitespace or a quote character: what may precede a command in text and ends its token.booleanisSensitive(String commandLine) Whether a command line starts with a registered command.static StringNormalises one command token: strips one leading/and anamespace:prefix, and lower-cases the rest withLocale.ROOT.redactCommandLine(String commandLine) Redacts one command line: when its command is registered and arguments follow, keeps the command as typed and replaces the arguments with***.redactText(String text) Redacts free text, such as a log line, an exception message or a stack trace, before it is sent to UltiCloud.voidRegisters command names whose arguments must not reach UltiCloud.A snapshot of the registered names, in their normalised form.private static intskipWhitespace(String text, int from, int to)
-
Field Details
-
REDACTED
What replaces a registered command's arguments.- See Also:
-
names
The registered names, normalised bynormalize(String).
-
-
Constructor Details
-
SensitiveCommandRegistry
public SensitiveCommandRegistry()Creates an empty registry.
-
-
Method Details
-
register
Registers command names whose arguments must not reach UltiCloud.Each name is normalised first (
normalize(String)), so"/Login","login"and"ultilogin:login"all registerlogin. Anullarray, andnullor blank names, are ignored. Registering a name twice is harmless.- Parameters:
commandNames- the command names and aliases to register
-
isSensitive
Whether a command line starts with a registered command.- Parameters:
commandLine- a command line as typed, with or without the leading/- Returns:
trueif the line'scommand nameis registered
-
normalize
Normalises one command token: strips one leading/and anamespace:prefix, and lower-cases the rest withLocale.ROOT."/login"and"/UltiLogin:LOGIN"give"login";"//login"gives"/login"(only one slash is stripped, so a//command stays distinct);"login:"gives an empty string.- Parameters:
commandToken- one command token, possiblynull- Returns:
- the normalised name, or an empty string for a
nullor blank token
-
commandName
The normalised name of a command line's command: its first whitespace-delimited token, passed throughnormalize(String)."/ultilogin:Login pw"gives"login"," /spawn"gives"spawn","/MSG Alex hi"gives"msg". This is the only part of a player's command that the framework sends to UltiCloud in a command event.- Parameters:
commandLine- a command line as typed, possiblynull- Returns:
- the normalised command name, or an empty string for a
nullor blank line
-
redactCommandLine
Redacts one command line: when its command is registered and arguments follow, keeps the command as typed and replaces the arguments with***.With
loginregistered,"/login hunter2"gives"/login ***", while"/login"and"/login "(no arguments) are returned unchanged, as is any line whose command is not registered.- Parameters:
commandLine- a command line as typed, possiblynull- Returns:
- the redacted line, or the line itself when nothing needs redacting
-
redactText
Redacts free text, such as a log line, an exception message or a stack trace, before it is sent to UltiCloud.Each line (
\n,\r\nor\rseparated; the separators are kept) is handled on its own. A command starts at a/that opens the line or follows whitespace or a quote character (",'or`), and runs to the next whitespace or quote character. At the first such command on the line whosenormalisedform is registered, and that is followed by an argument (anything other than whitespace and quote characters), the command is kept and the rest of the line is replaced with***. For example, withloginandregisterregistered:Steve issued server command: /register a bbecomesSteve issued server command: /register ***;said "/login pw"becomessaid "/login ***;see http://x/login/y,//login pw(a different command) andtyped "/login"are unchanged.
- Parameters:
text- the text, possiblynull- Returns:
- the redacted text, or the text itself when nothing needs redacting
-
registeredNames
A snapshot of the registered names, in their normalised form.- Returns:
- an unmodifiable copy; later registrations do not change it
-
findRedactionPoint
Finds where one line must be cut: the end of the first registered command that is followed by an argument, or-1when the line needs no redaction. -
hasArgument
Whether an argument lies in[from, to): any character other than whitespace and quote characters, so a closing quote alone is not an argument. -
isBoundary
private static boolean isBoundary(char c) Whitespace or a quote character: what may precede a command in text and ends its token. -
skipWhitespace
-