mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Fix toolshed commands not working on reconnect (#4766)
* Fix toolshed commands not working on reconnect * fix tests? * space * I love #if block errors
This commit is contained in:
@@ -9,6 +9,7 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Toolshed;
|
||||
@@ -260,6 +261,7 @@ namespace Robust.Shared.Scripting
|
||||
return true; // Do as I say!
|
||||
}
|
||||
|
||||
public NetUserId? User => null;
|
||||
public ICommonSession? Session => null;
|
||||
|
||||
public void WriteLine(string line)
|
||||
|
||||
@@ -17,7 +17,7 @@ internal sealed class DoCommand : ToolshedCommand
|
||||
[PipedArgument] IEnumerable<T> input,
|
||||
[CommandArgument] string command)
|
||||
{
|
||||
if (ctx is not OldShellInvocationContext { } reqCtx)
|
||||
if (ctx is not OldShellInvocationContext { } reqCtx || reqCtx.Shell == null)
|
||||
{
|
||||
throw new NotImplementedException("do can only be executed in a shell invocation context. Some commands like emplace provide their own context.");
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
@@ -50,6 +51,8 @@ internal record EmplaceContext<T>(IInvocationContext Inner, T Value, IEntityMana
|
||||
|
||||
public ICommonSession? Session => Inner.Session;
|
||||
public ToolshedManager Toolshed => Inner.Toolshed;
|
||||
public NetUserId? User => Inner.User;
|
||||
|
||||
public ToolshedEnvironment Environment => Inner.Environment;
|
||||
|
||||
public void WriteLine(string line)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
@@ -27,6 +28,8 @@ internal record ReduceContext<T>(IInvocationContext Inner, T Value) : IInvocatio
|
||||
|
||||
public ICommonSession? Session => Inner.Session;
|
||||
public ToolshedManager Toolshed => Inner.Toolshed;
|
||||
public NetUserId? User => Inner.User;
|
||||
|
||||
public ToolshedEnvironment Environment => Inner.Environment;
|
||||
|
||||
public void WriteLine(string line)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -33,10 +34,15 @@ public interface IInvocationContext
|
||||
ToolshedEnvironment Environment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The session this context is for, if any.
|
||||
/// The session for the <see cref="User"/>, if any currently exists.
|
||||
/// </summary>
|
||||
ICommonSession? Session { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The session this context is for, if any.
|
||||
/// </summary>
|
||||
NetUserId? User { get; }
|
||||
|
||||
ToolshedManager Toolshed { get; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -18,29 +19,33 @@ internal sealed class OldShellInvocationContext : IInvocationContext
|
||||
private readonly List<IConError> _errors = new();
|
||||
|
||||
/// <summary>
|
||||
/// Old system's shell associated with this context
|
||||
/// Old system's shell associated with this context. May be null if the player is currently disconnected.
|
||||
/// </summary>
|
||||
public IConsoleShell Shell;
|
||||
public IConsoleShell? Shell;
|
||||
|
||||
public OldShellInvocationContext(IConsoleShell shell)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
Shell = shell;
|
||||
User = Session?.UserId;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICommonSession? Session => Shell.Player;
|
||||
public NetUserId? User { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICommonSession? Session => Shell?.Player;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WriteLine(string line)
|
||||
{
|
||||
Shell.WriteLine(line);
|
||||
Shell?.WriteLine(line);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void WriteLine(FormattedMessage line)
|
||||
{
|
||||
Shell.WriteLine(line);
|
||||
Shell?.WriteLine(line);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Console;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Toolshed.Invocation;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
@@ -30,10 +26,16 @@ public sealed partial class ToolshedManager
|
||||
[Dependency] private readonly IEntityManager _entity = default!;
|
||||
[Dependency] private readonly IReflectionManager _reflection = default!;
|
||||
[Dependency] private readonly ILogManager _logManager = default!;
|
||||
#if !CLIENT_SCRIPTING
|
||||
[Dependency] private readonly INetManager _net = default!;
|
||||
#endif
|
||||
[Dependency] private readonly ISharedPlayerManager _player = default!;
|
||||
[Dependency] private readonly IConsoleHost _conHost = default!;
|
||||
|
||||
private ISawmill _log = default!;
|
||||
|
||||
private Dictionary<NetUserId, OldShellInvocationContext> _contexts = new();
|
||||
|
||||
/// <summary>
|
||||
/// If you're not an engine developer, you probably shouldn't call this.
|
||||
/// </summary>
|
||||
@@ -42,9 +44,28 @@ public sealed partial class ToolshedManager
|
||||
_log = _logManager.GetSawmill("toolshed");
|
||||
|
||||
InitializeParser();
|
||||
_player.PlayerStatusChanged += OnStatusChanged;
|
||||
}
|
||||
|
||||
private Dictionary<NetUserId, IInvocationContext> _contexts = new();
|
||||
private void OnStatusChanged(object? sender, SessionStatusEventArgs e)
|
||||
{
|
||||
if (!_contexts.TryGetValue(e.Session.UserId, out var ctx))
|
||||
return;
|
||||
|
||||
DebugTools.Assert(ctx.User == e.Session.UserId);
|
||||
if (e.NewStatus == SessionStatus.Disconnected)
|
||||
{
|
||||
DebugTools.Assert(ctx.Session == e.Session);
|
||||
ctx.Shell = null;
|
||||
}
|
||||
|
||||
if (e.NewStatus == SessionStatus.InGame)
|
||||
{
|
||||
DebugTools.AssertNull(ctx.Session);
|
||||
DebugTools.AssertNull(ctx.Shell);
|
||||
ctx.Shell = new ConsoleShell(_conHost, e.Session, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes a command as the given user.
|
||||
@@ -85,12 +106,12 @@ public sealed partial class ToolshedManager
|
||||
/// <param name="input">An input value to use, if any.</param>
|
||||
/// <param name="result">The resulting value, if any.</param>
|
||||
/// <returns>Invocation success.</returns>
|
||||
/// <example><code>
|
||||
/// ToolshedManager toolshed = ...;
|
||||
/// IConsoleShell ctx = ...;
|
||||
/// // Now run some user provided command and get a result!
|
||||
/// toolshed.InvokeCommand(ctx, userCommand, "my input value", out var result);
|
||||
/// </code></example>
|
||||
/// <example><code>
|
||||
/// ToolshedManager toolshed = ...;
|
||||
/// IConsoleShell ctx = ...;
|
||||
/// // Now run some user provided command and get a result!
|
||||
/// toolshed.InvokeCommand(ctx, userCommand, "my input value", out var result);
|
||||
/// </code></example>
|
||||
/// <remarks>
|
||||
/// This will use the same IInvocationContext as the one used by the user for debug console commands.
|
||||
/// </remarks>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Errors;
|
||||
@@ -102,6 +103,8 @@ public abstract class ToolshedTest : RobustIntegrationTest, IInvocationContext
|
||||
|
||||
protected ICommonSession? InvocationSession { get; set; }
|
||||
|
||||
public NetUserId? User => Session?.UserId;
|
||||
|
||||
public ICommonSession? Session
|
||||
{
|
||||
get
|
||||
|
||||
Reference in New Issue
Block a user