diff --git a/AssM.csproj b/AssM.csproj
index 5bf58c0..c6b55a4 100644
--- a/AssM.csproj
+++ b/AssM.csproj
@@ -5,11 +5,11 @@
enable
true
app.manifest
- 1.8.1
+ 1.9.0
SubZeroPL
https://github.com/SubZeroPL/AssM
- 1.8.1
- 1.8.1
+ 1.9.0
+ 1.9.0
AssM
https://github.com/SubZeroPL/AssM/blob/master/LICENSE
https://github.com/SubZeroPL/AssM/
@@ -19,17 +19,17 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
+
+
+
diff --git a/Avalonia.Labs b/Avalonia.Labs
index 657577c..7d86b80 160000
--- a/Avalonia.Labs
+++ b/Avalonia.Labs
@@ -1 +1 @@
-Subproject commit 657577c0d42872c2f922d83f3dbdf407bbcb6685
+Subproject commit 7d86b80d576b9c0052fda104303c1ec1acb74f53
diff --git a/Classes/Functions.cs b/Classes/Functions.cs
index 06a5ba7..b0fc9d7 100644
--- a/Classes/Functions.cs
+++ b/Classes/Functions.cs
@@ -5,6 +5,8 @@
using System.IO;
using System.Linq;
using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
using AssM.Data;
using Avalonia.Threading;
using DiscTools;
@@ -12,7 +14,7 @@
namespace AssM.Classes;
-public static class Functions
+public static partial class Functions
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static string OutputPath(Game game) => Path.Combine(game.Platform.ToString(), game.Id);
@@ -229,12 +231,23 @@ public static List GetReadmeFilesInDirectory(string directory)
public static Game? AddGameToList(string imagePath, Configuration configuration, ObservableCollection gameList)
{
Logger.Debug($"Adding game to list from {imagePath}");
- var di = DiscInspector.ScanDisc(imagePath);
+ var di = DiscInspector.ScanDiscQuick(imagePath);
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - apparently there are games that have no Id in image (like SLPS-00018)
if (di.Data.SerialNumber == null)
{
- Logger.Error($"Failed to add game to list from {imagePath}{Environment.NewLine}Id not present in image");
- return null;
+ // let's try to find the ID manually
+ var id = ScanForId(imagePath);
+ if (id != null)
+ {
+ di.Data.SerialNumber = id;
+ di.DetectedDiscType = DetectedDiscType.SonyPS2;
+ }
+ else
+ {
+ Logger.Error(
+ $"Failed to add game to list from {imagePath}{Environment.NewLine}Id not present in image");
+ return null;
+ }
}
var title = configuration.GetTitleFromCue ? Path.GetFileNameWithoutExtension(imagePath) : di.Data.GameTitle;
@@ -259,6 +272,43 @@ public static List GetReadmeFilesInDirectory(string directory)
return game;
}
+
+ [GeneratedRegex(@"(SL[A-Z]{2}_\d+\.\d+)(?=;)")]
+ private static partial Regex IdPsRegex();
+
+ [GeneratedRegex("""FILE "(.+\.bin)" BINARY""")]
+ private static partial Regex BinFile();
+
+ private static string? ScanForId(string imagePath)
+ {
+ if (imagePath.EndsWith(".cue", StringComparison.OrdinalIgnoreCase))
+ {
+ var lines = File.ReadAllLines(imagePath);
+ var match = BinFile().Match(lines[0]);
+ if (match.Success)
+ {
+ var dir = Path.GetDirectoryName(imagePath);
+ var file = match.Groups[1].Value;
+ imagePath = Path.Join(dir, file);
+ }
+ }
+ using var fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
+ var buf = new Span(new byte[1024 * 8]);
+ const int backtrack = 15;
+ var read = fs.Read(buf);
+ while (read > 0 && read != backtrack)
+ {
+ var textId = Encoding.ASCII.GetString(buf);
+ var matches = IdPsRegex().Match(textId);
+ if (matches.Success)
+ {
+ return matches.Groups[1].Value.Replace('_', '-').Replace(".", "");
+ }
+ fs.Seek(-backtrack, SeekOrigin.Current);
+ read = fs.Read(buf);
+ }
+ return null;
+ }
public static void ProcessJson(Configuration configuration, Game game, Action reportProgress)
{
diff --git a/Windows/AddFolderProgressWindow.axaml b/Windows/AddFolderProgressWindow.axaml
index 42e5e7d..ce33eed 100644
--- a/Windows/AddFolderProgressWindow.axaml
+++ b/Windows/AddFolderProgressWindow.axaml
@@ -14,7 +14,7 @@
-
+
diff --git a/Windows/AddFolderProgressWindow.axaml.cs b/Windows/AddFolderProgressWindow.axaml.cs
index d24fb08..c9e57af 100644
--- a/Windows/AddFolderProgressWindow.axaml.cs
+++ b/Windows/AddFolderProgressWindow.axaml.cs
@@ -6,6 +6,7 @@
using AssM.Data;
using Avalonia.Controls;
using Avalonia.Interactivity;
+using Avalonia.Labs.Gif;
namespace AssM.Windows;
@@ -21,9 +22,13 @@ public partial class AddFolderProgressWindow : Window
{
private readonly BackgroundWorker _worker;
+ private readonly GifStreamSource _gifStreamSource =
+ GifStreamSource.FromUriString("avares://AssM/Assets/loading.gif");
+
public AddFolderProgressWindow()
{
InitializeComponent();
+ GifImage.Source = _gifStreamSource;
_worker = new BackgroundWorker();
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
@@ -101,6 +106,7 @@ private void CancelButton_OnClick(object? sender, RoutedEventArgs e)
private void Window_OnClosing(object? sender, WindowClosingEventArgs e)
{
_worker.CancelAsync();
+ _gifStreamSource.Dispose();
if (!e.IsProgrammatic) e.Cancel = true;
}
}
\ No newline at end of file
diff --git a/Windows/MainWindow.axaml b/Windows/MainWindow.axaml
index 185ef58..df3a7c1 100644
--- a/Windows/MainWindow.axaml
+++ b/Windows/MainWindow.axaml
@@ -76,11 +76,11 @@
-
+
+ PlaceholderText="Enter game description" KeyUp="TextDescription_OnKeyUp">