Clients send the latest received campaign ID to the server when in the lobby instead of requesting it once with a reliable message. -> Now the server reattempts sending the save file if the transfer fails at either end.

This commit is contained in:
Joonas Rikkonen
2017-11-23 20:16:47 +02:00
parent 18db667c1e
commit 4689bec441
6 changed files with 61 additions and 19 deletions
@@ -1,4 +1,5 @@
using Lidgren.Network; using Lidgren.Network;
using Microsoft.Xna.Framework;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -86,10 +87,13 @@ namespace Barotrauma.Networking
Connection = connection; Connection = connection;
Status = FileTransferStatus.NotStarted;
}
public void OpenStream()
{
WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None);
TimeStarted = Environment.TickCount; TimeStarted = Environment.TickCount;
Status = FileTransferStatus.NotStarted;
} }
public void ReadBytes(NetIncomingMessage inc) public void ReadBytes(NetIncomingMessage inc)
@@ -103,7 +107,7 @@ namespace Barotrauma.Networking
if (GameSettings.VerboseLogging) if (GameSettings.VerboseLogging)
{ {
DebugConsole.Log("Received "+all.Length+" bytes of the file "+FileName+" ("+Received+"/"+FileSize+" received)"); DebugConsole.Log("Received " + all.Length + " bytes of the file " + FileName + " (" + Received + "/" + FileSize + " received)");
} }
BytesPerSecond = Received / psec; BytesPerSecond = Received / psec;
@@ -137,8 +141,9 @@ namespace Barotrauma.Networking
const int MaxFileSize = 1000000; const int MaxFileSize = 1000000;
public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver); public delegate void TransferInDelegate(FileTransferIn fileStreamReceiver);
public OnFinishedDelegate OnFinished; public TransferInDelegate OnFinished;
public TransferInDelegate OnTransferFailed;
private List<FileTransferIn> activeTransfers; private List<FileTransferIn> activeTransfers;
@@ -223,11 +228,25 @@ namespace Barotrauma.Networking
} }
} }
var newTransfer = new FileTransferIn(inc.SenderConnection, Path.Combine(downloadFolder, fileName), (FileTransferType)fileType); FileTransferIn newTransfer = new FileTransferIn(inc.SenderConnection, Path.Combine(downloadFolder, fileName), (FileTransferType)fileType);
newTransfer.SequenceChannel = inc.SequenceChannel; newTransfer.SequenceChannel = inc.SequenceChannel;
newTransfer.Status = FileTransferStatus.Receiving; newTransfer.Status = FileTransferStatus.Receiving;
newTransfer.FileSize = fileSize; newTransfer.FileSize = fileSize;
try
{
newTransfer.OpenStream();
}
catch (IOException e)
{
GameMain.Client.CancelFileTransfer(inc.SequenceChannel);
DebugConsole.NewMessage("Failed to initiate a file transfer {" + e.Message + "}", Color.Red);
newTransfer.Status = FileTransferStatus.Error;
OnTransferFailed(newTransfer);
return;
}
activeTransfers.Add(newTransfer); activeTransfers.Add(newTransfer);
break; break;
@@ -240,7 +259,7 @@ namespace Barotrauma.Networking
return; return;
} }
if (activeTransfer.Received + (ulong)(inc.LengthBytes-inc.PositionInBytes) > activeTransfer.FileSize) if (activeTransfer.Received + (ulong)(inc.LengthBytes - inc.PositionInBytes) > activeTransfer.FileSize)
{ {
GameMain.Client.CancelFileTransfer(inc.SequenceChannel); GameMain.Client.CancelFileTransfer(inc.SequenceChannel);
DebugConsole.ThrowError("File transfer error: Received more data than expected"); DebugConsole.ThrowError("File transfer error: Received more data than expected");
@@ -256,7 +275,7 @@ namespace Barotrauma.Networking
catch (Exception e) catch (Exception e)
{ {
GameMain.Client.CancelFileTransfer(inc.SequenceChannel); GameMain.Client.CancelFileTransfer(inc.SequenceChannel);
DebugConsole.ThrowError("File transfer error: "+e.Message); DebugConsole.ThrowError("File transfer error: " + e.Message);
activeTransfer.Status = FileTransferStatus.Error; activeTransfer.Status = FileTransferStatus.Error;
StopTransfer(activeTransfer, true); StopTransfer(activeTransfer, true);
return; return;
@@ -990,7 +990,15 @@ namespace Barotrauma.Networking
outmsg.Write(ChatMessage.LastID); outmsg.Write(ChatMessage.LastID);
var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign; var campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
outmsg.Write(campaign == null ? 0 : campaign.LastUpdateID); if (campaign == null || campaign.LastSaveID == 0)
{
outmsg.Write((UInt16)0);
}
else
{
outmsg.Write(campaign.LastSaveID);
outmsg.Write(campaign.LastUpdateID);
}
chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID)); chatMsgQueue.RemoveAll(cMsg => !NetIdUtils.IdMoreRecent(cMsg.NetStateID, lastSentChatMsgID));
for (int i = 0; i < chatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++) for (int i = 0; i < chatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++)
@@ -1090,10 +1098,10 @@ namespace Barotrauma.Networking
private void OnFileReceived(FileReceiver.FileTransferIn transfer) private void OnFileReceived(FileReceiver.FileTransferIn transfer)
{ {
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
switch (transfer.FileType) switch (transfer.FileType)
{ {
case FileTransferType.Submarine: case FileTransferType.Submarine:
new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully.");
var newSub = new Submarine(transfer.FilePath); var newSub = new Submarine(transfer.FilePath);
Submarine.SavedSubmarines.RemoveAll(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash); Submarine.SavedSubmarines.RemoveAll(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash);
Submarine.SavedSubmarines.Add(newSub); Submarine.SavedSubmarines.Add(newSub);
@@ -356,7 +356,7 @@ namespace Barotrauma
//server has a newer save file //server has a newer save file
if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID)) if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID))
{ {
//stop any active campaign save transfers, they're outdated now /*//stop any active campaign save transfers, they're outdated now
List<FileReceiver.FileTransferIn> saveTransfers = List<FileReceiver.FileTransferIn> saveTransfers =
GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave);
@@ -365,7 +365,7 @@ namespace Barotrauma
GameMain.Client.FileReceiver.StopTransfer(transfer); GameMain.Client.FileReceiver.StopTransfer(transfer);
} }
GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null); GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/
campaign.PendingSaveID = saveID; campaign.PendingSaveID = saveID;
} }
//we've got the latest save file //we've got the latest save file
@@ -44,6 +44,7 @@ namespace Barotrauma.Networking
public UInt16 lastRecvEntityEventID = 0; public UInt16 lastRecvEntityEventID = 0;
public UInt16 lastRecvCampaignUpdate = 0; public UInt16 lastRecvCampaignUpdate = 0;
public UInt16 lastRecvCampaignSave = 0;
public List<ChatMessage> chatMsgQueue = new List<ChatMessage>(); public List<ChatMessage> chatMsgQueue = new List<ChatMessage>();
public UInt16 lastChatMsgQueueID; public UInt16 lastChatMsgQueueID;
@@ -156,6 +156,7 @@ namespace Barotrauma.Networking
catch (Exception e) catch (Exception e)
{ {
DebugConsole.ThrowError("Failed to initiate file transfer", e); DebugConsole.ThrowError("Failed to initiate file transfer", e);
return null;
} }
OnStarted(transfer); OnStarted(transfer);
@@ -601,7 +601,11 @@ namespace Barotrauma.Networking
c.lastRecvGeneralUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvGeneralUpdate, GameMain.NetLobbyScreen.LastUpdateID); c.lastRecvGeneralUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvGeneralUpdate, GameMain.NetLobbyScreen.LastUpdateID);
c.lastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvChatMsgID, c.lastChatMsgQueueID); c.lastRecvChatMsgID = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvChatMsgID, c.lastChatMsgQueueID);
c.lastRecvCampaignUpdate = inc.ReadUInt16(); c.lastRecvCampaignSave = inc.ReadUInt16();
if (c.lastRecvCampaignSave > 0)
{
c.lastRecvCampaignUpdate = inc.ReadUInt16();
}
break; break;
case ClientNetObject.CHAT_MESSAGE: case ClientNetObject.CHAT_MESSAGE:
ChatMessage.ServerRead(inc, c); ChatMessage.ServerRead(inc, c);
@@ -816,6 +820,15 @@ namespace Barotrauma.Networking
} }
ClientWriteLobby(c); ClientWriteLobby(c);
MultiplayerCampaign campaign = GameMain.GameSession?.GameMode as MultiplayerCampaign;
if (campaign != null && NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.lastRecvCampaignSave))
{
if (!fileSender.ActiveTransfers.Any(t => t.Connection == c.Connection && t.FileType == FileTransferType.CampaignSave))
{
fileSender.StartTransfer(c.Connection, FileTransferType.CampaignSave, GameMain.GameSession.SavePath);
}
}
} }
} }
@@ -1976,7 +1989,7 @@ namespace Barotrauma.Networking
gender = Gender.Male; gender = Gender.Male;
headSpriteId = 0; headSpriteId = 0;
DebugConsole.Log("Received invalid characterinfo from \"" +sender.name+"\"! { "+e.Message+" }"); DebugConsole.Log("Received invalid characterinfo from \"" + sender.name + "\"! { " + e.Message + " }");
} }
List<JobPrefab> jobPreferences = new List<JobPrefab>(); List<JobPrefab> jobPreferences = new List<JobPrefab>();