Merge branch 'dev' of https://github.com/Regalis11/Barotrauma into unstable

This commit is contained in:
EvilFactory
2022-09-29 12:13:55 -03:00
602 changed files with 19759 additions and 16312 deletions
@@ -18,29 +18,39 @@ namespace Barotrauma.Networking
{
if (!PropEquals(lastSyncedValue, Value))
{
LastUpdateID = (UInt16)(GameMain.NetLobbyScreen.LastUpdateID);
LastUpdateID = GameMain.NetLobbyScreen.LastUpdateID;
lastSyncedValue = Value;
}
}
public void ForceUpdate()
{
LastUpdateID = GameMain.NetLobbyScreen.LastUpdateID++;
}
}
public static readonly string ClientPermissionsFile = "Data" + Path.DirectorySeparatorChar + "clientpermissions.xml";
public static readonly char SubmarineSeparatorChar = '|';
public readonly Dictionary<NetFlags, UInt16> LastUpdateIdForFlag = new Dictionary<NetFlags, UInt16>();
public UInt16 LastPropertyUpdateId { get; private set; } = 1;
public readonly Dictionary<NetFlags, UInt16> LastUpdateIdForFlag
= ((NetFlags[])Enum.GetValues(typeof(NetFlags)))
.Select(f => (f, (ushort)1))
.ToDictionary();
public void UpdateFlag(NetFlags flag)
=> LastUpdateIdForFlag[flag] = (UInt16)(GameMain.NetLobbyScreen.LastUpdateID + 1);
public NetFlags UnsentFlags()
=> LastUpdateIdForFlag.Keys
.Where(k => NetIdUtils.IdMoreRecent(LastUpdateIdForFlag[k], GameMain.NetLobbyScreen.LastUpdateID))
.Aggregate(NetFlags.None, (f1, f2) => f1 | f2);
private bool IsFlagRequired(Client c, NetFlags flag)
=> NetIdUtils.IdMoreRecent(LastUpdateIdForFlag[flag], c.LastRecvLobbyUpdate);
public NetFlags GetRequiredFlags(Client c)
=> LastUpdateIdForFlag.Keys
.Where(k => IsFlagRequired(c, k))
.Concat(NetFlags.None.ToEnumerable()) //prevents InvalidOperationException in Aggregate
.Aggregate((f1, f2) => f1 | f2);
.Aggregate(NetFlags.None, (f1, f2) => f1 | f2);
partial void InitProjSpecific()
{
@@ -48,6 +58,15 @@ namespace Barotrauma.Networking
LoadClientPermissions();
}
public void ForcePropertyUpdate()
{
UpdateFlag(NetFlags.Properties);
foreach (NetPropertyData property in netProperties.Values)
{
property.ForceUpdate();
}
}
private void WriteNetProperties(IWriteMessage outMsg, Client c)
{
foreach (UInt32 key in netProperties.Keys)
@@ -56,40 +75,39 @@ namespace Barotrauma.Networking
property.SyncValue();
if (NetIdUtils.IdMoreRecent(property.LastUpdateID, c.LastRecvLobbyUpdate))
{
outMsg.Write(key);
outMsg.WriteUInt32(key);
netProperties[key].Write(outMsg);
}
}
outMsg.Write((UInt32)0);
outMsg.WriteUInt32((UInt32)0);
}
public void ServerAdminWrite(IWriteMessage outMsg, Client c)
{
c.LastSentServerSettingsUpdate = LastPropertyUpdateId;
c.LastSentServerSettingsUpdate = LastUpdateIdForFlag[NetFlags.Properties];
WriteNetProperties(outMsg, c);
WriteMonsterEnabled(outMsg);
BanList.ServerAdminWrite(outMsg, c);
Whitelist.ServerAdminWrite(outMsg, c);
}
public void ServerWrite(IWriteMessage outMsg, Client c)
{
NetFlags requiredFlags = GetRequiredFlags(c);
outMsg.Write((byte)requiredFlags);
outMsg.WriteByte((byte)requiredFlags);
if (requiredFlags.HasFlag(NetFlags.Name))
{
outMsg.Write(ServerName);
outMsg.WriteString(ServerName);
}
if (requiredFlags.HasFlag(NetFlags.Message))
{
outMsg.Write(ServerMessageText);
outMsg.WriteString(ServerMessageText);
}
outMsg.Write((byte)PlayStyle);
outMsg.Write((byte)MaxPlayers);
outMsg.Write(HasPassword);
outMsg.Write(IsPublic);
outMsg.Write(AllowFileTransfers);
outMsg.WriteByte((byte)PlayStyle);
outMsg.WriteByte((byte)MaxPlayers);
outMsg.WriteBoolean(HasPassword);
outMsg.WriteBoolean(IsPublic);
outMsg.WriteBoolean(AllowFileTransfers);
outMsg.WritePadBits();
outMsg.WriteRangedInteger(TickRate, 1, 60);
@@ -104,16 +122,18 @@ namespace Barotrauma.Networking
}
if (c.HasPermission(Networking.ClientPermissions.ManageSettings)
&& !NetIdUtils.IdMoreRecentOrMatches(c.LastRecvServerSettingsUpdate, LastPropertyUpdateId))
&& NetIdUtils.IdMoreRecent(
newID: LastUpdateIdForFlag[NetFlags.Properties],
oldID: c.LastRecvServerSettingsUpdate))
{
outMsg.Write(true);
outMsg.WriteBoolean(true);
outMsg.WritePadBits();
ServerAdminWrite(outMsg, c);
}
else
{
outMsg.Write(false);
outMsg.WriteBoolean(false);
outMsg.WritePadBits();
}
}
@@ -171,12 +191,10 @@ namespace Barotrauma.Networking
propertiesChanged |= changedMonsterSettings;
if (changedMonsterSettings) { ReadMonsterEnabled(incMsg); }
propertiesChanged |= BanList.ServerAdminRead(incMsg, c);
propertiesChanged |= Whitelist.ServerAdminRead(incMsg, c);
if (propertiesChanged)
{
UpdateFlag(NetFlags.Properties);
LastPropertyUpdateId = (UInt16)(GameMain.NetLobbyScreen.LastUpdateID + 1);
}
changed |= propertiesChanged;
}
@@ -192,27 +210,32 @@ namespace Barotrauma.Networking
{
int orBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
GameMain.NetLobbyScreen.MissionType = (Barotrauma.MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);
GameMain.NetLobbyScreen.MissionType = (MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);
int traitorSetting = (int)TraitorsEnabled + incMsg.ReadByte() - 1;
if (traitorSetting < 0) traitorSetting = 2;
if (traitorSetting > 2) traitorSetting = 0;
if (traitorSetting < 0) { traitorSetting = 2; }
if (traitorSetting > 2) { traitorSetting = 0; }
TraitorsEnabled = (YesNoMaybe)traitorSetting;
int botCount = BotCount + incMsg.ReadByte() - 1;
if (botCount < 0) botCount = MaxBotCount;
if (botCount > MaxBotCount) botCount = 0;
if (botCount < 0) { botCount = MaxBotCount; }
if (botCount > MaxBotCount) { botCount = 0; }
BotCount = botCount;
int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1;
if (botSpawnMode < 0) botSpawnMode = 1;
if (botSpawnMode > 1) botSpawnMode = 0;
if (botSpawnMode < 0) { botSpawnMode = 1; }
if (botSpawnMode > 1) { botSpawnMode = 0; }
BotSpawnMode = (BotSpawnMode)botSpawnMode;
float levelDifficulty = incMsg.ReadSingle();
if (levelDifficulty >= 0.0f) SelectedLevelDifficulty = levelDifficulty;
if (levelDifficulty >= 0.0f) { SelectedLevelDifficulty = levelDifficulty; }
UseRespawnShuttle = incMsg.ReadBoolean();
bool changedUseRespawnShuttle = incMsg.ReadBoolean();
bool useRespawnShuttle = incMsg.ReadBoolean();
if (changedUseRespawnShuttle)
{
UseRespawnShuttle = useRespawnShuttle;
}
bool changedAutoRestart = incMsg.ReadBoolean();
bool autoRestart = incMsg.ReadBoolean();
@@ -444,31 +467,27 @@ namespace Barotrauma.Networking
{
ClientPermissions.Clear();
if (!File.Exists(ClientPermissionsFile))
{
if (File.Exists("Data/clientpermissions.txt"))
{
LoadClientPermissionsOld("Data/clientpermissions.txt");
}
return;
}
if (!File.Exists(ClientPermissionsFile)) { return; }
XDocument doc = XMLExtensions.TryLoadXml(ClientPermissionsFile);
if (doc == null) { return; }
foreach (XElement clientElement in doc.Root.Elements())
{
string clientName = clientElement.GetAttributeString("name", "");
string clientEndPoint = clientElement.GetAttributeString("endpoint", null) ?? clientElement.GetAttributeString("ip", "");
string steamIdStr = clientElement.GetAttributeString("steamid", "");
string addressStr = clientElement.GetAttributeString("address", null)
?? clientElement.GetAttributeString("endpoint", null)
?? clientElement.GetAttributeString("ip", "");
string accountIdStr = clientElement.GetAttributeString("accountid", null)
?? clientElement.GetAttributeString("steamid", "");
if (string.IsNullOrWhiteSpace(clientName))
{
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have a name and an IP address.");
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have a name.");
continue;
}
if (string.IsNullOrWhiteSpace(clientEndPoint) && string.IsNullOrWhiteSpace(steamIdStr))
if (string.IsNullOrWhiteSpace(addressStr) && string.IsNullOrWhiteSpace(accountIdStr))
{
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have an IP address or a Steam ID.");
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - all clients must have an endpoint or a Steam ID.");
continue;
}
@@ -542,69 +561,33 @@ namespace Barotrauma.Networking
}
}
if (!string.IsNullOrEmpty(steamIdStr))
if (!string.IsNullOrEmpty(accountIdStr))
{
if (ulong.TryParse(steamIdStr, out ulong steamID))
if (AccountId.Parse(accountIdStr).TryUnwrap(out var accountId))
{
ClientPermissions.Add(new SavedClientPermission(clientName, steamID, permissions, permittedCommands));
ClientPermissions.Add(new SavedClientPermission(clientName, accountId, permissions, permittedCommands));
}
else
{
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + steamIdStr + "\" is not a valid Steam ID.");
continue;
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + accountIdStr + "\" is not a valid account ID.");
}
}
else
{
ClientPermissions.Add(new SavedClientPermission(clientName, clientEndPoint, permissions, permittedCommands));
}
}
}
/// <summary>
/// Method for loading old .txt client permission files to provide backwards compatibility
/// </summary>
private void LoadClientPermissionsOld(string file)
{
if (!File.Exists(file)) return;
string[] lines;
try
{
lines = File.ReadAllLines(file);
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to open client permission file " + ClientPermissionsFile, e);
return;
}
ClientPermissions.Clear();
foreach (string line in lines)
{
string[] separatedLine = line.Split('|');
if (separatedLine.Length < 3) { continue; }
string name = string.Join("|", separatedLine.Take(separatedLine.Length - 2));
string ip = separatedLine[separatedLine.Length - 2];
ClientPermissions permissions;
if (Enum.TryParse(separatedLine.Last(), out permissions))
{
ClientPermissions.Add(new SavedClientPermission(name, ip, permissions, new HashSet<DebugConsole.Command>()));
if (Address.Parse(addressStr).TryUnwrap(out var address))
{
ClientPermissions.Add(new SavedClientPermission(clientName, address, permissions, permittedCommands));
}
else
{
DebugConsole.ThrowError("Error in " + ClientPermissionsFile + " - \"" + addressStr + "\" is not a valid endpoint.");
}
}
}
}
public void SaveClientPermissions()
{
//delete old client permission file
if (File.Exists("Data/clientpermissions.txt"))
{
File.Delete("Data/clientpermissions.txt");
}
GameServer.Log("Saving client permissions", ServerLog.MessageType.ServerMessage);
XDocument doc = new XDocument(new XElement("ClientPermissions"));
@@ -612,6 +595,7 @@ namespace Barotrauma.Networking
foreach (SavedClientPermission clientPermission in ClientPermissions)
{
var matchingPreset = PermissionPreset.List.Find(p => p.MatchesPermissions(clientPermission.Permissions, clientPermission.PermittedCommands));
#warning TODO: this is broken because of localization
if (matchingPreset != null && matchingPreset.Name == "None")
{
continue;
@@ -620,23 +604,14 @@ namespace Barotrauma.Networking
XElement clientElement = new XElement("Client",
new XAttribute("name", clientPermission.Name));
if (clientPermission.SteamID > 0)
{
clientElement.Add(new XAttribute("steamid", clientPermission.SteamID));
}
else
{
clientElement.Add(new XAttribute("endpoint", clientPermission.EndPoint));
}
clientElement.Add(clientPermission.AddressOrAccountId.TryGet(out AccountId accountId)
? new XAttribute("accountid", accountId.StringRepresentation)
: new XAttribute("address", ((Address)clientPermission.AddressOrAccountId).StringRepresentation));
if (matchingPreset == null)
{
clientElement.Add(new XAttribute("permissions", clientPermission.Permissions.ToString()));
}
else
{
clientElement.Add(new XAttribute("preset", matchingPreset.Name));
}
clientElement.Add(matchingPreset == null
? new XAttribute("permissions", clientPermission.Permissions.ToString())
: new XAttribute("preset", matchingPreset.Name));
if (clientPermission.Permissions.HasFlag(Networking.ClientPermissions.ConsoleCommands))
{
foreach (DebugConsole.Command command in clientPermission.PermittedCommands)