Merge remote-tracking branch 'upstream/master' into develop

This commit is contained in:
EvilFactory
2024-06-18 12:19:13 -03:00
263 changed files with 7788 additions and 2849 deletions
@@ -60,6 +60,15 @@ namespace Barotrauma.Networking
{
get
{
if (Type == ChatMessageType.Radio && Sender is Item)
{
if (translatedText.IsNullOrEmpty())
{
translatedText = TextManager.Get(Text).Fallback(Text).Value;
}
return translatedText;
}
if (Type.HasFlag(ChatMessageType.Server) || Type.HasFlag(ChatMessageType.Error) || Type.HasFlag(ChatMessageType.ServerLog))
{
if (translatedText.IsNullOrEmpty())
@@ -80,8 +89,9 @@ namespace Barotrauma.Networking
public PlayerConnectionChangeType ChangeType;
public string IconStyle;
public Character Sender;
public Client SenderClient;
public Character SenderCharacter => Sender as Character;
public readonly Entity Sender;
public readonly Client SenderClient;
public readonly string SenderName;
@@ -120,7 +130,7 @@ namespace Barotrauma.Networking
public ChatMode ChatMode { get; set; } = ChatMode.None;
protected ChatMessage(string senderName, string text, ChatMessageType type, Character sender, Client client, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
protected ChatMessage(string senderName, string text, ChatMessageType type, Entity sender, Client client, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
{
Text = text;
Type = type;
@@ -134,7 +144,7 @@ namespace Barotrauma.Networking
customTextColor = textColor;
}
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Character sender, Client client = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
public static ChatMessage Create(string senderName, string text, ChatMessageType type, Entity sender, Client client = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
{
return new ChatMessage(senderName, text, type, sender, client ?? GameMain.NetworkMember?.ConnectedClients?.Find(c => c.Character != null && c.Character == sender), changeType, textColor);
}
@@ -33,12 +33,13 @@ namespace Barotrauma.Networking
ERROR, //tell the server that an error occurred
CREW, //hiring UI
MEDICAL, //medical clinic
TRANSFER_MONEY, // wallet transfers
REWARD_DISTRIBUTION, // wallet reward distribution
TRANSFER_MONEY, // wallet transfers
REWARD_DISTRIBUTION, // wallet reward distribution
RESET_REWARD_DISTRIBUTION,
CIRCUITBOX,
READY_CHECK,
READY_TO_SPAWN,
READY_TO_SPAWN,
TAKEOVERBOT
LUA_NET_MESSAGE
}
@@ -75,6 +76,7 @@ namespace Barotrauma.Networking
FILE_TRANSFER,
VOICE,
VOICE_AMPLITUDE_DEBUG,
PING_REQUEST, //ping the client
CLIENT_PINGS, //tell the client the pings of all other clients
@@ -209,9 +211,9 @@ namespace Barotrauma.Networking
public TimeSpan UpdateInterval => new TimeSpan(0, 0, 0, 0, MathHelper.Clamp(1000 / ServerSettings.TickRate, 1, 500));
public void AddChatMessage(string message, ChatMessageType type, string senderName = "", Client senderClient = null, Character senderCharacter = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
public void AddChatMessage(string message, ChatMessageType type, string senderName = "", Client senderClient = null, Entity senderEntity = null, PlayerConnectionChangeType changeType = PlayerConnectionChangeType.None, Color? textColor = null)
{
AddChatMessage(ChatMessage.Create(senderName, message, type, senderCharacter, senderClient, changeType: changeType, textColor: textColor));
AddChatMessage(ChatMessage.Create(senderName, message, type, senderEntity, senderClient, changeType: changeType, textColor: textColor));
}
public abstract void AddChatMessage(ChatMessage message);
@@ -39,15 +39,24 @@ namespace Barotrauma.Networking
}
public OrderChatMessage(Order order, string text, Character targetCharacter, Character sender, bool isNewOrder = true)
: base(sender?.Name, text, ChatMessageType.Order, sender, GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == sender))
public OrderChatMessage(Order order, string text, Character targetCharacter, Entity sender, bool isNewOrder = true)
: base(NameFromEntityOrNull(sender), text, ChatMessageType.Order, sender, GameMain.NetworkMember.ConnectedClients.Find(c => c.Character == sender))
{
Order = order;
TargetCharacter = targetCharacter;
IsNewOrder = isNewOrder;
}
public static void WriteOrder(IWriteMessage msg, Order order, Character targetCharacter, bool isNewOrder)
public static string NameFromEntityOrNull(Entity entity)
=> entity switch
{
null => null,
Character character => character.Name,
Item it => it.Name,
_ => throw new ArgumentException("Entity is not a character or item", nameof(entity))
};
public static void WriteOrder(IWriteMessage msg, Order order, Entity targetCharacter, bool isNewOrder)
{
msg.WriteIdentifier(order.Prefab.Identifier);
msg.WriteUInt16(targetCharacter == null ? (UInt16)0 : targetCharacter.ID);
@@ -23,6 +23,16 @@ namespace Barotrauma.Networking
/// </summary>
public static float SkillLossPercentageOnImmediateRespawn => GameMain.NetworkMember?.ServerSettings?.SkillLossPercentageOnImmediateRespawn ?? 10.0f;
public static RespawnMode RespawnMode => GameMain.NetworkMember?.ServerSettings?.RespawnMode ?? RespawnMode.MidRound;
public static bool UseDeathPrompt
{
get
{
return GameMain.GameSession?.GameMode is CampaignMode && Level.Loaded != null;
}
}
public enum State
{
Waiting,
@@ -71,14 +81,6 @@ namespace Barotrauma.Networking
public State CurrentState { get; private set; }
public static bool UseRespawnPrompt
{
get
{
return GameMain.GameSession?.GameMode is CampaignMode && Level.Loaded != null && Level.Loaded?.Type != LevelData.LevelType.Outpost;
}
}
private float maxTransportTime;
private float updateReturnTimer;
@@ -94,7 +96,7 @@ namespace Barotrauma.Networking
{
this.networkMember = networkMember;
if (shuttleInfo != null)
if (shuttleInfo != null && networkMember.ServerSettings is not { RespawnMode: RespawnMode.Permadeath })
{
RespawnShuttle = new Submarine(shuttleInfo, true);
RespawnShuttle.PhysicsBody.FarseerBody.OnCollision += OnShuttleCollision;
@@ -361,12 +363,39 @@ namespace Barotrauma.Networking
}
}
public static float GetReducedSkill(CharacterInfo characterInfo, Skill skill, float skillLossPercentage, float? currentSkillLevel = null)
{
var skillPrefab = characterInfo.Job.Prefab.Skills.Find(s => skill.Identifier == s.Identifier);
float currentLevel = currentSkillLevel ?? skill.Level;
if (skillPrefab == null || currentLevel < skillPrefab.LevelRange.End) { return currentLevel; }
return MathHelper.Lerp(currentLevel, skillPrefab.LevelRange.End, skillLossPercentage / 100.0f);
}
partial void RespawnCharactersProjSpecific(Vector2? shuttlePos);
public void RespawnCharacters(Vector2? shuttlePos)
{
RespawnCharactersProjSpecific(shuttlePos);
}
public static AfflictionPrefab GetRespawnPenaltyAfflictionPrefab()
{
return AfflictionPrefab.Prefabs.First(a => a.AfflictionType == "respawnpenalty");
}
public static Affliction GetRespawnPenaltyAffliction()
{
return GetRespawnPenaltyAfflictionPrefab()?.Instantiate(10.0f);
}
public static void GiveRespawnPenaltyAffliction(Character character)
{
var respawnPenaltyAffliction = GetRespawnPenaltyAffliction();
if (respawnPenaltyAffliction != null)
{
character.CharacterHealth.ApplyAffliction(targetLimb: null, respawnPenaltyAffliction);
}
}
public Vector2 FindSpawnPos()
{
if (Level.Loaded == null || Submarine.MainSub == null) { return Vector2.Zero; }
@@ -31,6 +31,14 @@ namespace Barotrauma.Networking
SomethingDifferent = 4
}
public enum RespawnMode
{
MidRound,
BetweenRounds,
Permadeath,
}
internal enum LootedMoneyDestination
{
Bank,
@@ -408,6 +416,13 @@ namespace Barotrauma.Networking
set { tickRate = MathHelper.Clamp(value, 1, 60); }
}
[Serialize(true, IsPropertySaveable.Yes, description: "Do clients need to be authenticated (e.g. based on Steam ID or an EGS ownership token). Can be disabled if you for example want to play the game in a local network without a connection to external services.")]
public bool RequireAuthentication
{
get;
set;
}
[Serialize(true, IsPropertySaveable.Yes)]
public bool RandomizeSeed
{
@@ -465,6 +480,27 @@ namespace Barotrauma.Networking
private set;
}
[Serialize(true, IsPropertySaveable.Yes)]
/// <summary>
/// Are players allowed to take over bots when permadeath is enabled?
/// </summary>
public bool AllowBotTakeoverOnPermadeath
{
get;
private set;
}
[Serialize(false, IsPropertySaveable.Yes)]
/// <summary>
/// This is an optional setting for permadeath mode. When it's enabled, a player client whose character dies cannot
/// respawn or get a new character in any way in that game (unlike in normal permadeath mode), and can only spectate.
/// </summary>
public bool IronmanMode
{
get;
private set;
}
[Serialize(60.0f, IsPropertySaveable.Yes)]
public float AutoRestartInterval
{
@@ -607,15 +643,15 @@ namespace Barotrauma.Networking
get; set;
}
private bool allowRespawn;
[Serialize(true, IsPropertySaveable.Yes)]
public bool AllowRespawn
private RespawnMode respawnMode;
[Serialize(RespawnMode.MidRound, IsPropertySaveable.Yes)]
public RespawnMode RespawnMode
{
get { return allowRespawn; }
get { return respawnMode; }
set
{
if (allowRespawn == value) { return; }
allowRespawn = value;
if (respawnMode == value) { return; }
respawnMode = value;
ServerDetailsChanged = true;
}
}
@@ -696,6 +732,13 @@ namespace Barotrauma.Networking
get;
set;
}
[Serialize(true, IsPropertySaveable.Yes)]
public bool AllowDragAndDropGive
{
get;
set;
}
[Serialize(false, IsPropertySaveable.Yes)]
public bool DestructibleOutposts
@@ -863,13 +906,28 @@ namespace Barotrauma.Networking
get;
private set;
}
/// <summary>
/// The number of seconds a disconnected player's Character remains in the world until despawned (via "braindeath").
/// </summary>
[Serialize(300.0f, IsPropertySaveable.Yes)]
public float KillDisconnectedTime
{
get;
private set;
}
/// <summary>
/// The number of seconds a disconnected player's Character remains in the world until despawned, in permadeath mode.
/// The Character is helpless and vulnerable, this should be short enough to avoid unintended permadeath, but
/// also long enough to discourage disconnecting just to avoid a potential incoming permadeath.
/// </summary>
[Serialize(10.0f, IsPropertySaveable.Yes)]
public float DespawnDisconnectedPermadeathTime
{
get;
private set;
}
[Serialize(600.0f, IsPropertySaveable.Yes)]
public float KickAFKTime
@@ -966,6 +1024,9 @@ namespace Barotrauma.Networking
[Serialize(999999, IsPropertySaveable.Yes)]
public int MaximumMoneyTransferRequest { get; set; }
[Serialize(0f, IsPropertySaveable.Yes)]
public float NewCampaignDefaultSalary { get; set; }
public CampaignSettings CampaignSettings { get; set; } = CampaignSettings.Empty;
private bool allowSubVoting;
@@ -1190,7 +1251,7 @@ namespace Barotrauma.Networking
set("subselectionmode", SubSelectionMode);
set("voicechatenabled", VoiceChatEnabled);
set("allowspectating", AllowSpectating);
set("allowrespawn", AllowRespawn);
set("allowrespawn", RespawnMode is RespawnMode.MidRound or RespawnMode.BetweenRounds);
set("traitors", TraitorProbability.ToString(CultureInfo.InvariantCulture));
set("friendlyfireenabled", AllowFriendlyFire);
set("karmaenabled", KarmaEnabled);
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Concentus.Structs;
namespace Barotrauma.Networking
{
@@ -9,5 +10,14 @@ namespace Barotrauma.Networking
public const int MAX_COMPRESSED_SIZE = 40; //amount of bytes we expect each 20ms of audio to fit in
public static readonly TimeSpan SEND_INTERVAL = new TimeSpan(0,0,0,0,20);
public const int FREQUENCY = 48000; //48Khz
public const int BITRATE = 16000; //16Kbps
public const int BUFFER_SIZE = (8 * MAX_COMPRESSED_SIZE * FREQUENCY) / BITRATE; //20ms window
public static OpusDecoder CreateDecoder()
{
return new OpusDecoder(FREQUENCY, 1);
}
}
}