Unstable 1.1.14.0

This commit is contained in:
Markus Isberg
2023-10-02 16:43:54 +03:00
parent 94f5a93a0c
commit cf8f0de659
606 changed files with 21906 additions and 11456 deletions
@@ -538,7 +538,7 @@ namespace Barotrauma.Networking
{
string extension = Path.GetExtension(file);
if ((!extension.Equals(".sub", StringComparison.OrdinalIgnoreCase)
&& !file.Equals("gamesession.xml"))
&& !file.Equals(SaveUtil.GameSessionFileName))
|| file.CleanUpPathCrossPlatform(correctFilenameCase: false).Contains('/'))
{
ErrorMessage = $"Found unexpected file in \"{fileTransfer.FileName}\"! ({file})";
@@ -112,9 +112,8 @@ namespace Barotrauma.Networking
//has the client been given a character to control this round
public bool HasSpawned;
public bool SpawnAsTraitor;
public LocalizedString TraitorFirstObjective;
public TraitorMissionPrefab TraitorMission = null;
public TraitorEventPrefab TraitorMission = null;
public byte SessionId { get; private set; }
@@ -404,7 +403,7 @@ namespace Barotrauma.Networking
if (SteamManager.IsInitialized && steamConnection.AccountInfo.AccountId.TryUnwrap(out var accountId) && accountId is SteamId steamId)
{
serverDisplayName = steamId.ToString();
string steamUserName = Steamworks.SteamFriends.GetFriendPersonaName(steamId.Value);
string steamUserName = new Steamworks.Friend(steamId.Value).Name;
if (!string.IsNullOrEmpty(steamUserName) && steamUserName != "[unknown]")
{
serverDisplayName = steamUserName;
@@ -775,15 +774,15 @@ namespace Barotrauma.Networking
}
}
byte traitorCount = inc.ReadByte();
List<TraitorMissionResult> traitorResults = new List<TraitorMissionResult>();
for (int i = 0; i<traitorCount; i++)
bool includesTraitorInfo = inc.ReadBoolean();
TraitorManager.TraitorResults? traitorResults = null;
if (includesTraitorInfo)
{
traitorResults.Add(new TraitorMissionResult(inc));
traitorResults = INetSerializableStruct.Read<TraitorManager.TraitorResults>(inc);
}
roundInitStatus = RoundInitStatus.Interrupted;
CoroutineManager.StartCoroutine(EndGame(endMessage, traitorResults, transitionType), "EndGame");
CoroutineManager.StartCoroutine(EndGame(endMessage, transitionType, traitorResults), "EndGame");
GUI.SetSavingIndicatorState(save);
break;
case ServerPacketHeader.CAMPAIGN_SETUP_INFO:
@@ -829,18 +828,21 @@ namespace Barotrauma.Networking
case ServerPacketHeader.MEDICAL:
campaign?.MedicalClinic?.ClientRead(inc);
break;
case ServerPacketHeader.CIRCUITBOX:
ReadCircuitBoxMessage(inc);
break;
case ServerPacketHeader.MONEY:
campaign?.ClientReadMoney(inc);
break;
case ServerPacketHeader.READY_CHECK:
ReadyCheck.ClientRead(inc);
break;
case ServerPacketHeader.TRAITOR_MESSAGE:
TraitorManager.ClientRead(inc);
break;
case ServerPacketHeader.FILE_TRANSFER:
FileReceiver.ReadMessage(inc);
break;
case ServerPacketHeader.TRAITOR_MESSAGE:
ReadTraitorMessage(inc);
break;
case ServerPacketHeader.MISSION:
{
int missionIndex = inc.ReadByte();
@@ -985,7 +987,7 @@ namespace Barotrauma.Networking
if (disconnectPacket.IsEventSyncError)
{
GameMain.NetLobbyScreen.Select();
GameMain.GameSession?.EndRound("", null);
GameMain.GameSession?.EndRound("");
GameStarted = false;
myCharacter = null;
}
@@ -1179,44 +1181,20 @@ namespace Barotrauma.Networking
}
}
private void ReadTraitorMessage(IReadMessage inc)
private static void ReadCircuitBoxMessage(IReadMessage inc)
{
TraitorMessageType messageType = (TraitorMessageType)inc.ReadByte();
string missionIdentifier = inc.ReadString();
string messageFmt = inc.ReadString();
LocalizedString message = TextManager.GetServerMessage(messageFmt);
var header = INetSerializableStruct.Read<NetCircuitBoxHeader>(inc);
var missionPrefab = TraitorMissionPrefab.Prefabs.Find(t => t.Identifier == missionIdentifier);
Sprite icon = missionPrefab?.Icon;
switch (messageType)
INetSerializableStruct data = header.Opcode switch
{
case TraitorMessageType.Objective:
var isTraitor = !message.IsNullOrEmpty();
SpawnAsTraitor = isTraitor;
TraitorFirstObjective = message;
TraitorMission = missionPrefab;
if (Character != null)
{
Character.IsTraitor = isTraitor;
Character.TraitorCurrentObjective = message;
}
break;
case TraitorMessageType.Console:
GameMain.Client.AddChatMessage(ChatMessage.Create("", message.Value, ChatMessageType.Console, null));
DebugConsole.NewMessage(message);
break;
case TraitorMessageType.ServerMessageBox:
var msgBox = new GUIMessageBox("", message, Array.Empty<LocalizedString>(), type: GUIMessageBox.Type.InGame, icon: icon);
if (msgBox.Icon != null)
{
msgBox.IconColor = missionPrefab.IconColor;
}
break;
case TraitorMessageType.Server:
default:
GameMain.Client.AddChatMessage(message.Value, ChatMessageType.Server);
break;
CircuitBoxOpcode.Cursor => INetSerializableStruct.Read<NetCircuitBoxCursorInfo>(inc),
CircuitBoxOpcode.Error => INetSerializableStruct.Read<CircuitBoxErrorEvent>(inc),
_ => throw new ArgumentOutOfRangeException(nameof(header.Opcode), header.Opcode, "This data cannot be handled using direct network messages.")
};
if (header.FindTarget().TryUnwrap(out CircuitBox box))
{
box.ClientRead(data);
}
}
@@ -1372,7 +1350,6 @@ namespace Barotrauma.Networking
ServerSettings.AllowRewiring = inc.ReadBoolean();
ServerSettings.AllowFriendlyFire = inc.ReadBoolean();
ServerSettings.LockAllDefaultWires = inc.ReadBoolean();
ServerSettings.AllowRagdollButton = inc.ReadBoolean();
ServerSettings.AllowLinkingWifiToChat = inc.ReadBoolean();
ServerSettings.MaximumMoneyTransferRequest = inc.ReadInt32();
bool usingShuttle = GameMain.NetLobbyScreen.UsingShuttle = inc.ReadBoolean();
@@ -1698,7 +1675,7 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Success;
}
public IEnumerable<CoroutineStatus> EndGame(string endMessage, List<TraitorMissionResult> traitorResults = null, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None)
public IEnumerable<CoroutineStatus> EndGame(string endMessage, CampaignMode.TransitionType transitionType = CampaignMode.TransitionType.None, TraitorManager.TraitorResults? traitorResults = null)
{
//round starting up, wait for it to finish
DateTime timeOut = DateTime.Now + new TimeSpan(0, 0, 60);
@@ -1717,14 +1694,13 @@ namespace Barotrauma.Networking
yield return CoroutineStatus.Success;
}
GameMain.GameSession?.EndRound(endMessage, traitorResults, transitionType);
GameMain.GameSession?.EndRound(endMessage, transitionType, traitorResults);
ServerSettings.ServerDetailsChanged = true;
GameStarted = false;
Character.Controlled = null;
WaitForNextRoundRespawn = null;
SpawnAsTraitor = false;
GameMain.GameScreen.Cam.TargetPos = Vector2.Zero;
GameMain.LightManager.LosEnabled = false;
RespawnManager = null;
@@ -1976,7 +1952,9 @@ namespace Barotrauma.Networking
bool allowSpectating = inc.ReadBoolean();
YesNoMaybe traitorsEnabled = (YesNoMaybe)inc.ReadRangedInteger(0, 2);
float traitorProbability = inc.ReadSingle();
int traitorDangerLevel = inc.ReadRangedInteger(TraitorEventPrefab.MinDangerLevel, TraitorEventPrefab.MaxDangerLevel);
MissionType missionType = (MissionType)inc.ReadRangedInteger(0, (int)MissionType.All);
int modeIndex = inc.ReadByte();
@@ -2020,7 +1998,9 @@ namespace Barotrauma.Networking
if (!allowSubVoting) { GameMain.NetLobbyScreen.TrySelectSub(selectSubName, selectSubHash, GameMain.NetLobbyScreen.SubList); }
GameMain.NetLobbyScreen.TrySelectSub(selectShuttleName, selectShuttleHash, GameMain.NetLobbyScreen.ShuttleList.ListBox);
GameMain.NetLobbyScreen.SetTraitorsEnabled(traitorsEnabled);
GameMain.NetLobbyScreen.SetTraitorProbability(traitorProbability);
GameMain.NetLobbyScreen.SetTraitorDangerLevel(traitorDangerLevel);
GameMain.NetLobbyScreen.SetMissionType(missionType);
GameMain.NetLobbyScreen.SelectMode(modeIndex);
@@ -2498,9 +2478,9 @@ namespace Barotrauma.Networking
break;
case FileTransferType.CampaignSave:
XDocument gameSessionDoc = SaveUtil.LoadGameSessionDoc(transfer.FilePath);
byte campaignID = (byte)MathHelper.Clamp(gameSessionDoc.Root.GetAttributeInt("campaignid", 0), 0, 255);
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.CampaignID != campaignID)
XElement gameSessionDocRoot = SaveUtil.DecompressSaveAndLoadGameSessionDoc(transfer.FilePath)?.Root;
byte campaignID = (byte)MathHelper.Clamp(gameSessionDocRoot.GetAttributeInt("campaignid", 0), 0, 255);
if (GameMain.GameSession?.GameMode is not MultiPlayerCampaign campaign || campaign.CampaignID != campaignID)
{
string savePath = transfer.FilePath;
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, CampaignSettings.Empty);
@@ -2512,7 +2492,7 @@ namespace Barotrauma.Networking
GameMain.GameSession.SavePath = transfer.FilePath;
if (GameMain.GameSession.SubmarineInfo == null || campaign.Map == null)
{
string subPath = Path.Combine(SaveUtil.TempPath, gameSessionDoc.Root.GetAttributeString("submarine", "")) + ".sub";
string subPath = Path.Combine(SaveUtil.TempPath, gameSessionDocRoot.GetAttributeString("submarine", "")) + ".sub";
GameMain.GameSession.SubmarineInfo = new SubmarineInfo(subPath, "");
}
@@ -2528,7 +2508,8 @@ namespace Barotrauma.Networking
if (Screen.Selected == GameMain.NetLobbyScreen)
{
//reselect to refrest the state of the lobby screen (enable spectate button, etc)
//reselect to refresh the state of the lobby screen (enable spectate button, etc)
GameMain.NetLobbyScreen.SaveAppearance();
GameMain.NetLobbyScreen.Select();
}
@@ -2606,7 +2587,7 @@ namespace Barotrauma.Networking
public void WriteCharacterInfo(IWriteMessage msg, string newName = null)
{
msg.WriteBoolean(characterInfo == null);
msg.WriteBoolean(GameMain.NetLobbyScreen.Spectating);
msg.WritePadBits();
if (characterInfo == null) { return; }
@@ -53,7 +53,7 @@ namespace Barotrauma.Networking
protected ConnectionInitialization initializationStep;
public bool ContentPackageOrderReceived { get; set; }
protected int passwordSalt;
protected Steamworks.AuthTicket? steamAuthTicket;
protected Option<Steamworks.AuthTicket> steamAuthTicket;
private GUIMessageBox? passwordMsgBox;
public bool WaitingForPassword
@@ -82,7 +82,7 @@ namespace Barotrauma.Networking
Initialization = ConnectionInitialization.SteamTicketAndVersion
};
if (steamAuthTicket is { Canceled: true })
if (steamAuthTicket.TryUnwrap(out var authTicket) && authTicket is { Canceled: true })
{
throw new InvalidOperationException("ReadConnectionInitializationStep failed: Steam auth ticket has been cancelled.");
}
@@ -92,11 +92,7 @@ namespace Barotrauma.Networking
Name = GameMain.Client.Name,
OwnerKey = ownerKey,
SteamId = SteamManager.GetSteamId().Select(id => (AccountId)id),
SteamAuthTicket = steamAuthTicket?.Data switch
{
null => Option<byte[]>.None(),
var ticketData => Option<byte[]>.Some(ticketData)
},
SteamAuthTicket = steamAuthTicket.Bind(t => t.Data != null ? Option.Some(t.Data) : Option.None),
GameVersion = GameMain.Version.ToString(),
Language = GameSettings.CurrentConfig.Language.Value
};
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Text;
using Lidgren.Network;
using Barotrauma.Steam;
using System.Net.Sockets;
namespace Barotrauma.Networking
{
@@ -28,8 +29,12 @@ namespace Barotrauma.Networking
netPeerConfiguration = new NetPeerConfiguration("barotrauma")
{
UseDualModeSockets = GameSettings.CurrentConfig.UseDualModeSockets
DualStack = GameSettings.CurrentConfig.UseDualModeSockets
};
if (endpoint.NetEndpoint.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
netPeerConfiguration.LocalAddress = System.Net.IPAddress.IPv6Any;
}
netPeerConfiguration.DisableMessageType(
NetIncomingMessageType.DebugMessage
@@ -53,8 +58,8 @@ namespace Barotrauma.Networking
if (SteamManager.IsInitialized)
{
steamAuthTicket = SteamManager.GetAuthSessionTicket();
if (steamAuthTicket == null)
steamAuthTicket = SteamManager.GetAuthSessionTicketForMultiplayer(ServerEndpoint);
if (steamAuthTicket.IsNone())
{
throw new Exception("GetAuthSessionTicket returned null");
}
@@ -207,8 +212,8 @@ namespace Barotrauma.Networking
netClient.Shutdown(peerDisconnectPacket.ToLidgrenStringRepresentation());
netClient = null;
steamAuthTicket?.Cancel();
steamAuthTicket = null;
if (steamAuthTicket.TryUnwrap(out var ticket)) { ticket.Cancel(); }
steamAuthTicket = Option.None;
callbacks.OnDisconnect.Invoke(peerDisconnectPacket);
}
@@ -40,7 +40,7 @@ namespace Barotrauma.Networking
ContentPackageOrderReceived = false;
steamAuthTicket = SteamManager.GetAuthSessionTicket();
steamAuthTicket = SteamManager.GetAuthSessionTicketForMultiplayer(ServerEndpoint);
//TODO: wait for GetAuthSessionTicketResponse_t
if (steamAuthTicket == null)
@@ -363,8 +363,8 @@ namespace Barotrauma.Networking
Steamworks.SteamNetworking.ResetActions();
Steamworks.SteamNetworking.CloseP2PSessionWithUser(hostSteamId.Value);
steamAuthTicket?.Cancel();
steamAuthTicket = null;
if (steamAuthTicket.TryUnwrap(out var ticket)) { ticket.Cancel(); }
steamAuthTicket = Option.None;
callbacks.OnDisconnect.Invoke(peerDisconnectPacket);
}
@@ -49,11 +49,15 @@ namespace Barotrauma.Networking
respawnPromptCoroutine = CoroutineManager.Invoke(() =>
{
if (Character.Controlled != null || (!(GameMain.GameSession?.IsRunning ?? false))) { return; }
if (Character.Controlled != null || (GameMain.GameSession is not { IsRunning: true })) { return; }
LocalizedString text =
TextManager.GetWithVariable("respawnskillpenalty", "[percentage]", ((int)(SkillReductionOnDeath * 100)).ToString())
+ "\n\n" + TextManager.Get("respawnquestionprompt");
LocalizedString text = TextManager.Get("respawnquestionprompt");
if (SkillLossPercentageOnDeath > 0)
{
text =
TextManager.GetWithVariable("respawnskillpenalty", "[percentage]", ((int)SkillLossPercentageOnDeath).ToString()) +
"\n\n" + text;
};
var respawnPrompt = new GUIMessageBox(
TextManager.Get("tutorial.tryagainheader"), text,
@@ -9,6 +9,7 @@ using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using Barotrauma.Steam;
using System.Globalization;
namespace Barotrauma.Networking
{
@@ -65,8 +66,8 @@ namespace Barotrauma.Networking
[Serialize(false, IsPropertySaveable.Yes)]
public bool AllowRespawn { get; set; }
[Serialize(YesNoMaybe.No, IsPropertySaveable.Yes)]
public YesNoMaybe TraitorsEnabled { get; set; }
[Serialize(0.0f, IsPropertySaveable.Yes)]
public float TraitorProbability { get; set; }
[Serialize(PlayStyle.Casual, IsPropertySaveable.Yes)]
public PlayStyle PlayStyle { get; set; }
@@ -397,10 +398,10 @@ namespace Barotrauma.Networking
public IEnumerable<Identifier> GetPlayStyleTags()
{
yield return $"Karma.{KarmaEnabled}".ToIdentifier();
yield return (TraitorsEnabled == YesNoMaybe.Yes ? $"Traitors.True" : $"Traitors.False").ToIdentifier();
yield return (TraitorProbability > 0.0f ? $"Traitors.True" : $"Traitors.False").ToIdentifier();
yield return $"VoIP.{VoipEnabled}".ToIdentifier();
yield return $"FriendlyFire.{FriendlyFireEnabled}".ToIdentifier();
yield return $"Modded.{ContentPackages.Any()}".ToIdentifier();
yield return $"Modded.{IsModded}".ToIdentifier();
}
public void UpdateInfo(Func<string, string?> valueGetter)
@@ -424,7 +425,7 @@ namespace Barotrauma.Networking
VoipEnabled = getBool("voicechatenabled");
GameMode = valueGetter("gamemode")?.ToIdentifier() ?? Identifier.Empty;
if (Enum.TryParse(valueGetter("traitors"), out YesNoMaybe traitorsEnabled)) { TraitorsEnabled = traitorsEnabled; }
if (float.TryParse(valueGetter("traitors"), NumberStyles.Any, CultureInfo.InvariantCulture, out float traitorProbability)) { TraitorProbability = traitorProbability; }
if (Enum.TryParse(valueGetter("playstyle"), out PlayStyle playStyle)) { PlayStyle = playStyle; }
Language = valueGetter("language")?.ToLanguageIdentifier() ?? LanguageIdentifier.None;
@@ -146,7 +146,9 @@ namespace Barotrauma.Networking
List<GUITickBox> tickBoxes = new List<GUITickBox>();
foreach (MessageType msgType in Enum.GetValues(typeof(MessageType)))
{
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, (int)(25 * GUI.Scale)), tickBoxContainer.RectTransform), TextManager.Get("ServerLog." + messageTypeName[msgType]), font: GUIStyle.SmallFont)
var tickBox = new GUITickBox(new RectTransform(new Point(tickBoxContainer.Rect.Width, (int)(25 * GUI.Scale)), tickBoxContainer.RectTransform),
TextManager.Get("ServerLog." + messageTypeName[msgType]).Fallback(messageTypeName[msgType]),
font: GUIStyle.SmallFont)
{
Selected = true,
TextColor = messageColor[msgType],
@@ -182,7 +182,8 @@ namespace Barotrauma.Networking
int? missionTypeAnd = null,
float? levelDifficulty = null,
bool? autoRestart = null,
int traitorSetting = 0,
float? traitorProbability = null,
int traitorDangerLevel = 0,
int botCount = 0,
int botSpawnMode = 0,
bool? useRespawnShuttle = null)
@@ -244,7 +245,11 @@ namespace Barotrauma.Networking
{
outMsg.WriteRangedInteger(missionTypeOr ?? (int)Barotrauma.MissionType.None, 0, (int)Barotrauma.MissionType.All);
outMsg.WriteRangedInteger(missionTypeAnd ?? (int)Barotrauma.MissionType.All, 0, (int)Barotrauma.MissionType.All);
outMsg.WriteByte((byte)(traitorSetting + 1));
outMsg.WriteBoolean(traitorProbability != null);
outMsg.WriteSingle(traitorProbability ?? 0.0f);
outMsg.WriteByte((byte)(traitorDangerLevel + 1));
outMsg.WriteByte((byte)(botCount + 1));
outMsg.WriteByte((byte)(botSpawnMode + 1));
@@ -557,6 +562,26 @@ namespace Barotrauma.Networking
};
slider.OnMoved(slider, slider.BarScroll);
LocalizedString skillLossLabel = TextManager.Get("ServerSettingsSkillLossPercentageOnDeath");
var skillLossText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), roundsContent.RectTransform), skillLossLabel);
var skillLossSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), roundsContent.RectTransform), barSize: 0.1f, style: "GUISlider")
{
UserData = skillLossText,
Range = new Vector2(0, 100),
StepValue = 1,
OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
GUITextBlock text = scrollBar.UserData as GUITextBlock;
text.Text = TextManager.AddPunctuation(
':',
skillLossLabel,
TextManager.GetWithVariable("percentageformat", "[value]", ((int)Math.Round(scrollBar.BarScrollValue)).ToString()));
return true;
}
};
GetPropertyData(nameof(SkillLossPercentageOnDeath)).AssignGUIComponent(skillLossSlider);
skillLossSlider.OnMoved(skillLossSlider, skillLossSlider.BarScroll);
var respawnBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), sliderLayout.RectTransform),
TextManager.Get("ServerSettingsAllowRespawning"));
GetPropertyData(nameof(AllowRespawn)).AssignGUIComponent(respawnBox);
@@ -690,7 +715,7 @@ namespace Barotrauma.Networking
Stretch = true
};
var traitorsMinPlayerCount = CreateLabeledNumberInput(numberLayout, "ServerSettingsTraitorsMinPlayerCount", 1, 16, "ServerSettingsTraitorsMinPlayerCountToolTip");
var traitorsMinPlayerCount = CreateLabeledNumberInput(numberLayout, "ServerSettingsTraitorsMinPlayerCount", 2, 16, "ServerSettingsTraitorsMinPlayerCountToolTip");
GetPropertyData(nameof(TraitorsMinPlayerCount)).AssignGUIComponent(traitorsMinPlayerCount);
var maximumTransferAmount = CreateLabeledNumberInput(numberLayout, "serversettingsmaximumtransferrequest", 0, CampaignMode.MaxMoney, "serversettingsmaximumtransferrequesttooltip");
@@ -701,9 +726,6 @@ namespace Barotrauma.Networking
lootedMoneyDestination.AddItem(TextManager.Get("lootedmoneydestination.wallet"), LootedMoneyDestination.Wallet);
GetPropertyData(nameof(LootedMoneyDestination)).AssignGUIComponent(lootedMoneyDestination);
var ragdollButtonBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), numberLayout.RectTransform), TextManager.Get("ServerSettingsAllowRagdollButton"));
GetPropertyData(nameof(AllowRagdollButton)).AssignGUIComponent(ragdollButtonBox);
var disableBotConversationsBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), numberLayout.RectTransform), TextManager.Get("ServerSettingsDisableBotConversations"));
GetPropertyData(nameof(DisableBotConversations)).AssignGUIComponent(disableBotConversationsBox);
@@ -188,6 +188,10 @@ namespace Barotrauma
msg.WriteBoolean(false); //not initiating a vote
msg.WriteInt32(money);
break;
case VoteType.Traitor:
//use 0 to indicate we voted for no-one
msg.WriteInt32((data as Client)?.SessionId ?? 0);
break;
}
msg.WritePadBits();