Merge branch 'master' of https://github.com/Regalis11/Barotrauma.git into Regalis11-master
This commit is contained in:
@@ -160,7 +160,7 @@ namespace Barotrauma.Networking
|
||||
public TransferInDelegate OnTransferFailed;
|
||||
|
||||
private readonly List<FileTransferIn> activeTransfers;
|
||||
private readonly List<Pair<int, double>> finishedTransfers;
|
||||
private readonly List<(int transferId, double finishedTime)> finishedTransfers;
|
||||
|
||||
private readonly Dictionary<FileTransferType, string> downloadFolders = new Dictionary<FileTransferType, string>()
|
||||
{
|
||||
@@ -176,7 +176,7 @@ namespace Barotrauma.Networking
|
||||
public FileReceiver()
|
||||
{
|
||||
activeTransfers = new List<FileTransferIn>();
|
||||
finishedTransfers = new List<Pair<int, double>>();
|
||||
finishedTransfers = new List<(int transferId, double finishedTime)>();
|
||||
}
|
||||
|
||||
public void ReadMessage(IReadMessage inc)
|
||||
@@ -193,8 +193,8 @@ namespace Barotrauma.Networking
|
||||
case (byte)FileTransferMessageType.Initiate:
|
||||
{
|
||||
byte transferId = inc.ReadByte();
|
||||
var existingTransfer = activeTransfers.Find(t => t.ID == transferId);
|
||||
finishedTransfers.RemoveAll(t => t.First == transferId);
|
||||
var existingTransfer = activeTransfers.Find(t => t.Connection.EndpointMatches(t.Connection.EndPointString) && t.ID == transferId);
|
||||
finishedTransfers.RemoveAll(t => t.transferId == transferId);
|
||||
byte fileType = inc.ReadByte();
|
||||
//ushort chunkLen = inc.ReadUInt16();
|
||||
int fileSize = inc.ReadInt32();
|
||||
@@ -211,7 +211,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else //resend acknowledgement packet
|
||||
{
|
||||
GameMain.Client.UpdateFileTransfer(transferId, 0);
|
||||
GameMain.Client.UpdateFileTransfer(transferId, existingTransfer.Received);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -316,14 +316,14 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
byte transferId = inc.ReadByte();
|
||||
|
||||
var activeTransfer = activeTransfers.Find(t => t.Connection == inc.Sender && t.ID == transferId);
|
||||
var activeTransfer = activeTransfers.Find(t => t.Connection.EndpointMatches(t.Connection.EndPointString) && t.ID == transferId);
|
||||
if (activeTransfer == null)
|
||||
{
|
||||
//it's possible for the server to send some extra data
|
||||
//before it acknowledges that the download is finished,
|
||||
//so let's suppress the error message in that case
|
||||
finishedTransfers.RemoveAll(t => t.Second + 5.0 < Timing.TotalTime);
|
||||
if (!finishedTransfers.Any(t => t.First == transferId))
|
||||
finishedTransfers.RemoveAll(t => t.finishedTime + 5.0 < Timing.TotalTime);
|
||||
if (!finishedTransfers.Any(t => t.transferId == transferId))
|
||||
{
|
||||
GameMain.Client.CancelFileTransfer(transferId);
|
||||
DebugConsole.ThrowError("File transfer error: received data without a transfer initiation message");
|
||||
@@ -373,7 +373,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (ValidateReceivedData(activeTransfer, out string errorMessage))
|
||||
{
|
||||
finishedTransfers.Add(new Pair<int, double>(transferId, Timing.TotalTime));
|
||||
finishedTransfers.Add((transferId, Timing.TotalTime));
|
||||
StopTransfer(activeTransfer);
|
||||
Md5Hash.RemoveFromCache(activeTransfer.FilePath);
|
||||
OnFinished(activeTransfer);
|
||||
@@ -391,7 +391,7 @@ namespace Barotrauma.Networking
|
||||
case (byte)FileTransferMessageType.Cancel:
|
||||
{
|
||||
byte transferId = inc.ReadByte();
|
||||
var matchingTransfer = activeTransfers.Find(t => t.Connection == inc.Sender && t.ID == transferId);
|
||||
var matchingTransfer = activeTransfers.Find(t => t.Connection.EndpointMatches(t.Connection.EndPointString) && t.ID == transferId);
|
||||
if (matchingTransfer != null)
|
||||
{
|
||||
new GUIMessageBox("File transfer cancelled", "The server has cancelled the transfer of the file \"" + matchingTransfer.FileName + "\".");
|
||||
@@ -528,7 +528,7 @@ namespace Barotrauma.Networking
|
||||
transfer.Status = FileTransferStatus.Canceled;
|
||||
}
|
||||
|
||||
if (activeTransfers.Contains(transfer)) activeTransfers.Remove(transfer);
|
||||
if (activeTransfers.Contains(transfer)) { activeTransfers.Remove(transfer); }
|
||||
transfer.Dispose();
|
||||
|
||||
if (deleteFile && File.Exists(transfer.FilePath))
|
||||
|
||||
@@ -462,7 +462,7 @@ namespace Barotrauma.Networking
|
||||
private bool wrongPassword;
|
||||
|
||||
// Before main looping starts, we loop here and wait for approval message
|
||||
private IEnumerable<object> WaitForStartingInfo()
|
||||
private IEnumerable<CoroutineStatus> WaitForStartingInfo()
|
||||
{
|
||||
GUI.SetCursorWaiting();
|
||||
requiresPw = false;
|
||||
@@ -651,7 +651,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
errorMsg += "\nInner exception: " + e.InnerException.Message + "\n" + e.InnerException.StackTrace.CleanupStackTrace();
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
DebugConsole.ThrowError("Error while reading a message from server.", e);
|
||||
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", new string[2] { "[message]", "[targetsite]" }, new string[2] { e.Message, e.TargetSite.ToString() }));
|
||||
Disconnect();
|
||||
@@ -781,7 +781,7 @@ namespace Barotrauma.Networking
|
||||
#if DEBUG
|
||||
DebugConsole.ThrowError("Error while reading an ingame update message from server.", e);
|
||||
#endif
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadDataMessage:ReadIngameUpdate", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadDataMessage:ReadIngameUpdate", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw;
|
||||
}
|
||||
break;
|
||||
@@ -793,7 +793,7 @@ namespace Barotrauma.Networking
|
||||
errorMsg += "\n" + Environment.StackTrace.CleanupStackTrace();
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"GameClient.ReadDataMessage:VoipClientNull",
|
||||
GameMain.Client == null ? GameAnalyticsSDK.Net.EGAErrorSeverity.Error : GameAnalyticsSDK.Net.EGAErrorSeverity.Warning,
|
||||
GameMain.Client == null ? GameAnalyticsManager.ErrorSeverity.Error : GameAnalyticsManager.ErrorSeverity.Warning,
|
||||
errorMsg);
|
||||
return;
|
||||
}
|
||||
@@ -863,8 +863,8 @@ namespace Barotrauma.Networking
|
||||
if (roundInitStatus == RoundInitStatus.WaitingForStartGameFinalize)
|
||||
{
|
||||
//waiting for a save file
|
||||
if (campaign != null &&
|
||||
campaign.PendingSaveID > campaign.LastSaveID &&
|
||||
if (campaign != null &&
|
||||
NetIdUtils.IdMoreRecent(campaign.PendingSaveID, campaign.LastSaveID) &&
|
||||
fileReceiver.ActiveTransfers.Any(t => t.FileType == FileTransferType.CampaignSave))
|
||||
{
|
||||
return;
|
||||
@@ -874,6 +874,7 @@ namespace Barotrauma.Networking
|
||||
break;
|
||||
case ServerPacketHeader.ENDGAME:
|
||||
CampaignMode.TransitionType transitionType = (CampaignMode.TransitionType)inc.ReadByte();
|
||||
bool save = inc.ReadBoolean();
|
||||
string endMessage = string.Empty;
|
||||
|
||||
endMessage = inc.ReadString();
|
||||
@@ -907,6 +908,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
CoroutineManager.StartCoroutine(EndGame(endMessage, traitorResults, transitionType), "EndGame");
|
||||
GUI.SetSavingIndicatorState(save);
|
||||
break;
|
||||
case ServerPacketHeader.CAMPAIGN_SETUP_INFO:
|
||||
UInt16 saveCount = inc.ReadUInt16();
|
||||
@@ -992,7 +994,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
string errorMsg = "Submarine equality check failed. The submarine loaded at your end doesn't match the one loaded by the server." +
|
||||
" There may have been an error in receiving the up-to-date submarine file from the server.";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:SubsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:SubsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
|
||||
@@ -1013,7 +1015,7 @@ namespace Barotrauma.Networking
|
||||
if (!GameMain.GameSession.Missions.Select(m => m.Prefab.Identifier).OrderBy(id => id).SequenceEqual(serverMissionIdentifiers.OrderBy(id => id)))
|
||||
{
|
||||
string errorMsg = $"Mission equality check failed. The mission selected at your end doesn't match the one loaded by the server (server: {string.Join(", ", serverMissionIdentifiers)}, client: {string.Join(", ", GameMain.GameSession.Missions.Select(m => m.Prefab.Identifier))})";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:MissionsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:MissionsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
GameMain.GameSession.EnforceMissionOrder(serverMissionIdentifiers);
|
||||
@@ -1034,7 +1036,7 @@ namespace Barotrauma.Networking
|
||||
", seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortHash + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
else
|
||||
@@ -1050,7 +1052,7 @@ namespace Barotrauma.Networking
|
||||
", seed: " + Level.Loaded.Seed +
|
||||
", sub: " + Submarine.MainSub.Info.Name + " (" + Submarine.MainSub.Info.MD5Hash.ShortHash + ")" +
|
||||
", mirrored: " + Level.Loaded.Mirrored + ").";
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:LevelsDontMatch" + Level.Loaded.Seed, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
}
|
||||
@@ -1120,8 +1122,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"GameClient.HandleDisconnectMessage",
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Debug,
|
||||
"Client received a disconnect message. Reason: " + disconnectReason.ToString() + ", message: " + disconnectMsg);
|
||||
GameAnalyticsManager.ErrorSeverity.Debug,
|
||||
"Client received a disconnect message. Reason: " + disconnectReason.ToString());
|
||||
}
|
||||
|
||||
if (disconnectReason == DisconnectReason.ServerFull)
|
||||
@@ -1241,7 +1243,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitInServerQueue()
|
||||
private IEnumerable<CoroutineStatus> WaitInServerQueue()
|
||||
{
|
||||
waitInServerQueueBox = new GUIMessageBox(
|
||||
TextManager.Get("ServerQueuePleaseWait"),
|
||||
@@ -1429,7 +1431,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.RefreshEnabledElements();
|
||||
}
|
||||
|
||||
private IEnumerable<object> StartGame(IReadMessage inc)
|
||||
private IEnumerable<CoroutineStatus> StartGame(IReadMessage inc)
|
||||
{
|
||||
Character?.Remove();
|
||||
Character = null;
|
||||
@@ -1473,6 +1475,7 @@ namespace Barotrauma.Networking
|
||||
serverSettings.AllowFriendlyFire = inc.ReadBoolean();
|
||||
serverSettings.LockAllDefaultWires = inc.ReadBoolean();
|
||||
serverSettings.AllowRagdollButton = inc.ReadBoolean();
|
||||
serverSettings.AllowLinkingWifiToChat = inc.ReadBoolean();
|
||||
GameMain.NetLobbyScreen.UsingShuttle = inc.ReadBoolean();
|
||||
GameMain.LightManager.LosMode = (LosMode)inc.ReadByte();
|
||||
bool includesFinalize = inc.ReadBoolean(); inc.ReadPadBits();
|
||||
@@ -1535,7 +1538,7 @@ namespace Barotrauma.Networking
|
||||
gameStarted = true;
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:FailedToSelectSub" + subName, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:FailedToSelectSub" + subName, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
@@ -1547,7 +1550,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
string errorMsg = "Failed to select shuttle \"" + shuttleName + "\" (hash: " + shuttleHash + ").";
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:FailedToSelectShuttle" + shuttleName, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.StartGame:FailedToSelectShuttle" + shuttleName, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
@@ -1567,31 +1570,47 @@ namespace Barotrauma.Networking
|
||||
if (GameMain.GameSession?.CrewManager != null) { GameMain.GameSession.CrewManager.Reset(); }
|
||||
|
||||
byte campaignID = inc.ReadByte();
|
||||
UInt16 campaignSaveID = inc.ReadUInt16();
|
||||
int nextLocationIndex = inc.ReadInt32();
|
||||
int nextConnectionIndex = inc.ReadInt32();
|
||||
int selectedLocationIndex = inc.ReadInt32();
|
||||
bool mirrorLevel = inc.ReadBoolean();
|
||||
|
||||
|
||||
if (campaign.CampaignID != campaignID)
|
||||
{
|
||||
string errorMsg = "Failed to start campaign round (campaign ID does not match).";
|
||||
gameStarted = true;
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
DebugConsole.ThrowError("Failed to start campaign round (campaign ID does not match).");
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
else if (campaign.Map == null)
|
||||
{
|
||||
string errorMsg = "Failed to start campaign round (campaign map not loaded yet).";
|
||||
gameStarted = true;
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
DebugConsole.ThrowError("Failed to start campaign round (campaign map not loaded yet).");
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(campaignSaveID, campaign.PendingSaveID))
|
||||
{
|
||||
campaign.PendingSaveID = campaignSaveID;
|
||||
DateTime saveFileTimeOut = DateTime.Now + new TimeSpan(0,0,60);
|
||||
while (NetIdUtils.IdMoreRecent(campaignSaveID, campaign.LastSaveID))
|
||||
{
|
||||
if (DateTime.Now > saveFileTimeOut)
|
||||
{
|
||||
gameStarted = true;
|
||||
DebugConsole.ThrowError("Failed to start campaign round (timed out while waiting for the up-to-date save file).");
|
||||
GameMain.NetLobbyScreen.Select();
|
||||
roundInitStatus = RoundInitStatus.Interrupted;
|
||||
yield return CoroutineStatus.Failure;
|
||||
}
|
||||
yield return new WaitForSeconds(0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
campaign.Map.SelectLocation(selectedLocationIndex);
|
||||
|
||||
LevelData levelData = nextLocationIndex > -1 ?
|
||||
@@ -1670,10 +1689,6 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
if (roundInitStatus != RoundInitStatus.WaitingForStartGameFinalize) { break; }
|
||||
|
||||
clientPeer.Update((float)Timing.Step);
|
||||
|
||||
if (roundInitStatus != RoundInitStatus.WaitingForStartGameFinalize) { break; }
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -1749,7 +1764,7 @@ namespace Barotrauma.Networking
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
public IEnumerable<object> EndGame(string endMessage, List<TraitorMissionResult> traitorResults = null, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
|
||||
public IEnumerable<CoroutineStatus> EndGame(string endMessage, List<TraitorMissionResult> traitorResults = null, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
|
||||
{
|
||||
//round starting up, wait for it to finish
|
||||
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 60);
|
||||
@@ -1859,8 +1874,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.GameSession.OwnedSubmarines = new List<SubmarineInfo>();
|
||||
for (int i = 0; i < ownedIndexes.Length; i++)
|
||||
{
|
||||
int index;
|
||||
if (int.TryParse(ownedIndexes[i], out index))
|
||||
if (int.TryParse(ownedIndexes[i], out int index))
|
||||
{
|
||||
SubmarineInfo sub = GameMain.Client.ServerSubmarines[index];
|
||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "owned"))
|
||||
@@ -2108,9 +2122,6 @@ namespace Barotrauma.Networking
|
||||
bool autoRestartEnabled = inc.ReadBoolean();
|
||||
float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f;
|
||||
|
||||
bool radiationEnabled = inc.ReadBoolean();
|
||||
byte maxMissionCount = inc.ReadByte();
|
||||
|
||||
//ignore the message if we already a more up-to-date one
|
||||
//or if we're still waiting for the initial update
|
||||
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID) &&
|
||||
@@ -2160,22 +2171,15 @@ namespace Barotrauma.Networking
|
||||
if (GameMain.NetLobbyScreen.CheckIfCampaignSubMatches(sub, "campaign"))
|
||||
{
|
||||
GameMain.NetLobbyScreen.CampaignSubmarines.Add(sub);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasPermission(ClientPermissions.ManageCampaign) && !gameStarted && GameMain.NetLobbyScreen?.CampaignSetupUI != null)
|
||||
{
|
||||
GameMain.NetLobbyScreen.CampaignSetupUI.RefreshMultiplayerCampaignSubUI(GameMain.NetLobbyScreen.CampaignSubmarines);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||
GameMain.NetLobbyScreen.SetRadiationEnabled(radiationEnabled);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
GameMain.NetLobbyScreen.SetMaxMissionCount(maxMissionCount);
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
||||
|
||||
serverSettings.VoiceChatEnabled = voiceChatEnabled;
|
||||
@@ -2347,7 +2351,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
errorLines.Add("[" + DebugConsole.Messages[i].Time + "] " + DebugConsole.Messages[i].Text);
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadInGameUpdate", GameAnalyticsSDK.Net.EGAErrorSeverity.Critical, string.Join("\n", errorLines));
|
||||
GameAnalyticsManager.AddErrorEventOnce("GameClient.ReadInGameUpdate", GameAnalyticsManager.ErrorSeverity.Critical, string.Join("\n", errorLines));
|
||||
|
||||
DebugConsole.ThrowError("Writing object data to \"networkerror_data.log\", please send this file to us at http://github.com/Regalis11/Barotrauma/issues");
|
||||
|
||||
@@ -2583,29 +2587,29 @@ namespace Barotrauma.Networking
|
||||
subElement.ToolTip = newSub.Description;
|
||||
}
|
||||
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedSub != null &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.First == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.Second == newSub.MD5Hash.Hash)
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedSub.HasValue &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.Value.Name == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedSub.Value.Hash == newSub.MD5Hash.Hash)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TrySelectSub(newSub.Name, newSub.MD5Hash.Hash, GameMain.NetLobbyScreen.SubList);
|
||||
}
|
||||
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedShuttle != null &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.First == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Second == newSub.MD5Hash.Hash)
|
||||
if (GameMain.NetLobbyScreen.FailedSelectedShuttle.HasValue &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Value.Name == newSub.Name &&
|
||||
GameMain.NetLobbyScreen.FailedSelectedShuttle.Value.Hash == newSub.MD5Hash.Hash)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TrySelectSub(newSub.Name, newSub.MD5Hash.Hash, GameMain.NetLobbyScreen.ShuttleList.ListBox);
|
||||
}
|
||||
|
||||
Pair<string, string> failedCampaignSub = GameMain.NetLobbyScreen.FailedCampaignSubs.Find(s => s.First == newSub.Name && s.Second == newSub.MD5Hash.Hash);
|
||||
if (failedCampaignSub != null)
|
||||
NetLobbyScreen.FailedSubInfo failedCampaignSub = GameMain.NetLobbyScreen.FailedCampaignSubs.Find(s => s.Name == newSub.Name && s.Hash == newSub.MD5Hash.Hash);
|
||||
if (failedCampaignSub != default)
|
||||
{
|
||||
GameMain.NetLobbyScreen.CampaignSubmarines.Add(newSub);
|
||||
GameMain.NetLobbyScreen.FailedCampaignSubs.Remove(failedCampaignSub);
|
||||
}
|
||||
|
||||
Pair<string, string> failedOwnedSub = GameMain.NetLobbyScreen.FailedOwnedSubs.Find(s => s.First == newSub.Name && s.Second == newSub.MD5Hash.Hash);
|
||||
if (failedOwnedSub != null)
|
||||
NetLobbyScreen.FailedSubInfo failedOwnedSub = GameMain.NetLobbyScreen.FailedOwnedSubs.Find(s => s.Name == newSub.Name && s.Hash == newSub.MD5Hash.Hash);
|
||||
if (failedOwnedSub != default)
|
||||
{
|
||||
GameMain.NetLobbyScreen.ServerOwnedSubmarines.Add(newSub);
|
||||
GameMain.NetLobbyScreen.FailedOwnedSubs.Remove(failedOwnedSub);
|
||||
@@ -2675,8 +2679,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
public override void CreateEntityEvent(INetSerializable entity, object[] extraData)
|
||||
{
|
||||
if (!(entity is IClientSerializable)) throw new InvalidCastException("Entity is not IClientSerializable");
|
||||
entityEventManager.CreateEvent(entity as IClientSerializable, extraData);
|
||||
if (!(entity is IClientSerializable clientSerializable))
|
||||
{
|
||||
throw new InvalidCastException($"Entity is not {nameof(IClientSerializable)}");
|
||||
}
|
||||
entityEventManager.CreateEvent(clientSerializable, extraData);
|
||||
}
|
||||
|
||||
public bool HasPermission(ClientPermissions permission)
|
||||
@@ -2941,7 +2948,6 @@ namespace Barotrauma.Networking
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||
msg.Write((UInt16)ClientPermissions.SelectSub);
|
||||
msg.Write(false);
|
||||
msg.Write(isShuttle); msg.WritePadBits();
|
||||
msg.Write((UInt16)subIndex);
|
||||
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||
@@ -2949,23 +2955,6 @@ namespace Barotrauma.Networking
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the server to add / remove a purchasable submarine (permission required)
|
||||
/// </summary>
|
||||
public void RequestCampaignSub(SubmarineInfo sub, bool add)
|
||||
{
|
||||
if (!HasPermission(ClientPermissions.SelectSub) || sub == null) return;
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||
msg.Write((UInt16)ClientPermissions.SelectSub);
|
||||
msg.Write(true);
|
||||
msg.Write(sub.EqualityCheckVal);
|
||||
msg.Write(add);
|
||||
msg.Write((byte)ServerNetObject.END_OF_MESSAGE);
|
||||
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell the server to select a mode (permission required)
|
||||
/// </summary>
|
||||
@@ -3024,12 +3013,13 @@ namespace Barotrauma.Networking
|
||||
/// <summary>
|
||||
/// Tell the server to end the round (permission required)
|
||||
/// </summary>
|
||||
public void RequestRoundEnd()
|
||||
public void RequestRoundEnd(bool save)
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage();
|
||||
msg.Write((byte)ClientPacketHeader.SERVER_COMMAND);
|
||||
msg.Write((UInt16)ClientPermissions.ManageRound);
|
||||
msg.Write(true); //indicates round end
|
||||
msg.Write(save);
|
||||
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
@@ -3332,7 +3322,9 @@ namespace Barotrauma.Networking
|
||||
if (respawnManager.RespawnCountdownStarted)
|
||||
{
|
||||
float timeLeft = (float)(respawnManager.RespawnTime - DateTime.Now).TotalSeconds;
|
||||
respawnText = TextManager.GetWithVariable(respawnManager.UsingShuttle ? "RespawnShuttleDispatching" : "RespawningIn", "[time]", ToolBox.SecondsToReadableTime(timeLeft));
|
||||
respawnText = TextManager.GetWithVariable(
|
||||
respawnManager.UsingShuttle && !respawnManager.ForceSpawnInMainSub ?
|
||||
"RespawnShuttleDispatching" : "RespawningIn", "[time]", ToolBox.SecondsToReadableTime(timeLeft));
|
||||
}
|
||||
else if (respawnManager.PendingRespawnCount > 0)
|
||||
{
|
||||
@@ -3448,7 +3440,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
// Need a delayed selection due to the inputbox being deselected when a left click occurs outside of it
|
||||
IEnumerable<object> selectCoroutine()
|
||||
IEnumerable<CoroutineStatus> selectCoroutine()
|
||||
{
|
||||
yield return new WaitForSeconds(0.01f, true);
|
||||
chatBox.InputBox.Select(chatBox.InputBox.Text.Length);
|
||||
|
||||
@@ -72,6 +72,9 @@ namespace Barotrauma
|
||||
{
|
||||
CreateLabeledTickBox(parent, nameof(DangerousItemStealBots));
|
||||
}
|
||||
CreateLabeledSlider(parent, 0.0f, 30.0f, 0.5f, nameof(DangerousItemContainKarmaDecrease));
|
||||
CreateLabeledTickBox(parent, nameof(IsDangerousItemContainKarmaDecreaseIncremental));
|
||||
CreateLabeledSlider(parent, 0.0f, 100.0f, 1.0f, nameof(MaxDangerousItemContainKarmaDecrease));
|
||||
}
|
||||
|
||||
private void CreateLabeledSlider(GUIComponent parent, float min, float max, float step, string propertyName)
|
||||
|
||||
+11
-23
@@ -43,24 +43,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void CreateEvent(IClientSerializable entity, object[] extraData = null)
|
||||
{
|
||||
if (GameMain.Client == null || GameMain.Client.Character == null) return;
|
||||
if (GameMain.Client?.Character == null) { return; }
|
||||
|
||||
if (!(entity is Entity))
|
||||
{
|
||||
DebugConsole.ThrowError("Can't create an entity event for " + entity + "!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((Entity)entity).Removed)
|
||||
{
|
||||
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the entity has been removed.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
if (((Entity)entity).IdFreed)
|
||||
{
|
||||
DebugConsole.ThrowError("Can't create an entity event for " + entity + " - the ID of the entity has been freed.\n" + Environment.StackTrace.CleanupStackTrace());
|
||||
return;
|
||||
}
|
||||
if (!ValidateEntity(entity)) { return; }
|
||||
|
||||
var newEvent = new ClientEntityEvent(entity, (UInt16)(ID + 1))
|
||||
{
|
||||
@@ -161,7 +146,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
UInt16 firstEventID = msg.ReadUInt16();
|
||||
int eventCount = msg.ReadByte();
|
||||
|
||||
|
||||
for (int i = 0; i < eventCount; i++)
|
||||
{
|
||||
//16 = entity ID, 8 = msg length
|
||||
@@ -179,7 +164,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
UInt16 thisEventID = (UInt16)(firstEventID + (UInt16)i);
|
||||
UInt16 entityID = msg.ReadUInt16();
|
||||
|
||||
|
||||
if (entityID == Entity.NullEntityID)
|
||||
{
|
||||
if (GameSettings.VerboseLogging)
|
||||
@@ -240,12 +225,15 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (msg.BitPosition != msgPosition + msgLength * 8)
|
||||
{
|
||||
string errorMsg = "Message byte position incorrect after reading an event for the entity \"" + entity.ToString()
|
||||
+ "\". Read " + (msg.BitPosition - msgPosition) + " bits, expected message length was " + (msgLength * 8) + " bits.";
|
||||
var prevEntity = entities.Count >= 2 ? entities[entities.Count - 2] : null;
|
||||
ushort prevId = prevEntity is Entity p ? p.ID : (ushort)0;
|
||||
string errorMsg = $"Message byte position incorrect after reading an event for the entity \"{entity}\" (ID {(entity is Entity e ? e.ID : 0)}). "
|
||||
+$"The previous entity was \"{prevEntity}\" (ID {prevId}) "
|
||||
+$"Read {msg.BitPosition - msgPosition} bits, expected message length was {msgLength * 8} bits.";
|
||||
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:BitPosMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:BitPosMismatch", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
|
||||
//TODO: force the BitPosition to correct place? Having some entity in a potentially incorrect state is not as bad as a desync kick
|
||||
//msg.BitPosition = (int)(msgPosition + msgLength * 8);
|
||||
@@ -264,7 +252,7 @@ namespace Barotrauma.Networking
|
||||
DebugConsole.ThrowError("Failed to read event for entity \"" + entity.ToString() + "\"!", e);
|
||||
|
||||
GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:ReadFailed" + entity.ToString(),
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
msg.BitPosition = (int)(msgPosition + msgLength * 8);
|
||||
msg.ReadPadBits();
|
||||
}
|
||||
|
||||
@@ -60,11 +60,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black * 0.4f, true);
|
||||
|
||||
graphs[(int)NetStatType.ReceivedBytes].Draw(spriteBatch, rect, null, 0.0f, Color.Cyan);
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, 0.0f, GUI.Style.Orange);
|
||||
graphs[(int)NetStatType.ReceivedBytes].Draw(spriteBatch, rect, color: Color.Cyan);
|
||||
graphs[(int)NetStatType.SentBytes].Draw(spriteBatch, rect, null, color: GUI.Style.Orange);
|
||||
if (graphs[(int)NetStatType.ResentMessages].Average() > 0)
|
||||
{
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, null, 0.0f, GUI.Style.Red);
|
||||
graphs[(int)NetStatType.ResentMessages].Draw(spriteBatch, rect, color: GUI.Style.Red);
|
||||
GUI.SmallFont.DrawString(spriteBatch, "Peak resent: " + graphs[(int)NetStatType.ResentMessages].LargestValue() + " messages/s",
|
||||
new Vector2(rect.Right + 10, rect.Y + 50), GUI.Style.Red);
|
||||
}
|
||||
|
||||
+3
-5
@@ -115,13 +115,11 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
if (!isActive) { return; }
|
||||
|
||||
byte incByte = inc.ReadByte();
|
||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||
bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
|
||||
PacketHeader packetHeader = (PacketHeader)inc.ReadByte();
|
||||
|
||||
//Console.WriteLine(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte);
|
||||
|
||||
if (isConnectionInitializationStep && initializationStep != ConnectionInitialization.Success)
|
||||
if (packetHeader.IsConnectionInitializationStep() && initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
ReadConnectionInitializationStep(new ReadWriteMessage(inc.Data, (int)inc.Position, inc.LengthBits, false));
|
||||
}
|
||||
@@ -133,7 +131,7 @@ namespace Barotrauma.Networking
|
||||
initializationStep = ConnectionInitialization.Success;
|
||||
}
|
||||
UInt16 length = inc.ReadUInt16();
|
||||
IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, ServerConnection);
|
||||
IReadMessage msg = new ReadOnlyMessage(inc.Data, packetHeader.IsCompressed(), inc.PositionInBytes, length, ServerConnection);
|
||||
OnMessageReceived?.Invoke(msg);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-14
@@ -112,33 +112,28 @@ namespace Barotrauma.Networking
|
||||
NetworkConnection.TimeoutThresholdInGame :
|
||||
NetworkConnection.TimeoutThreshold;
|
||||
|
||||
byte incByte = data[0];
|
||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||
bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
|
||||
bool isDisconnectMessage = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
|
||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
||||
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
||||
PacketHeader packetHeader = (PacketHeader)data[0];
|
||||
|
||||
if (!isServerMessage) { return; }
|
||||
if (!packetHeader.IsServerMessage()) { return; }
|
||||
|
||||
if (isConnectionInitializationStep)
|
||||
if (packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
ulong low = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8);
|
||||
ulong high = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8 + 32);
|
||||
ulong lobbyId = low + (high << 32);
|
||||
|
||||
Steam.SteamManager.JoinLobby(lobbyId, false);
|
||||
IReadMessage inc = new ReadOnlyMessage(data, false, 1 + 8, dataLength - 9, ServerConnection);
|
||||
IReadMessage inc = new ReadOnlyMessage(data, false, 1 + 8, dataLength - (1 + 8), ServerConnection);
|
||||
if (initializationStep != ConnectionInitialization.Success)
|
||||
{
|
||||
incomingInitializationMessages.Add(inc);
|
||||
}
|
||||
}
|
||||
else if (isHeartbeatMessage)
|
||||
else if (packetHeader.IsHeartbeatMessage())
|
||||
{
|
||||
return; //TODO: implement heartbeats
|
||||
}
|
||||
else if (isDisconnectMessage)
|
||||
else if (packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
IReadMessage inc = new ReadOnlyMessage(data, false, 1, dataLength - 1, ServerConnection);
|
||||
string msg = inc.ReadString();
|
||||
@@ -147,10 +142,9 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt16 length = data[1];
|
||||
length |= (UInt16)(((UInt32)data[2]) << 8);
|
||||
UInt16 length = Lidgren.Network.NetBitWriter.ReadUInt16(data, 16, 8);
|
||||
|
||||
IReadMessage inc = new ReadOnlyMessage(data, isCompressed, 3, length, ServerConnection);
|
||||
IReadMessage inc = new ReadOnlyMessage(data, packetHeader.IsCompressed(), 3, length, ServerConnection);
|
||||
incomingDataMessages.Add(inc);
|
||||
}
|
||||
}
|
||||
|
||||
+31
-28
@@ -147,18 +147,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
||||
|
||||
byte incByte = data[1];
|
||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||
bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
|
||||
bool isDisconnectMessage = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
|
||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
||||
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
||||
PacketHeader packetHeader = (PacketHeader)data[1];
|
||||
|
||||
if (!remotePeer.Authenticated & !remotePeer.Authenticating && isConnectionInitializationStep)
|
||||
if (!remotePeer.Authenticated & !remotePeer.Authenticating && packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
remotePeer.DisconnectTime = null;
|
||||
|
||||
IReadMessage authMsg = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
|
||||
IReadMessage authMsg = new ReadOnlyMessage(data, packetHeader.IsCompressed(), 2, dataLength - 2, null);
|
||||
ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
|
||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
|
||||
{
|
||||
@@ -242,17 +237,11 @@ namespace Barotrauma.Networking
|
||||
|
||||
int p2pDataStart = inc.BytePosition;
|
||||
|
||||
byte incByte = inc.ReadByte();
|
||||
|
||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||
bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
|
||||
bool isDisconnectMessage = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
|
||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
||||
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
||||
PacketHeader packetHeader = (PacketHeader)inc.ReadByte();
|
||||
|
||||
if (recipientSteamId != selfSteamID)
|
||||
{
|
||||
if (!isServerMessage)
|
||||
if (!packetHeader.IsServerMessage())
|
||||
{
|
||||
DebugConsole.ThrowError("Received non-server message meant for remote peer");
|
||||
return;
|
||||
@@ -262,7 +251,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (peer == null) { return; }
|
||||
|
||||
if (isDisconnectMessage)
|
||||
if (packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
DisconnectPeer(peer, inc.ReadString());
|
||||
return;
|
||||
@@ -273,8 +262,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
case DeliveryMethod.Reliable:
|
||||
case DeliveryMethod.ReliableOrdered:
|
||||
//the documentation seems to suggest that the Reliable send type
|
||||
//enforces packet order (TODO: verify)
|
||||
//the documentation seems to suggest that the
|
||||
//Reliable send type enforces packet order
|
||||
sendType = Steamworks.P2PSend.Reliable;
|
||||
break;
|
||||
default:
|
||||
@@ -284,17 +273,31 @@ namespace Barotrauma.Networking
|
||||
|
||||
byte[] p2pData;
|
||||
|
||||
if (isConnectionInitializationStep)
|
||||
if (packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
p2pData = new byte[inc.LengthBytes - p2pDataStart + 8];
|
||||
p2pData[0] = inc.Buffer[p2pDataStart];
|
||||
Lidgren.Network.NetBitWriter.WriteUInt64(SteamManager.CurrentLobbyID, 64, p2pData, 8);
|
||||
Array.Copy(inc.Buffer, p2pDataStart+1, p2pData, 9, inc.LengthBytes - p2pDataStart - 1);
|
||||
Lidgren.Network.NetBitWriter.WriteUInt64(SteamManager.CurrentLobbyID, 8 * 8, p2pData, 1 * 8);
|
||||
Array.Copy(inc.Buffer, p2pDataStart+1, p2pData, 1 + 8, inc.LengthBytes - p2pDataStart - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
p2pData = new byte[inc.LengthBytes - p2pDataStart];
|
||||
Array.Copy(inc.Buffer, p2pDataStart, p2pData, 0, p2pData.Length);
|
||||
|
||||
if (!packetHeader.IsHeartbeatMessage() && !packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
UInt16 length = Lidgren.Network.NetBitWriter.ReadUInt16(p2pData, 16, 8);
|
||||
if (length > p2pData.Length - 2)
|
||||
{
|
||||
string errorMsg = $"Length written in message to send to client is larger than buffer size ({length} > {p2pData.Length - 2})";
|
||||
DebugConsole.ThrowError(errorMsg);
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"SteamP2POwnerPeerLengthValidationFail",
|
||||
GameAnalyticsManager.ErrorSeverity.Error,
|
||||
errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p2pData.Length + 4 >= MsgConstants.MTU)
|
||||
@@ -323,21 +326,21 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isDisconnectMessage)
|
||||
if (packetHeader.IsDisconnectMessage())
|
||||
{
|
||||
DebugConsole.ThrowError("Received disconnect message from owned server");
|
||||
return;
|
||||
}
|
||||
if (!isServerMessage)
|
||||
if (!packetHeader.IsServerMessage())
|
||||
{
|
||||
DebugConsole.ThrowError("Received non-server message from owned server");
|
||||
return;
|
||||
}
|
||||
if (isHeartbeatMessage)
|
||||
if (packetHeader.IsHeartbeatMessage())
|
||||
{
|
||||
return; //timeout is handled by Lidgren, ignore this message
|
||||
return; //no timeout since we're using pipes, ignore this message
|
||||
}
|
||||
if (isConnectionInitializationStep)
|
||||
if (packetHeader.IsConnectionInitializationStep())
|
||||
{
|
||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||
outMsg.Write(selfSteamID);
|
||||
@@ -358,7 +361,7 @@ namespace Barotrauma.Networking
|
||||
initializationStep = ConnectionInitialization.Success;
|
||||
}
|
||||
UInt16 length = inc.ReadUInt16();
|
||||
IReadMessage msg = new ReadOnlyMessage(inc.Buffer, isCompressed, inc.BytePosition, length, ServerConnection);
|
||||
IReadMessage msg = new ReadOnlyMessage(inc.Buffer, packetHeader.IsCompressed(), inc.BytePosition, length, ServerConnection);
|
||||
OnMessageReceived?.Invoke(msg);
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -17,6 +18,11 @@ namespace Barotrauma.Networking
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public bool ForceSpawnInMainSub
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
partial void UpdateTransportingProjSpecific(float deltaTime)
|
||||
{
|
||||
if (GameMain.Client?.Character == null || GameMain.Client.Character.Submarine != RespawnShuttle) { return; }
|
||||
@@ -30,10 +36,46 @@ namespace Barotrauma.Networking
|
||||
GameMain.Client.AddChatMessage("ServerMessage.ShuttleLeaving", ChatMessageType.Server);
|
||||
}
|
||||
}
|
||||
|
||||
private CoroutineHandle respawnPromptCoroutine;
|
||||
|
||||
public void ShowRespawnPromptIfNeeded(float delay = 5.0f)
|
||||
{
|
||||
if (!UseRespawnPrompt) { return; }
|
||||
if (CoroutineManager.IsCoroutineRunning(respawnPromptCoroutine) || GUIMessageBox.MessageBoxes.Any(mb => mb.UserData as string == "respawnquestionprompt"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
respawnPromptCoroutine = CoroutineManager.Invoke(() =>
|
||||
{
|
||||
if (Character.Controlled != null || (!(GameMain.GameSession?.IsRunning ?? false))) { return; }
|
||||
var respawnPrompt = new GUIMessageBox(
|
||||
TextManager.Get("tutorial.tryagainheader"), TextManager.Get("respawnquestionprompt"),
|
||||
new string[] { TextManager.Get("respawnquestionpromptrespawn"), TextManager.Get("respawnquestionpromptwait") })
|
||||
{
|
||||
UserData = "respawnquestionprompt"
|
||||
};
|
||||
respawnPrompt.Buttons[0].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: false);
|
||||
respawnPrompt.Close();
|
||||
return true;
|
||||
};
|
||||
respawnPrompt.Buttons[1].OnClicked += (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: true);
|
||||
respawnPrompt.Close();
|
||||
return true;
|
||||
};
|
||||
}, delay: delay);
|
||||
}
|
||||
|
||||
public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime)
|
||||
{
|
||||
bool respawnPromptPending = false;
|
||||
var newState = (State)msg.ReadRangedInteger(0, Enum.GetNames(typeof(State)).Length);
|
||||
|
||||
ForceSpawnInMainSub = false;
|
||||
switch (newState)
|
||||
{
|
||||
case State.Transporting:
|
||||
@@ -46,13 +88,14 @@ namespace Barotrauma.Networking
|
||||
if (CurrentState != newState)
|
||||
{
|
||||
CoroutineManager.StopCoroutines("forcepos");
|
||||
//CoroutineManager.StartCoroutine(ForceShuttleToPos(Level.Loaded.StartPosition - Vector2.UnitY * Level.ShaftHeight, 100.0f), "forcepos");
|
||||
}
|
||||
break;
|
||||
case State.Waiting:
|
||||
PendingRespawnCount = msg.ReadUInt16();
|
||||
RequiredRespawnCount = msg.ReadUInt16();
|
||||
respawnPromptPending = msg.ReadBoolean();
|
||||
RespawnCountdownStarted = msg.ReadBoolean();
|
||||
ForceSpawnInMainSub = msg.ReadBoolean();
|
||||
ResetShuttle();
|
||||
float newRespawnTime = msg.ReadSingle();
|
||||
RespawnTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, milliseconds: (int)(newRespawnTime * 1000.0f));
|
||||
@@ -63,6 +106,12 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
CurrentState = newState;
|
||||
|
||||
if (respawnPromptPending)
|
||||
{
|
||||
GameMain.Client.HasSpawned = true;
|
||||
ShowRespawnPromptIfNeeded(delay: 1.0f);
|
||||
}
|
||||
|
||||
msg.ReadPadBits();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +106,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void CreatePreviewWindow(GUIFrame frame)
|
||||
{
|
||||
frame.ClearChildren();
|
||||
|
||||
if (frame == null) { return; }
|
||||
|
||||
frame.ClearChildren();
|
||||
|
||||
var title = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), frame.RectTransform), ServerName, font: GUI.LargeFont)
|
||||
{
|
||||
ToolTip = ServerName
|
||||
|
||||
@@ -242,7 +242,8 @@ namespace Barotrauma.Networking
|
||||
textBlock.ClickableAreas.Add(new GUITextBlock.ClickableArea()
|
||||
{
|
||||
Data = data,
|
||||
OnClick = GameMain.NetLobbyScreen.SelectPlayer
|
||||
OnClick = GameMain.NetLobbyScreen.SelectPlayer,
|
||||
OnSecondaryClick = GameMain.NetLobbyScreen.ShowPlayerContextMenu
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,8 +128,18 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
cachedServerListInfo = null;
|
||||
|
||||
ServerName = incMsg.ReadString();
|
||||
ServerMessageText = incMsg.ReadString();
|
||||
NetFlags requiredFlags = (NetFlags)incMsg.ReadByte();
|
||||
|
||||
if (requiredFlags.HasFlag(NetFlags.Name))
|
||||
{
|
||||
ServerName = incMsg.ReadString();
|
||||
}
|
||||
|
||||
if (requiredFlags.HasFlag(NetFlags.Message))
|
||||
{
|
||||
ServerMessageText = incMsg.ReadString();
|
||||
}
|
||||
PlayStyle = (PlayStyle)incMsg.ReadByte();
|
||||
MaxPlayers = incMsg.ReadByte();
|
||||
HasPassword = incMsg.ReadBoolean();
|
||||
IsPublic = incMsg.ReadBoolean();
|
||||
@@ -139,9 +149,13 @@ namespace Barotrauma.Networking
|
||||
TickRate = incMsg.ReadRangedInteger(1, 60);
|
||||
GameMain.NetworkMember.TickRate = TickRate;
|
||||
|
||||
ReadExtraCargo(incMsg);
|
||||
|
||||
Voting.ClientRead(incMsg);
|
||||
if (requiredFlags.HasFlag(NetFlags.Properties))
|
||||
{
|
||||
ReadExtraCargo(incMsg);
|
||||
}
|
||||
|
||||
ReadHiddenSubs(incMsg);
|
||||
GameMain.NetLobbyScreen.UpdateSubVisibility();
|
||||
|
||||
bool isAdmin = incMsg.ReadBoolean();
|
||||
incMsg.ReadPadBits();
|
||||
@@ -151,7 +165,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? radiationEnabled = null, bool? useRespawnShuttle = null, int maxMissionCount = 0)
|
||||
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null)
|
||||
{
|
||||
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
||||
|
||||
@@ -202,6 +216,11 @@ namespace Barotrauma.Networking
|
||||
Whitelist.ClientAdminWrite(outMsg);
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.HiddenSubs))
|
||||
{
|
||||
WriteHiddenSubs(outMsg);
|
||||
}
|
||||
|
||||
if (dataToSend.HasFlag(NetFlags.Misc))
|
||||
{
|
||||
outMsg.WriteRangedInteger(missionTypeOr ?? (int)Barotrauma.MissionType.None, 0, (int)Barotrauma.MissionType.All);
|
||||
@@ -216,8 +235,6 @@ namespace Barotrauma.Networking
|
||||
|
||||
outMsg.Write(autoRestart != null);
|
||||
outMsg.Write(autoRestart ?? false);
|
||||
outMsg.Write(radiationEnabled ?? RadiationEnabled);
|
||||
outMsg.Write((byte)maxMissionCount + 1);
|
||||
|
||||
outMsg.WritePadBits();
|
||||
}
|
||||
@@ -288,7 +305,7 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
|
||||
//center frames
|
||||
GUIFrame innerFrame = new GUIFrame(new RectTransform(new Vector2(0.4f, 0.8f), settingsFrame.RectTransform, Anchor.Center) { MinSize = new Point(400, 430) });
|
||||
GUIFrame innerFrame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.85f), settingsFrame.RectTransform, Anchor.Center) { MinSize = new Point(400, 430) });
|
||||
GUILayoutGroup paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), innerFrame.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||
{
|
||||
Stretch = true,
|
||||
@@ -363,7 +380,7 @@ namespace Barotrauma.Networking
|
||||
selectionFrame.RectTransform.NonScaledSize = new Point(selectionFrame.Rect.Width, selectionFrame.Children.First().Rect.Height);
|
||||
selectionFrame.RectTransform.IsFixedSize = true;
|
||||
|
||||
GetPropertyData("SubSelectionMode").AssignGUIComponent(selectionMode);
|
||||
GetPropertyData(nameof(SubSelectionMode)).AssignGUIComponent(selectionMode);
|
||||
|
||||
// Mode Selection
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("ServerSettingsModeSelection"), font: GUI.SubHeadingFont);
|
||||
@@ -381,7 +398,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
selectionFrame.RectTransform.NonScaledSize = new Point(selectionFrame.Rect.Width, selectionFrame.Children.First().Rect.Height);
|
||||
selectionFrame.RectTransform.IsFixedSize = true;
|
||||
GetPropertyData("ModeSelectionMode").AssignGUIComponent(selectionMode);
|
||||
GetPropertyData(nameof(ModeSelectionMode)).AssignGUIComponent(selectionMode);
|
||||
|
||||
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), serverTab.RectTransform), style: "HorizontalLine");
|
||||
|
||||
@@ -389,7 +406,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
var voiceChatEnabled = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsVoiceChatEnabled"));
|
||||
GetPropertyData("VoiceChatEnabled").AssignGUIComponent(voiceChatEnabled);
|
||||
GetPropertyData(nameof(VoiceChatEnabled)).AssignGUIComponent(voiceChatEnabled);
|
||||
|
||||
//***********************************************
|
||||
|
||||
@@ -407,14 +424,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
};
|
||||
startIntervalSlider.Range = new Vector2(10.0f, 300.0f);
|
||||
GetPropertyData("AutoRestartInterval").AssignGUIComponent(startIntervalSlider);
|
||||
GetPropertyData(nameof(AutoRestartInterval)).AssignGUIComponent(startIntervalSlider);
|
||||
startIntervalSlider.OnMoved(startIntervalSlider, startIntervalSlider.BarScroll);
|
||||
|
||||
//***********************************************
|
||||
|
||||
var startWhenClientsReady = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsStartWhenClientsReady"));
|
||||
GetPropertyData("StartWhenClientsReady").AssignGUIComponent(startWhenClientsReady);
|
||||
GetPropertyData(nameof(StartWhenClientsReady)).AssignGUIComponent(startWhenClientsReady);
|
||||
|
||||
CreateLabeledSlider(serverTab, "ServerSettingsStartWhenClientsReadyRatio", out GUIScrollBar slider, out GUITextBlock sliderLabel);
|
||||
string clientsReadyRequiredLabel = sliderLabel.Text;
|
||||
@@ -425,19 +442,19 @@ namespace Barotrauma.Networking
|
||||
((GUITextBlock)scrollBar.UserData).Text = clientsReadyRequiredLabel.Replace("[percentage]", ((int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f)).ToString());
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("StartWhenClientsReadyRatio").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(StartWhenClientsReadyRatio)).AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
//***********************************************
|
||||
|
||||
var allowSpecBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsAllowSpectating"));
|
||||
GetPropertyData("AllowSpectating").AssignGUIComponent(allowSpecBox);
|
||||
GetPropertyData(nameof(AllowSpectating)).AssignGUIComponent(allowSpecBox);
|
||||
|
||||
var shareSubsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsShareSubFiles"));
|
||||
GetPropertyData("AllowFileTransfers").AssignGUIComponent(shareSubsBox);
|
||||
GetPropertyData(nameof(AllowFileTransfers)).AssignGUIComponent(shareSubsBox);
|
||||
|
||||
var randomizeLevelBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsRandomizeSeed"));
|
||||
GetPropertyData("RandomizeSeed").AssignGUIComponent(randomizeLevelBox);
|
||||
GetPropertyData(nameof(RandomizeSeed)).AssignGUIComponent(randomizeLevelBox);
|
||||
|
||||
var saveLogsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), serverTab.RectTransform), TextManager.Get("ServerSettingsSaveLogs"))
|
||||
{
|
||||
@@ -448,7 +465,7 @@ namespace Barotrauma.Networking
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GetPropertyData("SaveServerLogs").AssignGUIComponent(saveLogsBox);
|
||||
GetPropertyData(nameof(SaveServerLogs)).AssignGUIComponent(saveLogsBox);
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// game settings
|
||||
@@ -480,20 +497,20 @@ namespace Barotrauma.Networking
|
||||
selectionPlayStyle.AddRadioButton((int)playStyle, selectionTick);
|
||||
playStyleTickBoxes.Add(selectionTick);
|
||||
}
|
||||
GetPropertyData("PlayStyle").AssignGUIComponent(selectionPlayStyle);
|
||||
GetPropertyData(nameof(PlayStyle)).AssignGUIComponent(selectionPlayStyle);
|
||||
GUITextBlock.AutoScaleAndNormalize(playStyleTickBoxes.Select(t => t.TextBlock));
|
||||
playstyleList.RectTransform.MinSize = new Point(0, (int)(playstyleList.Content.Children.First().Rect.Height * 2.0f + playstyleList.Padding.Y + playstyleList.Padding.W));
|
||||
|
||||
var endVoteBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsEndRoundVoting"));
|
||||
GetPropertyData("AllowEndVoting").AssignGUIComponent(endVoteBox);
|
||||
GetPropertyData(nameof(AllowEndVoting)).AssignGUIComponent(endVoteBox);
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsEndRoundVotesRequired", out slider, out sliderLabel);
|
||||
|
||||
string endRoundLabel = sliderLabel.Text;
|
||||
slider.Step = 0.2f;
|
||||
slider.Range = new Vector2(0.5f, 1.0f);
|
||||
GetPropertyData("EndVoteRequiredRatio").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(EndVoteRequiredRatio)).AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = endRoundLabel + " " + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
@@ -503,13 +520,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
var respawnBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRespawning"));
|
||||
GetPropertyData("AllowRespawn").AssignGUIComponent(respawnBox);
|
||||
GetPropertyData(nameof(AllowRespawn)).AssignGUIComponent(respawnBox);
|
||||
|
||||
CreateLabeledSlider(roundsTab, "ServerSettingsRespawnInterval", out slider, out sliderLabel);
|
||||
string intervalLabel = sliderLabel.Text;
|
||||
slider.Range = new Vector2(10.0f, 600.0f);
|
||||
slider.StepValue = 10.0f;
|
||||
GetPropertyData("RespawnInterval").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(RespawnInterval)).AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
GUITextBlock text = scrollBar.UserData as GUITextBlock;
|
||||
@@ -518,18 +535,26 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var minRespawnText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), "")
|
||||
var respawnLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), roundsTab.RectTransform),
|
||||
isHorizontal: true);
|
||||
|
||||
var minRespawnLayout
|
||||
= new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), respawnLayout.RectTransform));
|
||||
|
||||
var minRespawnText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), minRespawnLayout.RectTransform), "")
|
||||
{
|
||||
ToolTip = TextManager.Get("ServerSettingsMinRespawnToolTip")
|
||||
};
|
||||
|
||||
string minRespawnLabel = TextManager.Get("ServerSettingsMinRespawn") + " ";
|
||||
CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel);
|
||||
CreateLabeledSlider(minRespawnLayout, "", out slider, out sliderLabel);
|
||||
sliderLabel.RectTransform.RelativeSize = Vector2.Zero;
|
||||
slider.RectTransform.RelativeSize = new Vector2(1.0f, 0.5f);
|
||||
slider.ToolTip = minRespawnText.RawToolTip;
|
||||
slider.UserData = minRespawnText;
|
||||
slider.Step = 0.1f;
|
||||
slider.Range = new Vector2(0.0f, 1.0f);
|
||||
GetPropertyData("MinRespawnRatio").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(MinRespawnRatio)).AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
((GUITextBlock)scrollBar.UserData).Text = minRespawnLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
@@ -537,13 +562,18 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
slider.OnMoved(slider, MinRespawnRatio);
|
||||
|
||||
var respawnDurationText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), "")
|
||||
var respawnDurationLayout
|
||||
= new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), respawnLayout.RectTransform));
|
||||
|
||||
var respawnDurationText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), respawnDurationLayout.RectTransform), "")
|
||||
{
|
||||
ToolTip = TextManager.Get("ServerSettingsRespawnDurationToolTip")
|
||||
};
|
||||
|
||||
string respawnDurationLabel = TextManager.Get("ServerSettingsRespawnDuration") + " ";
|
||||
CreateLabeledSlider(roundsTab, "", out slider, out sliderLabel);
|
||||
CreateLabeledSlider(respawnDurationLayout, "", out slider, out sliderLabel);
|
||||
sliderLabel.RectTransform.RelativeSize = Vector2.Zero;
|
||||
slider.RectTransform.RelativeSize = new Vector2(1.0f, 0.5f);
|
||||
slider.ToolTip = respawnDurationText.RawToolTip;
|
||||
slider.UserData = respawnDurationText;
|
||||
slider.Step = 0.1f;
|
||||
@@ -556,7 +586,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
return value <= 0.0f ? 1.0f : (value - scrollBar.Range.X) / (scrollBar.Range.Y - scrollBar.Range.X);
|
||||
};
|
||||
GetPropertyData("MaxTransportTime").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(MaxTransportTime)).AssignGUIComponent(slider);
|
||||
slider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
|
||||
{
|
||||
if (barScroll == 1.0f)
|
||||
@@ -572,14 +602,34 @@ namespace Barotrauma.Networking
|
||||
};
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
|
||||
var losModeLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform),
|
||||
TextManager.Get("LosEffect"));
|
||||
|
||||
var losModeRadioButtonLayout
|
||||
= new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), roundsTab.RectTransform),
|
||||
isHorizontal: true)
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
var losModeRadioButtonGroup = new GUIRadioButtonGroup();
|
||||
LosMode[] losModes = (LosMode[])Enum.GetValues(typeof(LosMode));
|
||||
for (int i = 0; i < losModes.Length; i++)
|
||||
{
|
||||
var losTick = new GUITickBox(new RectTransform(new Vector2(0.3f, 1.0f), losModeRadioButtonLayout.RectTransform), TextManager.Get($"LosMode{losModes[i]}"), font: GUI.SmallFont, style: "GUIRadioButton");
|
||||
losModeRadioButtonGroup.AddRadioButton(i, losTick);
|
||||
}
|
||||
GetPropertyData(nameof(LosMode)).AssignGUIComponent(losModeRadioButtonGroup);
|
||||
|
||||
var traitorsMinPlayerCount = CreateLabeledNumberInput(roundsTab, "ServerSettingsTraitorsMinPlayerCount", 1, 16, "ServerSettingsTraitorsMinPlayerCountToolTip");
|
||||
GetPropertyData("TraitorsMinPlayerCount").AssignGUIComponent(traitorsMinPlayerCount);
|
||||
GetPropertyData(nameof(TraitorsMinPlayerCount)).AssignGUIComponent(traitorsMinPlayerCount);
|
||||
|
||||
var ragdollButtonBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsAllowRagdollButton"));
|
||||
GetPropertyData("AllowRagdollButton").AssignGUIComponent(ragdollButtonBox);
|
||||
GetPropertyData(nameof(AllowRagdollButton)).AssignGUIComponent(ragdollButtonBox);
|
||||
|
||||
var disableBotConversationsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), roundsTab.RectTransform), TextManager.Get("ServerSettingsDisableBotConversations"));
|
||||
GetPropertyData("DisableBotConversations").AssignGUIComponent(disableBotConversationsBox);
|
||||
GetPropertyData(nameof(DisableBotConversations)).AssignGUIComponent(disableBotConversationsBox);
|
||||
|
||||
var buttonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), roundsTab.RectTransform), isHorizontal: true)
|
||||
{
|
||||
@@ -669,7 +719,6 @@ namespace Barotrauma.Networking
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
|
||||
if (ip.InventoryIcon != null || ip.sprite != null)
|
||||
{
|
||||
GUIImage img = new GUIImage(new RectTransform(new Point(itemFrame.Rect.Height), itemFrame.RectTransform),
|
||||
@@ -692,7 +741,7 @@ namespace Barotrauma.Networking
|
||||
GUINumberInput.NumberType.Int, textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
MinValueInt = 0,
|
||||
MaxValueInt = 100,
|
||||
MaxValueInt = MaxExtraCargoItemsOfType,
|
||||
IntValue = cargoVal
|
||||
};
|
||||
amountInput.OnValueChanged += (numberInput) =>
|
||||
@@ -700,16 +749,26 @@ namespace Barotrauma.Networking
|
||||
if (ExtraCargo.ContainsKey(ip))
|
||||
{
|
||||
ExtraCargo[ip] = numberInput.IntValue;
|
||||
if (numberInput.IntValue <= 0) ExtraCargo.Remove(ip);
|
||||
if (numberInput.IntValue <= 0) { ExtraCargo.Remove(ip); }
|
||||
}
|
||||
else
|
||||
else if (ExtraCargo.Keys.Count() < MaxExtraCargoItemTypes)
|
||||
{
|
||||
ExtraCargo.Add(ip, numberInput.IntValue);
|
||||
}
|
||||
numberInput.IntValue = ExtraCargo.ContainsKey(ip) ? ExtraCargo[ip] : 0;
|
||||
CoroutineManager.Invoke(() =>
|
||||
{
|
||||
foreach (var child in cargoFrame.Content.GetAllChildren())
|
||||
{
|
||||
if (child.GetChild<GUINumberInput>() is GUINumberInput otherNumberInput)
|
||||
{
|
||||
otherNumberInput.PlusButton.Enabled = ExtraCargo.Keys.Count() < MaxExtraCargoItemTypes && otherNumberInput.IntValue < otherNumberInput.MaxValueInt;
|
||||
}
|
||||
}
|
||||
}, 0.0f);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// antigriefing
|
||||
//--------------------------------------------------------------------------------
|
||||
@@ -729,35 +788,35 @@ namespace Barotrauma.Networking
|
||||
|
||||
var allowFriendlyFire = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowFriendlyFire"));
|
||||
GetPropertyData("AllowFriendlyFire").AssignGUIComponent(allowFriendlyFire);
|
||||
GetPropertyData(nameof(AllowFriendlyFire)).AssignGUIComponent(allowFriendlyFire);
|
||||
|
||||
var killableNPCs = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsKillableNPCs"));
|
||||
GetPropertyData("KillableNPCs").AssignGUIComponent(killableNPCs);
|
||||
GetPropertyData(nameof(KillableNPCs)).AssignGUIComponent(killableNPCs);
|
||||
|
||||
var destructibleOutposts = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsDestructibleOutposts"));
|
||||
GetPropertyData("DestructibleOutposts").AssignGUIComponent(destructibleOutposts);
|
||||
GetPropertyData(nameof(DestructibleOutposts)).AssignGUIComponent(destructibleOutposts);
|
||||
|
||||
var lockAllDefaultWires = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsLockAllDefaultWires"));
|
||||
GetPropertyData("LockAllDefaultWires").AssignGUIComponent(lockAllDefaultWires);
|
||||
GetPropertyData(nameof(LockAllDefaultWires)).AssignGUIComponent(lockAllDefaultWires);
|
||||
|
||||
var allowRewiring = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowRewiring"));
|
||||
GetPropertyData("AllowRewiring").AssignGUIComponent(allowRewiring);
|
||||
GetPropertyData(nameof(AllowRewiring)).AssignGUIComponent(allowRewiring);
|
||||
|
||||
var allowWifiChatter = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowWifiChat"));
|
||||
GetPropertyData("AllowLinkingWifiToChat").AssignGUIComponent(allowWifiChatter);
|
||||
GetPropertyData(nameof(AllowLinkingWifiToChat)).AssignGUIComponent(allowWifiChatter);
|
||||
|
||||
var allowDisguises = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowDisguises"));
|
||||
GetPropertyData("AllowDisguises").AssignGUIComponent(allowDisguises);
|
||||
GetPropertyData(nameof(AllowDisguises)).AssignGUIComponent(allowDisguises);
|
||||
|
||||
var voteKickBox = new GUITickBox(new RectTransform(new Vector2(0.48f, 0.05f), tickBoxContainer.Content.RectTransform),
|
||||
TextManager.Get("ServerSettingsAllowVoteKick"));
|
||||
GetPropertyData("AllowVoteKick").AssignGUIComponent(voteKickBox);
|
||||
GetPropertyData(nameof(AllowVoteKick)).AssignGUIComponent(voteKickBox);
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(tickBoxContainer.Content.Children.Select(c => ((GUITickBox)c).TextBlock));
|
||||
|
||||
@@ -772,7 +831,7 @@ namespace Barotrauma.Networking
|
||||
((GUITextBlock)scrollBar.UserData).Text = votesRequiredLabel + (int)MathUtils.Round(scrollBar.BarScrollValue * 100.0f, 10.0f) + " %";
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("KickVoteRequiredRatio").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(KickVoteRequiredRatio)).AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
CreateLabeledSlider(antigriefingTab, "ServerSettingsAutobanTime", out slider, out sliderLabel);
|
||||
@@ -784,13 +843,13 @@ namespace Barotrauma.Networking
|
||||
((GUITextBlock)scrollBar.UserData).Text = autobanLabel + ToolBox.SecondsToReadableTime(scrollBar.BarScrollValue);
|
||||
return true;
|
||||
};
|
||||
GetPropertyData("AutoBanTime").AssignGUIComponent(slider);
|
||||
GetPropertyData(nameof(AutoBanTime)).AssignGUIComponent(slider);
|
||||
slider.OnMoved(slider, slider.BarScroll);
|
||||
|
||||
var wrongPasswordBanBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform), TextManager.Get("ServerSettingsBanAfterWrongPassword"));
|
||||
GetPropertyData("BanAfterWrongPassword").AssignGUIComponent(wrongPasswordBanBox);
|
||||
GetPropertyData(nameof(BanAfterWrongPassword)).AssignGUIComponent(wrongPasswordBanBox);
|
||||
var allowedPasswordRetries = CreateLabeledNumberInput(antigriefingTab, "ServerSettingsPasswordRetriesBeforeBan", 0, 10);
|
||||
GetPropertyData("MaxPasswordRetriesBeforeBan").AssignGUIComponent(allowedPasswordRetries);
|
||||
GetPropertyData(nameof(MaxPasswordRetriesBeforeBan)).AssignGUIComponent(allowedPasswordRetries);
|
||||
wrongPasswordBanBox.OnSelected += (tb) =>
|
||||
{
|
||||
allowedPasswordRetries.Enabled = tb.Selected;
|
||||
@@ -800,7 +859,7 @@ namespace Barotrauma.Networking
|
||||
// karma --------------------------------------------------------------------------
|
||||
|
||||
var karmaBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform), TextManager.Get("ServerSettingsUseKarma"));
|
||||
GetPropertyData("KarmaEnabled").AssignGUIComponent(karmaBox);
|
||||
GetPropertyData(nameof(KarmaEnabled)).AssignGUIComponent(karmaBox);
|
||||
|
||||
karmaPresetDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), antigriefingTab.RectTransform));
|
||||
foreach (string karmaPreset in GameMain.NetworkMember.KarmaManager.Presets.Keys)
|
||||
@@ -871,6 +930,7 @@ namespace Barotrauma.Networking
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
Whitelist.CreateWhiteListFrame(settingsTabs[(int)SettingsTab.Whitelist]);
|
||||
Whitelist.localEnabled = Whitelist.Enabled;
|
||||
}
|
||||
|
||||
private void CreateLabeledSlider(GUIComponent parent, string labelTag, out GUIScrollBar slider, out GUITextBlock label)
|
||||
|
||||
@@ -147,7 +147,14 @@ namespace Barotrauma.Steam
|
||||
|
||||
if (currentLobby == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to create Steam lobby");
|
||||
DebugConsole.ThrowError("Failed to create Steam lobby: returned lobby was null");
|
||||
lobbyState = LobbyState.NotConnected;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentLobby.Value.Result != Steamworks.Result.OK)
|
||||
{
|
||||
DebugConsole.ThrowError($"Failed to create Steam lobby: result was {currentLobby.Value.Result}");
|
||||
lobbyState = LobbyState.NotConnected;
|
||||
return;
|
||||
}
|
||||
@@ -525,18 +532,6 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
|
||||
#region Connecting to servers
|
||||
private static Steamworks.AuthTicket currentTicket = null;
|
||||
public static Steamworks.AuthTicket GetAuthSessionTicket()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
currentTicket?.Cancel();
|
||||
currentTicket = Steamworks.SteamUser.GetAuthSessionTicket();
|
||||
return currentTicket;
|
||||
}
|
||||
|
||||
public static Steamworks.BeginAuthResult StartAuthSession(byte[] authTicketData, ulong clientSteamID)
|
||||
{
|
||||
@@ -884,9 +879,9 @@ namespace Barotrauma.Steam
|
||||
|
||||
catch (Exception e)
|
||||
{
|
||||
string errorMsg = "Failed to save workshop item preview image to \"" + previewImagePath + "\" when creating workshop item staging folder.";
|
||||
string errorMsg = "Failed to save workshop item preview image when creating workshop item staging folder.";
|
||||
GameAnalyticsManager.AddErrorEventOnce("SteamManager.CreateWorkshopItemStaging:WriteAllBytesFailed" + previewImagePath,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + e.Message);
|
||||
GameAnalyticsManager.ErrorSeverity.Error, errorMsg + "\n" + e.Message);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -935,7 +930,7 @@ namespace Barotrauma.Steam
|
||||
return workshopPublishStatus;
|
||||
}
|
||||
|
||||
private static IEnumerable<object> PublishItem(WorkshopPublishStatus workshopPublishStatus)
|
||||
private static IEnumerable<CoroutineStatus> PublishItem(WorkshopPublishStatus workshopPublishStatus)
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
@@ -1434,8 +1429,8 @@ namespace Barotrauma.Steam
|
||||
"\" not found. Could not combine path (" + (item.Directory ?? "directory name empty") + ").";
|
||||
DebugConsole.ThrowError(errorMessage);
|
||||
GameAnalyticsManager.AddErrorEventOnce("SteamManager.CheckWorkshopItemInstalled:PathCombineException" + item.Title,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
errorMessage);
|
||||
GameAnalyticsManager.ErrorSeverity.Error,
|
||||
"Metadata file for a Workshop item not found. Could not combine path.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1567,8 +1562,8 @@ namespace Barotrauma.Steam
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce(
|
||||
"SteamManager.AutoUpdateWorkshopItems:" + e.Message,
|
||||
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
"Failed to autoupdate workshop item \"" + item.Title + "\". " + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
|
||||
GameAnalyticsManager.ErrorSeverity.Error,
|
||||
"Failed to autoupdate workshop item. " + e.Message + "\n" + e.StackTrace.CleanupStackTrace());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Barotrauma.Networking
|
||||
UserData = "capturedevicenotfound"
|
||||
};
|
||||
}
|
||||
GameAnalyticsManager.AddErrorEventOnce("Alc.CaptureDeviceOpenFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
|
||||
GameAnalyticsManager.AddErrorEventOnce("Alc.CaptureDeviceOpenFailed", GameAnalyticsManager.ErrorSeverity.Error,
|
||||
"Alc.CaptureDeviceOpen(" + deviceName + ") failed. Error code: " + errorCode);
|
||||
GameMain.Config.VoiceSetting = GameSettings.VoiceMode.Disabled;
|
||||
Instance?.Dispose();
|
||||
|
||||
@@ -17,7 +17,11 @@ namespace Barotrauma
|
||||
allowSubVoting = value;
|
||||
GameMain.NetLobbyScreen.SubList.Enabled = value ||
|
||||
(GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.SelectSub));
|
||||
GameMain.NetLobbyScreen.Frame.FindChild("subvotes", true).Visible = value;
|
||||
var subVotesLabel = GameMain.NetLobbyScreen.Frame.FindChild("subvotes", true) as GUITextBlock;
|
||||
subVotesLabel.Visible = value;
|
||||
var subVisButton = GameMain.NetLobbyScreen.SubVisibilityButton;
|
||||
subVisButton.RectTransform.AbsoluteOffset
|
||||
= new Point(value ? (int)(subVotesLabel.TextSize.X + subVisButton.Rect.Width) : 0, 0);
|
||||
|
||||
UpdateVoteTexts(null, VoteType.Sub);
|
||||
GameMain.NetLobbyScreen.SubList.Deselect();
|
||||
@@ -66,10 +70,10 @@ namespace Barotrauma
|
||||
|
||||
if (clients == null) { return; }
|
||||
|
||||
List<Pair<object, int>> voteList = GetVoteList(voteType, clients);
|
||||
foreach (Pair<object, int> votable in voteList)
|
||||
IReadOnlyDictionary<object, int> voteList = GetVoteCounts<object>(voteType, clients);
|
||||
foreach (KeyValuePair<object, int> votable in voteList)
|
||||
{
|
||||
SetVoteText(listBox, votable.First, votable.Second);
|
||||
SetVoteText(listBox, votable.Key, votable.Value);
|
||||
}
|
||||
break;
|
||||
case VoteType.StartRound:
|
||||
|
||||
@@ -56,17 +56,12 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
nameBox.Enabled = box.Selected;
|
||||
ipBox.Enabled = box.Selected;
|
||||
addNewButton.Enabled = box.Selected;
|
||||
|
||||
addNewButton.Enabled = box.Selected && !string.IsNullOrEmpty(ipBox.Text) && !string.IsNullOrEmpty(nameBox.Text);
|
||||
localEnabled = box.Selected;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
localEnabled = Enabled;
|
||||
|
||||
var listBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.7f), whitelistFrame.RectTransform));
|
||||
foreach (WhiteListedPlayer wlp in whitelistedPlayers)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user