Unstable 0.17.0.0

This commit is contained in:
Markus Isberg
2022-02-26 02:43:01 +09:00
parent a83f375681
commit 3974067915
913 changed files with 32472 additions and 32364 deletions
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -69,8 +70,25 @@ namespace Barotrauma
return doc;
}
public static XDocument TryLoadXml(ContentPath path) => TryLoadXml(path.Value);
public static XDocument TryLoadXml(string filePath)
{
var doc = TryLoadXml(filePath, out var exception);
if (exception != null)
{
DebugConsole.ThrowError($"Couldn't load xml document \"{filePath}\"!", exception);
}
else if (doc is null)
{
DebugConsole.ThrowError($"File \"{filePath}\" could not be loaded: Document or the root element is invalid!");
}
return doc;
}
public static XDocument TryLoadXml(string filePath, out Exception exception)
{
exception = null;
XDocument doc;
try
{
@@ -81,42 +99,16 @@ namespace Barotrauma
}
catch (Exception e)
{
DebugConsole.ThrowError("Couldn't load xml document \"" + filePath + "\"!", e);
exception = e;
return null;
}
if (doc?.Root == null)
{
DebugConsole.ThrowError("File \"" + filePath + "\" could not be loaded: Document or the root element is invalid!");
return null;
}
return doc;
}
public static XDocument LoadXml(string filePath)
{
XDocument doc = null;
ToolBox.IsProperFilenameCase(filePath);
if (File.Exists(filePath))
{
try
{
using FileStream stream = File.Open(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
using XmlReader reader = CreateReader(stream, Path.GetFullPath(filePath));
doc = XDocument.Load(reader);
}
catch
{
return null;
}
if (doc.Root == null) { return null; }
}
return doc;
}
public static object GetAttributeObject(XAttribute attribute)
{
if (attribute == null) { return null; }
@@ -151,8 +143,48 @@ namespace Barotrauma
public static string GetAttributeString(this XElement element, string name, string defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
return GetAttributeString(element.Attribute(name), defaultValue);
if (element?.GetAttribute(name) == null) { return defaultValue; }
string str = GetAttributeString(element.GetAttribute(name), defaultValue);
#if DEBUG
if (!str.IsNullOrEmpty() &&
(str.Contains("%ModDir", StringComparison.OrdinalIgnoreCase)
|| str.CleanUpPathCrossPlatform(correctFilenameCase: false).StartsWith("Content/", StringComparison.OrdinalIgnoreCase)))
{
DebugConsole.ThrowError($"Use {nameof(GetAttributeContentPath)} instead of {nameof(GetAttributeString)}\n{Environment.StackTrace.CleanupStackTrace()}");
if (Debugger.IsAttached) { Debugger.Break(); }
}
#endif
return str;
}
public static string GetAttributeStringUnrestricted(this XElement element, string name, string defaultValue)
{
#warning TODO: remove?
if (element?.GetAttribute(name) == null) { return defaultValue; }
return GetAttributeString(element.GetAttribute(name), defaultValue);
}
public static bool DoesAttributeReferenceFileNameAlone(this XElement element, string name)
{
string texName = element.GetAttributeStringUnrestricted(name, "");
return !texName.IsNullOrEmpty() & !texName.Contains("/") && !texName.Contains("%ModDir", StringComparison.OrdinalIgnoreCase);
}
public static ContentPath GetAttributeContentPath(this XElement element, string name,
ContentPackage contentPackage)
{
if (element?.GetAttribute(name) == null) { return null; }
return ContentPath.FromRaw(contentPackage, GetAttributeString(element.GetAttribute(name), null));
}
public static Identifier GetAttributeIdentifier(this XElement element, string name, string defaultValue)
{
return element.GetAttributeString(name, defaultValue).ToIdentifier();
}
public static Identifier GetAttributeIdentifier(this XElement element, string name, Identifier defaultValue)
{
return element.GetAttributeIdentifier(name, defaultValue.Value);
}
private static string GetAttributeString(XAttribute attribute, string defaultValue)
@@ -163,43 +195,41 @@ namespace Barotrauma
public static string[] GetAttributeStringArray(this XElement element, string name, string[] defaultValue, bool trim = true, bool convertToLowerInvariant = false)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
string stringValue = element.Attribute(name).Value;
string stringValue = element.GetAttribute(name).Value;
if (string.IsNullOrEmpty(stringValue)) { return defaultValue; }
string[] splitValue = stringValue.Split(',', '');
if (convertToLowerInvariant)
for (int i = 0; i < splitValue.Length; i++)
{
for (int i = 0; i < splitValue.Length; i++)
{
splitValue[i] = splitValue[i].ToLowerInvariant();
}
}
if (trim)
{
for (int i = 0; i < splitValue.Length; i++)
{
splitValue[i] = splitValue[i].Trim();
}
if (convertToLowerInvariant) { splitValue[i] = splitValue[i].ToLowerInvariant(); }
if (trim) { splitValue[i] = splitValue[i].Trim(); }
}
return splitValue;
}
public static Identifier[] GetAttributeIdentifierArray(this XElement element, string name, Identifier[] defaultValue, bool trim = true)
{
return element.GetAttributeStringArray(name, null, trim: trim, convertToLowerInvariant: false)
?.ToIdentifiers()
?? defaultValue;
}
public static float GetAttributeFloat(this XElement element, float defaultValue, params string[] matchingAttributeName)
{
if (element == null) { return defaultValue; }
foreach (string name in matchingAttributeName)
{
if (element.Attribute(name) == null) { continue; }
if (element.GetAttribute(name) == null) { continue; }
float val;
try
{
string strVal = element.Attribute(name).Value;
string strVal = element.GetAttribute(name).Value;
if (strVal.LastOrDefault() == 'f')
{
strVal = strVal.Substring(0, strVal.Length - 1);
@@ -219,12 +249,12 @@ namespace Barotrauma
public static float GetAttributeFloat(this XElement element, string name, float defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
float val = defaultValue;
try
{
string strVal = element.Attribute(name).Value;
string strVal = element.GetAttribute(name).Value;
if (strVal.LastOrDefault() == 'f')
{
strVal = strVal.Substring(0, strVal.Length - 1);
@@ -286,9 +316,9 @@ namespace Barotrauma
public static float[] GetAttributeFloatArray(this XElement element, string name, float[] defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
string stringValue = element.Attribute(name).Value;
string stringValue = element.GetAttribute(name).Value;
if (string.IsNullOrEmpty(stringValue)) { return defaultValue; }
string[] splitValue = stringValue.Split(',');
@@ -315,15 +345,15 @@ namespace Barotrauma
public static int GetAttributeInt(this XElement element, string name, int defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
int val = defaultValue;
try
{
if (!Int32.TryParse(element.Attribute(name).Value, NumberStyles.Any, CultureInfo.InvariantCulture, out val))
if (!Int32.TryParse(element.GetAttribute(name).Value, NumberStyles.Any, CultureInfo.InvariantCulture, out val))
{
val = (int)float.Parse(element.Attribute(name).Value, CultureInfo.InvariantCulture);
val = (int)float.Parse(element.GetAttribute(name).Value, CultureInfo.InvariantCulture);
}
}
catch (Exception e)
@@ -336,13 +366,13 @@ namespace Barotrauma
public static uint GetAttributeUInt(this XElement element, string name, uint defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
uint val = defaultValue;
try
{
val = UInt32.Parse(element.Attribute(name).Value);
val = UInt32.Parse(element.GetAttribute(name).Value);
}
catch (Exception e)
{
@@ -354,13 +384,31 @@ namespace Barotrauma
public static UInt64 GetAttributeUInt64(this XElement element, string name, UInt64 defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
UInt64 val = defaultValue;
try
{
val = UInt64.Parse(element.Attribute(name).Value);
val = UInt64.Parse(element.GetAttribute(name).Value, NumberStyles.Any, CultureInfo.InvariantCulture);
}
catch (Exception e)
{
DebugConsole.ThrowError("Error in " + element + "! ", e);
}
return val;
}
public static Version GetAttributeVersion(this XElement element, string name, Version defaultValue)
{
if (element?.GetAttribute(name) == null) return defaultValue;
Version val = defaultValue;
try
{
val = Version.Parse(element.GetAttribute(name).Value);
}
catch (Exception e)
{
@@ -372,13 +420,13 @@ namespace Barotrauma
public static UInt64 GetAttributeSteamID(this XElement element, string name, UInt64 defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
UInt64 val = defaultValue;
try
{
val = Steam.SteamManager.SteamIDStringToUInt64(element.Attribute(name).Value);
val = Steam.SteamManager.SteamIDStringToUInt64(element.GetAttribute(name).Value);
}
catch (Exception e)
{
@@ -390,9 +438,9 @@ namespace Barotrauma
public static int[] GetAttributeIntArray(this XElement element, string name, int[] defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
string stringValue = element.Attribute(name).Value;
string stringValue = element.GetAttribute(name).Value;
if (string.IsNullOrEmpty(stringValue)) { return defaultValue; }
string[] splitValue = stringValue.Split(',');
@@ -414,9 +462,9 @@ namespace Barotrauma
}
public static ushort[] GetAttributeUshortArray(this XElement element, string name, ushort[] defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
string stringValue = element.Attribute(name).Value;
string stringValue = element.GetAttribute(name).Value;
if (string.IsNullOrEmpty(stringValue)) { return defaultValue; }
string[] splitValue = stringValue.Split(',');
@@ -448,8 +496,8 @@ namespace Barotrauma
public static bool GetAttributeBool(this XElement element, string name, bool defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
return element.Attribute(name).GetAttributeBool(defaultValue);
if (element?.GetAttribute(name) == null) { return defaultValue; }
return element.GetAttribute(name).GetAttributeBool(defaultValue);
}
public static bool GetAttributeBool(this XAttribute attribute, bool defaultValue)
@@ -472,45 +520,45 @@ namespace Barotrauma
public static Point GetAttributePoint(this XElement element, string name, Point defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
return ParsePoint(element.Attribute(name).Value);
if (element?.GetAttribute(name) == null) { return defaultValue; }
return ParsePoint(element.GetAttribute(name).Value);
}
public static Vector2 GetAttributeVector2(this XElement element, string name, Vector2 defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
return ParseVector2(element.Attribute(name).Value);
if (element?.GetAttribute(name) == null) { return defaultValue; }
return ParseVector2(element.GetAttribute(name).Value);
}
public static Vector3 GetAttributeVector3(this XElement element, string name, Vector3 defaultValue)
{
if (element == null || element.Attribute(name) == null) { return defaultValue; }
return ParseVector3(element.Attribute(name).Value);
if (element == null || element.GetAttribute(name) == null) { return defaultValue; }
return ParseVector3(element.GetAttribute(name).Value);
}
public static Vector4 GetAttributeVector4(this XElement element, string name, Vector4 defaultValue)
{
if (element == null || element.Attribute(name) == null) { return defaultValue; }
return ParseVector4(element.Attribute(name).Value);
if (element == null || element.GetAttribute(name) == null) { return defaultValue; }
return ParseVector4(element.GetAttribute(name).Value);
}
public static Color GetAttributeColor(this XElement element, string name, Color defaultValue)
{
if (element == null || element.Attribute(name) == null) { return defaultValue; }
return ParseColor(element.Attribute(name).Value);
if (element == null || element.GetAttribute(name) == null) { return defaultValue; }
return ParseColor(element.GetAttribute(name).Value);
}
public static Color? GetAttributeColor(this XElement element, string name)
{
if (element == null || element.Attribute(name) == null) { return null; }
return ParseColor(element.Attribute(name).Value);
if (element == null || element.GetAttribute(name) == null) { return null; }
return ParseColor(element.GetAttribute(name).Value);
}
public static Color[] GetAttributeColorArray(this XElement element, string name, Color[] defaultValue)
{
if (element?.Attribute(name) == null) { return defaultValue; }
if (element?.GetAttribute(name) == null) { return defaultValue; }
string stringValue = element.Attribute(name).Value;
string stringValue = element.GetAttribute(name).Value;
if (string.IsNullOrEmpty(stringValue)) { return defaultValue; }
string[] splitValue = stringValue.Split(';');
@@ -531,10 +579,31 @@ namespace Barotrauma
return colorValue;
}
#if CLIENT
public static KeyOrMouse GetAttributeKeyOrMouse(this XElement element, string name, KeyOrMouse defaultValue)
{
string strValue = element.GetAttributeString(name, defaultValue?.ToString() ?? "");
if (Enum.TryParse(strValue, true, out Microsoft.Xna.Framework.Input.Keys key))
{
return key;
}
else if (Enum.TryParse(strValue, out MouseButton mouseButton))
{
return mouseButton;
}
else if (int.TryParse(strValue, NumberStyles.Any, CultureInfo.InvariantCulture, out int mouseButtonInt) &&
(Enum.GetValues(typeof(MouseButton)) as MouseButton[]).Contains((MouseButton)mouseButtonInt))
{
return (MouseButton)mouseButtonInt;
}
return defaultValue;
}
#endif
public static Rectangle GetAttributeRect(this XElement element, string name, Rectangle defaultValue)
{
if (element == null || element.Attribute(name) == null) { return defaultValue; }
return ParseRect(element.Attribute(name).Value, false);
if (element == null || element.GetAttribute(name) == null) { return defaultValue; }
return ParseRect(element.GetAttribute(name).Value, false);
}
//TODO: nested tuples and and n-uples where n!=2 are unsupported
@@ -703,16 +772,10 @@ namespace Barotrauma
if (stringColor.StartsWith("gui.", StringComparison.OrdinalIgnoreCase))
{
#if CLIENT
if (GUI.Style != null)
Identifier colorName = stringColor.Substring(4).ToIdentifier();
if (GUIStyle.Colors.TryGetValue(colorName, out GUIColor guiColor))
{
string colorName = stringColor.Substring(4);
var property = GUI.Style.GetType().GetProperties().FirstOrDefault(
p => p.PropertyType == typeof(Color) &&
p.Name.Equals(colorName, StringComparison.OrdinalIgnoreCase));
if (property != null)
{
return (Color)property?.GetValue(GUI.Style);
}
return guiColor.Value;
}
#endif
return Color.White;
@@ -727,7 +790,7 @@ namespace Barotrauma
if (strComponents.Length == 1)
{
bool hexFailed = true;
bool altParseFailed = true;
stringColor = stringColor.Trim();
if (stringColor.Length > 0 && stringColor[0] == '#')
{
@@ -744,11 +807,40 @@ namespace Barotrauma
components[2] = ((float)((colorInt & 0x0000ff00) >> 8)) / 255.0f;
components[3] = ((float)(colorInt & 0x000000ff)) / 255.0f;
hexFailed = false;
altParseFailed = false;
}
}
else if (stringColor.Length > 0 && stringColor[0] == '{')
{
stringColor = stringColor.Substring(1, stringColor.Length-2);
string[] mgComponents = stringColor.Split(' ');
if (mgComponents.Length == 4)
{
altParseFailed = false;
string[] expectedPrefixes = {"R:", "G:", "B:", "A:"};
for (int i = 0; i < 4; i++)
{
if (mgComponents[i].StartsWith(expectedPrefixes[i], StringComparison.OrdinalIgnoreCase))
{
string strToParse = mgComponents[i]
.Remove(expectedPrefixes[i], StringComparison.OrdinalIgnoreCase)
.Trim();
int val = 0;
altParseFailed |= !int.TryParse(strToParse, out val);
components[i] = ((float) val) / 255f;
}
else
{
altParseFailed = true;
break;
}
}
}
}
if (hexFailed)
if (altParseFailed)
{
if (errorMessages) { DebugConsole.ThrowError("Failed to parse the string \"" + stringColor + "\" to Color"); }
return Color.White;
@@ -807,18 +899,27 @@ namespace Barotrauma
return floatArray;
}
public static Identifier VariantOf(this XElement element) =>
element.GetAttributeIdentifier("inherit", element.GetAttributeIdentifier("variantof", ""));
public static string[] ParseStringArray(string stringArrayValues)
{
return string.IsNullOrEmpty(stringArrayValues) ? new string[0] : stringArrayValues.Split(';');
return string.IsNullOrEmpty(stringArrayValues) ? Array.Empty<string>() : stringArrayValues.Split(';');
}
public static Identifier[] ParseIdentifierArray(string stringArrayValues)
{
return ParseStringArray(stringArrayValues).ToIdentifiers().ToArray();
}
public static bool IsOverride(this XElement element) => element.Name.ToString().Equals("override", StringComparison.OrdinalIgnoreCase);
public static bool IsCharacterVariant(this XElement element) => element.Name.ToString().Equals("charactervariant", StringComparison.OrdinalIgnoreCase);
public static bool IsOverride(this XElement element) => element.NameAsIdentifier() == "override";
public static XElement FirstElement(this XElement element) => element.Elements().FirstOrDefault();
public static XAttribute GetAttribute(this XElement element, string name, StringComparison comparisonMethod = StringComparison.OrdinalIgnoreCase) => element.GetAttribute(a => a.Name.ToString().Equals(name, comparisonMethod));
public static XAttribute GetAttribute(this XElement element, Identifier name) => element.GetAttribute(name.Value, StringComparison.OrdinalIgnoreCase);
public static XAttribute GetAttribute(this XElement element, Func<XAttribute, bool> predicate) => element.Attributes().FirstOrDefault(predicate);
/// <summary>
@@ -830,5 +931,31 @@ namespace Barotrauma
/// Returns all child elements that match the name using the provided comparison method.
/// </summary>
public static IEnumerable<XElement> GetChildElements(this XContainer container, string name, StringComparison comparisonMethod = StringComparison.OrdinalIgnoreCase) => container.Elements().Where(e => e.Name.ToString().Equals(name, comparisonMethod));
public static IEnumerable<XElement> GetChildElements(this XContainer container, params string[] names)
{
return names.SelectMany(name => container.GetChildElements(name));
}
public static bool ComesAfter(this XElement element, XElement other)
{
if (element.Parent != other.Parent) { return false; }
foreach (var child in element.Parent.Elements())
{
if (child == element) { return false; }
if (child == other) { return true; }
}
return false;
}
public static Identifier NameAsIdentifier(this XElement elem)
{
return elem.Name.LocalName.ToIdentifier();
}
public static Identifier NameAsIdentifier(this XAttribute attr)
{
return attr.Name.LocalName.ToIdentifier();
}
}
}