mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
* Strongly order network prototypes and resources.
When a new client connects, both the uploaded prototypes and resources get sent at once. There was no ordering here, which means that prototypes could easily load before resources. This would then obviously give load errors at runtime. In practice though this seemed fine because the RSI or something would just load fine after when spawned or something.
This was then broken by ae1051e813, which made ResourceCache start caching "that RSI doesn't exist" so it never really tried again.
I originally tried to fix this by adding an API to IResourceManager that allows content to invalidate the aforementioned cache (commit 316a7e4ac10100593202ff7f53dc2992611bbd1e, for however GitHub will track that) but then realized resource uploading isn't part of content like I first thought. Lol whoops. That API might still be useful for other dynamic content use cases, but I'm not committing it for now. That fix still caused errors to be spammed if the prototype was loaded before the resources were ready.
The new fix is to just load resources before prototypes. This is done by making them both ordered relative to each other, and running resources first.
Fixes #5291
* Release notes
78 lines
2.6 KiB
C#
78 lines
2.6 KiB
C#
using System;
|
|
using Robust.Server.Console;
|
|
using Robust.Server.Player;
|
|
using Robust.Shared;
|
|
using Robust.Shared.Configuration;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Network;
|
|
using Robust.Shared.Player;
|
|
using Robust.Shared.Upload;
|
|
using Robust.Shared.ViewVariables;
|
|
|
|
namespace Robust.Server.Upload;
|
|
|
|
public sealed class NetworkResourceManager : SharedNetworkResourceManager
|
|
{
|
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
|
[Dependency] private readonly IServerNetManager _serverNetManager = default!;
|
|
[Dependency] private readonly IConfigurationManager _cfgManager = default!;
|
|
[Dependency] private readonly IConGroupController _controller = default!;
|
|
|
|
public event Action<ICommonSession, NetworkResourceUploadMessage>? OnResourceUploaded;
|
|
|
|
[ViewVariables] public bool Enabled { get; private set; } = true;
|
|
[ViewVariables] public float SizeLimit { get; private set; }
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
_cfgManager.OnValueChanged(CVars.ResourceUploadingEnabled, value => Enabled = value, true);
|
|
_cfgManager.OnValueChanged(CVars.ResourceUploadingLimitMb, value => SizeLimit = value, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Callback for when a client attempts to upload a resource.
|
|
/// </summary>
|
|
/// <param name="msg"></param>
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
protected override void ResourceUploadMsg(NetworkResourceUploadMessage msg)
|
|
{
|
|
// Do not allow uploading any new resources if it has been disabled.
|
|
// Note: Any resources uploaded before being disabled will still be kept and sent.
|
|
if (!Enabled)
|
|
return;
|
|
|
|
if (!_playerManager.TryGetSessionByChannel(msg.MsgChannel, out var session))
|
|
return;
|
|
|
|
if (!_controller.CanCommand(session, "uploadfile"))
|
|
return;
|
|
|
|
// Ensure the data is under the current size limit, if it's currently enabled.
|
|
if (SizeLimit > 0f && msg.Data.Length * BytesToMegabytes > SizeLimit)
|
|
return;
|
|
|
|
base.ResourceUploadMsg(msg);
|
|
|
|
// Now we broadcast the message!
|
|
foreach (var channel in _serverNetManager.Channels)
|
|
{
|
|
channel.SendMessage(msg);
|
|
}
|
|
|
|
OnResourceUploaded?.Invoke(session, msg);
|
|
}
|
|
|
|
internal void SendToNewUser(INetChannel channel)
|
|
{
|
|
foreach (var (path, data) in ContentRoot.GetAllFiles())
|
|
{
|
|
var msg = new NetworkResourceUploadMessage();
|
|
msg.RelativePath = path;
|
|
msg.Data = data;
|
|
channel.SendMessage(msg);
|
|
}
|
|
}
|
|
}
|