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:
@@ -154,6 +154,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public FileReceiver(string downloadFolder)
|
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>();
|
activeTransfers = new List<FileTransferIn>();
|
||||||
|
|
||||||
this.downloadFolder = downloadFolder;
|
this.downloadFolder = downloadFolder;
|
||||||
@@ -161,6 +166,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void ReadMessage(NetIncomingMessage inc)
|
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 =>
|
System.Diagnostics.Debug.Assert(!activeTransfers.Any(t =>
|
||||||
t.Status == FileTransferStatus.Error ||
|
t.Status == FileTransferStatus.Error ||
|
||||||
t.Status == FileTransferStatus.Canceled ||
|
t.Status == FileTransferStatus.Canceled ||
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
private NetPeer peer;
|
private NetPeer peer;
|
||||||
|
|
||||||
|
public List<FileTransferOut> ActiveTransfers
|
||||||
|
{
|
||||||
|
get { return activeTransfers; }
|
||||||
|
}
|
||||||
|
|
||||||
public FileSender(NetworkMember networkMember)
|
public FileSender(NetworkMember networkMember)
|
||||||
{
|
{
|
||||||
peer = networkMember.netPeer;
|
peer = networkMember.netPeer;
|
||||||
|
|||||||
@@ -629,6 +629,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (Character != null) Character.Remove();
|
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();
|
Entity.Spawner.Clear();
|
||||||
entityEventManager.Clear();
|
entityEventManager.Clear();
|
||||||
LastSentEntityEventID = 0;
|
LastSentEntityEventID = 0;
|
||||||
@@ -999,6 +1003,15 @@ namespace Barotrauma.Networking
|
|||||||
client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
|
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)
|
private void OnFileReceived(FileReceiver.FileTransferIn transfer)
|
||||||
{
|
{
|
||||||
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
|
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),
|
MathUtils.GetBytesReadable((long)transfer.Received) + " / " + MathUtils.GetBytesReadable((long)transfer.FileSize),
|
||||||
Color.White, null, 0, GUI.SmallFont);
|
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);
|
fileReceiver.StopTransfer(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1210,12 +1224,12 @@ namespace Barotrauma.Networking
|
|||||||
public bool SpectateClicked(GUIButton button, object userData)
|
public bool SpectateClicked(GUIButton button, object userData)
|
||||||
{
|
{
|
||||||
if (button != null) button.Enabled = false;
|
if (button != null) button.Enabled = false;
|
||||||
|
|
||||||
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
|
NetOutgoingMessage readyToStartMsg = client.CreateMessage();
|
||||||
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
|
readyToStartMsg.Write((byte)ClientPacketHeader.RESPONSE_STARTGAME);
|
||||||
|
|
||||||
//correct sub & shuttle files found
|
//assume we have the required sub files to start the round
|
||||||
//TODO: check if they're actually found
|
//(if not, we'll find out when the server sends the STARTGAME message and can initiate a file transfer)
|
||||||
readyToStartMsg.Write(true);
|
readyToStartMsg.Write(true);
|
||||||
|
|
||||||
WriteCharacterInfo(readyToStartMsg);
|
WriteCharacterInfo(readyToStartMsg);
|
||||||
|
|||||||
@@ -982,14 +982,32 @@ namespace Barotrauma.Networking
|
|||||||
server.SendMessage(msg, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0);
|
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
|
//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)
|
while (connectedClients.Any(c => !c.ReadyToStart) && waitForResponseTimer > 0.0f)
|
||||||
{
|
{
|
||||||
waitForResponseTimer -= CoroutineManager.UnscaledDeltaTime;
|
waitForResponseTimer -= CoroutineManager.UnscaledDeltaTime;
|
||||||
yield return CoroutineStatus.Running;
|
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);
|
GameMain.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);
|
||||||
|
|||||||
@@ -473,6 +473,16 @@ namespace Barotrauma
|
|||||||
base.Select();
|
base.Select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ShowSpectateButton()
|
||||||
|
{
|
||||||
|
if (GameMain.Client == null) return;
|
||||||
|
|
||||||
|
infoFrame.RemoveChild(infoFrame.children.Find(c => c.UserData as string == "spectateButton"));
|
||||||
|
GUIButton spectateButton = new GUIButton(new Rectangle(0, 0, 80, 30), "Spectate", Alignment.BottomRight, GUI.Style, infoFrame);
|
||||||
|
spectateButton.OnClicked = GameMain.Client.SpectateClicked;
|
||||||
|
spectateButton.UserData = "spectateButton";
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdatePlayerFrame(CharacterInfo characterInfo)
|
private void UpdatePlayerFrame(CharacterInfo characterInfo)
|
||||||
{
|
{
|
||||||
if (myPlayerFrame.children.Count <= 1)
|
if (myPlayerFrame.children.Count <= 1)
|
||||||
@@ -1227,16 +1237,14 @@ namespace Barotrauma
|
|||||||
|
|
||||||
errorMsg += "Do you want to download the file from the server host?";
|
errorMsg += "Do you want to download the file from the server host?";
|
||||||
|
|
||||||
if (GUIMessageBox.MessageBoxes.Count > 0)
|
//already showing a message about the same sub
|
||||||
|
if (GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "request" + subName))
|
||||||
{
|
{
|
||||||
var currentMessageBox = GUIMessageBox.VisibleBox;
|
return false;
|
||||||
if (currentMessageBox != null && currentMessageBox.UserData as string == subName)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestFileBox = new GUIMessageBox("Submarine not found!", errorMsg, new string[] { "Yes", "No" }, 400, 300);
|
var requestFileBox = new GUIMessageBox("Submarine not found!", errorMsg, new string[] { "Yes", "No" }, 400, 300);
|
||||||
|
requestFileBox.UserData = "request" + subName;
|
||||||
requestFileBox.Buttons[0].UserData = subName;
|
requestFileBox.Buttons[0].UserData = subName;
|
||||||
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
|
requestFileBox.Buttons[0].OnClicked += requestFileBox.Close;
|
||||||
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
|
requestFileBox.Buttons[0].OnClicked += (GUIButton button, object userdata) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user