diff --git a/Robust.Client/Replays/Loading/IReplayLoadManager.cs b/Robust.Client/Replays/Loading/IReplayLoadManager.cs
index b3f97f990..58325285d 100644
--- a/Robust.Client/Replays/Loading/IReplayLoadManager.cs
+++ b/Robust.Client/Replays/Loading/IReplayLoadManager.cs
@@ -19,7 +19,8 @@ public interface IReplayLoadManager
public MappingDataNode? LoadYamlMetadata(IWritableDirProvider dir, ResPath path);
///
- /// Async task that loads up a replay for playback.
+ /// Async task that loads up a replay for playback. Note that this will have some side effects, such as loading
+ /// networked resources and prototypes. These resources are not tracked or automatically unloaded.
///
///
/// This task is intended to be used with a so that the loading can happen over several frame
@@ -34,7 +35,9 @@ public interface IReplayLoadManager
Task LoadReplayAsync(IWritableDirProvider dir, ResPath path, LoadReplayCallback callback);
///
- /// Async task that loads the initial state of a replay, including spawning & initializing all entities.
+ /// Async task that loads the initial state of a replay, including spawning & initializing all entities. Note that
+ /// this will have some side effects, such as loading networked resources and prototypes. These resources are not
+ /// tracked or automatically unloaded.
///
///
/// This task is intended to be used with a so that the loading can happen over several frame
diff --git a/Robust.Client/Upload/NetworkResourceManager.cs b/Robust.Client/Upload/NetworkResourceManager.cs
index 250f0b709..c597d6670 100644
--- a/Robust.Client/Upload/NetworkResourceManager.cs
+++ b/Robust.Client/Upload/NetworkResourceManager.cs
@@ -1,9 +1,25 @@
+using Robust.Shared.IoC;
using Robust.Shared.Upload;
namespace Robust.Client.Upload;
public sealed class NetworkResourceManager : SharedNetworkResourceManager
{
+ [Dependency] private readonly IBaseClient _client = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ _client.RunLevelChanged += OnLevelChanged;
+ }
+
+ private void OnLevelChanged(object? sender, RunLevelChangedEventArgs e)
+ {
+ // Clear networked resources when disconnecting from a multiplayer game.
+ if (e.OldLevel == ClientRunLevel.InGame)
+ ClearResources();
+ }
+
///
/// Callback for when the server sends a new resource.
///
@@ -12,4 +28,12 @@ public sealed class NetworkResourceManager : SharedNetworkResourceManager
{
ContentRoot.AddOrUpdateFile(msg.RelativePath, msg.Data);
}
+
+ ///
+ /// Clears all the networked resources. If used while connected to a server, this will probably cause issues.
+ ///
+ public void ClearResources()
+ {
+ ContentRoot.Clear();
+ }
}
diff --git a/Robust.Shared/ContentPack/MemoryContentRoot.cs b/Robust.Shared/ContentPack/MemoryContentRoot.cs
index 745fab39a..b4478acb3 100644
--- a/Robust.Shared/ContentPack/MemoryContentRoot.cs
+++ b/Robust.Shared/ContentPack/MemoryContentRoot.cs
@@ -55,6 +55,22 @@ public sealed class MemoryContentRoot : IContentRoot, IDisposable
}
}
+ ///
+ /// Removes ALL files from this content root.
+ ///
+ public void Clear()
+ {
+ _lock.EnterWriteLock();
+ try
+ {
+ _files.Clear();
+ }
+ finally
+ {
+ _lock.ExitWriteLock();
+ }
+ }
+
public bool FileExists(ResPath relPath)
{
_lock.EnterReadLock();