Build 0.18.4.0
This commit is contained in:
+24
-8
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
-34
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user