using System; using System.IO; using System.Threading.Tasks; using Robust.Shared; using Robust.Shared.Asynchronous; using Robust.Shared.Configuration; using Robust.Shared.Log; using Robust.Shared.Network; using Robust.Shared.Network.Messages.Transfer; using Robust.Shared.Network.Transfer; namespace Robust.Client.Network.Transfer; internal sealed class ClientTransferManager : BaseTransferManager, ITransferManager { private readonly IClientNetManager _netManager; private readonly IConfigurationManager _cfg; private BaseTransferImpl? _transferImpl; public event Action? ClientHandshakeComplete; internal ClientTransferManager( IClientNetManager netManager, ILogManager logManager, ITaskManager taskManager, IConfigurationManager cfg) : base(logManager, NetMessageAccept.Client, taskManager) { _netManager = netManager; _cfg = cfg; } public Stream StartTransfer(INetChannel channel, TransferStartInfo startInfo) { if (_transferImpl == null) throw new InvalidOperationException("Not connected yet!"); if (channel != _netManager.ServerChannel) throw new InvalidOperationException("Invalid channel!"); return _transferImpl.StartTransfer(startInfo); } public void Initialize() { _netManager.RegisterNetMessage(RxTransferInit, NetMessageAccept.Client | NetMessageAccept.Handshake); _netManager.RegisterNetMessage(); _netManager.RegisterNetMessage(RxTransferData, NetMessageAccept.Client | NetMessageAccept.Handshake); _netManager.Disconnect += OnNetDisconnect; } private void OnNetDisconnect(object? sender, NetDisconnectedArgs e) { _transferImpl?.Dispose(); _transferImpl = null; } private async void RxTransferInit(MsgTransferInit message) { BaseTransferImpl impl; if (message.HttpInfo is { } httpInfo) { impl = new ClientTransferImplWebSocket( httpInfo, Sawmill, this, message.MsgChannel, _cfg.GetCVar(CVars.TransferArtificialDelay)); } else { impl = new TransferImplLidgren(Sawmill, message.MsgChannel, this, _netManager); } _transferImpl = impl; await _transferImpl.ClientInit(default); ClientHandshakeComplete?.Invoke(); } private void RxTransferData(MsgTransferData message) { if (_transferImpl is not TransferImplLidgren lidgren) { message.MsgChannel.Disconnect("Not lidgren"); return; } lidgren.ReceiveData(message); } public Task ServerHandshake(INetChannel channel) { throw new NotSupportedException(); } }