Skip to content
This repository has been archived by the owner on Jan 14, 2023. It is now read-only.

Commit

Permalink
some extra guard rails
Browse files Browse the repository at this point in the history
  • Loading branch information
yretenai committed Dec 30, 2021
1 parent 5421461 commit 07c5c13
Show file tree
Hide file tree
Showing 13 changed files with 113 additions and 22 deletions.
1 change: 1 addition & 0 deletions Snuggle.Core/Implementations/Animation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace Snuggle.Core.Implementations;

// [ObjectImplementation(UnityClassId.Animation)]
public class Animation : Behaviour {
public Animation(BiEndianBinaryReader reader, UnityObjectInfo info, SerializedFile serializedFile) : base(reader, info, serializedFile) {
AnimationClip = PPtr<SerializedObject>.FromReader(reader, serializedFile);
Expand Down
1 change: 1 addition & 0 deletions Snuggle.Core/Implementations/Animator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace Snuggle.Core.Implementations;

// [ObjectImplementation(UnityClassId.Animator)]
public class Animator : Behaviour {
public Animator(BiEndianBinaryReader reader, UnityObjectInfo info, SerializedFile serializedFile) : base(reader, info, serializedFile) {
Avatar = PPtr<SerializedObject>.FromReader(reader, serializedFile);
Expand Down
4 changes: 1 addition & 3 deletions Snuggle.Core/Implementations/AnimatorController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
using System.IO;
using System.Text.Json.Serialization;
using Snuggle.Core.IO;
using Snuggle.Core.Meta;
using Snuggle.Core.Models;
using Snuggle.Core.Models.Objects.Animation;
using Snuggle.Core.Models.Serialization;
using Snuggle.Core.Options;

namespace Snuggle.Core.Implementations;

[ObjectImplementation(UnityClassId.AnimatorController)]
// [ObjectImplementation(UnityClassId.AnimatorController)]
public class AnimatorController : RuntimeAnimatorController {
public AnimatorController(BiEndianBinaryReader reader, UnityObjectInfo info, SerializedFile serializedFile) : base(reader, info, serializedFile) {
var controllerSize = reader.ReadInt32();
Expand Down Expand Up @@ -67,7 +66,6 @@ public override void Deserialize(BiEndianBinaryReader reader, ObjectDeserializat

if (ShouldDeserializeController) {
Controller = ControllerConstant.FromReader(reader, options);
// TODO(naomi): Deserialize Controller
}
}

Expand Down
1 change: 1 addition & 0 deletions Snuggle.Core/Implementations/AnimatorOverrideController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

namespace Snuggle.Core.Implementations;

// [ObjectImplementation(UnityClassId.AnimatorOverrideController)]
public class AnimatorOverrideController : RuntimeAnimatorController {
public AnimatorOverrideController(BiEndianBinaryReader reader, UnityObjectInfo info, SerializedFile serializedFile) : base(reader, info, serializedFile) {
Controller = PPtr<AnimatorController>.FromReader(reader, serializedFile);
Expand Down
5 changes: 5 additions & 0 deletions Snuggle.Core/Logging/FileLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ namespace Snuggle.Core.Logging;

[PublicAPI]
public sealed class FileLogger : ILogger {
public bool IsDisposed { get; private set; }
public FileLogger(Stream baseStream) => Writer = new StreamWriter(baseStream, Encoding.UTF8);

private StreamWriter Writer { get; }

public void Dispose() {
Writer.Dispose();
IsDisposed = true;
GC.SuppressFinalize(this);
}

public void Log(LogLevel level, string? category, string message, Exception? exception) {
if (IsDisposed) {
return;
}
if (exception != null) {
message += $"\n{exception}";
}
Expand Down
6 changes: 6 additions & 0 deletions Snuggle.Core/Snuggle.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@
</None>
</ItemGroup>

<Target Name="SetSourceRevisionId" BeforeTargets="BeforeBuild">
<Exec Command="git describe --long --always --dirty --exclude=* --abbrev=8" ConsoleToMSBuild="True" IgnoreExitCode="False" ContinueOnError="True">
<Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput"/>
</Exec>
</Target>

</Project>
4 changes: 3 additions & 1 deletion Snuggle/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:renderers="clr-namespace:Snuggle.Components.Renderers"
StartupUri="Windows/Main.xaml">
StartupUri="Windows/Main.xaml"
DispatcherUnhandledException="Crash"
Exit="Cleanup">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
Expand Down
54 changes: 54 additions & 0 deletions Snuggle/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Threading;
using DragonLib;
using Snuggle.Core.Logging;
using Snuggle.Core.Meta;
using Snuggle.Handlers;

namespace Snuggle;

Expand All @@ -11,6 +18,23 @@ static App() {
var _ = CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded);
}

public App() {
InitializeComponent();
var logFile = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "./", "Log", $"SnuggleLog_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds():D}.log");
logFile.EnsureDirectoryExists();
Log = new FileLogger(new FileStream(logFile, FileMode.Create));
Log.Log(LogLevel.Info, "System", $"(ノ◕ヮ◕)ノ*:・゚✧ {SnuggleCore.GetVersion()}", null);
Log.Log(LogLevel.Info, "System", "System Info:", null);
Log.Log(LogLevel.Info, "System", $"\tRuntime: NET {Environment.Version.ToString()}", null);
Log.Log(LogLevel.Info, "System", $"\tOS: {Environment.OSVersion}", null);
Log.Log(LogLevel.Info, "System", $"\t64-bit: {Environment.Is64BitOperatingSystem}", null);

AppDomain.CurrentDomain.UnhandledException += Crash;
AppDomain.CurrentDomain.ProcessExit += Cleanup;
}

public FileLogger Log { get; }

[DllImport("Ole32.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
private static extern int CoInitializeEx([In] [Optional] IntPtr pvReserved, [In] CoInit dwCoInit);

Expand All @@ -27,4 +51,34 @@ static App() {
private enum CoInit : uint {
MultiThreaded = 0x00,
}

private void Crash(object sender, EventArgs e) {
Exception? ex = default;
switch (e)
{
case UnhandledExceptionEventArgs { IsTerminating: false }:
return;
case UnhandledExceptionEventArgs ueea:
ex = ueea.ExceptionObject as Exception;
break;
case DispatcherUnhandledExceptionEventArgs dueea:
ex = dueea.Exception;
break;
}

Log.Log(LogLevel.Crash, "System", "Unrecoverable crash", ex);
SnuggleCore.Instance.Dispose();
Log.Dispose();
}

private void Cleanup(object? sender, EventArgs e) {
if (e is ExitEventArgs exitEventArgs) {
Log.Log(LogLevel.Info, "System", $"Exiting ({exitEventArgs:X8})...", null);
} else {
Log.Log(LogLevel.Info, "System", "Exiting...", null);
}

SnuggleCore.Instance.Dispose();
Log.Dispose();
}
}
7 changes: 4 additions & 3 deletions Snuggle/Components/Assets.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
<ListView ItemsSource="{Binding Objects, Mode=OneWay}" GridViewColumnHeader.Click="SortColumn"
x:Name="Entries" SelectionChanged="UpdateSelected" SelectionMode="Extended"
VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.CacheLength="1,1"
VirtualizingPanel.ScrollUnit="Item" VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.CacheLengthUnit="Page" VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.IsVirtualizingWhenGrouping="True" ScrollViewer.CanContentScroll="True">
VirtualizingPanel.ScrollUnit="Item" VirtualizingPanel.VirtualizationMode="Standard"
VirtualizingPanel.CacheLengthUnit="Page" VirtualizingPanel.IsContainerVirtualizable="False"
VirtualizingPanel.IsVirtualizingWhenGrouping="True" ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="True">
<ListView.Resources>
<ContextMenu x:Key="Context">
<MenuItem Header="Save Data" Click="ExtractSerialize" />
Expand Down
14 changes: 7 additions & 7 deletions Snuggle/Components/Navigation.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
d:DesignHeight="30" d:DesignWidth="500">
<Menu Height="30">
<MenuItem Header="_File" Height="30">
<MenuItem Header="Load _Directory" Click="LoadDirectories" />
<MenuItem Header="Load _File" Click="LoadFiles" />
<MenuItem Header="_Recent" x:Name="RecentItems" />
<MenuItem Header="Load _Directory" Click="LoadDirectories" IsEnabled="{Binding IsFree}" />
<MenuItem Header="Load _File" Click="LoadFiles" IsEnabled="{Binding IsFree}" />
<MenuItem Header="_Recent" x:Name="RecentItems" IsEnabled="{Binding IsFree}" />
<Separator />
<MenuItem Header="_Clear Memory" ToolTip="This will try to unload all large data blocks"
Click="FreeMemory" />
Click="FreeMemory" IsEnabled="{Binding IsFree}" />
<MenuItem Header="_Reset" Click="ResetTrampoline" />
<MenuItem Header="_Exit" Click="ExitTrampoline" />
</MenuItem>
<MenuItem Header="_Extract" Height="30">
<MenuItem Header="_Extract" Height="30" IsEnabled="{Binding IsFree}">
<MenuItem Header="_All">
<MenuItem Header="_Raw" Click="ExtractRaw" Tag="1" />
<MenuItem Header="_Convert" Click="ExtractConvert" Tag="1" />
Expand All @@ -39,7 +39,7 @@
<MenuItem Header="_Serialize" Click="ExtractSerialize" Tag="2" />
</MenuItem>
</MenuItem>
<MenuItem Header="{Binding FormattedProjectName, Mode=OneWay}" Height="30">
<MenuItem Header="{Binding FormattedProjectName, Mode=OneWay}" Height="30" IsEnabled="{Binding IsFree}">
<MenuItem Header="_Cache Memory"
ToolTip="This can significantly increase performance at a heavy memory cost"
IsCheckable="True" Click="ToggleCacheData" x:Name="CacheData" />
Expand All @@ -58,6 +58,6 @@
<MenuItem Header="_Game" x:Name="UnityGameList" />
<MenuItem Header="Game _Options" x:Name="GameOptions" Visibility="Collapsed" />
</MenuItem>
<MenuItem Header="_Filter" Height="30" x:Name="Filters" Visibility="{Binding HasAssetsVisibility}" />
<MenuItem Header="_Filter" Height="30" x:Name="Filters" IsEnabled="{Binding IsFree}" />
</Menu>
</UserControl>
6 changes: 6 additions & 0 deletions Snuggle/Components/Navigation.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public Navigation() {
BuildSettingMenu(RendererOptions, typeof(SnuggleMeshExportOptions), nameof(SnuggleOptions.MeshExportOptions));
PopulateGameOptions();
PopulateRecentItems();
PopulateItemTypes();

instance.PropertyChanged += (_, args) => {
switch (args.PropertyName) {
Expand Down Expand Up @@ -233,6 +234,11 @@ private void PopulateItemTypes() {
letterMenuItem.Items.Add(menuItem);
}

if (Filters.Items.IsEmpty) {
var reset = new MenuItem { Header = "Nothing to show" };
Filters.Items.Add(reset);
}

Filters.Visibility = Filters.Items.IsEmpty ? Visibility.Collapsed : Visibility.Visible;
}

Expand Down
28 changes: 22 additions & 6 deletions Snuggle/Handlers/SnuggleCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ public SnuggleCore() {
SettingsFile = Path.Combine(workDir, $"{ProjectName}.json");
WorkerThread = new Thread(WorkLoop);
WorkerThread.Start();
if (!Directory.Exists(Path.Combine(workDir, "Log"))) {
Directory.CreateDirectory(Path.Combine(workDir, "Log"));
}

LogTarget = new MultiLogger { Loggers = { new ConsoleLogger(), new DebugLogger(), new FileLogger(new FileStream(Path.Combine(workDir, "Log", $"SnuggleLog_{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds():D}.log"), FileMode.Create)) } };
LogTarget = new MultiLogger { Loggers = { new ConsoleLogger(), new DebugLogger(), ((App)Application.Current).Log } };
SetOptions(File.Exists(SettingsFile) ? SnuggleOptions.FromJson(File.ReadAllText(SettingsFile)) : SnuggleOptions.Default);
ResourceLocator.SetColorScheme(Application.Current.Resources, Settings.LightMode ? ResourceLocator.LightColorScheme : ResourceLocator.DarkColorScheme);
}
Expand All @@ -57,6 +53,7 @@ public SnuggleCore() {
public HashSet<object> Filters { get; set; } = new();
public IReadOnlyList<SnuggleObject> SelectedObjects { get; set; } = Array.Empty<SnuggleObject>();
public string? Search { get; set; }
public bool IsDisposed { get; private set; }

public string Title {
get {
Expand Down Expand Up @@ -86,6 +83,8 @@ public string Title {
public string ProjectName { get; } = Assembly.GetExecutingAssembly().GetName().Name ?? "Snuggle";
public string FormattedProjectName { get; } = Navigation.SplitName(Assembly.GetExecutingAssembly().GetName().Name ?? "Snuggle");

public bool IsFree { get; set; } = true;

public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
Expand All @@ -98,6 +97,11 @@ public void Dispose() {
}

protected void Dispose(bool disposing) {
if (IsDisposed) {
return;
}

IsDisposed = true;
Reset(false);

if (disposing) {
Expand All @@ -114,6 +118,8 @@ private void WorkLoop() {
foreach (var (name, task) in tasks.GetConsumingEnumerable(TokenSource.Token)) {
try {
sw.Start();
IsFree = false;
Dispatcher.Invoke(() => OnPropertyChanged(nameof(IsFree)));
task(TokenSource.Token);
sw.Stop();
var elapsed = sw.Elapsed;
Expand All @@ -124,6 +130,8 @@ private void WorkLoop() {
}

LogTarget.Info("Worker", $"Memory Tension: {GC.GetTotalMemory(false).GetHumanReadableBytes()}");
IsFree = true;
Dispatcher.Invoke(() => OnPropertyChanged(nameof(IsFree)));
}
} catch (TaskCanceledException) {
// ignored
Expand All @@ -139,7 +147,10 @@ public void Reset(bool respawn = true) {
Tasks = new BlockingCollection<(string Name, Action<CancellationToken> Work)>();
TokenSource.Cancel();
TokenSource.Dispose();
WorkerThread.Join();
if (respawn) {
WorkerThread.Join();
}

SelectedObject = null;
Status.Reset();
Search = string.Empty;
Expand Down Expand Up @@ -249,4 +260,9 @@ public void FreeMemory(bool bundles) {

AssetCollection.Collect();
}

public static string GetVersion() {
var pv = FileVersionInfo.GetVersionInfo(typeof(Bundle).Assembly.Location).ProductVersion;
return pv?.Contains('+') == true ? $"{BaseTitle} {pv.Split('+', StringSplitOptions.TrimEntries).Last()}" : string.Empty;
}
}
4 changes: 2 additions & 2 deletions Snuggle/Windows/Main.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
</Grid.RowDefinitions>
<Snuggle:Navigation DataContext="{Binding}" Grid.Column="0" Height="30" />
<TextBox KeyDown="Search" Width="300" x:Name="SearchBox"
adonisExtensions:WatermarkExtension.Watermark="Search" Visibility="{Binding HasAssetsVisibility}"
Grid.Column="1" />
adonisExtensions:WatermarkExtension.Watermark="Search"
Grid.Column="1" IsEnabled="{Binding IsFree}" />
<Label Content="{Binding Title}" VerticalAlignment="Center" FontWeight="Bold"
HorizontalContentAlignment="Center" Grid.Column="2" />
</Grid>
Expand Down

0 comments on commit 07c5c13

Please sign in to comment.