Unstable v0.19.3.0

This commit is contained in:
Juan Pablo Arce
2022-09-02 15:10:56 -03:00
parent 28789616bd
commit 3f2c843247
336 changed files with 7152 additions and 7739 deletions
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
namespace Barotrauma
{
public static class IPExtensions
{
//TODO: remove?
//workaround for .NET Framework 4.5 bug; presumably fixed in later versions
//see https://stackoverflow.com/questions/23608829/why-does-ipaddress-maptoipv4-throw-argumentoutofrangeexception
public static IPAddress MapToIPv4NoThrow(this IPAddress address)
{
byte[] addressBytes = address.GetAddressBytes();
return new IPAddress(addressBytes.Skip(addressBytes.Length - 4).ToArray());
}
}
}
@@ -231,7 +231,19 @@ namespace Barotrauma.IO
public static bool IsPathRooted(string path) => System.IO.Path.IsPathRooted(path);
public static IEnumerable<char> GetInvalidFileNameChars() => System.IO.Path.GetInvalidFileNameChars();
private static readonly ImmutableHashSet<char> invalidFileNameChars = ImmutableHashSet.Create
(
'\"', '<', '>', '|', '\0',
(char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
(char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
(char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
(char)31, ':', '*', '?', '\\', '/'
);
/// <summary>
/// Returns file name characters that are invalid on any of our supported platforms (essentially the list of invalid characters on Windows)
/// </summary>
public static ImmutableHashSet<char> GetInvalidFileNameCharsCrossPlatform() => invalidFileNameChars;
}
public static class Directory
@@ -1,15 +1,13 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Barotrauma.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using Steamworks.Data;
using Color = Microsoft.Xna.Framework.Color;
using System.Text.RegularExpressions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
@@ -20,7 +18,7 @@ namespace Barotrauma
#if OSX
//"/*user*/Library/Application Support/Daedalic Entertainment GmbH/" on Mac
public static string SaveFolder = Path.Combine(
public static readonly string SaveFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"Library",
"Application Support",
@@ -29,7 +27,7 @@ namespace Barotrauma
#else
//"C:/Users/*user*/AppData/Local/Daedalic Entertainment GmbH/" on Windows
//"/home/*user*/.local/share/Daedalic Entertainment GmbH/" on Linux
public static string SaveFolder = Path.Combine(
public static readonly string SaveFolder = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
"Daedalic Entertainment GmbH",
"Barotrauma");
@@ -165,15 +163,6 @@ namespace Barotrauma
return ownedSubmarines;
}
/*public static void LoadMultiplayerCampaignState(string filePath, MultiPlayerCampaign multiplayerCampaign)
{
DebugConsole.Log("Loading save file for an existing game session (" + filePath + ")");
DecompressToDirectory(filePath, TempPath, null);
XDocument doc = XMLExtensions.TryLoadXml(Path.Combine(TempPath, "gamesession.xml"));
if (doc == null) { return; }
gameSession.Load(doc.Root);
}*/
public static XDocument LoadGameSessionDoc(string filePath)
{
DebugConsole.Log("Loading game session doc: " + filePath);
@@ -391,73 +380,69 @@ namespace Barotrauma
}
public static System.IO.Stream DecompressFiletoStream(string fileName)
public static System.IO.Stream DecompressFileToStream(string fileName)
{
using (FileStream originalFileStream = File.Open(fileName, System.IO.FileMode.Open))
{
System.IO.MemoryStream decompressedFileStream = new System.IO.MemoryStream();
using FileStream originalFileStream = File.Open(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.MemoryStream streamToReturn = new System.IO.MemoryStream();
using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))
{
decompressionStream.CopyTo(decompressedFileStream);
return decompressedFileStream;
}
}
using GZipStream gzipStream = new GZipStream(originalFileStream, CompressionMode.Decompress);
gzipStream.CopyTo(streamToReturn);
streamToReturn.Position = 0;
return streamToReturn;
}
private static bool DecompressFile(bool writeFile, string sDir, GZipStream zipStream, ProgressDelegate progress, out string fileName)
private static bool IsExtractionPathValid(string rootDir, string fileDir)
{
string getFullPath(string dir)
=> (string.IsNullOrEmpty(dir)
? Directory.GetCurrentDirectory()
: Path.GetFullPath(dir))
.CleanUpPathCrossPlatform(correctFilenameCase: false);
string rootDirFull = getFullPath(rootDir);
string fileDirFull = getFullPath(fileDir);
return fileDirFull.StartsWith(rootDirFull, StringComparison.OrdinalIgnoreCase);
}
private static bool DecompressFile(bool writeFile, string sDir, System.IO.BinaryReader reader, ProgressDelegate progress, out string fileName)
{
fileName = null;
if (reader.PeekChar() < 0) { return false; }
//Decompress file name
byte[] bytes = new byte[sizeof(int)];
int Readed = Read(zipStream, bytes, sizeof(int));
if (Readed < sizeof(int))
return false;
int iNameLen = BitConverter.ToInt32(bytes, 0);
if (iNameLen > 255)
int nameLen = reader.ReadInt32();
if (nameLen > 255)
{
throw new Exception("Failed to decompress \"" + sDir + "\" (file name length > 255). The file may be corrupted.");
throw new Exception(
$"Failed to decompress \"{sDir}\" (file name length > 255). The file may be corrupted.");
}
bytes = new byte[sizeof(char)];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < iNameLen; i++)
{
Read(zipStream, bytes, sizeof(char));
char c = BitConverter.ToChar(bytes, 0);
sb.Append(c);
}
string sFileName = sb.ToString().Replace('\\', '/');
byte[] strBytes = reader.ReadBytes(nameLen * sizeof(char));
string sFileName = Encoding.Unicode.GetString(strBytes)
.Replace('\\', '/');
fileName = sFileName;
progress?.Invoke(sFileName);
//Decompress file content
bytes = new byte[sizeof(int)];
Read(zipStream, bytes, sizeof(int));
int iFileLen = BitConverter.ToInt32(bytes, 0);
bytes = new byte[iFileLen];
Read(zipStream, bytes, bytes.Length);
int contentLen = reader.ReadInt32();
byte[] contentBytes = reader.ReadBytes(contentLen);
string sFilePath = Path.Combine(sDir, sFileName);
string sFinalDir = Path.GetDirectoryName(sFilePath);
string sDirFull = (string.IsNullOrEmpty(sDir) ? Directory.GetCurrentDirectory() : Path.GetFullPath(sDir)).CleanUpPathCrossPlatform(correctFilenameCase: false);
string sFinalDirFull = (string.IsNullOrEmpty(sFinalDir) ? Directory.GetCurrentDirectory() : Path.GetFullPath(sFinalDir)).CleanUpPathCrossPlatform(correctFilenameCase: false);
if (!sFinalDirFull.StartsWith(sDirFull, StringComparison.OrdinalIgnoreCase))
if (!IsExtractionPathValid(sDir, sFinalDir))
{
throw new InvalidOperationException(
$"Error extracting \"{sFileName}\": cannot be extracted to parent directory");
}
if (!writeFile) { return true; }
if (!Directory.Exists(sFinalDir))
Directory.CreateDirectory(sFinalDir);
Directory.CreateDirectory(sFinalDir);
int maxRetries = 4;
for (int i = 0; i <= maxRetries; i++)
{
@@ -465,7 +450,7 @@ namespace Barotrauma
{
using (FileStream outFile = File.Open(sFilePath, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
outFile.Write(bytes, 0, iFileLen);
outFile.Write(contentBytes, 0, contentLen);
}
break;
}
@@ -479,26 +464,6 @@ namespace Barotrauma
return true;
}
private static int Read(GZipStream zipStream, byte[] bytes, int amount)
{
int read = 0;
// BUG workaround for .NET6 causing save decompression to fail
#if NET6_0
for (int i = 0; i < amount; i++)
{
int result = zipStream.ReadByte();
if (result < 0) { break; }
bytes[i] = (byte) result;
read++;
}
#else
read = zipStream.Read(bytes, 0, amount);
#endif
return read;
}
public static void DecompressToDirectory(string sCompressedFile, string sDir, ProgressDelegate progress)
{
DebugConsole.Log("Decompressing " + sCompressedFile + " to " + sDir + "...");
@@ -507,9 +472,9 @@ namespace Barotrauma
{
try
{
using (FileStream inFile = File.Open(sCompressedFile, System.IO.FileMode.Open, System.IO.FileAccess.Read))
using (GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true))
while (DecompressFile(true, sDir, zipStream, progress, out _)) { };
using (var memStream = DecompressFileToStream(sCompressedFile))
using (System.IO.BinaryReader reader = new System.IO.BinaryReader(memStream))
while (DecompressFile(true, sDir, reader, progress, out _)) { };
break;
}
@@ -530,12 +495,12 @@ namespace Barotrauma
{
try
{
using FileStream inFile = File.Open(sCompressedFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);
using GZipStream zipStream = new GZipStream(inFile, CompressionMode.Decompress, true);
while (DecompressFile(false, "", zipStream, null, out string fileName))
{
paths.Add(fileName);
}
using (var memStream = DecompressFileToStream(sCompressedFile))
using (System.IO.BinaryReader reader = new System.IO.BinaryReader(memStream))
while (DecompressFile(false, "", reader, null, out string fileName))
{
paths.Add(fileName);
}
}
catch (System.IO.IOException e)
{
@@ -3,13 +3,12 @@ using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Barotrauma.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Runtime.CompilerServices;
namespace Barotrauma
{
@@ -161,7 +160,7 @@ namespace Barotrauma
public static string RemoveInvalidFileNameChars(string fileName)
{
var invalidChars = Path.GetInvalidFileNameChars().Concat(new char[] {':', ';', '<', '>', '"', '/', '\\', '|', '?', '*'});
var invalidChars = Path.GetInvalidFileNameCharsCrossPlatform().Concat(new char[] {';'});
foreach (char invalidChar in invalidChars)
{
fileName = fileName.Replace(invalidChar.ToString(), "");
@@ -424,7 +423,7 @@ namespace Barotrauma
for (int i = 0; i < numberOfBits; i++)
{
bool bit = originalBuffer.ReadBoolean();
buffer.Write(bit);
buffer.WriteBoolean(bit);
}
buffer.BitPosition = 0;
@@ -713,9 +712,14 @@ namespace Barotrauma
return e;
}
public static void ThrowIfNull<T>(T o)
public static void ThrowIfNull<T>([NotNull] T o)
{
if (o is null) { throw new ArgumentNullException(); }
}
public static string GetFormattedPercentage(float v)
{
return TextManager.GetWithVariable("percentageformat", "[value]", ((int)MathF.Round(v * 100)).ToString()).Value;
}
}
}