Build 0.21.1.0

This commit is contained in:
Markus Isberg
2023-01-13 18:10:35 +02:00
parent 2f7205fb4b
commit 697ec52120
155 changed files with 2423 additions and 1237 deletions
@@ -66,9 +66,20 @@ namespace Barotrauma.Networking
};
var addressOrAccountId = bannedPlayer.AddressOrAccountId;
GUITextBlock textBlock = new GUITextBlock(
new RectTransform(new Vector2(0.5f, 1.0f), topArea.RectTransform),
bannedPlayer.Name + " (" + addressOrAccountId + ")") { CanBeFocused = true };
string nameText = bannedPlayer.Name;
if (addressOrAccountId.TryCast(out Address address))
{
nameText += $" ({address.StringRepresentation})";
}
else if (addressOrAccountId.TryCast(out AccountId accountId))
{
nameText += $" ({accountId.StringRepresentation})";
}
GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), topArea.RectTransform), nameText)
{
CanBeFocused = true
};
textBlock.RectTransform.MinSize = new Point(
(int)textBlock.Font.MeasureString(textBlock.Text.SanitizedValue).X, 0);
@@ -106,7 +117,7 @@ namespace Barotrauma.Networking
private bool RemoveBan(GUIButton button, object obj)
{
if (!(obj is BannedPlayer banned)) { return false; }
if (obj is not BannedPlayer banned) { return false; }
localRemovedBans.Add(banned.UniqueIdentifier);
RecreateBanFrame();
@@ -34,6 +34,7 @@ namespace Barotrauma.Networking
catch
{
DebugConsole.ThrowError($"Failed to start ChildServerRelay Process. File: {processInfo.FileName}, arguments: {processInfo.Arguments}");
ForceShutDown();
throw;
}
@@ -522,7 +522,7 @@ namespace Barotrauma.Networking
if (GameStarted && Screen.Selected == GameMain.GameScreen)
{
EndVoteTickBox.Visible = ServerSettings.AllowEndVoting && HasSpawned && !(GameMain.GameSession?.GameMode is CampaignMode);
EndVoteTickBox.Visible = ServerSettings.AllowEndVoting && HasSpawned;
RespawnManager?.Update(deltaTime);
@@ -1102,11 +1102,7 @@ namespace Barotrauma.Networking
VoipClient = new VoipClient(this, ClientPeer);
//if we're still in the game, roundsummary or lobby screen, we don't need to redownload the mods
if (!(Screen.Selected is GameScreen) && !(Screen.Selected is RoundSummaryScreen) && !(Screen.Selected is NetLobbyScreen))
{
GameMain.ModDownloadScreen.Select();
}
else
if (Screen.Selected is GameScreen or RoundSummaryScreen or NetLobbyScreen)
{
EntityEventManager.ClearSelf();
foreach (Character c in Character.CharacterList)
@@ -1114,6 +1110,10 @@ namespace Barotrauma.Networking
c.ResetNetState();
}
}
else
{
GameMain.ModDownloadScreen.Select();
}
chatBox.InputBox.Enabled = true;
if (GameMain.NetLobbyScreen?.ChatInput != null)
@@ -1535,8 +1535,9 @@ namespace Barotrauma.Networking
roundInitStatus = RoundInitStatus.WaitingForStartGameFinalize;
DateTime? timeOut = null;
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
TimeSpan timeOutDuration = new TimeSpan(0, 0, seconds: 30);
DateTime timeOut = DateTime.Now + timeOutDuration;
DateTime requestFinalizeTime = DateTime.Now;
TimeSpan requestFinalizeInterval = new TimeSpan(0, 0, 2);
IWriteMessage msg = new WriteOnlyMessage();
@@ -1545,11 +1546,15 @@ namespace Barotrauma.Networking
GUIMessageBox interruptPrompt = null;
while (true)
if (includesFinalize)
{
try
ReadStartGameFinalize(inc);
}
else
{
while (true)
{
if (timeOut.HasValue)
try
{
if (DateTime.Now > requestFinalizeTime)
{
@@ -1583,41 +1588,30 @@ namespace Barotrauma.Networking
return true;
};
}
}
else
{
if (includesFinalize)
if (!connected)
{
ReadStartGameFinalize(inc);
roundInitStatus = RoundInitStatus.Interrupted;
break;
}
//wait for up to 30 seconds for the server to send the STARTGAMEFINALIZE message
timeOut = DateTime.Now + timeOutDuration;
if (roundInitStatus != RoundInitStatus.WaitingForStartGameFinalize) { break; }
}
if (!connected)
catch (Exception e)
{
roundInitStatus = RoundInitStatus.Interrupted;
DebugConsole.ThrowError("There was an error initializing the round.", e, true);
roundInitStatus = RoundInitStatus.Error;
break;
}
if (roundInitStatus != RoundInitStatus.WaitingForStartGameFinalize) { break; }
//waiting for a STARTGAMEFINALIZE message
yield return CoroutineStatus.Running;
}
catch (Exception e)
{
DebugConsole.ThrowError("There was an error initializing the round.", e, true);
roundInitStatus = RoundInitStatus.Error;
break;
}
//waiting for a STARTGAMEFINALIZE message
yield return CoroutineStatus.Running;
}
interruptPrompt?.Close();
interruptPrompt = null;
if (roundInitStatus != RoundInitStatus.Started)
{
if (roundInitStatus != RoundInitStatus.Interrupted)
@@ -1767,7 +1761,7 @@ namespace Barotrauma.Networking
{
string subName = inc.ReadString();
string subHash = inc.ReadString();
byte subClass = inc.ReadByte();
SubmarineClass subClass = (SubmarineClass)inc.ReadByte();
bool isShuttle = inc.ReadBoolean();
bool requiredContentPackagesInstalled = inc.ReadBoolean();
@@ -1776,7 +1770,7 @@ namespace Barotrauma.Networking
{
matchingSub = new SubmarineInfo(Path.Combine(SaveUtil.SubmarineDownloadFolder, subName) + ".sub", subHash, tryLoad: false)
{
SubmarineClass = (SubmarineClass)subClass
SubmarineClass = subClass
};
if (isShuttle) { matchingSub.AddTag(SubmarineTag.Shuttle); }
}
@@ -2009,10 +2003,10 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
GameMain.NetLobbyScreen.SetMissionType(missionType);
if (!allowModeVoting) GameMain.NetLobbyScreen.SelectMode(modeIndex);
GameMain.NetLobbyScreen.SelectMode(modeIndex);
if (isInitialUpdate && GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
{
if (GameMain.Client.IsServerOwner) RequestSelectMode(modeIndex);
if (GameMain.Client.IsServerOwner) { RequestSelectMode(modeIndex); }
}
if (GameMain.NetLobbyScreen.SelectedMode == GameModePreset.MultiPlayerCampaign)
@@ -2101,13 +2095,12 @@ namespace Barotrauma.Networking
case ServerNetSegment.EntityPosition:
inc.ReadPadBits(); //padding is required here to make sure any padding bits within tempBuffer are read correctly
bool isItem = inc.ReadBoolean(); inc.ReadPadBits();
UInt32 incomingUintIdentifier = inc.ReadUInt32();
UInt16 id = inc.ReadUInt16();
uint msgLength = inc.ReadVariableUInt32();
int msgEndPos = (int)(inc.BitPosition + msgLength * 8);
var entity = Entity.FindEntityByID(id) as IServerPositionSync;
var header = INetSerializableStruct.Read<EntityPositionHeader>(inc);
var entity = Entity.FindEntityByID(header.EntityId) as IServerPositionSync;
if (msgEndPos > inc.LengthBits)
{
DebugConsole.ThrowError($"Error while reading a position update for the entity \"({entity?.ToString() ?? "null"})\". Message length exceeds the size of the buffer.");
@@ -2117,15 +2110,15 @@ namespace Barotrauma.Networking
debugEntityList.Add(entity);
if (entity != null)
{
if (entity is Item != isItem)
if (entity is Item != header.IsItem)
{
DebugConsole.AddWarning($"Received a potentially invalid ENTITY_POSITION message. Entity type does not match (server entity is {(isItem ? "an item" : "not an item")}, client entity is {(entity?.GetType().ToString() ?? "null")}). Ignoring the message...");
DebugConsole.AddWarning($"Received a potentially invalid ENTITY_POSITION message. Entity type does not match (server entity is {(header.IsItem ? "an item" : "not an item")}, client entity is {(entity?.GetType().ToString() ?? "null")}). Ignoring the message...");
}
else if (entity is MapEntity { Prefab: { UintIdentifier: { } uintIdentifier } } me &&
uintIdentifier != incomingUintIdentifier)
else if (entity is MapEntity { Prefab.UintIdentifier: var uintIdentifier } me &&
uintIdentifier != header.PrefabUintIdentifier)
{
DebugConsole.AddWarning($"Received a potentially invalid ENTITY_POSITION message."
+$"Entity identifier does not match (server entity is {MapEntityPrefab.List.FirstOrDefault(p => p.UintIdentifier == incomingUintIdentifier)?.Identifier.Value ?? "[not found]"}, "
+$"Entity identifier does not match (server entity is {MapEntityPrefab.List.FirstOrDefault(p => p.UintIdentifier == header.PrefabUintIdentifier)?.Identifier.Value ?? "[not found]"}, "
+$"client entity is {me.Prefab.Identifier}). Ignoring the message...");
}
else
@@ -2133,7 +2126,6 @@ namespace Barotrauma.Networking
entity.ClientReadPosition(inc, sendingTime);
}
}
//force to the correct position in case the entity doesn't exist
//or the message wasn't read correctly for whatever reason
inc.BitPosition = msgEndPos;
@@ -2144,7 +2136,7 @@ namespace Barotrauma.Networking
break;
case ServerNetSegment.EntityEvent:
case ServerNetSegment.EntityEventInitial:
if (!EntityEventManager.Read(segment, inc, sendingTime, debugEntityList))
if (!EntityEventManager.Read(segment, inc, sendingTime))
{
return SegmentTableReader<ServerNetSegment>.BreakSegmentReading.Yes;
}
@@ -2413,7 +2405,9 @@ namespace Barotrauma.Networking
var newSub = new SubmarineInfo(transfer.FilePath);
if (newSub.IsFileCorrupted) { return; }
var existingSubs = SubmarineInfo.SavedSubmarines.Where(s => s.Name == newSub.Name && s.MD5Hash.StringRepresentation == newSub.MD5Hash.StringRepresentation).ToList();
var existingSubs = SubmarineInfo.SavedSubmarines
.Where(s => s.Name == newSub.Name && s.MD5Hash == newSub.MD5Hash)
.ToList();
foreach (SubmarineInfo existingSub in existingSubs)
{
existingSub.Dispose();
@@ -2472,12 +2466,13 @@ namespace Barotrauma.Networking
}
// Replace a submarine dud with the downloaded version
SubmarineInfo existingServerSub = ServerSubmarines.Find(s => s.Name == newSub.Name && s.MD5Hash?.StringRepresentation == newSub.MD5Hash?.StringRepresentation);
SubmarineInfo existingServerSub = ServerSubmarines.Find(s =>
s.Name == newSub.Name
&& s.MD5Hash == newSub.MD5Hash);
if (existingServerSub != null)
{
int existingIndex = ServerSubmarines.IndexOf(existingServerSub);
ServerSubmarines.RemoveAt(existingIndex);
ServerSubmarines.Insert(existingIndex, newSub);
ServerSubmarines[existingIndex] = newSub;
existingServerSub.Dispose();
}
@@ -2798,7 +2793,6 @@ namespace Barotrauma.Networking
/// </summary>
public void RequestSelectMode(int modeIndex)
{
if (!HasPermission(ClientPermissions.SelectMode)) return;
if (modeIndex < 0 || modeIndex >= GameMain.NetLobbyScreen.ModeList.Content.CountChildren)
{
DebugConsole.ThrowError("Gamemode index out of bounds (" + modeIndex + ")\n" + Environment.StackTrace.CleanupStackTrace());
@@ -2852,13 +2846,14 @@ namespace Barotrauma.Networking
/// <summary>
/// Tell the server to end the round (permission required)
/// </summary>
public void RequestRoundEnd(bool save)
public void RequestRoundEnd(bool save, bool quitCampaign = false)
{
IWriteMessage msg = new WriteOnlyMessage();
msg.WriteByte((byte)ClientPacketHeader.SERVER_COMMAND);
msg.WriteUInt16((UInt16)ClientPermissions.ManageRound);
msg.WriteBoolean(true); //indicates round end
msg.WriteBoolean(save);
msg.WriteBoolean(quitCampaign);
ClientPeer.Send(msg, DeliveryMethod.Reliable);
}
@@ -109,16 +109,15 @@ namespace Barotrauma.Networking
private UInt16? firstNewID;
private readonly List<IServerSerializable> tempEntityList = new List<IServerSerializable>();
/// <summary>
/// Read the events from the message, ignoring ones we've already received. Returns false if reading the events fails.
/// </summary>
public bool Read(ServerNetSegment type, IReadMessage msg, float sendingTime, List<IServerSerializable> entities)
public bool Read(ServerNetSegment type, IReadMessage msg, float sendingTime)
{
UInt16 unreceivedEntityEventCount = 0;
if (type == ServerNetSegment.EntityEventInitial)
{
unreceivedEntityEventCount = msg.ReadUInt16();
UInt16 unreceivedEntityEventCount = msg.ReadUInt16();
firstNewID = msg.ReadUInt16();
if (GameSettings.CurrentConfig.VerboseLogging)
@@ -143,7 +142,7 @@ namespace Barotrauma.Networking
}
}
entities.Clear();
tempEntityList.Clear();
msg.ReadPadBits();
UInt16 firstEventID = msg.ReadUInt16();
@@ -156,9 +155,9 @@ namespace Barotrauma.Networking
{
string errorMsg = $"Error while reading a message from the server. Entity event data exceeds the size of the buffer (current position: {msg.BitPosition}, length: {msg.LengthBits}).";
errorMsg += "\nPrevious entities:";
for (int j = entities.Count - 1; j >= 0; j--)
for (int j = tempEntityList.Count - 1; j >= 0; j--)
{
errorMsg += "\n" + (entities[j] == null ? "NULL" : entities[j].ToString());
errorMsg += "\n" + (tempEntityList[j] == null ? "NULL" : tempEntityList[j].ToString());
}
DebugConsole.ThrowError(errorMsg);
return false;
@@ -174,7 +173,7 @@ namespace Barotrauma.Networking
DebugConsole.NewMessage("received msg " + thisEventID + " (null entity)",
Microsoft.Xna.Framework.Color.Orange);
}
entities.Add(null);
tempEntityList.Add(null);
if (thisEventID == (UInt16)(lastReceivedID + 1)) { lastReceivedID++; }
continue;
}
@@ -182,7 +181,7 @@ namespace Barotrauma.Networking
int msgLength = (int)msg.ReadVariableUInt32();
IServerSerializable entity = Entity.FindEntityByID(entityID) as IServerSerializable;
entities.Add(entity);
tempEntityList.Add(entity);
//skip the event if we've already received it or if the entity isn't found
if (thisEventID != (UInt16)(lastReceivedID + 1) || entity == null)
@@ -223,7 +222,7 @@ namespace Barotrauma.Networking
if (msg.BitPosition != msgPosition + msgLength * 8)
{
var prevEntity = entities.Count >= 2 ? entities[entities.Count - 2] : null;
var prevEntity = tempEntityList.Count >= 2 ? tempEntityList[tempEntityList.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}) "
@@ -30,6 +30,8 @@ namespace Barotrauma.Networking
protected readonly bool isOwner;
protected readonly Option<int> ownerKey;
public bool IsActive => isActive;
protected bool isActive;
public ClientPeer(Endpoint serverEndpoint, Callbacks callbacks, Option<int> ownerKey)
@@ -98,16 +98,15 @@ namespace Barotrauma
foreach (GUIComponent comp in listBox.Content.Children)
{
if (comp.UserData != userData) { continue; }
if (!(comp.FindChild("votes") is GUITextBlock voteText))
if (comp.FindChild("votes") is not GUITextBlock voteText)
{
voteText = new GUITextBlock(new RectTransform(new Point(30, comp.Rect.Height), comp.RectTransform, Anchor.CenterRight),
"", textAlignment: Alignment.CenterRight)
voteText = new GUITextBlock(new RectTransform(new Point(GUI.IntScale(30), comp.Rect.Height), comp.RectTransform, Anchor.CenterRight),
"", textAlignment: Alignment.Center)
{
Padding = Vector4.Zero,
UserData = "votes"
};
}
voteText.Text = votes == 0 ? "" : votes.ToString();
}
}