Skip to content

Commit

Permalink
Add wildcard file list for files in archive, doc updates
Browse files Browse the repository at this point in the history
  • Loading branch information
fraganator committed Jan 13, 2022
1 parent 8da8c6a commit bba5f16
Show file tree
Hide file tree
Showing 12 changed files with 224 additions and 167 deletions.
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Archive Cache Manager change history

## v2.0.8 (2022-01-13)
* Wildcard based filename matching for file priorities in archive
* Prioritize a file extension, filename, or combination
* Create priorities to automatically play preferred ROM region from GoodMerged archives
* Performance improvements, especially for archives with many hundreds or thousands files
* [BigBox] "Select ROM In Archive" menu option (accepts keyboard input only)

## v2.0.7 (2021-03-30)
* Badge to indicate if game is in cache
* Available under Badges -> Enable Archive Cached menu
Expand Down
40 changes: 27 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Archive Cache Manager
![Achive Cache Manager logo](images/logo-v2-title.png?raw=true "Achive Cache Manager")

A LaunchBox plugin which caches extracted ROM archives, letting you play games faster. Also allows launching individual files from archives, and loading preferred file type from an archive.
A LaunchBox plugin which caches extracted ROM archives, letting you play games faster. Also allows launching individual files from archives, and loading preferred files from an archive.

## New in v2.0.7
* Badge for cached games. Also includes Simple White and Neon style badges to match your theme.
* ![Badge icon to indicate if a game is cached](images/badges.png?raw=true "Badge icon to indicate if a game is cached")
* ROMs previously selected using the "Select ROM In Archive..." menu are automatically loaded the next time a game is played.
## New in v2.0.8
* Wildcard based filename matching for file priorities in archive
* Prioritize a file extension, filename, or combination
* Create priorities to automatically play preferred ROM region from GoodMerged archives
* Performance improvements, especially for archives with many hundreds or thousands files
* [BigBox] "Select ROM In Archive" menu option (accepts keyboard input only)

## Description
When a compressed ROM (in zip, 7z, or rar format) is first extracted, it is stored in the archive cache. The next time it is played, the game is loaded directly from the cache, virtually eliminating wait time.
Expand All @@ -22,7 +24,7 @@ As the cache approaches its maximum size, the least recently played games are de
* Configurable minimum archive size (skip caching small archives).
* Option to keep select ROMs cached and ready to play.
* Select and play individual ROM files from an archive.
* File extension priorities per emulator and platform (cue, bin, iso, etc).
* Filename and extension priorities per emulator and platform (cue, bin, iso, etc).

### Example Use Cases
Why use Archive Cache Manager? Here's some example use cases.
Expand Down Expand Up @@ -58,11 +60,15 @@ The next time the game is launched via the normal Play option, the previous ROM

![ROM file selection window](images/select-file-window.png?raw=true "ROM file selection window")

The same menu is also available in BigBox, though currently only supports keyboard input.

![ROM file selection window](images/select-file-window-bigbox.png?raw=true "ROM file selection window")

### Keeping Games Cached
Games can be marked 'Keep' so they stay cached and ready to play. To keep a game cached, open the plugin configuration window from the _Tools->Archive Cache Manager_ menu. From there a list of games in the cache is shown. Check the Keep box next to the game, then click OK.

### Badge
The plugin includes a badge to indicate if a game is currently in the cache. It is available under the _Badges->Enable Archive Cached_ menu. There are additional Simple White and Neon style badges, which can be found in the `LaunchBox\Plugins\ArchiveCacheManager\Badges` folder.
The plugin includes a badge to indicate if a game is currently in the cache. It is available under the _Badges->Plugin Badges->Enable Archive Cached_ menu. There are additional Simple White and Neon style badges, which can be found in the `LaunchBox\Plugins\ArchiveCacheManager\Badges` folder. Copy your preferred icon to the `LaunchBox\Images\Badges` folder and rename it `Archive Cached.png`.

![Badge icon to indicate if a game is cached](images/badges.png?raw=true "Badge icon to indicate if a game is cached")

Expand All @@ -78,7 +84,7 @@ An overview of each of the configuration items is below.
This section shows a summary of the cache including the _Cache Path_, _Cache Size_, and _Keep Size_. It also displays a list of the items currently in the cache.

#### Cached Items & Keep
Each item in the cache has a _Keep_ flag, which when set will prevent the item from being removed from the cache when the cache is full. This is useful for less frequently played games which you still want to load without waiting (party games, favourites, children's games, etc).
Each item in the cache has a _Keep_ flag, which when set will prevent the item from being removed from the cache when the cache is full. This is useful for less frequently played games which you still want to load without waiting (very large games, party games, favourites, children's games, etc).

Items marked _Keep_ are not included in the cache size calculation. The total size of _Keep_ items is listed in the cache details summary.

Expand Down Expand Up @@ -106,7 +112,7 @@ This is the maximum cache size on disk in megabytes. The oldest played games wil
Default: _20,000 MB (20 GB)_

##### Configure Cache - Minimum Archive Size
This is the minimum size in megabytes of an uncompressed archive to be added to the cache. Archives smaller than this won't be added to the cache.
This is the minimum size in megabytes of an uncompressed archive before it will be added to the cache. Archives smaller than this won't be added to the cache.

Default: _100 MB_

Expand All @@ -122,12 +128,20 @@ Clicking on the `Delete` button will remove the selected items from the cache (i
#### Purge Cache
Clicking on the `Delete All` button will delete everything from the cache (including items with the _Keep_ setting).

### File Extension Priority
This defines the file extension priority for the specified emulator and platform combination. Use the Add / Edit / Delete buttons to manage file extension priorities.
### Filename Priority
Files from an archive can be prioritized in cases where an emulator requires a certain filename or file type. This option defines the filename and/or extension priority for the specified emulator and platform combination. Use the Add / Edit / Delete buttons to manage priorities.

A wildcard (*) can be used to perform partial filename matches. Examples include:

* *Files ending with bin, then files ending in iso, then all other files:* `bin, iso`

* *Files named eboot.bin, then all other files:* `eboot.bin`

* *GoodMerged style - European 'good' ROM dumps, then USA 'good' ROM dumps, then other region 'good' ROM dumps, then all other files:* `*(*E*)*[!].*, *(*U*)*[!].*, *[!].*`

File extensions are a comma delimited list, where the highest priority is the first extension, the next highest priority is the second extension, and so on. If the file extension is not found in the archive when a game is loaded, the default LaunchBox priority is used.
The priorities are a comma delimited list, where the highest priority is the first entry, the next highest priority is the second entry, and so on. If the filename extension is not found in the archive when a game is loaded, the default LaunchBox priority is used.

Note that the extension priority is applied to all archives, even if they are not cached.
Note that the priority is applied to all archives, even if they are not cached.

Default: _PCSX2 \ Sony Playstation 2 \ bin, iso_

Expand Down
Binary file added images/select-file-window-bigbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/ArchiveCacheManager/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Archive Cache Manager")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

Expand Down
155 changes: 64 additions & 91 deletions src/Core/CacheManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,55 @@ public static string ListFileArchive(ref string stderr, ref int exitCode)
string selectedFilePath = string.Empty;
string fileList = string.Empty;

if (!launchGameInfo.SelectedFile.Equals(string.Empty))
{
if (Zip.GetFileList(Archive.Path, launchGameInfo.SelectedFile).Length > 0)
{
fileList = "Path = " + Path.Combine(PathUtils.ArchiveCachePath(Archive.Path), launchGameInfo.SelectedFile);
Logger.Log(string.Format("Selected individual file from archive \"{0}\".", launchGameInfo.SelectedFile));
}
}

if (fileList == string.Empty)
{
try
{
string[] extensionPriority = Config.FilenamePriority[string.Format(@"{0} \ {1}", launchGameInfo.Emulator, launchGameInfo.Platform)].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

// Search the extensions in priority order
foreach (string extension in extensionPriority)
{
List<string> filePaths = Zip.GetFileList(Archive.Path, string.Format("*{0}", extension.Trim())).ToList();

if (filePaths.Count > 0)
{
fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
Logger.Log(string.Format("Using filename priority \"{0}\".", extension.Trim()));
break;
}
}
}
catch (KeyNotFoundException)
{

}
}

if (fileList == string.Empty)
{
List<string> filePaths = Zip.GetFileList(Archive.Path).ToList();

if (filePaths.Count > 0)
{
fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
}
}

return fileList;

/*
Zip.ListVerbose(Archive.Path, ref stdout, ref stderr, ref exitCode);
selectedFilePath = "Path = " + launchGameInfo.SelectedFile;
Expand All @@ -202,8 +251,8 @@ public static string ListFileArchive(ref string stderr, ref int exitCode)
{
fileList = ApplyExtensionPriority(stdout);
}

return fileList;
return fileList;*/
}

/// <summary>
Expand Down Expand Up @@ -231,7 +280,7 @@ public static string ListCacheArchive()
{
try
{
string[] extensionPriority = Config.ExtensionPriority[string.Format(@"{0} \ {1}", launchGameInfo.Emulator, launchGameInfo.Platform)].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
string[] extensionPriority = Config.FilenamePriority[string.Format(@"{0} \ {1}", launchGameInfo.Emulator, launchGameInfo.Platform)].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

// Search the extensions in priority order
foreach (string extension in extensionPriority)
Expand All @@ -243,8 +292,13 @@ public static string ListCacheArchive()
filePaths.Remove(ex);
}

fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
if (filePaths.Count > 0)
{
fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
Logger.Log(string.Format("Using filename priority \"{0}\".", extension.Trim()));
break;
}
}
}
catch (KeyNotFoundException)
Expand All @@ -262,8 +316,11 @@ public static string ListCacheArchive()
filePaths.Remove(ex);
}

fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
if (filePaths.Count > 0)
{
fileList = string.Join("\r\nPath = ", filePaths);
fileList = string.Format("Path = {0}\r\n", fileList);
}
}

return fileList;
Expand Down Expand Up @@ -417,89 +474,5 @@ public static void ExtractArchive()
}
UpdateArchiveCachePlaytime(Archive.CachePath);
}

/// <summary>
/// DEPRECATED. Use ListCacheArchive() instead.
/// Generates an absolute path list of files in the archive cache based on the file list from 7z.
/// </summary>
/// <param name="listStdout"></param>
/// <returns></returns>
static string MakeArchiveListAbsolute(string listStdout)
{
string absoluteStdout = listStdout;
Match match = null;

// Find the first "Path = " entry in the 7z list stdout, then skip to the next match (the first file within the archive)
match = Regex.Match(listStdout, @"Path = .*", RegexOptions.IgnoreCase).NextMatch();

if (match.Success)
{
absoluteStdout = string.Empty;
}

// Loop through all of the matches, building up a string of files with the absolute path
while (match.Success)
{
// Remove the leading "Path = " portion of the result
// Remove any white space from the result (namely a trailing \r)
// LB only seems to check for "Path = X" strings in 7z list stdout, so we only need to build a string containing "Path = "
absoluteStdout = string.Format("{0}\r\nPath = {1}", absoluteStdout, Path.Combine(Archive.CachePath, match.Value.Replace("Path = ", string.Empty).Trim()));
match = match.NextMatch();
}

return absoluteStdout;
}

/// <summary>
/// Applies the current file entension priority to the input file list by filtering out any files where the file extensions do not match the priority list.
/// If there is no file priority list, or no files match, the file list will be unchanged.
/// </summary>
/// <param name="listStdout">Current file list.</param>
/// <returns>Modified file list, or identical file list if no file priority applied.</returns>
static string ApplyExtensionPriority(string listStdout)
{
string priorityStdout = listStdout;
Match match = null;
bool extensionFound = false;

try
{
string[] extensionPriority = Config.ExtensionPriority[string.Format(@"{0} \ {1}", launchGameInfo.Emulator, launchGameInfo.Platform)].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

// Search the extensions in priority order
foreach (string extension in extensionPriority)
{
// Find the first "Path = " entry in the 7z list stdout with the specified extension
match = Regex.Match(listStdout, string.Format(@"Path = .*\.{0}", extension.Trim()), RegexOptions.IgnoreCase);

if (match.Success)
{
priorityStdout = string.Empty;
extensionFound = true;

Logger.Log(string.Format("Applying extension priority \"{0}\".", extension.Trim()));
}

// Loop through all of the matches, building up a string of files with the priority extension
while (match.Success)
{
priorityStdout = string.Format("{0}\r\n{1}", priorityStdout, match.Value.Trim());
match = match.NextMatch();
}

// Stop looking for extensions if we found one already
if (extensionFound)
{
break;
}
}
}
catch (KeyNotFoundException)
{

}

return priorityStdout;
}
}
}
Loading

0 comments on commit bba5f16

Please sign in to comment.