Skip to content

Commit

Permalink
Strongly order network prototypes and resources. (#5293)
Browse files Browse the repository at this point in the history
* 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 ae1051e, 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 316a7e4, 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
  • Loading branch information
PJB3005 authored Jul 12, 2024
1 parent c3d8080 commit 3657b0a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 10 deletions.
2 changes: 1 addition & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ END TEMPLATE-->

### Bugfixes

*None yet*
* Clients connecting to a server now always load prototype uploads after resource uploads, fixing ordering bugs that could cause various errors.

### Other

Expand Down
2 changes: 2 additions & 0 deletions Robust.Server/ServerIoC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ internal static void RegisterIoC(IDependencyCollection deps)
deps.Register<IServerNetConfigurationManager, ServerNetConfigurationManager>();
deps.Register<INetConfigurationManagerInternal, ServerNetConfigurationManager>();
deps.Register<IGamePrototypeLoadManager, GamePrototypeLoadManager>();
deps.Register<GamePrototypeLoadManager>();
deps.Register<NetworkResourceManager>();
deps.Register<IHttpClientHolder, HttpClientHolder>();
deps.Register<UploadedContentManager>();
}
}
}
6 changes: 2 additions & 4 deletions Robust.Server/Upload/GamePrototypeLoadManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public override void Initialize()
base.Initialize();

_sawmill = _logManager.GetSawmill("adminbus");

_netManager.Connected += NetManagerOnConnected;
}

public override void SendGamePrototype(string prototype)
Expand All @@ -50,7 +48,7 @@ protected override void LoadPrototypeData(GamePrototypeLoadMessage message)
}
}

private void NetManagerOnConnected(object? sender, NetChannelArgs e)
internal void SendToNewUser(INetChannel channel)
{
// Just dump all the prototypes on connect, before them missing could be an issue.
foreach (var prototype in LoadedPrototypes)
Expand All @@ -59,7 +57,7 @@ private void NetManagerOnConnected(object? sender, NetChannelArgs e)
{
PrototypeData = prototype
};
e.Channel.SendMessage(msg);
channel.SendMessage(msg);
}
}
}
5 changes: 2 additions & 3 deletions Robust.Server/Upload/NetworkResourceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ public override void Initialize()
{
base.Initialize();

_serverNetManager.Connected += ServerNetManagerOnConnected;
_cfgManager.OnValueChanged(CVars.ResourceUploadingEnabled, value => Enabled = value, true);
_cfgManager.OnValueChanged(CVars.ResourceUploadingLimitMb, value => SizeLimit = value, true);
}
Expand Down Expand Up @@ -65,14 +64,14 @@ protected override void ResourceUploadMsg(NetworkResourceUploadMessage msg)
OnResourceUploaded?.Invoke(session, msg);
}

private void ServerNetManagerOnConnected(object? sender, NetChannelArgs e)
internal void SendToNewUser(INetChannel channel)
{
foreach (var (path, data) in ContentRoot.GetAllFiles())
{
var msg = new NetworkResourceUploadMessage();
msg.RelativePath = path;
msg.Data = data;
e.Channel.SendMessage(msg);
channel.SendMessage(msg);
}
}
}
28 changes: 28 additions & 0 deletions Robust.Server/Upload/UploadedContentManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Robust.Shared.IoC;
using Robust.Shared.Network;

namespace Robust.Server.Upload;

/// <summary>
/// Responsible for sending uploaded content to clients when they connect.
/// </summary>
internal sealed class UploadedContentManager
{
[Dependency] private readonly IServerNetManager _netManager = default!;
[Dependency] private readonly GamePrototypeLoadManager _prototypeLoadManager = default!;
[Dependency] private readonly NetworkResourceManager _networkResourceManager = default!;

public void Initialize()
{
_netManager.Connected += NetManagerOnConnected;
}

private void NetManagerOnConnected(object? sender, NetChannelArgs e)
{
// This just shells out to the other managers, ensuring they are ordered properly.
// Resources must be done before prototypes.
// Note: both net messages sent here are on the same group and are therefore ordered.
_networkResourceManager.SendToNewUser(e.Channel);
_prototypeLoadManager.SendToNewUser(e.Channel);
}
}
3 changes: 1 addition & 2 deletions Robust.Shared/Upload/NetworkResourceUploadMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ namespace Robust.Shared.Upload;

public sealed class NetworkResourceUploadMessage : NetMessage
{
public override NetDeliveryMethod DeliveryMethod => NetDeliveryMethod.ReliableUnordered;
public override MsgGroups MsgGroup => MsgGroups.Command;
public override MsgGroups MsgGroup => MsgGroups.String;

public byte[] Data { get; set; } = Array.Empty<byte>();
public ResPath RelativePath { get; set; } = ResPath.Self;
Expand Down

0 comments on commit 3657b0a

Please sign in to comment.