diff --git a/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs b/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs index a9e91230c..1d0b71451 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs @@ -1,4 +1,5 @@ using Lidgren.Network; +using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.IO; @@ -84,14 +85,17 @@ namespace Barotrauma.Networking FileName = Path.GetFileName(FilePath); FileType = fileType; - Connection = connection; - - WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); - TimeStarted = Environment.TickCount; + Connection = connection; Status = FileTransferStatus.NotStarted; } + public void OpenStream() + { + WriteStream = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None); + TimeStarted = Environment.TickCount; + } + public void ReadBytes(NetIncomingMessage inc) { byte[] all = inc.ReadBytes(inc.LengthBytes - inc.PositionInBytes); @@ -100,17 +104,17 @@ namespace Barotrauma.Networking int passed = Environment.TickCount - TimeStarted; float psec = passed / 1000.0f; - + 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; Status = Received >= FileSize ? FileTransferStatus.Finished : FileTransferStatus.Receiving; } - + private bool disposed = false; protected virtual void Dispose(bool disposing) { @@ -137,8 +141,9 @@ namespace Barotrauma.Networking const int MaxFileSize = 1000000; - public delegate void OnFinishedDelegate(FileTransferIn fileStreamReceiver); - public OnFinishedDelegate OnFinished; + public delegate void TransferInDelegate(FileTransferIn fileStreamReceiver); + public TransferInDelegate OnFinished; + public TransferInDelegate OnTransferFailed; private List 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.Status = FileTransferStatus.Receiving; 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); break; @@ -240,7 +259,7 @@ namespace Barotrauma.Networking 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); DebugConsole.ThrowError("File transfer error: Received more data than expected"); @@ -256,7 +275,7 @@ namespace Barotrauma.Networking catch (Exception e) { GameMain.Client.CancelFileTransfer(inc.SequenceChannel); - DebugConsole.ThrowError("File transfer error: "+e.Message); + DebugConsole.ThrowError("File transfer error: " + e.Message); activeTransfer.Status = FileTransferStatus.Error; StopTransfer(activeTransfer, true); return; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 7942fe4c2..9ba45a475 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -990,7 +990,15 @@ namespace Barotrauma.Networking outmsg.Write(ChatMessage.LastID); 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)); for (int i = 0; i < chatMsgQueue.Count && i < ChatMessage.MaxMessagesPerPacket; i++) @@ -1090,10 +1098,10 @@ namespace Barotrauma.Networking private void OnFileReceived(FileReceiver.FileTransferIn transfer) { - new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully."); switch (transfer.FileType) { case FileTransferType.Submarine: + new GUIMessageBox("Download finished", "File \"" + transfer.FileName + "\" was downloaded succesfully."); var newSub = new Submarine(transfer.FilePath); Submarine.SavedSubmarines.RemoveAll(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash); Submarine.SavedSubmarines.Add(newSub); diff --git a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs index 7c671cd86..3375aac52 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSession/GameModes/MultiplayerCampaign.cs @@ -356,7 +356,7 @@ namespace Barotrauma //server has a newer save file 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 saveTransfers = GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave); @@ -365,7 +365,7 @@ namespace Barotrauma GameMain.Client.FileReceiver.StopTransfer(transfer); } - GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null); + GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/ campaign.PendingSaveID = saveID; } //we've got the latest save file diff --git a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs index 691266248..293b340fd 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/Client.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/Client.cs @@ -44,6 +44,7 @@ namespace Barotrauma.Networking public UInt16 lastRecvEntityEventID = 0; public UInt16 lastRecvCampaignUpdate = 0; + public UInt16 lastRecvCampaignSave = 0; public List chatMsgQueue = new List(); public UInt16 lastChatMsgQueueID; diff --git a/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileSender.cs b/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileSender.cs index 2d47499e4..f119d3f26 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileSender.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileSender.cs @@ -156,6 +156,7 @@ namespace Barotrauma.Networking catch (Exception e) { DebugConsole.ThrowError("Failed to initiate file transfer", e); + return null; } OnStarted(transfer); diff --git a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs index 9cdb67c42..20e159d9f 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/GameServer.cs @@ -601,7 +601,11 @@ namespace Barotrauma.Networking c.lastRecvGeneralUpdate = NetIdUtils.Clamp(inc.ReadUInt16(), c.lastRecvGeneralUpdate, GameMain.NetLobbyScreen.LastUpdateID); 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; case ClientNetObject.CHAT_MESSAGE: ChatMessage.ServerRead(inc, c); @@ -816,6 +820,15 @@ namespace Barotrauma.Networking } 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,9 +1989,9 @@ namespace Barotrauma.Networking gender = Gender.Male; headSpriteId = 0; - DebugConsole.Log("Received invalid characterinfo from \"" +sender.name+"\"! { "+e.Message+" }"); + DebugConsole.Log("Received invalid characterinfo from \"" + sender.name + "\"! { " + e.Message + " }"); } - + List jobPreferences = new List(); int count = message.ReadByte(); for (int i = 0; i < Math.Min(count, 3); i++)