Unstable 1.8.4.0
This commit is contained in:
@@ -11,6 +11,9 @@ using System.Text;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class DoNotSyncOverNetwork : Attribute { }
|
||||
|
||||
public enum SelectionMode
|
||||
{
|
||||
Manual = 0, Random = 1, Vote = 2
|
||||
@@ -32,6 +35,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public enum RespawnMode
|
||||
{
|
||||
None,
|
||||
MidRound,
|
||||
BetweenRounds,
|
||||
Permadeath,
|
||||
@@ -64,6 +68,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
public static readonly string PermissionPresetFile = "Data" + Path.DirectorySeparatorChar + "permissionpresets.xml";
|
||||
public static readonly string PermissionPresetFileCustom = "Data" + Path.DirectorySeparatorChar + "permissionpresets_player.xml";
|
||||
|
||||
public string Name
|
||||
{
|
||||
@@ -280,7 +285,9 @@ namespace Barotrauma.Networking
|
||||
|
||||
HiddenSubs = new HashSet<string>();
|
||||
|
||||
PermissionPreset.List.Clear();
|
||||
PermissionPreset.LoadAll(PermissionPresetFile);
|
||||
PermissionPreset.LoadAll(PermissionPresetFileCustom);
|
||||
InitProjSpecific();
|
||||
|
||||
ServerName = serverName;
|
||||
@@ -300,6 +307,7 @@ namespace Barotrauma.Networking
|
||||
string typeName = SerializableProperty.GetSupportedTypeName(property.PropertyType);
|
||||
if (typeName != null || property.PropertyType.IsEnum)
|
||||
{
|
||||
if (property.GetAttribute<DoNotSyncOverNetwork>() is not null) { continue; }
|
||||
NetPropertyData netPropertyData = new NetPropertyData(this, property, typeName);
|
||||
UInt32 key = ToolBoxCore.IdentifierToUint32Hash(netPropertyData.Name, md5);
|
||||
if (key == 0) { key++; } //0 is reserved to indicate the end of the netproperties section of a message
|
||||
@@ -412,6 +420,19 @@ namespace Barotrauma.Networking
|
||||
set { tickRate = MathHelper.Clamp(value, 1, 60); }
|
||||
}
|
||||
|
||||
private int maxLagCompensation = 150;
|
||||
[Serialize(150, IsPropertySaveable.Yes, description:
|
||||
"Maximum amount of lag compensation for firing weapons, in milliseconds. " +
|
||||
"E.g. when a client fires a gun, the server will be notified about it with some latency, and checks if it hit anything in the past (at the time the shot was taken), up to this limit. " +
|
||||
"The largest allowed lag compensation is 500 milliseconds.")]
|
||||
public int MaxLagCompensation
|
||||
{
|
||||
get { return maxLagCompensation; }
|
||||
set { maxLagCompensation = MathHelper.Clamp(value, 0, 500); }
|
||||
}
|
||||
|
||||
public float MaxLagCompensationSeconds => maxLagCompensation / 1000.0f;
|
||||
|
||||
[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
|
||||
{
|
||||
@@ -500,13 +521,16 @@ namespace Barotrauma.Networking
|
||||
/// <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>
|
||||
/// NOTE: this setting will do nothing if respawn mode is not set to PermaDeath.
|
||||
/// </summary>
|
||||
public bool IronmanMode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public bool IronmanModeActive => IronmanMode && respawnMode == RespawnMode.Permadeath;
|
||||
|
||||
[Serialize(60.0f, IsPropertySaveable.Yes)]
|
||||
public float AutoRestartInterval
|
||||
{
|
||||
@@ -520,6 +544,20 @@ namespace Barotrauma.Networking
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(PvpTeamSelectionMode.PlayerPreference, IsPropertySaveable.Yes)]
|
||||
public PvpTeamSelectionMode PvpTeamSelectionMode
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(1, IsPropertySaveable.Yes)]
|
||||
public int PvpAutoBalanceThreshold
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0.8f, IsPropertySaveable.Yes)]
|
||||
public float StartWhenClientsReadyRatio
|
||||
@@ -527,6 +565,41 @@ namespace Barotrauma.Networking
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.Yes)]
|
||||
public float PvPStunResist
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(false, IsPropertySaveable.Yes)]
|
||||
public bool PvPSpawnMonsters
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool PvPSpawnWrecks
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize("Random", IsPropertySaveable.Yes)]
|
||||
public Identifier Biome
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize("Random", IsPropertySaveable.Yes)]
|
||||
public Identifier SelectedOutpostName
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
private bool allowSpectating;
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
@@ -541,6 +614,19 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private bool allowAFK;
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool AllowAFK
|
||||
{
|
||||
get { return allowAFK; }
|
||||
private set
|
||||
{
|
||||
if (allowAFK == value) { return; }
|
||||
allowAFK = value;
|
||||
ServerDetailsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool SaveServerLogs
|
||||
{
|
||||
@@ -922,7 +1008,7 @@ namespace Barotrauma.Networking
|
||||
public float KillDisconnectedTime
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -993,10 +1079,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
[Serialize("All", IsPropertySaveable.Yes)]
|
||||
public string MissionType
|
||||
public string MissionTypes
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get => string.Join(",", AllowedRandomMissionTypes.Select(t => t.ToIdentifier()));
|
||||
set
|
||||
{
|
||||
AllowedRandomMissionTypes = value.Split(",").Select(t => t.ToIdentifier()).Distinct().ToList();
|
||||
ValidateMissionTypes();
|
||||
}
|
||||
}
|
||||
|
||||
[Serialize(8, IsPropertySaveable.Yes)]
|
||||
@@ -1006,10 +1096,13 @@ namespace Barotrauma.Networking
|
||||
set { maxPlayers = MathHelper.Clamp(value, 1, NetConfig.MaxPlayers); }
|
||||
}
|
||||
|
||||
public List<MissionType> AllowedRandomMissionTypes
|
||||
/// <summary>
|
||||
/// Wrapper for <see cref="MissionTypes"/>.
|
||||
/// </summary>
|
||||
public List<Identifier> AllowedRandomMissionTypes
|
||||
{
|
||||
get;
|
||||
set;
|
||||
private set;
|
||||
}
|
||||
|
||||
[Serialize(60f * 60.0f, IsPropertySaveable.Yes)]
|
||||
@@ -1035,6 +1128,24 @@ namespace Barotrauma.Networking
|
||||
[Serialize(0f, IsPropertySaveable.Yes)]
|
||||
public float NewCampaignDefaultSalary { get; set; }
|
||||
|
||||
[Serialize(true, IsPropertySaveable.Yes)]
|
||||
public bool TrackOpponentInPvP { get; set; }
|
||||
|
||||
[Serialize(7, IsPropertySaveable.Yes)]
|
||||
public int DisembarkPointAllowance { get; set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.Yes), DoNotSyncOverNetwork]
|
||||
public Identifier[] SelectedCoalitionPerks { get; set; } = Array.Empty<Identifier>();
|
||||
|
||||
/// <summary>
|
||||
/// The score required to win a PvP mission (if it is a mission with some scoring system, such as a deathmatch mission)
|
||||
/// </summary>
|
||||
[Serialize(200, IsPropertySaveable.Yes)]
|
||||
public int WinScorePvP { get; set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.Yes), DoNotSyncOverNetwork]
|
||||
public Identifier[] SelectedSeparatistsPerks { get; set; } = Array.Empty<Identifier>();
|
||||
|
||||
public CampaignSettings CampaignSettings { get; set; } = CampaignSettings.Empty;
|
||||
|
||||
private bool allowSubVoting;
|
||||
@@ -1093,6 +1204,9 @@ namespace Barotrauma.Networking
|
||||
public void SetPassword(string password)
|
||||
{
|
||||
this.password = string.IsNullOrEmpty(password) ? null : password;
|
||||
#if SERVER
|
||||
GameMain.Server?.ClearRecentlyDisconnectedClients();
|
||||
#endif
|
||||
}
|
||||
|
||||
public static byte[] SaltPassword(byte[] password, int salt)
|
||||
@@ -1136,7 +1250,7 @@ namespace Barotrauma.Networking
|
||||
=> monsterEnabled.Keys
|
||||
.OrderBy(k => CharacterPrefab.Prefabs[k].UintIdentifier)
|
||||
.ToImmutableArray();
|
||||
|
||||
|
||||
public bool ReadMonsterEnabled(IReadMessage inc)
|
||||
{
|
||||
bool changed = false;
|
||||
@@ -1214,6 +1328,75 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
public void WritePerks(IWriteMessage msg)
|
||||
{
|
||||
List<DisembarkPerkPrefab> coalitionPerks = GetPerks(SelectedCoalitionPerks);
|
||||
|
||||
msg.WriteVariableUInt32((uint)coalitionPerks.Count);
|
||||
foreach (DisembarkPerkPrefab perk in coalitionPerks)
|
||||
{
|
||||
msg.WriteUInt32(perk.UintIdentifier);
|
||||
}
|
||||
|
||||
List<DisembarkPerkPrefab> separatistsPerks = GetPerks(SelectedSeparatistsPerks);
|
||||
msg.WriteVariableUInt32((uint)separatistsPerks.Count);
|
||||
foreach (DisembarkPerkPrefab perk in separatistsPerks)
|
||||
{
|
||||
msg.WriteUInt32(perk.UintIdentifier);
|
||||
}
|
||||
|
||||
static List<DisembarkPerkPrefab> GetPerks(Identifier[] perkIdentifiers)
|
||||
{
|
||||
List<DisembarkPerkPrefab> perks = new();
|
||||
foreach (Identifier perk in perkIdentifiers)
|
||||
{
|
||||
if (!DisembarkPerkPrefab.Prefabs.TryGet(perk, out var prefab)) { continue; }
|
||||
perks.Add(prefab);
|
||||
}
|
||||
return perks;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ReadPerks(IReadMessage msg)
|
||||
{
|
||||
uint coalitionCount = msg.ReadVariableUInt32();
|
||||
Identifier[] newCoalitionPerks = new Identifier[coalitionCount];
|
||||
for (int i = 0; i < coalitionCount; i++)
|
||||
{
|
||||
uint id = msg.ReadUInt32();
|
||||
DisembarkPerkPrefab prefab = DisembarkPerkPrefab.Prefabs.Find(p => p.UintIdentifier == id);
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Perk not found: {id}");
|
||||
continue;
|
||||
}
|
||||
|
||||
newCoalitionPerks[i] = prefab.Identifier;
|
||||
}
|
||||
|
||||
uint separatistsCount = msg.ReadVariableUInt32();
|
||||
Identifier[] newSeparatistsPerks = new Identifier[separatistsCount];
|
||||
for (int i = 0; i < separatistsCount; i++)
|
||||
{
|
||||
uint id = msg.ReadUInt32();
|
||||
DisembarkPerkPrefab prefab = DisembarkPerkPrefab.Prefabs.Find(p => p.UintIdentifier == id);
|
||||
if (prefab == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"Perk not found: {id}");
|
||||
continue;
|
||||
}
|
||||
|
||||
newSeparatistsPerks[i] = prefab.Identifier;
|
||||
}
|
||||
|
||||
bool changed = !SelectedCoalitionPerks.SequenceEqual(newCoalitionPerks) ||
|
||||
!SelectedSeparatistsPerks.SequenceEqual(newSeparatistsPerks);
|
||||
|
||||
SelectedCoalitionPerks = newCoalitionPerks;
|
||||
SelectedSeparatistsPerks = newSeparatistsPerks;
|
||||
return changed;
|
||||
}
|
||||
|
||||
public void ReadHiddenSubs(IReadMessage msg)
|
||||
{
|
||||
var subList = GameMain.NetLobbyScreen.GetSubList();
|
||||
@@ -1285,5 +1468,34 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that there's at least one mission type selected for both co-op and PvP game modes.
|
||||
/// </summary>
|
||||
private void ValidateMissionTypes()
|
||||
{
|
||||
ValidateMissionTypes(MissionPrefab.CoOpMissionClasses.Values);
|
||||
ValidateMissionTypes(MissionPrefab.PvPMissionClasses.Values);
|
||||
}
|
||||
|
||||
private void ValidateMissionTypes(IEnumerable<Type> availableMissionClasses)
|
||||
{
|
||||
if (AllowedRandomMissionTypes.Contains(Tags.MissionTypeAll)) { return; }
|
||||
//no selectable mission types that match any of the available mission classes
|
||||
//(e.g. no mission types that use pvp-specific mission classes)
|
||||
if (MissionPrefab.GetAllMultiplayerSelectableMissionTypes().None(missionType =>
|
||||
MissionPrefab.Prefabs.Any(p => p.Type == missionType && AllowedRandomMissionTypes.Contains(p.Type) && availableMissionClasses.Contains(p.MissionClass))))
|
||||
{
|
||||
var matchingMission = MissionPrefab.Prefabs.First(p => availableMissionClasses.Contains(p.MissionClass));
|
||||
if (matchingMission == null)
|
||||
{
|
||||
DebugConsole.ThrowError($"No missions found for any of the available mission classes ({string.Join(",", availableMissionClasses)})");
|
||||
}
|
||||
else
|
||||
{
|
||||
AllowedRandomMissionTypes.Add(matchingMission.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user