diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs index da6fe39d0..a4935fd62 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/Machines/Sonar.cs @@ -785,8 +785,9 @@ namespace Barotrauma.Items.Components foreach (Limb limb in c.AnimController.Limbs) { - float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared(); + if (!limb.body.Enabled) { continue; } + float pointDist = ((limb.WorldPosition - pingSource) * displayScale).LengthSquared(); if (limb.SimPosition == Vector2.Zero || pointDist > DisplayRadius * DisplayRadius) continue; if (pointDist > prevPingRadiusSqr && pointDist < pingRadiusSqr) diff --git a/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs b/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs index 446fbaa42..fc1a5765e 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/FileTransfer/FileReceiver.cs @@ -177,75 +177,105 @@ namespace Barotrauma.Networking t.Status == FileTransferStatus.Canceled || t.Status == FileTransferStatus.Finished), "List of active file transfers contains entires that should have been removed"); - byte transferMessageType = inc.ReadByte(); + byte transferMessageType = inc.ReadByte(); switch (transferMessageType) { case (byte)FileTransferMessageType.Initiate: - var existingTransfer = activeTransfers.Find(t => t.SequenceChannel == inc.SequenceChannel); - if (existingTransfer != null) { - GameMain.Client.CancelFileTransfer(inc.SequenceChannel); - DebugConsole.ThrowError("File transfer error: file transfer initiated on a sequence channel that's already in use"); - return; - } - - byte fileType = inc.ReadByte(); - ushort chunkLen = inc.ReadUInt16(); - ulong fileSize = inc.ReadUInt64(); - string fileName = inc.ReadString(); - - string errorMsg; - if (!ValidateInitialData(fileType, fileName, fileSize, out errorMsg)) - { - GameMain.Client.CancelFileTransfer(inc.SequenceChannel); - DebugConsole.ThrowError("File transfer failed (" + errorMsg + ")"); - return; - } - - if (GameSettings.VerboseLogging) - { - DebugConsole.Log("Received file transfer initiation message: "); - DebugConsole.Log(" File: " + fileName); - DebugConsole.Log(" Size: " + fileSize); - DebugConsole.Log(" Sequence channel: " + inc.SequenceChannel); - } - - string downloadFolder = downloadFolders[(FileTransferType)fileType]; - - if (!Directory.Exists(downloadFolder)) - { - try + var existingTransfer = activeTransfers.Find(t => t.SequenceChannel == inc.SequenceChannel); + if (existingTransfer != null) { - Directory.CreateDirectory(downloadFolder); - } - catch (Exception e) - { - DebugConsole.ThrowError("Could not start a file transfer: failed to create the folder \"" + downloadFolder + "\".", e); + GameMain.Client.CancelFileTransfer(inc.SequenceChannel); + DebugConsole.ThrowError("File transfer error: file transfer initiated on a sequence channel that's already in use"); return; } + + byte fileType = inc.ReadByte(); + ushort chunkLen = inc.ReadUInt16(); + ulong fileSize = inc.ReadUInt64(); + string fileName = inc.ReadString(); + + string errorMsg; + if (!ValidateInitialData(fileType, fileName, fileSize, out errorMsg)) + { + GameMain.Client.CancelFileTransfer(inc.SequenceChannel); + DebugConsole.ThrowError("File transfer failed (" + errorMsg + ")"); + return; + } + + if (GameSettings.VerboseLogging) + { + DebugConsole.Log("Received file transfer initiation message: "); + DebugConsole.Log(" File: " + fileName); + DebugConsole.Log(" Size: " + fileSize); + DebugConsole.Log(" Sequence channel: " + inc.SequenceChannel); + } + + string downloadFolder = downloadFolders[(FileTransferType)fileType]; + if (!Directory.Exists(downloadFolder)) + { + try + { + Directory.CreateDirectory(downloadFolder); + } + catch (Exception e) + { + DebugConsole.ThrowError("Could not start a file transfer: failed to create the folder \"" + downloadFolder + "\".", e); + return; + } + } + + FileTransferIn newTransfer = new FileTransferIn(inc.SenderConnection, Path.Combine(downloadFolder, fileName), (FileTransferType)fileType) + { + SequenceChannel = inc.SequenceChannel, + Status = FileTransferStatus.Receiving, + 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); } - - FileTransferIn newTransfer = new FileTransferIn(inc.SenderConnection, Path.Combine(downloadFolder, fileName), (FileTransferType)fileType); - newTransfer.SequenceChannel = inc.SequenceChannel; - newTransfer.Status = FileTransferStatus.Receiving; - newTransfer.FileSize = fileSize; - - try + break; + case (byte)FileTransferMessageType.TransferOnSameMachine: { - newTransfer.OpenStream(); + byte fileType = inc.ReadByte(); + string filePath = inc.ReadString(); + + if (GameSettings.VerboseLogging) + { + DebugConsole.Log("Received file transfer message on the same machine: "); + DebugConsole.Log(" File: " + filePath); + DebugConsole.Log(" Sequence channel: " + inc.SequenceChannel); + } + + if (!File.Exists(filePath)) + { + DebugConsole.ThrowError("File transfer on the same machine failed, file \"" + filePath + "\" not found."); + GameMain.Client.CancelFileTransfer(inc.SequenceChannel); + return; + } + + FileTransferIn directTransfer = new FileTransferIn(inc.SenderConnection, filePath, (FileTransferType)fileType) + { + SequenceChannel = inc.SequenceChannel, + Status = FileTransferStatus.Finished, + FileSize = 0 + }; + OnFinished(directTransfer); } - 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; case (byte)FileTransferMessageType.Data: var activeTransfer = activeTransfers.Find(t => t.Connection == inc.SenderConnection && t.SequenceChannel == inc.SequenceChannel); @@ -287,8 +317,7 @@ namespace Barotrauma.Networking { activeTransfer.Dispose(); - string errorMessage = ""; - if (ValidateReceivedData(activeTransfer, out errorMessage)) + if (ValidateReceivedData(activeTransfer, out string errorMessage)) { StopTransfer(activeTransfer); OnFinished(activeTransfer); @@ -387,9 +416,11 @@ namespace Barotrauma.Networking { stream.Position = 0; - XmlReaderSettings settings = new XmlReaderSettings(); - settings.DtdProcessing = DtdProcessing.Prohibit; - settings.IgnoreProcessingInstructions = true; + XmlReaderSettings settings = new XmlReaderSettings + { + DtdProcessing = DtdProcessing.Prohibit, + IgnoreProcessingInstructions = true + }; using (var reader = XmlReader.Create(stream, settings)) { diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 9ca24580f..2992282f5 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1109,7 +1109,7 @@ namespace Barotrauma.Networking { string errorMsg = "Level equality check failed. The level generated at your end doesn't match the level generated by the server (seed " + Level.Loaded.Seed + ")."; DebugConsole.ThrowError(errorMsg, createMessageBox: true); - GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch"+levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + levelSeed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); CoroutineManager.StartCoroutine(EndGame("")); yield return CoroutineStatus.Failure; } @@ -1675,7 +1675,7 @@ namespace Barotrauma.Networking break; case FileTransferType.CampaignSave: var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign; - if (campaign == null) return; + if (campaign == null) { return; } GameMain.GameSession.SavePath = transfer.FilePath; if (GameMain.GameSession.Submarine == null) @@ -1687,6 +1687,8 @@ namespace Barotrauma.Networking SaveUtil.LoadGame(GameMain.GameSession.SavePath, GameMain.GameSession); campaign.LastSaveID = campaign.PendingSaveID; + + DebugConsole.Log("Campaign save received, save ID " + campaign.LastSaveID); //decrement campaign update ID so the server will send us the latest data //(as there may have been campaign updates after the save file was created) campaign.LastUpdateID--; @@ -1704,7 +1706,7 @@ namespace Barotrauma.Networking public override void CreateEntityEvent(INetSerializable entity, object[] extraData) { - if (!(entity is IClientSerializable)) throw new InvalidCastException("entity is not IClientSerializable"); + if (!(entity is IClientSerializable)) throw new InvalidCastException("Entity is not IClientSerializable"); entityEventManager.CreateEvent(entity as IClientSerializable, extraData); } diff --git a/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs index 14667cf7f..0e1667db4 100644 --- a/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs +++ b/Barotrauma/BarotraumaServer/Source/GameSession/GameModes/MultiPlayerCampaign.cs @@ -251,6 +251,7 @@ namespace Barotrauma } lastSaveID++; + DebugConsole.Log("Campaign saved, save ID " + lastSaveID); } } } diff --git a/Barotrauma/BarotraumaServer/Source/Networking/FileTransfer/FileSender.cs b/Barotrauma/BarotraumaServer/Source/Networking/FileTransfer/FileSender.cs index c6ee74b25..22bf12ea6 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/FileTransfer/FileSender.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/FileTransfer/FileSender.cs @@ -172,7 +172,7 @@ namespace Barotrauma.Networking transfer.WaitTimer -= deltaTime; if (transfer.WaitTimer > 0.0f) continue; - if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, 1)) continue; + if (!transfer.Connection.CanSendImmediately(NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel)) continue; transfer.WaitTimer = 0.05f;// transfer.Connection.AverageRoundtripTime; @@ -187,22 +187,38 @@ namespace Barotrauma.Networking { message = peer.CreateMessage(); message.Write((byte)ServerPacketHeader.FILE_TRANSFER); - message.Write((byte)FileTransferMessageType.Initiate); - message.Write((byte)transfer.FileType); - message.Write((ushort)chunkLen); - message.Write((ulong)transfer.Data.Length); - message.Write(transfer.FileName); - GameMain.Server.CompressOutgoingMessage(message); - transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel); - transfer.Status = FileTransferStatus.Sending; - - if (GameSettings.VerboseLogging) + //if the recipient is the owner of the server (= a client running the server from the main exe) + //we don't need to send anything, the client can just read the file directly + if (transfer.Connection == GameMain.Server.OwnerConnection) { - DebugConsole.Log("Sending file transfer initiation message: "); - DebugConsole.Log(" File: " + transfer.FileName); - DebugConsole.Log(" Size: " + transfer.Data.Length); - DebugConsole.Log(" Sequence channel: " + transfer.SequenceChannel); + message.Write((byte)FileTransferMessageType.TransferOnSameMachine); + message.Write((byte)transfer.FileType); + message.Write(transfer.FilePath); + GameMain.Server.CompressOutgoingMessage(message); + transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel); + transfer.Status = FileTransferStatus.Finished; + return; + } + else + { + message.Write((byte)FileTransferMessageType.Initiate); + message.Write((byte)transfer.FileType); + message.Write((ushort)chunkLen); + message.Write((ulong)transfer.Data.Length); + message.Write(transfer.FileName); + GameMain.Server.CompressOutgoingMessage(message); + transfer.Connection.SendMessage(message, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel); + + transfer.Status = FileTransferStatus.Sending; + + if (GameSettings.VerboseLogging) + { + DebugConsole.Log("Sending file transfer initiation message: "); + DebugConsole.Log(" File: " + transfer.FileName); + DebugConsole.Log(" Size: " + transfer.Data.Length); + DebugConsole.Log(" Sequence channel: " + transfer.SequenceChannel); + } } } diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs index f51fd45f1..dd514f544 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs @@ -1203,8 +1203,7 @@ namespace Barotrauma.Networking ClientWriteLobby(c); if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign && - NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave) && - c.Connection != OwnerConnection) //no need to send saves if the client is playing on the same machine + NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave)) { //already sent an up-to-date campaign save if (c.LastCampaignSaveSendTime != null && campaign.LastSaveID == c.LastCampaignSaveSendTime.First) diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs index 630c09a08..4bd7a0077 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs @@ -164,7 +164,7 @@ namespace Barotrauma.Networking if (connectedClient != null) { Log("Disconnecting client " + connectedClient.Name + " (Steam ID: " + steamID + "). Steam authentication no longer valid (" + status + ").", ServerLog.MessageType.ServerMessage); - KickClient(connectedClient, $"DisconnectMessage.SteamAuthNoLongerValid_[status]={status.ToString()}"); + KickClient(connectedClient, $"DisconnectMessage.SteamAuthNoLongerValid~[status]={status.ToString()}"); } }*/ } @@ -342,7 +342,7 @@ namespace Barotrauma.Networking if (clVersion != GameMain.Version.ToString()) { DisconnectUnauthClient(inc, unauthClient, DisconnectReason.InvalidVersion, - $"DisconnectMessage.InvalidVersion_[version]={GameMain.Version.ToString()}_[clientversion]={clVersion}"); + $"DisconnectMessage.InvalidVersion~[version]={GameMain.Version.ToString()}~[clientversion]={clVersion}"); Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (wrong game version)", ServerLog.MessageType.Error); DebugConsole.NewMessage(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (wrong game version)", Color.Red); @@ -368,7 +368,7 @@ namespace Barotrauma.Networking if (missingPackages.Count == 1) { - DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackage_[missingcontentpackage]={GetPackageStr(missingPackages[0])}"); + DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}"); Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content package " + GetPackageStr(missingPackages[0]) + ")", ServerLog.MessageType.Error); return; } @@ -376,7 +376,7 @@ namespace Barotrauma.Networking { List packageStrs = new List(); missingPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp))); - DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackages_[missingcontentpackages]={string.Join(", ", packageStrs)}"); + DisconnectUnauthClient(inc, unauthClient, DisconnectReason.MissingContentPackage, $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}"); Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (missing content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error); return; } @@ -399,7 +399,7 @@ namespace Barotrauma.Networking if (incompatiblePackages.Count == 1) { DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage, - $"DisconnectMessage.IncompatibleContentPackage_[incompatiblecontentpackage]={GetPackageStr2(incompatiblePackages[0])}"); + $"DisconnectMessage.IncompatibleContentPackage~[incompatiblecontentpackage]={GetPackageStr2(incompatiblePackages[0])}"); Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content package " + GetPackageStr2(incompatiblePackages[0]) + ")", ServerLog.MessageType.Error); return; } @@ -408,7 +408,7 @@ namespace Barotrauma.Networking List packageStrs = new List(); incompatiblePackages.ForEach(cp => packageStrs.Add(GetPackageStr2(cp))); DisconnectUnauthClient(inc, unauthClient, DisconnectReason.IncompatibleContentPackage, - $"DisconnectMessage.IncompatibleContentPackages_[incompatiblecontentpackages]={string.Join(", ", packageStrs)}"); + $"DisconnectMessage.IncompatibleContentPackages~[incompatiblecontentpackages]={string.Join(", ", packageStrs)}"); Log(clName + " (" + inc.SenderConnection.RemoteEndPoint.Address.ToString() + ") couldn't join the server (incompatible content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error); return; } @@ -500,7 +500,7 @@ namespace Barotrauma.Networking private void DisconnectUnauthClient(NetIncomingMessage inc, UnauthenticatedClient unauthClient, DisconnectReason reason, string message) { - inc.SenderConnection.Disconnect(reason.ToString() + "/ " + message); + inc.SenderConnection.Disconnect(reason.ToString() + "/ " + TextManager.GetServerMessage(message)); if (unauthClient.SteamID > 0) { Steam.SteamManager.StopAuthSession(unauthClient.SteamID); } if (unauthClient != null) { diff --git a/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs b/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs index c256d9ffa..326df08c3 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/NetEntityEvent/ServerEntityEventManager.cs @@ -185,7 +185,9 @@ namespace Barotrauma.Networking string entityName = bufferedEvent.TargetEntity == null ? "null" : bufferedEvent.TargetEntity.ToString(); if (GameSettings.VerboseLogging) { - DebugConsole.ThrowError("Failed to read server event for entity \"" + entityName + "\"!", e); + string errorMsg = "Failed to read server event for entity \"" + entityName + "\"!"; + GameServer.Log(errorMsg + "\n" + e.StackTrace, ServerLog.MessageType.Error); + DebugConsole.ThrowError(errorMsg, e); } GameAnalyticsManager.AddErrorEventOnce("ServerEntityEventManager.Read:ReadFailed" + entityName, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, @@ -226,7 +228,7 @@ namespace Barotrauma.Networking GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected old event " + (c.LastRecvEntityEventID + 1).ToString() + " (created " + (Timing.TotalTime - firstEventToResend.CreateTime).ToString("0.##") + " s ago)" + - " Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.ServerMessage); + " Events queued: " + events.Count + ", last sent to all: " + lastSentToAll, ServerLog.MessageType.Error); server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncOldEvent"); } ); @@ -240,7 +242,7 @@ namespace Barotrauma.Networking toKick.ForEach(c => { DebugConsole.NewMessage(c.Name + " was kicked due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", Color.Red); - GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", ServerLog.MessageType.ServerMessage); + GameServer.Log("Disconnecting client " + c.Name + " due to excessive desync (expected removed event " + (c.LastRecvEntityEventID + 1).ToString() + ", last available is " + events[0].ID.ToString() + ")", ServerLog.MessageType.Error); server.DisconnectClient(c, "", "ServerMessage.ExcessiveDesyncRemovedEvent"); }); } @@ -249,7 +251,7 @@ namespace Barotrauma.Networking var timedOutClients = clients.FindAll(c => c.InGame && c.NeedsMidRoundSync && Timing.TotalTime > c.MidRoundSyncTimeOut); foreach (Client timedOutClient in timedOutClients) { - GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.ServerMessage); + GameServer.Log("Disconnecting client " + timedOutClient.Name + ". Syncing the client with the server took too long.", ServerLog.MessageType.Error); GameMain.Server.DisconnectClient(timedOutClient, "", "ServerMessage.SyncTimeout"); } @@ -322,7 +324,10 @@ namespace Barotrauma.Networking count++; if (count > 3) { break; } } - + if (GameSettings.VerboseLogging) + { + GameServer.Log(warningMsg, ServerLog.MessageType.Error); + } DebugConsole.NewMessage(warningMsg, color); } } @@ -443,7 +448,7 @@ namespace Barotrauma.Networking { if (GameSettings.VerboseLogging) { - DebugConsole.NewMessage("received msg " + thisEventID, Microsoft.Xna.Framework.Color.Red); + DebugConsole.NewMessage("Received msg " + thisEventID, Color.Red); } msg.Position += msgLength * 8; } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs index 8ffc5630e..6f537c2c7 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/Level.cs @@ -231,7 +231,7 @@ namespace Barotrauma public static Level CreateRandom(LocationConnection locationConnection) { - string seed = locationConnection.Locations[0].Name + locationConnection.Locations[1].Name; + string seed = locationConnection.Locations[0].BaseName + locationConnection.Locations[1].BaseName; float sizeFactor = MathUtils.InverseLerp( MapGenerationParams.Instance.SmallLevelConnectionLength, diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Location.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Location.cs index c2e449bc8..f507b0796 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Location.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Location.cs @@ -15,6 +15,8 @@ namespace Barotrauma public int TypeChangeTimer; + public string BaseName { get => baseName; } + public string Name { get; private set; } public Vector2 MapPosition { get; private set; } @@ -34,7 +36,7 @@ namespace Barotrauma for (int i = availableMissions.Count; i < Connections.Count * 2; i++) { - int seed = (ToolBox.StringToInt(Name) + MissionsCompleted * 10 + i) % int.MaxValue; + int seed = (ToolBox.StringToInt(BaseName) + MissionsCompleted * 10 + i) % int.MaxValue; MTRandom rand = new MTRandom(seed); LocationConnection connection = Connections[(MissionsCompleted + i) % Connections.Count]; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index ba0ba04d5..5776ce80b 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -578,10 +578,12 @@ namespace Barotrauma location.MissionsCompleted = missionsCompleted; if (showNotifications && prevLocationType != location.Type) { - ChangeLocationType( - location, - prevLocationName, - prevLocationType.CanChangeTo.Find(c => c.ChangeToType.ToLowerInvariant() == location.Type.Identifier.ToLowerInvariant())); + var change = prevLocationType.CanChangeTo.Find(c => + c.ChangeToType.ToLowerInvariant() == location.Type.Identifier.ToLowerInvariant()); + if (change != null) + { + ChangeLocationType(location, prevLocationName, change); + } } break; case "connection": diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 1e7294d22..4e71afd3b 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; +using System.Threading; using System.Xml.Linq; using Voronoi2; @@ -317,7 +318,16 @@ namespace Barotrauma if (tryLoad) { - XDocument doc = OpenFile(filePath); + XDocument doc = null; + int maxLoadRetries = 4; + for (int i = 0; i <= maxLoadRetries; i++) + { + doc = OpenFile(filePath); + if (doc != null || i == maxLoadRetries) { break; } + DebugConsole.NewMessage("Opening submarine file \"" + filePath + "\" failed, retrying in 250 ms..."); + Thread.Sleep(250); + } + if (doc == null || doc.Root == null) { return; } if (doc != null && doc.Root != null) { @@ -1177,9 +1187,16 @@ namespace Barotrauma if (submarineElement == null) { - XDocument doc = OpenFile(filePath); - if (doc == null || doc.Root == null) return; - + XDocument doc = null; + int maxLoadRetries = 4; + for (int i = 0; i <= maxLoadRetries; i++) + { + doc = OpenFile(filePath); + if (doc != null || i == maxLoadRetries) { break; } + DebugConsole.NewMessage("Loading the submarine \"" + Name + "\" failed, retrying in 250 ms..."); + Thread.Sleep(250); + } + if (doc == null || doc.Root == null) { return; } submarineElement = doc.Root; } diff --git a/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileTransfer.cs b/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileTransfer.cs index 51a489698..a5d48f5eb 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileTransfer.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/FileTransfer/FileTransfer.cs @@ -7,7 +7,7 @@ enum FileTransferMessageType { - Unknown, Initiate, Data, Cancel + Unknown, Initiate, Data, TransferOnSameMachine, Cancel } enum FileTransferType diff --git a/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEventManager.cs b/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEventManager.cs index e88ae3b71..20cb9b39a 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEventManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/NetEntityEvent/NetEntityEventManager.cs @@ -43,13 +43,8 @@ namespace Barotrauma.Networking eventCount++; continue; } - - if (msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength) - { - //no more room in this packet - break; - } - + + //the length of the data is written as a byte, so the data needs to be less than 255 bytes long if (tempEventBuffer.LengthBytes > 255) { DebugConsole.ThrowError("Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes"); @@ -58,28 +53,24 @@ namespace Barotrauma.Networking "Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes"); //write an empty event to prevent breaking the event syncing - tempBuffer.Write((UInt16)0); + tempBuffer.Write(Entity.NullEntityID); tempBuffer.WritePadBits(); eventCount++; continue; } - //the ID has been taken by another entity (the original entity has been removed) -> write an empty event - /*else if (Entity.FindEntityByID(e.Entity.ID) != e.Entity || e.Entity.IdFreed) + + if (msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength) { - //technically the clients don't have any use for these, but removing events and shifting the IDs of all - //consecutive ones is so error-prone that I think this is a safer option - tempBuffer.Write(Entity.NullEntityID); - tempBuffer.WritePadBits(); - }*/ - else - { - tempBuffer.Write((UInt16)e.Entity.ID); - tempBuffer.Write((byte)tempEventBuffer.LengthBytes); - tempBuffer.Write(tempEventBuffer); - tempBuffer.WritePadBits(); - sentEvents.Add(e); + //no more room in this packet + break; } + tempBuffer.Write((UInt16)e.Entity.ID); + tempBuffer.Write((byte)tempEventBuffer.LengthBytes); + tempBuffer.Write(tempEventBuffer); + tempBuffer.WritePadBits(); + sentEvents.Add(e); + eventCount++; } diff --git a/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs b/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs index 55bf7cd97..79763e9a4 100644 --- a/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs +++ b/Barotrauma/BarotraumaShared/Source/Utils/SaveUtil.cs @@ -15,7 +15,11 @@ namespace Barotrauma public static string TempPath { +#if SERVER + get { return Path.Combine(SaveFolder, "temp_server"); } +#else get { return Path.Combine(SaveFolder, "temp"); } +#endif } public enum SaveType @@ -26,12 +30,10 @@ namespace Barotrauma public static void SaveGame(string filePath) { - string tempPath = Path.Combine(SaveFolder, "temp"); - - Directory.CreateDirectory(tempPath); + Directory.CreateDirectory(TempPath); try { - ClearFolder(tempPath, new string[] { GameMain.GameSession.Submarine.FilePath }); + ClearFolder(TempPath, new string[] { GameMain.GameSession.Submarine.FilePath }); } catch (Exception e) { @@ -42,7 +44,7 @@ namespace Barotrauma { if (Submarine.MainSub != null) { - string subPath = Path.Combine(tempPath, Submarine.MainSub.Name + ".sub"); + string subPath = Path.Combine(TempPath, Submarine.MainSub.Name + ".sub"); if (Submarine.Loaded.Contains(Submarine.MainSub)) { Submarine.MainSub.FilePath = subPath; @@ -62,7 +64,7 @@ namespace Barotrauma try { - GameMain.GameSession.Save(Path.Combine(tempPath, "gamesession.xml")); + GameMain.GameSession.Save(Path.Combine(TempPath, "gamesession.xml")); } catch (Exception e) @@ -72,7 +74,7 @@ namespace Barotrauma try { - CompressDirectory(tempPath, filePath, null); + CompressDirectory(TempPath, filePath, null); } catch (Exception e) @@ -101,11 +103,9 @@ namespace Barotrauma public static XDocument LoadGameSessionDoc(string filePath) { - string tempPath = Path.Combine(SaveFolder, "temp"); - try { - DecompressToDirectory(filePath, tempPath, null); + DecompressToDirectory(filePath, TempPath, null); } catch (Exception e) { @@ -113,7 +113,7 @@ namespace Barotrauma return null; } - return XMLExtensions.TryLoadXml(Path.Combine(tempPath, "gamesession.xml")); + return XMLExtensions.TryLoadXml(Path.Combine(TempPath, "gamesession.xml")); } public static void DeleteSave(string filePath) diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index d2cd1ff19..bfcc4904b 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub and b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub index aacc41a31..0e37eeee6 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub and b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub differ