Fix console command registration

This commit is contained in:
Evil Factory
2026-03-22 12:42:09 -03:00
parent 994610869d
commit de53b4514e
6 changed files with 89 additions and 58 deletions
@@ -223,8 +223,6 @@ namespace Barotrauma
private static bool IsCommandPermitted(Identifier command, GameClient client) private static bool IsCommandPermitted(Identifier command, GameClient client)
{ {
if (LuaCsSetup.Instance.Game.IsCustomCommandPermitted(command)) { return true; }
switch (command.Value.ToLowerInvariant()) switch (command.Value.ToLowerInvariant())
{ {
case "kick": case "kick":
@@ -351,6 +351,7 @@ namespace Barotrauma
LuaScriptManagementService.Reset(); LuaScriptManagementService.Reset();
PackageManagementService.Reset(); PackageManagementService.Reset();
NetworkingService.Reset(); NetworkingService.Reset();
Game.Reset();
_servicesProvider.GetService<MainMenuPatch>().Reset(); _servicesProvider.GetService<MainMenuPatch>().Reset();
Logger.LogMessage("Services have been reset"); Logger.LogMessage("Services have been reset");
@@ -1,11 +1,15 @@
using System; using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq;
namespace Barotrauma.LuaCs; namespace Barotrauma.LuaCs;
public class ConsoleCommandsService : IConsoleCommandsService internal class ConsoleCommandsService : IConsoleCommandsService
{ {
private readonly ConcurrentDictionary<string, DebugConsole.Command> _registeredCommands = new(); private readonly ConcurrentDictionary<string, DebugConsole.Command> _registeredCommands = new();
@@ -15,10 +19,12 @@ public class ConsoleCommandsService : IConsoleCommandsService
{ {
return; return;
} }
foreach (var cmd in _registeredCommands.Values.ToImmutableArray()) foreach (var cmd in _registeredCommands.Values.ToImmutableArray())
{ {
DebugConsole.Commands.Remove(cmd); DebugConsole.Commands.Remove(cmd);
} }
_registeredCommands.Clear(); _registeredCommands.Clear();
} }
@@ -28,18 +34,46 @@ public class ConsoleCommandsService : IConsoleCommandsService
get => ModUtils.Threading.GetBool(ref _isDisposed); get => ModUtils.Threading.GetBool(ref _isDisposed);
private set => ModUtils.Threading.SetBool(ref _isDisposed, value); private set => ModUtils.Threading.SetBool(ref _isDisposed, value);
} }
public FluentResults.Result RegisterCommand(string name, string help, Action<string[]> onExecute, Func<string[][]> getValidArgs = null, bool isCheat = false)
public void RegisterCommand(string name, string help, Action<string[]> onExecute, Func<string[][]> getValidArgs = null, bool isCheat = false)
{ {
IService.CheckDisposed(this); IService.CheckDisposed(this);
var cmd = new DebugConsole.Command(name, help, onExecute, getValidArgs, isCheat); var cmd = new DebugConsole.Command(name, help, onExecute, getValidArgs, isCheat);
if (!_registeredCommands.TryAdd(name, cmd)) if (!_registeredCommands.TryAdd(name, cmd))
{ {
return FluentResults.Result.Fail($"{nameof(RegisterCommand)}: A command with the name '{name}' is already added."); throw new ArgumentException($"A command with the name '{name}' is already registered.");
} }
DebugConsole.Commands.Add(cmd); DebugConsole.Commands.Add(cmd);
return FluentResults.Result.Ok();
} }
public void AssignOnExecute(string names, Action<string[]> onExecute)
{
var matchingCommand = DebugConsole.Commands.Find(c => c.Names.Intersect(names.Split('|').ToIdentifiers()).Any());
if (matchingCommand == null)
{
throw new Exception("AssignOnExecute failed. Command matching the name(s) \"" + names + "\" not found.");
}
else
{
matchingCommand.OnExecute = onExecute;
}
}
#if SERVER
public void AssignOnClientRequestExecute(string names, Action<Client, Vector2, string[]> onClientRequestExecute)
{
var matchingCommand = DebugConsole.Commands.Find(c => c.Names.Intersect(names.Split('|').ToIdentifiers()).Any());
if (matchingCommand == null)
{
throw new Exception("AssignOnClientRequestExecute failed. Command matching the name(s) \"" + names + "\" not found.");
}
else
{
matchingCommand.OnClientRequestExecute = onClientRequestExecute;
}
}
#endif
public void RemoveCommand(string name) public void RemoveCommand(string name)
{ {
IService.CheckDisposed(this); IService.CheckDisposed(this);
@@ -27,12 +27,16 @@ internal class HarmonyEventPatchesService : ISystem
private static ILoggerService _loggerService; private static ILoggerService _loggerService;
private readonly Harmony Harmony; private readonly Harmony Harmony;
private static int debugConsoleCommandVanillaIndex;
public HarmonyEventPatchesService(IEventService eventService, ILoggerService loggerService) public HarmonyEventPatchesService(IEventService eventService, ILoggerService loggerService)
{ {
_eventService = eventService; _eventService = eventService;
_loggerService = loggerService; _loggerService = loggerService;
Harmony = new Harmony("LuaCsForBarotrauma.Events"); Harmony = new Harmony("LuaCsForBarotrauma.Events");
Patch(); Patch();
debugConsoleCommandVanillaIndex = DebugConsole.Commands.Count;
} }
private void Patch() private void Patch()
@@ -136,6 +140,22 @@ internal class HarmonyEventPatchesService : ISystem
{ {
_eventService.PublishEvent<IEventKeyUpdate>(x => x.OnKeyUpdate(deltaTime)); _eventService.PublishEvent<IEventKeyUpdate>(x => x.OnKeyUpdate(deltaTime));
} }
[HarmonyPatch(typeof(DebugConsole), "IsCommandPermitted"), HarmonyPrefix]
public static bool DebugConsole_IsCommandPermitted(Identifier command, ref bool __result)
{
DebugConsole.Command c = DebugConsole.FindCommand(command.Value);
if (DebugConsole.Commands.IndexOf(c) >= debugConsoleCommandVanillaIndex)
{
__result = true;
return false;
}
return true;
}
#elif SERVER #elif SERVER
[HarmonyPatch(typeof(GameServer), "ReadDataMessage"), HarmonyPrefix] [HarmonyPatch(typeof(GameServer), "ReadDataMessage"), HarmonyPrefix]
public static void GameServer_ReadDataMessage_Pre(NetworkConnection sender, IReadMessage inc) public static void GameServer_ReadDataMessage_Pre(NetworkConnection sender, IReadMessage inc)
@@ -1,11 +1,16 @@
using System; using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
namespace Barotrauma.LuaCs; namespace Barotrauma.LuaCs;
public interface IConsoleCommandsService : IService public interface IConsoleCommandsService : IService
{ {
FluentResults.Result RegisterCommand(string name, string help, Action<string[]> onExecute, Func<string[][]> getValidArgs = null, void RegisterCommand(string name, string help, Action<string[]> onExecute, Func<string[][]> getValidArgs = null, bool isCheat = false);
bool isCheat = false); void AssignOnExecute(string names, Action<string[]> onExecute);
#if SERVER
internal void AssignOnClientRequestExecute(string names, Action<Client, Vector2, string[]> onClientRequestExecute);
#endif
void RemoveCommand(string name); void RemoveCommand(string name);
void RemoveRegisteredCommands(); void RemoveRegisteredCommands();
} }
@@ -147,7 +147,6 @@ namespace Barotrauma.LuaCs
public bool disableSpamFilter = false; public bool disableSpamFilter = false;
public bool disableDisconnectCharacter = false; public bool disableDisconnectCharacter = false;
public bool enableControlHusk = false; public bool enableControlHusk = false;
public int MapEntityUpdateInterval public int MapEntityUpdateInterval
{ {
get { return MapEntity.MapEntityUpdateInterval; } get { return MapEntity.MapEntityUpdateInterval; }
@@ -270,10 +269,12 @@ namespace Barotrauma.LuaCs
} }
#endif #endif
public LuaGame() private readonly IConsoleCommandsService _consoleCommands;
public LuaGame(IConsoleCommandsService consoleCommands)
{ {
/*LuaUserData.MakeFieldAccessible(UserData.RegisterType(typeof(GameSettings)), "currentConfig"); Settings = UserData.CreateStatic(typeof(GameSettings));
Settings = UserData.CreateStatic(typeof(GameSettings));*/ _consoleCommands = consoleCommands;
} }
public void OverrideTraitors(bool o) public void OverrideTraitors(bool o)
@@ -405,38 +406,16 @@ namespace Barotrauma.LuaCs
return new Signal(value, stepsTaken, sender, source, power, strength); return new Signal(value, stepsTaken, sender, source, power, strength);
} }
private List<DebugConsole.Command> luaAddedCommand = new List<DebugConsole.Command>();
public IEnumerable<DebugConsole.Command> LuaAddedCommand { get { return luaAddedCommand; } }
public bool IsCustomCommandPermitted(Identifier command)
{
DebugConsole.Command[] permitted = new DebugConsole.Command[]
{
DebugConsole.FindCommand("cl_reloadluacs"),
DebugConsole.FindCommand("cl_lua"),
DebugConsole.FindCommand("cl_toggleluadebug"),
};
foreach (var consoleCommand in LuaAddedCommand.Concat(permitted.AsEnumerable()))
{
if (consoleCommand.Names.Contains(command))
{
return true;
}
}
return false;
}
public void RemoveCommand(string name) public void RemoveCommand(string name)
{ {
for (var i = 0; i < DebugConsole.Commands.Count; i++) _consoleCommands.RemoveCommand(name);
for (var i = DebugConsole.Commands.Count - 1; i >= 0; i--)
{ {
foreach (var cmdname in DebugConsole.Commands[i].Names) foreach (var cmdname in DebugConsole.Commands[i].Names)
{ {
if (cmdname == name) if (cmdname == name)
{ {
luaAddedCommand.Remove(DebugConsole.Commands[i]);
DebugConsole.Commands.RemoveAt(i); DebugConsole.Commands.RemoveAt(i);
continue; continue;
} }
@@ -446,32 +425,28 @@ namespace Barotrauma.LuaCs
public void AddCommand(string name, string help, LuaCsAction onExecute, LuaCsFunc getValidArgs = null, bool isCheat = false) public void AddCommand(string name, string help, LuaCsAction onExecute, LuaCsFunc getValidArgs = null, bool isCheat = false)
{ {
var cmd = new DebugConsole.Command(name, help, (string[] arg1) => onExecute(new object[] { arg1 }), _consoleCommands.RegisterCommand(name, help,
(string[] args) =>
{
onExecute(new object[] { args });
},
() => () =>
{ {
if (getValidArgs == null) return null; if (getValidArgs == null) { return null; }
var validArgs = getValidArgs(); var validArgs = getValidArgs();
if (validArgs is DynValue luaValue) if (validArgs is DynValue luaValue)
{ {
return luaValue.ToObject<string[][]>(); return luaValue.ToObject<string[][]>();
} }
return (string[][])validArgs; return (string[][])validArgs;
}, isCheat); }
);
luaAddedCommand.Add(cmd);
DebugConsole.Commands.Add(cmd);
} }
public List<DebugConsole.Command> Commands => DebugConsole.Commands;
public bool IsDisposed => throw new NotImplementedException(); public bool IsDisposed => throw new NotImplementedException();
public void AssignOnExecute(string names, object onExecute) => DebugConsole.AssignOnExecute(names, public void AssignOnExecute(string names, LuaCsAction onExecute) =>
(string[] a) => _consoleCommands.AssignOnExecute(names, args => onExecute(args));
{
//GameMain.LuaCs.CallLuaFunction(onExecute, new object[] { a });
throw new NotImplementedException();
});
public void SaveGame(string path) public void SaveGame(string path)
{ {
@@ -532,7 +507,8 @@ namespace Barotrauma.LuaCs
GameMain.Server.EndGame(); GameMain.Server.EndGame();
} }
//public void AssignOnClientRequestExecute(string names, object onExecute) => DebugConsole.AssignOnClientRequestExecute(names, (Client a, Vector2 b, string[] c) => { GameMain.LuaCs.CallLuaFunction(onExecute, new object[] { a, b, c }); }); public void AssignOnClientRequestExecute(string names, LuaCsAction onExecute) =>
_consoleCommands.AssignOnClientRequestExecute(names, (Client client, Vector2 position, string[] args) => onExecute(client, position, args));
#endif #endif
@@ -541,10 +517,7 @@ namespace Barotrauma.LuaCs
MapEntityUpdateInterval = 1; MapEntityUpdateInterval = 1;
CharacterUpdateInterval = 1; CharacterUpdateInterval = 1;
foreach (var cmd in luaAddedCommand) _consoleCommands.RemoveRegisteredCommands();
{
DebugConsole.Commands.Remove(cmd);
}
} }
public FluentResults.Result Reset() public FluentResults.Result Reset()