Build 0.18.4.0

This commit is contained in:
Markus Isberg
2022-05-31 23:13:05 +09:00
parent 077917fa5d
commit 64db1a6a44
175 changed files with 4916 additions and 2393 deletions
@@ -2,12 +2,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using Barotrauma.IO;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -69,10 +67,10 @@ namespace Barotrauma
.ToImmutableHashSet();
}
public static Result<ContentFile, string> CreateFromXElement(ContentPackage contentPackage, XElement element)
public static Result<ContentFile, LoadError> CreateFromXElement(ContentPackage contentPackage, XElement element)
{
static Result<ContentFile, string> fail(string error, string? stackTrace = null)
=> Result<ContentFile, string>.Failure(error, stackTrace);
static Result<ContentFile, LoadError> fail(string error, Exception? exception = null)
=> Result<ContentFile, LoadError>.Failure(new LoadError(error, exception));
Identifier elemName = element.NameAsIdentifier();
var type = Types.FirstOrDefault(t => t.Names.Contains(elemName));
@@ -95,11 +93,11 @@ namespace Barotrauma
var file = type.CreateInstance(contentPackage, filePath);
return file is null
? throw new Exception($"Content type is not implemented correctly")
: Result<ContentFile, string>.Success(file);
: Result<ContentFile, LoadError>.Success(file);
}
catch (Exception e)
{
return fail($"Failed to load file \"{filePath}\" of type \"{elemName}\": {e.Message}", e.StackTrace.CleanupStackTrace());
return fail($"Failed to load file \"{filePath}\" of type \"{elemName}\": {e.Message}", e);
}
}
@@ -125,5 +123,23 @@ namespace Barotrauma
}
public bool NotSyncedInMultiplayer => Types.Any(t => t.Type == GetType() && t.NotSyncedInMultiplayer);
public readonly struct LoadError
{
public readonly string Message;
public readonly Exception? Exception;
public LoadError(string message, Exception? exception)
{
Message = message;
Exception = exception;
}
public override string ToString()
=> Message
+ (Exception is { StackTrace: var stackTrace }
? '\n' + stackTrace.CleanupStackTrace()
: string.Empty);
}
}
}
@@ -14,7 +14,7 @@ namespace Barotrauma
{
public abstract class ContentPackage
{
public static readonly Version MinimumHashCompatibleVersion = new Version(0, 17, 16, 0);
public static readonly Version MinimumHashCompatibleVersion = new Version(0, 18, 3, 0);
public const string LocalModsDir = "LocalMods";
public static readonly string WorkshopModsDir = Barotrauma.IO.Path.Combine(
@@ -33,11 +33,11 @@ namespace Barotrauma
public readonly Version GameVersion;
public readonly string ModVersion;
public readonly Md5Hash Hash;
public Md5Hash Hash { get; private set; }
public readonly DateTime? InstallTime;
public readonly ImmutableArray<ContentFile> Files;
public readonly ImmutableArray<(string error, string? stackTrace)> Errors;
public ImmutableArray<ContentFile> Files { get; private set; }
public ImmutableArray<ContentFile.LoadError> Errors { get; private set; }
public async Task<bool> IsUpToDate()
{
@@ -55,7 +55,7 @@ namespace Barotrauma
/// <summary>
/// Does the content package include some content that needs to match between all players in multiplayer.
/// </summary>
public readonly bool HasMultiplayerSyncedContent;
public bool HasMultiplayerSyncedContent { get; private set; }
protected ContentPackage(XDocument doc, string path)
{
@@ -84,13 +84,13 @@ namespace Barotrauma
.ToArray();
Files = fileResults
.OfType<Success<ContentFile, string>>()
.OfType<Success<ContentFile, ContentFile.LoadError>>()
.Select(f => f.Value)
.ToImmutableArray();
Errors = fileResults
.OfType<Failure<ContentFile, string>>()
.Select(f => (f.Error, f.StackTrace))
.OfType<Failure<ContentFile, ContentFile.LoadError>>()
.Select(f => f.Error)
.ToImmutableArray();
HasMultiplayerSyncedContent = Files.Any(f => !f.NotSyncedInMultiplayer);
@@ -127,18 +127,13 @@ namespace Barotrauma
try
{
if (doc.Root.GetAttributeBool("corepackage", false))
{
return new CorePackage(doc, path);
}
else
{
return new RegularPackage(doc, path);
}
return doc.Root.GetAttributeBool("corepackage", false)
? (ContentPackage)new CorePackage(doc, path)
: new RegularPackage(doc, path);
}
catch (Exception e)
{
while (e.InnerException != null) { e = e.InnerException; }
e = e.GetInnermost();
DebugConsole.ThrowError($"{e.Message}: {e.StackTrace}");
return null;
}
@@ -278,12 +273,42 @@ namespace Barotrauma
Files.ForEach(f => f.UnloadFile());
}
public override int GetHashCode()
public void ReloadSubsAndItemAssemblies()
{
byte[] shortHash = Encoding.ASCII.GetBytes(Hash.StringRepresentation.Substring(0, 4));
return (shortHash[0] << 24) | (shortHash[1] << 16) | (shortHash[2] << 8) | shortHash[3];
XDocument doc = XMLExtensions.TryLoadXml(Path);
List<ContentFile> newFileList = new List<ContentFile>();
XElement rootElement = doc.Root ?? throw new NullReferenceException("XML document is invalid: root element is null.");
var fileResults = rootElement.Elements()
.Select(e => ContentFile.CreateFromXElement(this, e))
.ToArray();
foreach (var result in fileResults)
{
switch (result)
{
case Success<ContentFile, ContentFile.LoadError> { Value: var file }:
if (file is BaseSubFile || file is ItemAssemblyFile)
{
newFileList.Add(file);
}
else
{
var existingFile = Files.FirstOrDefault(f => f.Path == file.Path);
newFileList.Add(existingFile ?? file);
}
break;
}
}
UnloadFilesOfType<BaseSubFile>();
UnloadFilesOfType<ItemAssemblyFile>();
Files = newFileList.ToImmutableArray();
Hash = CalculateHash();
LoadFilesOfType<BaseSubFile>();
LoadFilesOfType<ItemAssemblyFile>();
}
public static bool PathAllowedAsLocalModFile(string path)
{
#if DEBUG
@@ -305,21 +330,17 @@ namespace Barotrauma
public void LogErrors()
{
if (Errors.Any())
if (!Errors.Any())
{
DebugConsole.AddWarning(
$"The following errors occurred while loading the content package\"{Name}\". The package might not work correctly.\n" +
string.Join('\n', Errors.Select(e => errorToStr(e.error, e.stackTrace))));
static string errorToStr(string error, string? stackTrace)
{
string str = error;
if (stackTrace != null)
{
str += '\n' + stackTrace;
}
return str;
}
return;
}
DebugConsole.AddWarning(
$"The following errors occurred while loading the content package \"{Name}\". The package might not work correctly.\n" +
string.Join('\n', Errors.Select(errorToStr)));
static string errorToStr(ContentFile.LoadError error)
=> error.ToString();
}
}
}
@@ -430,9 +430,9 @@ namespace Barotrauma
public static void LoadVanillaFileList()
{
VanillaCorePackage = new CorePackage(XDocument.Load(VanillaFileList), VanillaFileList);
foreach ((string error, string? stackTrace) in VanillaCorePackage.Errors)
foreach (ContentFile.LoadError error in VanillaCorePackage.Errors)
{
DebugConsole.ThrowError(error + (stackTrace == null ? string.Empty : '\n' + stackTrace));
DebugConsole.ThrowError(error.ToString());
}
}
@@ -27,7 +27,7 @@ namespace Barotrauma
public string BaseUri => Element.BaseUri;
public XDocument Document => Element.Document ?? throw new NullReferenceException("XML element is invalid: document is null.");
public XDocument? Document => Element.Document;
public ContentXElement? FirstElement() => Elements().FirstOrDefault();