-
-
Notifications
You must be signed in to change notification settings - Fork 14
commit 59ce492
abduznik edited this page May 23, 2026
·
1 revision
Commit: 59ce4927943af70492e24e8a8276d0f40740679f
Author: abduznik
Date: 2026-04-28
Why: Adds a new feature or capability to the application.
lib/core/romm/rom_scanner_service.dart | 25 ++++++++++++++++++++++---
lib/core/storage/directory_service.dart | 12 +++++++-----
2 files changed, 29 insertions(+), 8 deletions(-)
lib/core/romm/rom_scanner_service.dartlib/core/storage/directory_service.dart
diff --git a/lib/core/romm/rom_scanner_service.dart b/lib/core/romm/rom_scanner_service.dart
index bc15360..11d3c95 100644
--- a/lib/core/romm/rom_scanner_service.dart
+++ b/lib/core/romm/rom_scanner_service.dart
@@ -133,15 +133,34 @@ class RomScannerService {
// Strategy B: Clean name match
if (matchedGame == null) {
final fNameClean = _cleanName(fileNameNoExt);
- matchedGame = platformGames.cast<Game?>().firstWhere((g) {
- if (g == null) return false;
+ final candidates = platformGames.where((g) {
if (_cleanName(g.name) == fNameClean) return true;
final gFileNoExt = p.basenameWithoutExtension(g.fileName ?? '').toLowerCase();
if (_cleanName(gFileNoExt) == fNameClean) return true;
final gFsNoExt = p.basenameWithoutExtension(g.fsName ?? '').toLowerCase();
if (_cleanName(gFsNoExt) == fNameClean) return true;
return false;
- }, orElse: () => null);
+ }).toList();
+
+ if (candidates.length == 1) {
+ final candidate = candidates.first;
+ // Additional confirmation: If both have sizes, they should be reasonably close
+ final localSize = index.fileSizes[entityPath] ?? (romsIndex?.fileSizes[entityPath] ?? 0);
+ if (candidate.fileSize > 0 && localSize > 0) {
+ // Allow for small differences in size (e.g. metadata or padding) but not completely different
+ final diff = (candidate.fileSize - localSize).abs();
+ if (diff < 1024 * 1024 * 10) { // < 10MB difference
+ matchedGame = candidate;
+ } else {
+ debugPrint('[Scanner] Fuzzy name match for $fileName -> ${candidate.name} REJECTED due to size mismatch ($localSize vs ${candidate.fileSize})');
+ }
+ } else {
+ // One side has no size, we have to trust the unique name match
+ matchedGame = candidate;
+ }
+ } else if (candidates.length > 1) {
+ debugPrint('[Scanner] Ambiguous match for $fileName: ${candidates.length} candidates found. Skipping.');
+ }
}
if (matchedGame != null) {
diff --git a/lib/core/storage/directory_service.dart b/lib/core/storage/directory_service.dart
index a070962..844303f 100644
--- a/lib/core/storage/directory_service.dart
+++ b/lib/core/storage/directory_service.dart
@@ -488,11 +488,13 @@ class DirectoryService {
}
}
- // Fuzzy match in index
+ // Fuzzy match in index (Last resort, only if name is very similar and not ambiguous)
for (final name in namesToCheck) {
final lowerName = name.toLowerCase();
for (final entry in index.files.entries) {
- if (entry.key.startsWith(lowerName) && !entry.key.endsWith('.part')) {
+ // Strict startsWith: only if the match is very close (e.g. adding a small suffix)
+ if (entry.key.startsWith(lowerName) && entry.key.length < lowerName.length + 5 && !entry.key.endsWith('.part')) {
+ // debugPrint('[Matching] Strict startsWith hit: ${entry.key}');
return entry.value;
}
}
@@ -575,9 +577,9 @@ class DirectoryService {
try {
await for (final entity in pDir.list()) {
if (entity is File) {
- final fname = p.basename(entity.path);
- final sanitizedFName = fname.replaceAll(RegExp(r'[<>:"/\\|?*]'), ' ').replaceAll(RegExp(r'\s+'), ' ').trim();
- if (sanitizedFName.toLowerCase().startsWith(baseName.toLowerCase()) && !fname.toLowerCase().endsWith('.part')) {
+ final fname = p.basename(entity.path).toLowerCase();
+ final target = baseName.toLowerCase();
+ if (fname == target || fname == '$target.iso' || fname == '$target.bin' || fname == '$target.pkg') {
return p.absolute(entity.path);
}
}