v1.5.7.0 (Summer Update)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
#nullable enable
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A serializable dictionary that can be sent over the network.
|
||||
/// </summary>
|
||||
/// <param name="Pairs">The backing array of key-value pairs that gets serialized.</param>
|
||||
/// <typeparam name="T">Key</typeparam>
|
||||
/// <typeparam name="U">Value</typeparam>
|
||||
/// <remarks>
|
||||
/// This isn't a full implementation of a dictionary, but rather a simple wrapper around a list of key-value pairs
|
||||
/// that can be serialized and deserialized in an INetSerializableStruct.
|
||||
/// Normally there wouldn't be duplicate keys in a dictionary, but this implementation doesn't enforce that.
|
||||
/// </remarks>
|
||||
[NetworkSerialize]
|
||||
public readonly record struct NetDictionary<T, U>(ImmutableArray<NetPair<T, U>> Pairs) : INetSerializableStruct where T : notnull
|
||||
{
|
||||
public Dictionary<T, U> ToDictionary()
|
||||
=> Pairs.ToDictionary(
|
||||
static pair => pair.First,
|
||||
static pair => pair.Second);
|
||||
|
||||
public ImmutableDictionary<T, U> ToImmutableDictionary()
|
||||
=> Pairs.ToImmutableDictionary(
|
||||
static pair => pair.First,
|
||||
static pair => pair.Second);
|
||||
}
|
||||
|
||||
public static class DictionaryExtensions
|
||||
{
|
||||
public static NetDictionary<T, U> ToNetDictionary<T, U>(this Dictionary<T, U> source) where T : notnull
|
||||
=> new NetDictionary<T, U>(source.Select(static pair => new NetPair<T, U>(pair.Key, pair.Value)).ToImmutableArray());
|
||||
|
||||
public static NetDictionary<T, U> ToNetDictionary<T, U>(this ImmutableDictionary<T, U> source) where T : notnull
|
||||
=> new NetDictionary<T, U>(source.Select(static pair => new NetPair<T, U>(pair.Key, pair.Value)).ToImmutableArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#nullable enable
|
||||
namespace Barotrauma
|
||||
{
|
||||
[NetworkSerialize]
|
||||
public readonly record struct NetPair<T, U>(T First, U Second) : INetSerializableStruct;
|
||||
}
|
||||
@@ -250,42 +250,92 @@ namespace Barotrauma.IO
|
||||
{
|
||||
public static string GetCurrentDirectory()
|
||||
{
|
||||
// Intentionally crash with all exceptions, if this fails.
|
||||
return System.IO.Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
public static void SetCurrentDirectory(string path)
|
||||
{
|
||||
{
|
||||
// Intentionally crash with all exceptions, if this fails.
|
||||
System.IO.Directory.SetCurrentDirectory(path);
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path)
|
||||
{
|
||||
return System.IO.Directory.GetFiles(path);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.GetFiles(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot get files at \"{path}\": unauthorized access. The folder/file(s) might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetFiles(string path, string pattern, System.IO.SearchOption option = System.IO.SearchOption.AllDirectories)
|
||||
{
|
||||
return System.IO.Directory.GetFiles(path, pattern, option);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.GetFiles(path, pattern, option);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot get files at \"{path}\": unauthorized access. The folder/file(s) might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetDirectories(string path, string searchPattern = "*", System.IO.SearchOption searchOption = System.IO.SearchOption.TopDirectoryOnly)
|
||||
{
|
||||
return System.IO.Directory.GetDirectories(path, searchPattern, searchOption);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.GetDirectories(path, searchPattern, searchOption);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot get directories at \"{path}\": unauthorized access. The folder(s) might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetFileSystemEntries(string path)
|
||||
{
|
||||
return System.IO.Directory.GetFileSystemEntries(path);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.GetFileSystemEntries(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot get file system entries at \"{path}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> EnumerateDirectories(string path, string pattern)
|
||||
{
|
||||
return System.IO.Directory.EnumerateDirectories(path, pattern);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.EnumerateDirectories(path, pattern);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot enumerate directories at \"{path}\": unauthorized access. The folder(s) might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<string> EnumerateFiles(string path, string pattern)
|
||||
{
|
||||
return System.IO.Directory.EnumerateFiles(path, pattern);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.EnumerateFiles(path, pattern);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot enumerate files at \"{path}\": unauthorized access. The file(s)/folder(s) might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Exists(string path)
|
||||
@@ -301,7 +351,15 @@ namespace Barotrauma.IO
|
||||
Validation.CanWrite(path, true);
|
||||
return null;
|
||||
}
|
||||
return System.IO.Directory.CreateDirectory(path);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.CreateDirectory(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot create directory at \"{path}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(string path, bool recursive=true)
|
||||
@@ -312,14 +370,21 @@ namespace Barotrauma.IO
|
||||
return;
|
||||
}
|
||||
//TODO: validate recursion?
|
||||
System.IO.Directory.Delete(path, recursive);
|
||||
try
|
||||
{
|
||||
System.IO.Directory.Delete(path, recursive);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot delete \"{path}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryDelete(string path, bool recursive = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, recursive);
|
||||
Delete(path, recursive);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
@@ -330,7 +395,15 @@ namespace Barotrauma.IO
|
||||
|
||||
public static DateTime GetLastWriteTime(string path)
|
||||
{
|
||||
return System.IO.Directory.GetLastWriteTime(path);
|
||||
try
|
||||
{
|
||||
return System.IO.Directory.GetLastWriteTime(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot get last write time at \"{path}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
return new DateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,14 +413,21 @@ namespace Barotrauma.IO
|
||||
|
||||
public static bool Exists(string path) => System.IO.File.Exists(path);
|
||||
|
||||
public static void Copy(string src, string dest, bool overwrite=false)
|
||||
public static void Copy(string src, string dest, bool overwrite = false)
|
||||
{
|
||||
if (!Validation.CanWrite(dest, false))
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot copy \"{src}\" to \"{dest}\": modifying the contents of this folder/using this extension is not allowed.");
|
||||
return;
|
||||
}
|
||||
System.IO.File.Copy(src, dest, overwrite);
|
||||
try
|
||||
{
|
||||
System.IO.File.Copy(src, dest, overwrite);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot copy \"{src}\" to \"{dest}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Move(string src, string dest)
|
||||
@@ -362,7 +442,14 @@ namespace Barotrauma.IO
|
||||
DebugConsole.ThrowError($"Cannot move \"{src}\" to \"{dest}\": modifying the contents of the destination folder is not allowed");
|
||||
return;
|
||||
}
|
||||
System.IO.File.Move(src, dest);
|
||||
try
|
||||
{
|
||||
System.IO.File.Move(src, dest);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot move \"{src}\" to \"{dest}\": unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(ContentPath path) => Delete(path.Value);
|
||||
@@ -374,7 +461,14 @@ namespace Barotrauma.IO
|
||||
DebugConsole.ThrowError($"Cannot delete file \"{path}\": modifying the contents of this folder/using this extension is not allowed.");
|
||||
return;
|
||||
}
|
||||
System.IO.File.Delete(path);
|
||||
try
|
||||
{
|
||||
System.IO.File.Delete(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot delete {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime GetLastWriteTime(string path)
|
||||
@@ -407,7 +501,15 @@ namespace Barotrauma.IO
|
||||
System.IO.FileAccess.Read :
|
||||
access;
|
||||
var shareVal = share ?? (access == System.IO.FileAccess.Read ? System.IO.FileShare.Read : System.IO.FileShare.None);
|
||||
return new FileStream(path, System.IO.File.Open(path, mode, access, shareVal));
|
||||
try
|
||||
{
|
||||
return new FileStream(path, System.IO.File.Open(path, mode, access, shareVal));
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot open {path} (stream): unauthorized access. The file/folder might be read-only!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static FileStream? OpenRead(string path)
|
||||
@@ -432,7 +534,14 @@ namespace Barotrauma.IO
|
||||
DebugConsole.ThrowError($"Cannot write all bytes to \"{path}\": modifying the files in this folder/with this extension is not allowed.");
|
||||
return;
|
||||
}
|
||||
System.IO.File.WriteAllBytes(path, contents);
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllBytes(path, contents);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot write at {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteAllText(string path, string contents, System.Text.Encoding? encoding = null)
|
||||
@@ -442,7 +551,14 @@ namespace Barotrauma.IO
|
||||
DebugConsole.ThrowError($"Cannot write all text to \"{path}\": modifying the files in this folder/with this extension is not allowed.");
|
||||
return;
|
||||
}
|
||||
System.IO.File.WriteAllText(path, contents, encoding ?? System.Text.Encoding.UTF8);
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllText(path, contents, encoding ?? System.Text.Encoding.UTF8);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot write at {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteAllLines(string path, IEnumerable<string> contents, System.Text.Encoding? encoding = null)
|
||||
@@ -452,22 +568,53 @@ namespace Barotrauma.IO
|
||||
DebugConsole.ThrowError($"Cannot write all lines to \"{path}\": modifying the files in this folder/with this extension is not allowed.");
|
||||
return;
|
||||
}
|
||||
System.IO.File.WriteAllLines(path, contents, encoding ?? System.Text.Encoding.UTF8);
|
||||
try
|
||||
{
|
||||
System.IO.File.WriteAllLines(path, contents, encoding ?? System.Text.Encoding.UTF8);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot write at {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
return System.IO.File.ReadAllBytes(path);
|
||||
try
|
||||
{
|
||||
return System.IO.File.ReadAllBytes(path);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot read {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadAllText(string path, System.Text.Encoding? encoding = null)
|
||||
{
|
||||
return System.IO.File.ReadAllText(path, encoding ?? System.Text.Encoding.UTF8);
|
||||
try
|
||||
{
|
||||
return System.IO.File.ReadAllText(path, encoding ?? System.Text.Encoding.UTF8);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot read {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] ReadAllLines(string path, System.Text.Encoding? encoding = null)
|
||||
{
|
||||
return System.IO.File.ReadAllLines(path, encoding ?? System.Text.Encoding.UTF8);
|
||||
try
|
||||
{
|
||||
return System.IO.File.ReadAllLines(path, encoding ?? System.Text.Encoding.UTF8);
|
||||
}
|
||||
catch (UnauthorizedAccessException e)
|
||||
{
|
||||
DebugConsole.ThrowError($"Cannot read {path}: unauthorized access. The file/folder might be read-only!", e);
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ namespace Barotrauma
|
||||
objects = objects.OrderBy(p => (p as PrefabWithUintIdentifier)?.UintIdentifier ?? 0);
|
||||
}
|
||||
List<T> objectList = objects.ToList();
|
||||
List<float> weights = objectList.Select(o => weightMethod(o)).ToList();
|
||||
List<float> weights = objectList.Select(weightMethod).ToList();
|
||||
return SelectWeightedRandom(objectList, weights, random);
|
||||
}
|
||||
|
||||
@@ -774,6 +774,32 @@ namespace Barotrauma
|
||||
return self.Equals(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a 16-bit audio sample to float value between -1 and 1.
|
||||
/// </summary>
|
||||
public static float ShortAudioSampleToFloat(short value)
|
||||
{
|
||||
return value / 32767f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a float value between -1 and 1 to a 16-bit audio sample.
|
||||
/// </summary>
|
||||
public static short FloatToShortAudioSample(float value)
|
||||
{
|
||||
int temp = (int)(32767 * value);
|
||||
if (temp > short.MaxValue)
|
||||
{
|
||||
temp = short.MaxValue;
|
||||
}
|
||||
else if (temp < short.MinValue)
|
||||
{
|
||||
temp = short.MinValue;
|
||||
}
|
||||
return (short)temp;
|
||||
}
|
||||
|
||||
/// <summary
|
||||
public static SquareLine GetSquareLineBetweenPoints(Vector2 start, Vector2 end, float knobLength = 24f)
|
||||
{
|
||||
Vector2[] points = new Vector2[6];
|
||||
@@ -811,5 +837,39 @@ namespace Barotrauma
|
||||
|
||||
return new SquareLine(points, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns closest point on a rectangle to a given point.
|
||||
/// If the point is inside the rectangle, the point itself is returned.
|
||||
/// </summary>
|
||||
/// <param name="rect"></param>
|
||||
/// <param name="point"></param>
|
||||
/// <returns></returns>
|
||||
public static Vector2 GetClosestPointOnRectangle(RectangleF rect, Vector2 point)
|
||||
{
|
||||
Vector2 closest = new Vector2(
|
||||
MathHelper.Clamp(point.X, rect.Left, rect.Right),
|
||||
MathHelper.Clamp(point.Y, rect.Top, rect.Bottom));
|
||||
|
||||
if (point.X < rect.Left)
|
||||
{
|
||||
closest.X = rect.Left;
|
||||
}
|
||||
else if (point.X > rect.Right)
|
||||
{
|
||||
closest.X = rect.Right;
|
||||
}
|
||||
|
||||
if (point.Y < rect.Top)
|
||||
{
|
||||
closest.Y = rect.Top;
|
||||
}
|
||||
else if (point.Y > rect.Bottom)
|
||||
{
|
||||
closest.Y = rect.Bottom;
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user