mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-15 06:42:25 +02:00
ConGroups are gone. Long live admin flags in content. (#1371)
This commit is contained in:
@@ -1,73 +1,53 @@
|
||||
using System;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracks the console group of the client and which commands they can use.
|
||||
/// Receives up to date permissions from the server whenever they change.
|
||||
/// </summary>
|
||||
public class ClientConGroupController : IClientConGroupController
|
||||
{
|
||||
[Dependency] private readonly IClientNetManager _netManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The console group this client is in. Determines which commands the client can use and if they can use vv.
|
||||
/// </summary>
|
||||
private ConGroup? _clientConGroup;
|
||||
|
||||
private IClientConGroupImplementation? _implementation;
|
||||
public event Action? ConGroupUpdated;
|
||||
|
||||
public void Initialize()
|
||||
public IClientConGroupImplementation? Implementation
|
||||
{
|
||||
_netManager.RegisterNetMessage<MsgConGroupUpdate>(MsgConGroupUpdate.Name, _onConGroupUpdate);
|
||||
set
|
||||
{
|
||||
if (_implementation != null)
|
||||
{
|
||||
_implementation.ConGroupUpdated -= GroupUpdated;
|
||||
}
|
||||
|
||||
_implementation = value!;
|
||||
_implementation.ConGroupUpdated += GroupUpdated;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCommand(string cmdName)
|
||||
{
|
||||
if (_clientConGroup == null)
|
||||
return false;
|
||||
return _clientConGroup.Commands!.Contains(cmdName);
|
||||
return _implementation?.CanCommand(cmdName) ?? false;
|
||||
}
|
||||
|
||||
public bool CanViewVar()
|
||||
{
|
||||
if (_clientConGroup == null)
|
||||
return false;
|
||||
return _clientConGroup.CanViewVar;
|
||||
return _implementation?.CanViewVar() ?? false;
|
||||
}
|
||||
|
||||
public bool CanAdminPlace()
|
||||
{
|
||||
if (_clientConGroup == null)
|
||||
return false;
|
||||
return _clientConGroup.CanAdminPlace;
|
||||
return _implementation?.CanAdminPlace() ?? false;
|
||||
}
|
||||
|
||||
public bool CanScript()
|
||||
{
|
||||
if (_clientConGroup == null)
|
||||
return false;
|
||||
return _clientConGroup.CanScript;
|
||||
return _implementation?.CanScript() ?? false;
|
||||
}
|
||||
|
||||
public bool CanAdminMenu()
|
||||
{
|
||||
if (_clientConGroup == null)
|
||||
return false;
|
||||
return _clientConGroup.CanAdminMenu;
|
||||
return _implementation?.CanAdminMenu() ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update client console group data with message from the server.
|
||||
/// </summary>
|
||||
/// <param name="msg">Server message listing what commands this client can use.</param>
|
||||
private void _onConGroupUpdate(MsgConGroupUpdate msg)
|
||||
private void GroupUpdated()
|
||||
{
|
||||
_clientConGroup = msg.ClientConGroup;
|
||||
|
||||
ConGroupUpdated?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +63,9 @@ namespace Robust.Client.Console.Commands
|
||||
filter = args[0];
|
||||
}
|
||||
|
||||
var conGroup = IoCManager.Resolve<IClientConGroupController>();
|
||||
foreach (var command in console.Commands.Values
|
||||
.Where(p => p.Command.Contains(filter))
|
||||
.Where(p => p.Command.Contains(filter) && conGroup.CanCommand(p.Command))
|
||||
.OrderBy(c => c.Command))
|
||||
{
|
||||
console.AddLine(command.Command + ": " + command.Description);
|
||||
|
||||
@@ -1,20 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public interface IClientConGroupController
|
||||
public interface IClientConGroupController : IClientConGroupImplementation
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
bool CanCommand(string cmdName);
|
||||
bool CanViewVar();
|
||||
bool CanAdminPlace();
|
||||
bool CanScript();
|
||||
bool CanAdminMenu();
|
||||
event Action ConGroupUpdated;
|
||||
IClientConGroupImplementation Implementation { set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Robust.Client.Console
|
||||
{
|
||||
public interface IClientConGroupImplementation
|
||||
{
|
||||
bool CanCommand(string cmdName);
|
||||
bool CanViewVar();
|
||||
bool CanAdminPlace();
|
||||
bool CanScript();
|
||||
bool CanAdminMenu();
|
||||
|
||||
event Action ConGroupUpdated;
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,6 @@ namespace Robust.Client
|
||||
[Dependency] private readonly IClydeInternal _clyde = default!;
|
||||
[Dependency] private readonly IFontManagerInternal _fontManager = default!;
|
||||
[Dependency] private readonly IModLoader _modLoader = default!;
|
||||
[Dependency] private readonly IClientConGroupController _conGroupController = default!;
|
||||
[Dependency] private readonly IScriptClient _scriptClient = default!;
|
||||
[Dependency] private readonly IComponentManager _componentManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
@@ -177,7 +176,6 @@ namespace Robust.Client
|
||||
_gameStateManager.Initialize();
|
||||
_placementManager.Initialize();
|
||||
_viewVariablesManager.Initialize();
|
||||
_conGroupController.Initialize();
|
||||
_scriptClient.Initialize();
|
||||
|
||||
_client.Initialize();
|
||||
|
||||
@@ -317,7 +317,6 @@ namespace Robust.Server
|
||||
prototypeManager.Resync();
|
||||
|
||||
IoCManager.Resolve<IConsoleShell>().Initialize();
|
||||
IoCManager.Resolve<IConGroupController>().Initialize();
|
||||
_entities.Startup();
|
||||
_scriptHost.Initialize();
|
||||
|
||||
@@ -472,7 +471,7 @@ namespace Robust.Server
|
||||
Logger.InfoS("game", $"Tickrate changed to: {b} on tick {_time.CurTick}");
|
||||
SendTickRateUpdateToClients(b);
|
||||
});
|
||||
|
||||
|
||||
cfgMgr.SetCVar(CVars.GameType, (int) GameType.Game);
|
||||
|
||||
_time.TickRate = (byte) _config.GetCVar(CVars.NetTickrate);
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Interfaces.Log;
|
||||
using Robust.Shared.Interfaces.Resources;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace Robust.Server.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the collection of groups for a console shell.
|
||||
/// </summary>
|
||||
internal class ConGroupContainer
|
||||
{
|
||||
private static readonly ResourcePath _groupPath = new ResourcePath("/Groups/groups.yml");
|
||||
|
||||
private readonly IResourceManager _resMan;
|
||||
private readonly ISawmill _logger;
|
||||
private readonly Dictionary<ConGroupIndex, ConGroup> _groups = new Dictionary<ConGroupIndex, ConGroup>();
|
||||
|
||||
/// <summary>
|
||||
/// Map (groupIndex -> PermGroup) of all groups inside the container.
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<ConGroupIndex, ConGroup> Groups => _groups;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="ConGroupContainer" /> .
|
||||
/// </summary>
|
||||
/// <param name="resMan">ResourceManager to use for file I/O.</param>
|
||||
/// <param name="logger">Sawmill to use for logging messages.</param>
|
||||
public ConGroupContainer(IResourceManager resMan, ISawmill logger)
|
||||
{
|
||||
_resMan = resMan;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads groups from the yaml file. Existing groups will not be overwritten.
|
||||
/// Call Clear() if you want to empty the container first.
|
||||
/// </summary>
|
||||
public void LoadGroups()
|
||||
{
|
||||
if (_resMan.UserData.Exists(_groupPath))
|
||||
{
|
||||
_logger.Info($"Loading permGroups from UserData: {_groupPath}");
|
||||
var file = _resMan.UserData.OpenRead(_groupPath);
|
||||
LoadGroupYamlStream(file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_resMan.TryContentFileRead(_groupPath, out var memoryStream))
|
||||
{
|
||||
_logger.Info($"Loading permGroups from content: {_groupPath}");
|
||||
LoadGroupYamlStream(memoryStream);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Warning($"Permission group file not found: {_groupPath}");
|
||||
}
|
||||
|
||||
private void LoadGroupYamlStream(Stream stream)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
var groupList = new Deserializer().Deserialize<List<ConGroup>>(reader);
|
||||
|
||||
foreach (var permGroup in groupList)
|
||||
{
|
||||
var grpIndex = new ConGroupIndex(permGroup.Index);
|
||||
if (!_groups.ContainsKey(grpIndex))
|
||||
_groups.Add(grpIndex, permGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error($"Could not parse the yaml group file! {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves groups to the yaml file.
|
||||
/// </summary>
|
||||
public void SaveGroups()
|
||||
{
|
||||
_logger.Info($"Saving permGroups to UserData: {_groupPath}");
|
||||
_resMan.UserData.CreateDir(_groupPath);
|
||||
var file = _resMan.UserData.Create(_groupPath);
|
||||
|
||||
using (var sw = new StreamWriter(file))
|
||||
{
|
||||
var serializer = new Serializer();
|
||||
serializer.Serialize(sw, _groups.Values);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all groups from the container.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_groups.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if a console group has a command defined.
|
||||
/// </summary>
|
||||
/// <param name="groupIndex">Group to test.</param>
|
||||
/// <param name="cmdName">Name of command to test for.</param>
|
||||
/// <returns>Result of test.</returns>
|
||||
public bool HasCommand(ConGroupIndex groupIndex, string cmdName)
|
||||
{
|
||||
if (_groups.TryGetValue(groupIndex, out var group))
|
||||
{
|
||||
return group.Commands!.Contains(cmdName);
|
||||
}
|
||||
|
||||
_logger.Error($"Unknown groupIndex: {groupIndex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanViewVar(ConGroupIndex groupIndex)
|
||||
{
|
||||
if (_groups.TryGetValue(groupIndex, out var group))
|
||||
{
|
||||
return group.CanViewVar;
|
||||
}
|
||||
|
||||
_logger.Error($"Unknown groupIndex: {groupIndex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GroupExists(ConGroupIndex index)
|
||||
{
|
||||
return _groups.ContainsKey(index);
|
||||
}
|
||||
|
||||
public bool CanAdminPlace(ConGroupIndex groupIndex)
|
||||
{
|
||||
if (_groups.TryGetValue(groupIndex, out var group))
|
||||
{
|
||||
return group.CanAdminPlace;
|
||||
}
|
||||
|
||||
_logger.Error($"Unknown groupIndex: {groupIndex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanScript(ConGroupIndex groupIndex)
|
||||
{
|
||||
if (_groups.TryGetValue(groupIndex, out var group))
|
||||
{
|
||||
return group.CanScript;
|
||||
}
|
||||
|
||||
_logger.Error($"Unknown groupIndex: {groupIndex}");
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanAdminMenu(ConGroupIndex groupIndex)
|
||||
{
|
||||
if (_groups.TryGetValue(groupIndex, out var group))
|
||||
{
|
||||
return group.CanAdminMenu;
|
||||
}
|
||||
|
||||
_logger.Error($"Unknown groupIndex: {groupIndex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,170 +1,34 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Log;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Resources;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
|
||||
namespace Robust.Server.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Mediates the group system of a console shell.
|
||||
/// </summary>
|
||||
internal class ConGroupController : IConGroupController
|
||||
internal sealed class ConGroupController : IConGroupController
|
||||
{
|
||||
[Dependency] private readonly IResourceManager _resourceManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||
[Dependency] private readonly INetManager _netManager = default!;
|
||||
|
||||
private ConGroupContainer _groups = default!;
|
||||
private SessionGroupContainer _sessions = default!;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
var logger = _logManager.GetSawmill("con.groups");
|
||||
|
||||
_netManager.RegisterNetMessage<MsgConGroupUpdate>(MsgConGroupUpdate.Name);
|
||||
|
||||
_playerManager.PlayerStatusChanged += _onClientStatusChanged;
|
||||
|
||||
// load the permission groups in the console
|
||||
_groups = new ConGroupContainer(_resourceManager, logger);
|
||||
_groups.LoadGroups();
|
||||
|
||||
// set up the session group container
|
||||
_sessions = new SessionGroupContainer(_configurationManager, logger);
|
||||
|
||||
UpdateAllClientData();
|
||||
}
|
||||
|
||||
private void _onClientStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||
{
|
||||
_sessions.OnClientStatusChanged(sender, e);
|
||||
|
||||
if (e.NewStatus == SessionStatus.Connected &&
|
||||
_configurationManager.GetCVar(CVars.ConsoleLoginLocal))
|
||||
{
|
||||
var session = e.Session;
|
||||
var address = session.ConnectedClient.RemoteEndPoint.Address;
|
||||
if (Equals(address, IPAddress.Loopback) || Equals(address, IPAddress.IPv6Loopback))
|
||||
{
|
||||
SetGroup(session, new ConGroupIndex(_configurationManager.GetCVar(CVars.ConsoleHostGroup)));
|
||||
UpdateClientData(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
public IConGroupControllerImplementation? Implementation { get; set; }
|
||||
|
||||
public bool CanCommand(IPlayerSession session, string cmdName)
|
||||
{
|
||||
// get group of session
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
|
||||
// check if group canCmd
|
||||
return _groups.HasCommand(group, cmdName);
|
||||
return Implementation?.CanCommand(session, cmdName) ?? false;
|
||||
}
|
||||
|
||||
public bool CanViewVar(IPlayerSession session)
|
||||
{
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
|
||||
return _groups.CanViewVar(group);
|
||||
return Implementation?.CanViewVar(session) ?? false;
|
||||
}
|
||||
|
||||
public bool CanAdminPlace(IPlayerSession session)
|
||||
{
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
|
||||
return _groups.CanAdminPlace(group);
|
||||
return Implementation?.CanAdminPlace(session) ?? false;
|
||||
}
|
||||
|
||||
public bool CanScript(IPlayerSession session)
|
||||
{
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
|
||||
return _groups.CanScript(group);
|
||||
return Implementation?.CanScript(session) ?? false;
|
||||
}
|
||||
|
||||
public bool CanAdminMenu(IPlayerSession session)
|
||||
{
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
|
||||
return _groups.CanAdminMenu(group);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all session data.
|
||||
/// </summary>
|
||||
public void ClearSessions()
|
||||
{
|
||||
_sessions.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the existing groups, and reloads from disk.
|
||||
/// </summary>
|
||||
public void ReloadGroups()
|
||||
{
|
||||
_groups.Clear();
|
||||
_groups.LoadGroups();
|
||||
UpdateAllClientData();
|
||||
}
|
||||
|
||||
public void SetGroup(IPlayerSession session, ConGroupIndex newGroup)
|
||||
{
|
||||
if (session == null)
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
|
||||
if (!_groups.GroupExists(newGroup))
|
||||
return;
|
||||
|
||||
_sessions.SetSessionGroup(session, newGroup);
|
||||
UpdateClientData(session);
|
||||
}
|
||||
|
||||
public ConGroupIndex GetGroupIndex(IPlayerSession session)
|
||||
{
|
||||
return _sessions.GetSessionGroup(session);
|
||||
}
|
||||
|
||||
public string? GetGroupName(ConGroupIndex index)
|
||||
{
|
||||
var groupDict = _groups.Groups;
|
||||
|
||||
return groupDict.TryGetValue(index, out var group) ? group?.Name : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update a single clients group data.
|
||||
/// </summary>
|
||||
/// <param name="session">The client session to update.</param>
|
||||
private void UpdateClientData(IPlayerSession session)
|
||||
{
|
||||
var group = _sessions.GetSessionGroup(session);
|
||||
var groupData = _groups.Groups[group];
|
||||
|
||||
var msg = _netManager.CreateNetMessage<MsgConGroupUpdate>();
|
||||
msg.ClientConGroup = groupData;
|
||||
_netManager.ServerSendMessage(msg, session.ConnectedClient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update group data for all clients.
|
||||
/// </summary>
|
||||
private void UpdateAllClientData()
|
||||
{
|
||||
foreach (var session in _playerManager.GetAllPlayers())
|
||||
{
|
||||
UpdateClientData(session);
|
||||
}
|
||||
return Implementation?.CanAdminMenu(session) ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,12 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Server.Interfaces.Console;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Log;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.IoC.Exceptions;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Network.Messages;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -166,155 +162,6 @@ namespace Robust.Server.Console
|
||||
return session != null ? $"{session.Name}" : "[HOST]";
|
||||
}
|
||||
|
||||
public bool ElevateShell(IPlayerSession session, string password)
|
||||
{
|
||||
if (session == null)
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
|
||||
var realPass = _configMan.GetCVar(CVars.ConsolePassword);
|
||||
var hostPass = _configMan.GetCVar(CVars.ConsoleHostPassword);
|
||||
|
||||
// password disabled
|
||||
if (string.IsNullOrWhiteSpace(realPass))
|
||||
return false;
|
||||
|
||||
// wrong password
|
||||
if (password != realPass && password != hostPass)
|
||||
return false;
|
||||
|
||||
// success!
|
||||
_groupController.SetGroup(session, new ConGroupIndex(_configMan.GetCVar(CVars.ConsoleAdminGroup)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class LoginCommand : IClientCommand
|
||||
{
|
||||
public string Command => "login";
|
||||
public string Description => "Elevates client to admin permission group.";
|
||||
public string Help => "login";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
|
||||
{
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
// If the password is null/empty/whitespace in the config, this effectively disables the command
|
||||
if (args.Length < 1 || string.IsNullOrWhiteSpace(args[0]))
|
||||
return;
|
||||
|
||||
// WE ARE AT THE BRIDGE OF DEATH
|
||||
if (shell.ElevateShell(player, args[0]))
|
||||
{
|
||||
shell.SendText(player, "Logged in.");
|
||||
return;
|
||||
}
|
||||
// CAST INTO THE GORGE OF ETERNAL PERIL
|
||||
Logger.WarningS(
|
||||
"con.auth",
|
||||
$"Failed console login authentication.\n NAME:{player}\n IP: {player.ConnectedClient.RemoteEndPoint}");
|
||||
|
||||
var net = IoCManager.Resolve<IServerNetManager>();
|
||||
net.DisconnectChannel(player.ConnectedClient, "Failed login authentication.");
|
||||
}
|
||||
}
|
||||
|
||||
public bool ElevateShellHost(IPlayerSession session, string password)
|
||||
{
|
||||
if (session == null)
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
|
||||
var realPass = _configMan.GetCVar(CVars.ConsoleHostPassword);
|
||||
|
||||
// password disabled
|
||||
if (string.IsNullOrWhiteSpace(realPass))
|
||||
return false;
|
||||
|
||||
// wrong password
|
||||
if (password != realPass)
|
||||
return false;
|
||||
|
||||
// success!
|
||||
_groupController.SetGroup(session, new ConGroupIndex(_configMan.GetCVar(CVars.ConsoleHostGroup)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class HostLoginCommand : IClientCommand
|
||||
{
|
||||
public string Command => "hostlogin";
|
||||
public string Description => "Elevates client to host permission group.";
|
||||
public string Help => "hostlogin";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
|
||||
{
|
||||
// system console can't log in to itself, and is pointless anyways
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
// If the password is null/empty/whitespace in the config, this effectively disables the command
|
||||
if (args.Length < 1 || string.IsNullOrWhiteSpace(args[0]))
|
||||
return;
|
||||
|
||||
// WE ARE AT THE BRIDGE OF DEATH
|
||||
if (shell.ElevateShellHost(player, args[0]))
|
||||
{
|
||||
shell.SendText(player, "Logged in as host.");
|
||||
return;
|
||||
}
|
||||
|
||||
// CAST INTO THE GORGE OF ETERNAL PERIL
|
||||
Logger.WarningS(
|
||||
"con.auth",
|
||||
$"Failed console hostlogin authentication.\n NAME:{player}\n IP: {player.ConnectedClient.RemoteEndPoint}");
|
||||
|
||||
var net = IoCManager.Resolve<IServerNetManager>();
|
||||
net.DisconnectChannel(player.ConnectedClient, "Failed login authentication.");
|
||||
}
|
||||
}
|
||||
|
||||
private class LogoutCommand : IClientCommand
|
||||
{
|
||||
public string Command => "logout";
|
||||
public string Description => "Demotes the client to player permission group.";
|
||||
public string Help => "logout";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
|
||||
{
|
||||
// system console can't log in to itself, and is pointless anyways
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var groupController = IoCManager.Resolve<IConGroupController>();
|
||||
groupController.SetGroup(player, new ConGroupIndex(1));
|
||||
shell.SendText(player, "Logged out.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class GroupCommand : IClientCommand
|
||||
{
|
||||
public string Command => "group";
|
||||
public string Description => "Prints your current permission group.";
|
||||
public string Help => "group";
|
||||
|
||||
public void Execute(IConsoleShell shell, IPlayerSession? player, string[] args)
|
||||
{
|
||||
// only the local server console bypasses permissions
|
||||
if (player == null)
|
||||
{
|
||||
shell.SendText((IPlayerSession?) null, "LOCAL_CONSOLE");
|
||||
return;
|
||||
}
|
||||
|
||||
var groupController = IoCManager.Resolve<IConGroupController>();
|
||||
var groupIndex = groupController.GetGroupIndex(player);
|
||||
var groupName = groupController.GetGroupName(groupIndex);
|
||||
|
||||
shell.SendText(player, $"Current group: {groupName}");
|
||||
}
|
||||
}
|
||||
|
||||
private class SudoCommand : IClientCommand
|
||||
{
|
||||
public string Command => "sudo";
|
||||
|
||||
@@ -1,19 +1,7 @@
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
namespace Robust.Server.Console
|
||||
namespace Robust.Server.Console
|
||||
{
|
||||
public interface IConGroupController
|
||||
public interface IConGroupController : IConGroupControllerImplementation
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
bool CanCommand(IPlayerSession session, string cmdName);
|
||||
bool CanViewVar(IPlayerSession session);
|
||||
bool CanAdminPlace(IPlayerSession session);
|
||||
bool CanScript(IPlayerSession session);
|
||||
bool CanAdminMenu(IPlayerSession session);
|
||||
void SetGroup(IPlayerSession session, ConGroupIndex newGroup);
|
||||
ConGroupIndex GetGroupIndex(IPlayerSession session);
|
||||
string? GetGroupName(ConGroupIndex index);
|
||||
public IConGroupControllerImplementation Implementation { set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
using Robust.Server.Interfaces.Player;
|
||||
|
||||
namespace Robust.Server.Console
|
||||
{
|
||||
public interface IConGroupControllerImplementation
|
||||
{
|
||||
bool CanCommand(IPlayerSession session, string cmdName);
|
||||
bool CanViewVar(IPlayerSession session);
|
||||
bool CanAdminPlace(IPlayerSession session);
|
||||
bool CanScript(IPlayerSession session);
|
||||
bool CanAdminMenu(IPlayerSession session);
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Log;
|
||||
|
||||
namespace Robust.Server.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a mapping of Session -> Group for the console shell.
|
||||
/// </summary>
|
||||
internal class SessionGroupContainer
|
||||
{
|
||||
private readonly Dictionary<IPlayerSession, ConGroupIndex> _sessionGroups = new Dictionary<IPlayerSession, ConGroupIndex>();
|
||||
private readonly IConfigurationManager _configMan;
|
||||
private readonly ISawmill _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Default group that users are put in when they join the server.
|
||||
/// </summary>
|
||||
public ConGroupIndex DefaultGroup
|
||||
{
|
||||
get => new ConGroupIndex(_configMan.GetCVar(CVars.ConsoleDefaultGroup));
|
||||
set => _configMan.SetCVar(CVars.ConsoleDefaultGroup, value.Index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs an instance of <see cref="SessionGroupContainer"/>.
|
||||
/// </summary>
|
||||
/// <param name="configMan">Configuration Dependency</param>
|
||||
/// <param name="logger"></param>
|
||||
public SessionGroupContainer(IConfigurationManager configMan, ISawmill logger)
|
||||
{
|
||||
_configMan = configMan;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for when the status of a player session changes.
|
||||
/// </summary>
|
||||
public void OnClientStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||
{
|
||||
switch (e.NewStatus)
|
||||
{
|
||||
case SessionStatus.Disconnected:
|
||||
if(_sessionGroups.ContainsKey(e.Session))
|
||||
_sessionGroups.Remove(e.Session);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries the container for the group of a given session.
|
||||
/// </summary>
|
||||
public ConGroupIndex GetSessionGroup(IPlayerSession session)
|
||||
{
|
||||
if(session == null)
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
|
||||
return _sessionGroups.TryGetValue(session, out var groupIndex) ? groupIndex : DefaultGroup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the session with the given group.
|
||||
/// </summary>
|
||||
public void SetSessionGroup(IPlayerSession session, ConGroupIndex group)
|
||||
{
|
||||
if(session == null)
|
||||
throw new ArgumentNullException(nameof(session));
|
||||
|
||||
_logger.Info($"Set group: {session}, {group.Index}");
|
||||
|
||||
_sessionGroups[session] = group;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all sessions from the container.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
_sessionGroups.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,21 +51,5 @@ namespace Robust.Server.Interfaces.Console
|
||||
/// <param name="player">Session of the remote player. If this is null, the command is executed as the local console.</param>
|
||||
/// <param name="command">Command string to execute.</param>
|
||||
void ExecuteCommand(IPlayerSession? player, string command);
|
||||
|
||||
/// <summary>
|
||||
/// Elevates a player shell from user group to administrator group.
|
||||
/// </summary>
|
||||
/// <param name="session">Session shell to elevate.</param>
|
||||
/// <param name="password">super user password.</param>
|
||||
/// <returns></returns>
|
||||
bool ElevateShell(IPlayerSession session, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Elevates a player shell from user group to host group.
|
||||
/// </summary>
|
||||
/// <param name="session">Session shell to elevate.</param>
|
||||
/// <param name="password">super user password.</param>
|
||||
/// <returns></returns>
|
||||
bool ElevateShellHost(IPlayerSession session, string password);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,9 +181,6 @@ namespace Robust.Shared
|
||||
public static readonly CVarDef<string> AuthServer =
|
||||
CVarDef.Create("auth.server", "https://central.spacestation14.io/auth/", CVar.SECURE);
|
||||
|
||||
public static readonly CVarDef<int> ConsoleDefaultGroup =
|
||||
CVarDef.Create("console.defaultGroup", 1, CVar.ARCHIVE);
|
||||
|
||||
public static readonly CVarDef<bool> DisplayVSync =
|
||||
CVarDef.Create("display.vsync", true, CVar.ARCHIVE);
|
||||
|
||||
@@ -226,22 +223,6 @@ namespace Robust.Shared
|
||||
public static readonly CVarDef<bool> DiscordEnabled =
|
||||
CVarDef.Create("discord.enabled", true);
|
||||
|
||||
public static readonly CVarDef<bool> ConsoleLoginLocal =
|
||||
CVarDef.Create("console.loginlocal", true, CVar.ARCHIVE);
|
||||
|
||||
// register console admin global password. DO NOT ADD THE REPLICATED FLAG
|
||||
public static readonly CVarDef<string> ConsolePassword =
|
||||
CVarDef.Create("console.password", string.Empty, CVar.ARCHIVE | CVar.SERVER | CVar.NOT_CONNECTED);
|
||||
|
||||
public static readonly CVarDef<string> ConsoleHostPassword =
|
||||
CVarDef.Create("console.hostpassword", string.Empty, CVar.ARCHIVE | CVar.SERVER | CVar.NOT_CONNECTED);
|
||||
|
||||
public static readonly CVarDef<int> ConsoleAdminGroup =
|
||||
CVarDef.Create("console.adminGroup", 100, CVar.ARCHIVE | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<int> ConsoleHostGroup =
|
||||
CVarDef.Create("console.hostGroup", 200, CVar.ARCHIVE | CVar.SERVER);
|
||||
|
||||
public static readonly CVarDef<bool> SignalsHandle =
|
||||
CVarDef.Create("signals.handle", true);
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Robust.Shared.Console
|
||||
{
|
||||
internal class ConGroup
|
||||
{
|
||||
public int Index { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public List<string>? Commands { get; set; }
|
||||
|
||||
// NOTE: When adding special permissions, do NOT forget to add it to MsgConGroupUpdate!!
|
||||
public bool CanViewVar { get; set; }
|
||||
public bool CanAdminPlace { get; set; }
|
||||
public bool CanScript { get; set; }
|
||||
public bool CanAdminMenu { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Robust.Shared.Console
|
||||
{
|
||||
public struct ConGroupIndex
|
||||
{
|
||||
public int Index { get; }
|
||||
|
||||
public ConGroupIndex(int index)
|
||||
{
|
||||
Index = index;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Index.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Robust.Shared.Console
|
||||
{
|
||||
/// <summary>
|
||||
/// Sent from server to client. Contains the console group of the client,
|
||||
/// which includes a list of commands they can use.
|
||||
/// </summary>
|
||||
class MsgConGroupUpdate : NetMessage
|
||||
{
|
||||
public const MsgGroups Group = MsgGroups.Command;
|
||||
public const string Name = nameof(MsgConGroupUpdate);
|
||||
|
||||
public MsgConGroupUpdate(INetChannel channel) : base(Name, Group)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//Client console group data
|
||||
public ConGroup ClientConGroup = new ConGroup();
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer)
|
||||
{
|
||||
ClientConGroup.Index = buffer.ReadInt32();
|
||||
ClientConGroup.Name = buffer.ReadString();
|
||||
ClientConGroup.CanViewVar = buffer.ReadBoolean();
|
||||
ClientConGroup.CanAdminPlace = buffer.ReadBoolean();
|
||||
ClientConGroup.CanScript = buffer.ReadBoolean();
|
||||
ClientConGroup.CanAdminMenu = buffer.ReadBoolean();
|
||||
|
||||
int numCommands = buffer.ReadInt32();
|
||||
ClientConGroup.Commands = new List<string>(numCommands);
|
||||
for (int i = 0; i < numCommands; i++)
|
||||
{
|
||||
ClientConGroup.Commands.Add(buffer.ReadString());
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer)
|
||||
{
|
||||
buffer.Write(ClientConGroup.Index);
|
||||
buffer.Write(ClientConGroup.Name);
|
||||
buffer.Write(ClientConGroup.CanViewVar);
|
||||
buffer.Write(ClientConGroup.CanAdminPlace);
|
||||
buffer.Write(ClientConGroup.CanScript);
|
||||
buffer.Write(ClientConGroup.CanAdminMenu);
|
||||
|
||||
buffer.Write(ClientConGroup.Commands.Count);
|
||||
foreach (var command in ClientConGroup.Commands)
|
||||
{
|
||||
buffer.Write(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user