Some more logic to handle missing sub files and active file transfers when starting a round:

- server waits for transfers to finish before starting the round (up to a max 20 seconds, can be skipped by the host)
- clients enable the spectate button when the round starts (in case they fail to start the round due to a missing sub file or an error)
- clients notify the server if a transfer is cancelled

+ FileReceivers can't be instantiated if a server is running
This commit is contained in:
Regalis
2017-03-09 19:56:27 +02:00
parent ca402396a0
commit e406b76cd5
5 changed files with 67 additions and 12 deletions
@@ -154,6 +154,11 @@ namespace Barotrauma.Networking
public FileReceiver(string downloadFolder)
{
if (GameMain.Server != null)
{
throw new InvalidOperationException("Creating a file receiver is not allowed when a server is running.");
}
activeTransfers = new List<FileTransferIn>();
this.downloadFolder = downloadFolder;
@@ -161,6 +166,11 @@ namespace Barotrauma.Networking
public void ReadMessage(NetIncomingMessage inc)
{
if (GameMain.Server != null)
{
throw new InvalidOperationException("Receiving files when a server is running is not allowed");
}
System.Diagnostics.Debug.Assert(!activeTransfers.Any(t =>
t.Status == FileTransferStatus.Error ||
t.Status == FileTransferStatus.Canceled ||
@@ -109,6 +109,11 @@ namespace Barotrauma.Networking
private NetPeer peer;
public List<FileTransferOut> ActiveTransfers
{
get { return activeTransfers; }
}
public FileSender(NetworkMember networkMember)
{
peer = networkMember.netPeer;
+18 -4
View File
@@ -629,6 +629,10 @@ namespace Barotrauma.Networking
{
if (Character != null) Character.Remove();
//enable spectate button in case we fail to start the round now
//(for example, due to a missing sub file or an error)
GameMain.NetLobbyScreen.ShowSpectateButton();
Entity.Spawner.Clear();
entityEventManager.Clear();
LastSentEntityEventID = 0;
@@ -999,6 +1003,15 @@ namespace Barotrauma.Networking
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
public void CancelFileTransfer(FileReceiver.FileTransferIn transfer)
{
NetOutgoingMessage msg = client.CreateMessage();
msg.Write((byte)ClientPacketHeader.FILE_REQUEST);
msg.Write((byte)FileTransferMessageType.Cancel);
msg.Write((byte)transfer.SequenceChannel);
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
}
private void OnFileReceived(FileReceiver.FileTransferIn transfer)
{
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
@@ -1062,8 +1075,9 @@ namespace Barotrauma.Networking
MathUtils.GetBytesReadable((long)transfer.Received) + " / " + MathUtils.GetBytesReadable((long)transfer.FileSize),
Color.White, null, 0, GUI.SmallFont);
if (GUI.DrawButton(spriteBatch, new Rectangle((int)pos.X + 140, (int)pos.Y + 15, 60, 15), "Cancel", new Color(0.47f, 0.13f, 0.15f, 0.08f)))
if (GUI.DrawButton(spriteBatch, new Rectangle((int)pos.X + 140, (int)pos.Y + 18, 60, 15), "Cancel", new Color(0.47f, 0.13f, 0.15f, 0.08f)))
{
CancelFileTransfer(transfer);
fileReceiver.StopTransfer(transfer);
}
@@ -1210,12 +1224,12 @@ namespace Barotrauma.Networking
public bool SpectateClicked(GUIButton button, object userData)
{
if (button != null) button.Enabled = false;
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
//correct sub & shuttle files found
//TODO: check if they're actually found
//assume we have the required sub files to start the round
//(if not, we'll find out when the server sends the STARTGAME message and can initiate a file transfer)
readyToStartMsg.Write(true);
WriteCharacterInfo(readyToStartMsg);
+20 -2
View File
@@ -982,14 +982,32 @@ namespace Barotrauma.Networking
server.SendMessage(msg, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0);
//give the clients a few seconds to request missing sub/shuttle files before starting the round
float waitForResponseTimer = 3.0f;
float waitForResponseTimer = 5.0f;
while (connectedClients.Any(c => !c.ReadyToStart) && waitForResponseTimer > 0.0f)
{
waitForResponseTimer -= CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
}
//todo: wait until file transfers are finished/cancelled
if (fileSender.ActiveTransfers.Count > 0)
{
var msgBox = new GUIMessageBox("", "Waiting for file transfers to finish before starting the round...", new string[] { "Start now" });
msgBox.Buttons[0].OnClicked += msgBox.Close;
float waitForTransfersTimer = 20.0f;
while (fileSender.ActiveTransfers.Count > 0 && waitForTransfersTimer > 0.0f)
{
waitForTransfersTimer -= CoroutineManager.UnscaledDeltaTime;
//message box close, break and start the round immediately
if (!GUIMessageBox.MessageBoxes.Contains(msgBox))
{
break;
}
yield return CoroutineStatus.Running;
}
}
}
GameMain.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);