Skip to content

Commit

Permalink
* Add support for Satisfactory and DOOM Eternal DLC2
Browse files Browse the repository at this point in the history
* Add wait cursor on manual backup
* Fix snapshots sorting
* Screenshot only if the process window is focused
* Tests: refactor to support Satisfactory cases
* Typo
  • Loading branch information
HgAlexx committed Mar 19, 2021
1 parent 7ad205e commit 0e3657f
Show file tree
Hide file tree
Showing 44 changed files with 2,180 additions and 735 deletions.
101 changes: 101 additions & 0 deletions Hg.SaveHistory/API/BackupHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,107 @@ public static class BackupHelper
{
#region Members

public static bool CopyFile(string sourceFullName, string targetFullName, bool overrideIfExists, bool withBackup)
{
Logger.Information(MethodBase.GetCurrentMethod().DeclaringType.Name, ".", MethodBase.GetCurrentMethod().Name);

Logger.Debug("sourcePath: ", sourceFullName);
Logger.Debug("targetPath: ", targetFullName);
Logger.Debug("overrideIfExists: ", overrideIfExists);
Logger.Debug("withBackup: ", withBackup);

try
{
if (!File.Exists(sourceFullName))
{
return false;
}

string targetDirectory = Path.GetDirectoryName(targetFullName);
if (targetDirectory == null)
{
return false;
}

Directory.CreateDirectory(targetDirectory);

bool canRestore = false;
if (withBackup)
{
try
{
string name = targetFullName + ".hg.bak";
if (File.Exists(targetFullName))
{
File.Move(targetFullName, name);

Thread.Sleep(100);

canRestore = true;
}
}
catch (Exception exception)
{
Utilities.Logger.Error("CopyFile, withBackup failed: ", exception.Message);
Utilities.Logger.LogException(exception);
}
}

try
{
File.Copy(sourceFullName, targetFullName, overrideIfExists);

Thread.Sleep(100);

if (withBackup)
{
string name = targetFullName + ".hg.bak";
if (File.Exists(name))
{
File.Delete(name);
canRestore = false;
}
}
}
catch (Exception ex)
{
Utilities.Logger.Error("CopyFile, files copy failed: ", ex.Message);
Utilities.Logger.LogException(ex);

if (withBackup && canRestore)
{
// Clean up
if (File.Exists(targetFullName))
{
File.Delete(targetFullName);
}

Thread.Sleep(100);

// Restore backup
string name = targetFullName + ".hg.bak";
if (File.Exists(name))
{
File.Move(name, targetFullName);
canRestore = false;
}
}

return false;
}

return true;
}
catch (Exception exception)
{
Utilities.Logger.Error("CopyFile: ", exception.Message);
Utilities.Logger.LogException(exception);
}

return false;
}


public static bool CopyFiles(string sourcePath, string targetPath, LuaFunction canCopy, LuaFunction mustWait, bool overrideIfExists,
bool withBackup)
{
Expand Down
16 changes: 8 additions & 8 deletions Hg.SaveHistory/API/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public class Engine

public event EventHandlerCategoriesChanged OnCategoriesChanges;

/// <summary>
/// After the profile is saved and before the engine unload
/// Release final resources here
/// </summary>
public LuaFunction OnClosed;

/// <summary>
/// Before the profile is saved to disk
/// Must return true to allow saving
Expand Down Expand Up @@ -53,12 +59,6 @@ public class Engine
/// </summary>
public LuaFunction OnOpened;

/// <summary>
/// After the profile is saved and before the engine unload
/// Release final resources here
/// </summary>
public LuaFunction OnClosed;

public LuaFunction OnSetupSuggestProfileName = null;

public LuaFunction OnSetupValidate = null;
Expand Down Expand Up @@ -135,7 +135,7 @@ public bool ActionSnapshotBackup(ActionSource actionSource, params object[] args
{
Logger.Information(MethodBase.GetCurrentMethod().DeclaringType.Name, ".", MethodBase.GetCurrentMethod().Name);

args = new object[] { actionSource }.Concat(args).ToArray();
args = new object[] {actionSource}.Concat(args).ToArray();
if (OnActionSnapshotBackup.Call(args).First() is bool b)
{
return b;
Expand All @@ -148,7 +148,7 @@ public bool ActionSnapshotRestore(ActionSource actionSource, EngineSnapshot snap
{
Logger.Information(MethodBase.GetCurrentMethod().DeclaringType.Name, ".", MethodBase.GetCurrentMethod().Name);

args = new object[] { actionSource, snapshot }.Concat(args).ToArray();
args = new object[] {actionSource, snapshot}.Concat(args).ToArray();
if (OnActionSnapshotRestore.Call(args).First() is bool b)
{
return b;
Expand Down
7 changes: 6 additions & 1 deletion Hg.SaveHistory/API/EngineSnapshotCategory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Hg.SaveHistory.API
{
public class EngineSnapshotCategory : IEquatable<EngineSnapshotCategory>
public class EngineSnapshotCategory : IEquatable<EngineSnapshotCategory>, IComparable<EngineSnapshotCategory>
{
#region Fields & Properties

Expand All @@ -25,6 +25,11 @@ public class EngineSnapshotCategory : IEquatable<EngineSnapshotCategory>

#region Members

public int CompareTo(EngineSnapshotCategory other)
{
return string.Compare(Name, other.Name, StringComparison.Ordinal);
}

public bool Equals(EngineSnapshotCategory other)
{
if (OnEquals != null && OnEquals.Call(this, other).First() is bool value)
Expand Down
2 changes: 1 addition & 1 deletion Hg.SaveHistory/API/EngineWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public EngineWatcher()
WatchChanged = false;
WatchRenamed = false;
Filter = "*";
NotifyFilter = (int) (NotifyFilters.FileName | NotifyFilters.DirectoryName);
NotifyFilter = (int) (NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastWrite);
WatchParent = true;
OnEvent = null;
Path = null;
Expand Down
105 changes: 105 additions & 0 deletions Hg.SaveHistory/API/HgScriptSpecific.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ namespace Hg.SaveHistory.API
{
public static class HgScriptSpecific
{
#region Types

public class SatisfactoryHeaderData
{
#region Fields & Properties

public int BuildVersion;
public TimeSpan PlayedTime;
public DateTime SavedAt;
public int SaveVersion;
public string SessionName;

#endregion
}

#endregion

#region Members

/// <summary>
Expand Down Expand Up @@ -58,6 +75,94 @@ public static string DOOMEternal_Decrypt(string fileKey, string filePath)
return plaintext;
}

/// <summary>
/// Parse save file
/// https://satisfactory.gamepedia.com/Save_files
/// </summary>
/// <param name="filePath"></param>
/// <returns>SatisfactoryHeaderData</returns>
public static SatisfactoryHeaderData Satisfactory_GetHeaderData(string filePath)
{
try
{
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var binaryReader = new BinaryReader(fileStream))
{
SatisfactoryHeaderData data = new SatisfactoryHeaderData();

// same variable to read binary value
int int32Byte;
long int64Byte;
string value;

// header version
int32Byte = binaryReader.ReadInt32();
// unused

// save version
int32Byte = binaryReader.ReadInt32();
data.SaveVersion = int32Byte;

// build version
int32Byte = binaryReader.ReadInt32();
data.BuildVersion = int32Byte;

string ReadString()
{
// get string size
int byteCount = binaryReader.ReadInt32();
if (byteCount == 0)
{
return "";
}

// ASCII string
if (byteCount > 0)
{
value = new string(binaryReader.ReadChars(byteCount));
}
else
{
// UTF16 string
byte[] bytes = binaryReader.ReadBytes(2 * -byteCount);
value = Encoding.Unicode.GetString(bytes);
}

return value.TrimEnd('\0');
}

// map name: size + data
value = ReadString();
// unused

// map options: size + data
value = ReadString();
// unused

// session name: size + data
value = ReadString();
data.SessionName = value;

// played time
int32Byte = binaryReader.ReadInt32();
data.PlayedTime = new TimeSpan(0, 0, int32Byte); // as seconds

// saved at
int64Byte = binaryReader.ReadInt64();
data.SavedAt = new DateTime(int64Byte, DateTimeKind.Utc).ToLocalTime(); // as ticks

return data;
}
}
}
catch (Exception exception)
{
Logger.Error(exception.Message);
return null;
}
}

#endregion
}
}
8 changes: 4 additions & 4 deletions Hg.SaveHistory/API/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ public class Logger

public static void Debug(params object[] objects)
{
HostLogger.Debug(new object[] { "Script: " }.Concat(objects).ToArray());
HostLogger.Debug(new object[] {"Script: "}.Concat(objects).ToArray());
}

public static void Error(params object[] objects)
{
HostLogger.Error(new object[] { "Script: " }.Concat(objects).ToArray());
HostLogger.Error(new object[] {"Script: "}.Concat(objects).ToArray());
}

public static void Information(params object[] objects)
{
HostLogger.Information(new object[] { "Script: " }.Concat(objects).ToArray());
HostLogger.Information(new object[] {"Script: "}.Concat(objects).ToArray());
}

public static void Warning(params object[] objects)
{
HostLogger.Warning(new object[] { "Script: " }.Concat(objects).ToArray());
HostLogger.Warning(new object[] {"Script: "}.Concat(objects).ToArray());
}

#endregion
Expand Down
23 changes: 23 additions & 0 deletions Hg.SaveHistory/API/ScreenshotHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ public bool Capture(Rectangle captureBounds, EngineSnapshot snapshot)

try
{
bool? focused = IsWindowFocused();
if (focused is null || focused == false)
{
Logger.Warning("Screenshot.Capture: The window is not focused.");
return false;
}

snapshot.HasScreenshot = false;

Bitmap bitmap = new Bitmap(captureBounds.Width, captureBounds.Height);
Expand Down Expand Up @@ -116,6 +123,17 @@ public bool HasTitleBar()
return ScreenShots.HasTitlebar(processPtr);
}

public bool? IsWindowFocused()
{
IntPtr processPtr = GetProcessPtr();
if (processPtr == IntPtr.Zero)
{
return null;
}

return ScreenShots.IsWindowFocused(processPtr);
}

public int TitleBarHeight()
{
return ScreenShots.GetTitleBarHeight();
Expand All @@ -135,6 +153,11 @@ private IntPtr GetProcessPtr()
if (_engine.ProcessNames.Contains(process.ProcessName))
{
processPtr = process.MainWindowHandle;
if (processPtr == IntPtr.Zero)
{
processPtr = process.Handle;
}

break;
}
}
Expand Down
Loading

0 comments on commit 0e3657f

Please sign in to comment.