feat: add built-in players app var

Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com>
Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/c9f7aa87-50b7-4725-aa39-613eba1a07fd
This commit is contained in:
copilot-swe-agent[bot] 2026-03-24 19:47:10 +00:00
parent 4c1b2197d7
commit 7b534ca547
4 changed files with 50 additions and 28 deletions

View file

@ -119,7 +119,7 @@
</resheader>
<data name="AppVars.Variables" xml:space="preserve">
<value>can be used in some other fields as %yourvar%
%username% and %serverip% are reserved variables.</value>
%username%, %login%, %serverip%, %serverport%, %datetime% and %players% are reserved read-only variables.</value>
</data>
<data name="ChatBot" xml:space="preserve">
<value>=============================== #
@ -930,4 +930,4 @@ Note: This does NOT require a Bot Token, only an Application ID. Discord must be
<data name="Main.General.AuthlibUser" xml:space="preserve">
<value>Yggdrasil authlib multi-user selection.</value>
</data>
</root>
</root>

View file

@ -1024,6 +1024,34 @@ namespace MinecraftClient
[NonSerialized]
readonly Lock varLock = new();
private static bool TryGetReadOnlyVar(string varName, [NotNullWhen(true)] out object? varData)
{
switch (Settings.ToLowerIfNeed(varName))
{
case "username":
varData = InternalConfig.Username;
return true;
case "login":
varData = InternalConfig.Account.Login;
return true;
case "serverip":
varData = InternalConfig.ServerIP;
return true;
case "serverport":
varData = InternalConfig.ServerPort;
return true;
case "datetime":
varData = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
return true;
case "players":
varData = string.Join(", ", McClient.Instance?.GetOnlinePlayers() ?? []);
return true;
default:
varData = null;
return false;
}
}
/// <summary>
/// Set a custom %variable% which will be available through expandVars()
/// </summary>
@ -1066,6 +1094,8 @@ namespace MinecraftClient
/// <returns>The value or null if the variable does not exists</returns>
public object? GetVar(string varName)
{
if (TryGetReadOnlyVar(varName, out object? readOnlyVar))
return readOnlyVar;
if (VarStirng.TryGetValue(varName, out string? valueString))
return valueString;
else if (VarObject.TryGetValue(varName, out object? valueObject))
@ -1081,6 +1111,8 @@ namespace MinecraftClient
/// <returns>The value or null if the variable does not exists</returns>
public bool TryGetVar(string varName, [NotNullWhen(true)] out object? varData)
{
if (TryGetReadOnlyVar(varName, out varData))
return true;
if (VarStirng.TryGetValue(varName, out string? valueString))
{
varData = valueString;
@ -1143,31 +1175,21 @@ namespace MinecraftClient
string varname_lower = Settings.ToLowerIfNeed(varname);
i = i + varname.Length + 1;
switch (varname_lower)
if (TryGetReadOnlyVar(varname_lower, out object? readOnlyVar))
{
case "username": result.Append(InternalConfig.Username); break;
case "login": result.Append(InternalConfig.Account.Login); break;
case "serverip": result.Append(InternalConfig.ServerIP); break;
case "serverport": result.Append(InternalConfig.ServerPort); break;
case "datetime":
DateTime time = DateTime.Now;
result.Append(String.Format("{0}-{1}-{2} {3}:{4}:{5}",
time.Year.ToString("0000"),
time.Month.ToString("00"),
time.Day.ToString("00"),
time.Hour.ToString("00"),
time.Minute.ToString("00"),
time.Second.ToString("00")));
break;
default:
if (localVars is not null && localVars.ContainsKey(varname_lower))
result.Append(localVars[varname_lower].ToString());
else if (TryGetVar(varname_lower, out object? var_value))
result.Append(var_value.ToString());
else
result.Append("%" + varname + '%');
break;
result.Append(readOnlyVar?.ToString());
}
else if (localVars is not null && localVars.ContainsKey(varname_lower))
{
result.Append(localVars[varname_lower].ToString());
}
else if (TryGetVar(varname_lower, out object? var_value))
{
result.Append(var_value.ToString());
}
else
{
result.Append("%" + varname + '%');
}
}
else result.Append(str[i]);

View file

@ -1066,7 +1066,7 @@ Coordinate = { x = 145, y = 64, z = 2045 }
<div class="custom-container tip"><p class="custom-container-title">Tip</p>
**`%username%`, `%serverip%`, `%datetime%` are reserved variables**
**`%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`, `%players%` are reserved read-only variables**
</div>

View file

@ -6,7 +6,7 @@ title: Creating Simple Script
A simple script is a text file with one command per line. See the [Internal Commands](usage.md#internal-commands) section, or type `/help` in the console to see the available commands. Any line beginning with `#` is ignored and treated as a comment.
Application variables defined with the `set` command or in the `[AppVars]` config section can be used. The following read-only variables are also available: `%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`.
Application variables defined with the `set` command or in the `[AppVars]` config section can be used. The following read-only variables are also available: `%username%`, `%login%`, `%serverip%`, `%serverport%`, `%datetime%`, `%players%` (`%players%` expands to the current online player names separated by commas).
## Example