Merge branch 'master' of https://github.com/Regalis11/Barotrauma into develop

This commit is contained in:
EvilFactory
2023-03-13 13:32:14 -03:00
335 changed files with 11052 additions and 5179 deletions
@@ -332,7 +332,6 @@ namespace Barotrauma.Networking
FileSize = 0
};
Md5Hash.Cache.Remove(directTransfer.FilePath);
OnFinished(directTransfer);
}
break;
@@ -414,7 +413,6 @@ namespace Barotrauma.Networking
{
finishedTransfers.Add((transferId, Timing.TotalTime));
StopTransfer(activeTransfer);
Md5Hash.Cache.Remove(activeTransfer.FilePath);
OnFinished(activeTransfer);
}
else
@@ -326,7 +326,7 @@ namespace Barotrauma.Networking
return serverEndpoint switch
{
LidgrenEndpoint lidgrenEndpoint => new LidgrenClientPeer(lidgrenEndpoint, callbacks, ownerKey),
SteamP2PEndpoint _ when ownerKey is Some<int> { Value: var key } => new SteamP2POwnerPeer(callbacks, key),
SteamP2PEndpoint _ when ownerKey.TryUnwrap(out var key) => new SteamP2POwnerPeer(callbacks, key),
SteamP2PEndpoint steamP2PServerEndpoint when ownerKey.IsNone() => new SteamP2PClientPeer(steamP2PServerEndpoint, callbacks),
_ => throw new ArgumentOutOfRangeException()
};
@@ -990,7 +990,7 @@ namespace Barotrauma.Networking
GameMain.ModDownloadScreen.Reset();
ContentPackageManager.EnabledPackages.Restore();
CampaignMode.StartRoundCancellationToken?.Cancel();
GameMain.GameSession?.Campaign?.CancelStartRound();
if (SteamManager.IsInitialized)
{
@@ -2627,7 +2627,13 @@ namespace Barotrauma.Networking
using (var segmentTable = SegmentTableWriter<ClientNetSegment>.StartWriting(msg))
{
segmentTable.StartNewSegment(ClientNetSegment.Vote);
Voting.ClientWrite(msg, voteType, data);
bool succeeded = Voting.ClientWrite(msg, voteType, data);
if (!succeeded)
{
throw new Exception(
$"Failed to write vote of type {voteType}: " +
$"data was of invalid type {data?.GetType().Name ?? "NULL"}");
}
}
ClientPeer.Send(msg, DeliveryMethod.Reliable);
@@ -156,7 +156,7 @@ namespace Barotrauma.Networking
var packet = INetSerializableStruct.Read<ClientSteamTicketAndVersionPacket>(inc);
packet.SteamAuthTicket.TryUnwrap(out byte[] ticket);
packet.SteamAuthTicket.TryUnwrap(out var ticket);
Steamworks.BeginAuthResult authSessionStartState = SteamManager.StartAuthSession(ticket, steamId);
if (authSessionStartState != Steamworks.BeginAuthResult.OK)
@@ -1,5 +1,6 @@
#nullable enable
using Barotrauma.Extensions;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
@@ -69,6 +70,9 @@ namespace Barotrauma.Networking
[Serialize(PlayStyle.Casual, IsPropertySaveable.Yes)]
public PlayStyle PlayStyle { get; set; }
[Serialize("", IsPropertySaveable.Yes)]
public LanguageIdentifier Language { get; set; }
public Version GameVersion { get; set; } = new Version(0, 0, 0, 0);
@@ -281,7 +285,7 @@ namespace Barotrauma.Networking
// -----------------------------------------------------------------------------
float elementHeight = 0.075f;
const float elementHeight = 0.075f;
// Spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.025f), content.RectTransform), style: null);
@@ -294,6 +298,11 @@ namespace Barotrauma.Networking
serverMsg.Content.RectTransform.SizeChanged += () => { msgText.CalculateHeightFromText(); };
msgText.RectTransform.SizeChanged += () => { serverMsg.UpdateScrollBarSize(); };
var languageLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), content.RectTransform), TextManager.Get("Language"));
new GUITextBlock(new RectTransform(Vector2.One, languageLabel.RectTransform),
ServerLanguageOptions.Options.FirstOrNull(o => o.Identifier == Language)?.Label ?? TextManager.Get("Unknown"),
textAlignment: Alignment.Right);
var gameMode = new GUITextBlock(new RectTransform(new Vector2(1.0f, elementHeight), content.RectTransform), TextManager.Get("GameMode"));
new GUITextBlock(new RectTransform(Vector2.One, gameMode.RectTransform),
TextManager.Get(GameMode.IsEmpty ? "Unknown" : "GameMode." + GameMode).Fallback(GameMode.Value),
@@ -363,7 +372,7 @@ namespace Barotrauma.Networking
packageText.Selected = true;
}
//workshop download link found
else if (package.Id is Some<ContentPackageId> { Value: var ugcId } && ugcId is SteamWorkshopId)
else if (package.Id.TryUnwrap(out var ugcId) && ugcId is SteamWorkshopId)
{
packageText.ToolTip = TextManager.GetWithVariable("ServerListIncompatibleContentPackageWorkshopAvailable", "[contentpackage]", package.Name);
}
@@ -417,6 +426,7 @@ namespace Barotrauma.Networking
GameMode = valueGetter("gamemode")?.ToIdentifier() ?? Identifier.Empty;
if (Enum.TryParse(valueGetter("traitors"), out YesNoMaybe traitorsEnabled)) { TraitorsEnabled = traitorsEnabled; }
if (Enum.TryParse(valueGetter("playstyle"), out PlayStyle playStyle)) { PlayStyle = playStyle; }
Language = valueGetter("language")?.ToLanguageIdentifier() ?? LanguageIdentifier.None;
ContentPackages = ExtractContentPackageInfo(valueGetter).ToImmutableArray();
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Barotrauma.Steam;
namespace Barotrauma.Networking
{
@@ -78,7 +79,7 @@ namespace Barotrauma.Networking
}
}
private Dictionary<Identifier, bool> tempMonsterEnabled;
partial void InitProjSpecific()
{
var properties = TypeDescriptor.GetProperties(GetType()).Cast<PropertyDescriptor>();
@@ -367,6 +368,15 @@ namespace Barotrauma.Networking
//***********************************************
// Language
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), serverTab.RectTransform), TextManager.Get("Language"), font: GUIStyle.SubHeadingFont);
var languageDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.02f), serverTab.RectTransform));
foreach (var language in ServerLanguageOptions.Options)
{
languageDD.AddItem(language.Label, language.Identifier);
}
GetPropertyData(nameof(Language)).AssignGUIComponent(languageDD);
//changing server visibility on the fly is not supported in dedicated servers
if (GameMain.Client?.ClientPeer is not LidgrenClientPeer)
{
@@ -116,7 +116,9 @@ namespace Barotrauma.Networking
bool spectating = Character.Controlled == null;
float rangeMultiplier = spectating ? 2.0f : 1.0f;
WifiComponent radio = null;
var messageType = !client.VoipQueue.ForceLocal && ChatMessage.CanUseRadio(client.Character, out radio) ? ChatMessageType.Radio : ChatMessageType.Default;
var messageType =
!client.VoipQueue.ForceLocal && ChatMessage.CanUseRadio(client.Character, out radio) && ChatMessage.CanUseRadio(Character.Controlled) ?
ChatMessageType.Radio : ChatMessageType.Default;
client.Character.ShowSpeechBubble(1.25f, ChatMessage.MessageColor[(int)messageType]);
client.VoipSound.UseRadioFilter = messageType == ChatMessageType.Radio && !GameSettings.CurrentConfig.Audio.DisableVoiceChatFilters;
@@ -13,13 +13,11 @@ namespace Barotrauma
{
public SubmarineInfo SubmarineInfo { get; set; }
public bool TransferItems { get; set; }
public int DeliveryFee { get; set; }
public SubmarineVoteInfo(SubmarineInfo submarineInfo, bool transferItems, int deliveryFee)
public SubmarineVoteInfo(SubmarineInfo submarineInfo, bool transferItems)
{
SubmarineInfo = submarineInfo;
TransferItems = transferItems;
DeliveryFee = deliveryFee;
}
}
@@ -128,64 +126,72 @@ namespace Barotrauma
UpdateVoteTexts(connectedClients, VoteType.Sub);
}
public void ClientWrite(IWriteMessage msg, VoteType voteType, object data)
/// <summary>
/// Returns true if the given data is valid for the given vote type,
/// returns false otherwise. If it returns false, the message must
/// be discarded or reset by the caller, as it is now malformed :)
/// </summary>
public bool ClientWrite(IWriteMessage msg, VoteType voteType, object data)
{
msg.WriteByte((byte)voteType);
switch (voteType)
{
case VoteType.Sub:
if (!(data is SubmarineInfo sub)) { return; }
if (data is not SubmarineInfo sub) { return false; }
msg.WriteInt32(sub.EqualityCheckVal);
if (sub.EqualityCheckVal == 0)
if (sub.EqualityCheckVal <= 0)
{
//sub doesn't exist client-side, use hash to let the server know which one we voted for
msg.WriteString(sub.MD5Hash.StringRepresentation);
}
break;
case VoteType.Mode:
if (!(data is GameModePreset gameMode)) { return; }
if (data is not GameModePreset gameMode) { return false; }
msg.WriteIdentifier(gameMode.Identifier);
break;
case VoteType.EndRound:
if (!(data is bool)) { return; }
msg.WriteBoolean((bool)data);
if (data is not bool endRound) { return false; }
msg.WriteBoolean(endRound);
break;
case VoteType.Kick:
if (!(data is Client votedClient)) { return; }
if (data is not Client votedClient) { return false; }
msg.WriteByte(votedClient.SessionId);
break;
case VoteType.StartRound:
if (!(data is bool)) { return; }
msg.WriteBoolean((bool)data);
if (data is not bool startRound) { return false; }
msg.WriteBoolean(startRound);
break;
case VoteType.PurchaseAndSwitchSub:
case VoteType.PurchaseSub:
case VoteType.SwitchSub:
if (data is (SubmarineInfo voteSub, bool transferItems))
{
//initiate sub vote
msg.WriteBoolean(true);
msg.WriteString(voteSub.Name);
msg.WriteBoolean(transferItems);
}
else
switch (data)
{
// vote
if (!(data is int)) { return; }
msg.WriteBoolean(false);
msg.WriteInt32((int)data);
case (SubmarineInfo voteSub, bool transferItems):
//initiate sub vote
msg.WriteBoolean(true);
msg.WriteString(voteSub.Name);
msg.WriteBoolean(transferItems);
break;
case int vote:
// vote
msg.WriteBoolean(false);
msg.WriteInt32(vote);
break;
default:
return false;
}
break;
case VoteType.TransferMoney:
if (!(data is int)) { return; }
if (data is not int money) { return false; }
msg.WriteBoolean(false); //not initiating a vote
msg.WriteInt32((int)data);
msg.WriteInt32(money);
break;
}
msg.WritePadBits();
return true;
}
public void ClientRead(IReadMessage inc)
@@ -322,33 +328,34 @@ namespace Barotrauma
case VoteType.PurchaseAndSwitchSub:
case VoteType.SwitchSub:
string subName2 = inc.ReadString();
var submarineInfo = GameMain.GameSession.OwnedSubmarines.FirstOrDefault(s => s.Name == subName2) ?? GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName2);
bool transferItems = inc.ReadBoolean();
int deliveryFee = inc.ReadInt16();
if (submarineInfo == null)
if (GameMain.GameSession != null)
{
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
return;
var submarineInfo = GameMain.GameSession.OwnedSubmarines.FirstOrDefault(s => s.Name == subName2) ?? GameMain.Client.ServerSubmarines.FirstOrDefault(s => s.Name == subName2);
if (submarineInfo == null)
{
DebugConsole.ThrowError("Failed to find a matching submarine, vote aborted");
return;
}
submarineVoteInfo = new SubmarineVoteInfo(submarineInfo, transferItems);
}
submarineVoteInfo = new SubmarineVoteInfo(submarineInfo, transferItems, deliveryFee);
break;
}
GameMain.Client.VotingInterface?.EndVote(passed, yesClientCount, noClientCount);
GameMain.Client.VotingInterface?.EndVote(passed, yesClientCount, noClientCount);
if (passed && submarineVoteInfo.SubmarineInfo is { } subInfo)
{
switch (voteType)
{
case VoteType.PurchaseAndSwitchSub:
GameMain.GameSession.PurchaseSubmarine(subInfo);
GameMain.GameSession.SwitchSubmarine(subInfo, submarineVoteInfo.TransferItems, 0);
GameMain.GameSession.SwitchSubmarine(subInfo, submarineVoteInfo.TransferItems);
break;
case VoteType.PurchaseSub:
GameMain.GameSession.PurchaseSubmarine(subInfo);
break;
case VoteType.SwitchSub:
GameMain.GameSession.SwitchSubmarine(subInfo, submarineVoteInfo.TransferItems, submarineVoteInfo.DeliveryFee);
GameMain.GameSession.SwitchSubmarine(subInfo, submarineVoteInfo.TransferItems);
break;
}