Refactored code, and added Amiga CDTV and CD32, and ColecoVision to the PlatformMap (#252)
* More bug fixes * Update PlatformMap for Amiga CDTV and CD32, and ColecoVision * Fixed default platform setting for library scan * Refactor of rematcher * Temp unzips are no longer deleted immediately - now kept and cleaned up after 5 minutes * Library Scan now spawns worker processes to perform scans in parallel. Number of workers is limited by MaxWorkers default = 4 * More logging * More null reference checks * Overhaul of ROM and MediaGroup handling in web page * Minor collections updates * Newlines are now replaced with breaks in HTML on Game summary page
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -403,3 +403,4 @@ ASALocalRun/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
gaseous-server/.DS_Store
|
||||
|
@@ -12,6 +12,7 @@ using IGDB.Models;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Newtonsoft.Json;
|
||||
using SharpCompress.Common;
|
||||
|
||||
namespace gaseous_server.Classes
|
||||
{
|
||||
@@ -66,7 +67,7 @@ namespace gaseous_server.Classes
|
||||
public static CollectionItem NewCollection(CollectionItem item)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "INSERT INTO RomCollections (`Name`, Description, Platforms, Genres, Players, PlayerPerspectives, Themes, MinimumRating, MaximumRating, MaximumRomsPerPlatform, MaximumBytesPerPlatform, MaximumCollectionSizeInBytes, FolderStructure, IncludeBIOSFiles, AlwaysInclude, BuiltStatus) VALUES (@name, @description, @platforms, @genres, @players, @playerperspectives, @themes, @minimumrating, @maximumrating, @maximumromsperplatform, @maximumbytesperplatform, @maximumcollectionsizeinbytes, @folderstructure, @includebiosfiles, @alwaysinclude, @builtstatus); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
string sql = "INSERT INTO RomCollections (`Name`, Description, Platforms, Genres, Players, PlayerPerspectives, Themes, MinimumRating, MaximumRating, MaximumRomsPerPlatform, MaximumBytesPerPlatform, MaximumCollectionSizeInBytes, FolderStructure, IncludeBIOSFiles, ArchiveType, AlwaysInclude, BuiltStatus) VALUES (@name, @description, @platforms, @genres, @players, @playerperspectives, @themes, @minimumrating, @maximumrating, @maximumromsperplatform, @maximumbytesperplatform, @maximumcollectionsizeinbytes, @folderstructure, @includebiosfiles, @archivetype, @alwaysinclude, @builtstatus); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("name", item.Name);
|
||||
dbDict.Add("description", item.Description);
|
||||
@@ -82,6 +83,7 @@ namespace gaseous_server.Classes
|
||||
dbDict.Add("maximumcollectionsizeinbytes", Common.ReturnValueIfNull(item.MaximumCollectionSizeInBytes, -1));
|
||||
dbDict.Add("folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous));
|
||||
dbDict.Add("includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0));
|
||||
dbDict.Add("archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip));
|
||||
dbDict.Add("alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List<CollectionItem.AlwaysIncludeItem>())));
|
||||
dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild);
|
||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||
@@ -97,7 +99,7 @@ namespace gaseous_server.Classes
|
||||
public static CollectionItem EditCollection(long Id, CollectionItem item, bool ForceRebuild = true)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "UPDATE RomCollections SET `Name`=@name, Description=@description, Platforms=@platforms, Genres=@genres, Players=@players, PlayerPerspectives=@playerperspectives, Themes=@themes, MinimumRating=@minimumrating, MaximumRating=@maximumrating, MaximumRomsPerPlatform=@maximumromsperplatform, MaximumBytesPerPlatform=@maximumbytesperplatform, MaximumCollectionSizeInBytes=@maximumcollectionsizeinbytes, FolderStructure=@folderstructure, IncludeBIOSFiles=@includebiosfiles, AlwaysInclude=@alwaysinclude, BuiltStatus=@builtstatus WHERE Id=@id";
|
||||
string sql = "UPDATE RomCollections SET `Name`=@name, Description=@description, Platforms=@platforms, Genres=@genres, Players=@players, PlayerPerspectives=@playerperspectives, Themes=@themes, MinimumRating=@minimumrating, MaximumRating=@maximumrating, MaximumRomsPerPlatform=@maximumromsperplatform, MaximumBytesPerPlatform=@maximumbytesperplatform, MaximumCollectionSizeInBytes=@maximumcollectionsizeinbytes, FolderStructure=@folderstructure, IncludeBIOSFiles=@includebiosfiles, ArchiveType=@archivetype, AlwaysInclude=@alwaysinclude, BuiltStatus=@builtstatus WHERE Id=@id";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("id", Id);
|
||||
dbDict.Add("name", item.Name);
|
||||
@@ -115,8 +117,9 @@ namespace gaseous_server.Classes
|
||||
dbDict.Add("folderstructure", Common.ReturnValueIfNull(item.FolderStructure, CollectionItem.FolderStructures.Gaseous));
|
||||
dbDict.Add("includebiosfiles", Common.ReturnValueIfNull(item.IncludeBIOSFiles, 0));
|
||||
dbDict.Add("alwaysinclude", Newtonsoft.Json.JsonConvert.SerializeObject(Common.ReturnValueIfNull(item.AlwaysInclude, new List<CollectionItem.AlwaysIncludeItem>())));
|
||||
dbDict.Add("archivetype", Common.ReturnValueIfNull(item.ArchiveType, CollectionItem.ArchiveTypes.Zip));
|
||||
|
||||
string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ".zip");
|
||||
string CollectionZipFile = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + item.ArchiveExtension);
|
||||
if (ForceRebuild == true)
|
||||
{
|
||||
dbDict.Add("builtstatus", CollectionItem.CollectionBuildStatus.WaitingForBuild);
|
||||
@@ -389,7 +392,7 @@ namespace gaseous_server.Classes
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
List<CollectionContents.CollectionPlatformItem> collectionPlatformItems = GetCollectionContent(collectionItem).Collection;
|
||||
string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, collectionItem.Id + ".zip");
|
||||
string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, collectionItem.Id + collectionItem.ArchiveExtension);
|
||||
string ZipFileTempPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, collectionItem.Id.ToString());
|
||||
|
||||
try
|
||||
@@ -508,7 +511,21 @@ namespace gaseous_server.Classes
|
||||
|
||||
// compress to zip
|
||||
Logging.Log(Logging.LogType.Information, "Collections", "Compressing collection");
|
||||
switch(collectionItem.ArchiveType)
|
||||
{
|
||||
case CollectionItem.ArchiveTypes.Zip:
|
||||
ZipFile.CreateFromDirectory(ZipFileTempPath, ZipFilePath, CompressionLevel.SmallestSize, false);
|
||||
break;
|
||||
|
||||
case CollectionItem.ArchiveTypes.RAR:
|
||||
|
||||
break;
|
||||
|
||||
case CollectionItem.ArchiveTypes.SevenZip:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// clean up
|
||||
if (Directory.Exists(ZipFileTempPath))
|
||||
@@ -567,6 +584,7 @@ namespace gaseous_server.Classes
|
||||
item.MaximumCollectionSizeInBytes = (long)Common.ReturnValueIfNull(row["MaximumCollectionSizeInBytes"], (long)-1);
|
||||
item.FolderStructure = (CollectionItem.FolderStructures)(int)Common.ReturnValueIfNull(row["FolderStructure"], 0);
|
||||
item.IncludeBIOSFiles = (bool)row["IncludeBIOSFiles"];
|
||||
item.ArchiveType = (CollectionItem.ArchiveTypes)(int)Common.ReturnValueIfNull(row["ArchiveType"], 0);
|
||||
item.AlwaysInclude = Newtonsoft.Json.JsonConvert.DeserializeObject<List<CollectionItem.AlwaysIncludeItem>>(strAlwaysInclude);
|
||||
item.BuildStatus = (CollectionItem.CollectionBuildStatus)(int)Common.ReturnValueIfNull(row["BuiltStatus"], 0);
|
||||
|
||||
@@ -595,6 +613,32 @@ namespace gaseous_server.Classes
|
||||
public long? MaximumCollectionSizeInBytes { get; set; }
|
||||
public FolderStructures FolderStructure { get; set; } = FolderStructures.Gaseous;
|
||||
public bool IncludeBIOSFiles { get; set; } = true;
|
||||
public ArchiveTypes ArchiveType { get; set; } = CollectionItem.ArchiveTypes.Zip;
|
||||
public string ArchiveExtension
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ArchiveType != null)
|
||||
{
|
||||
switch (ArchiveType)
|
||||
{
|
||||
case ArchiveTypes.Zip:
|
||||
default:
|
||||
return ".zip";
|
||||
|
||||
case ArchiveTypes.RAR:
|
||||
return ".rar";
|
||||
|
||||
case ArchiveTypes.SevenZip:
|
||||
return ".7z";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ".zip";
|
||||
}
|
||||
}
|
||||
}
|
||||
public List<AlwaysIncludeItem> AlwaysInclude { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
@@ -604,7 +648,7 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
if (_BuildStatus == CollectionBuildStatus.Completed)
|
||||
{
|
||||
if (File.Exists(Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ".zip")))
|
||||
if (File.Exists(Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension)))
|
||||
{
|
||||
return CollectionBuildStatus.Completed;
|
||||
}
|
||||
@@ -632,7 +676,7 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
if (BuildStatus == CollectionBuildStatus.Completed)
|
||||
{
|
||||
string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ".zip");
|
||||
string ZipFilePath = Path.Combine(Config.LibraryConfiguration.LibraryCollectionsDirectory, Id + ArchiveExtension);
|
||||
if (File.Exists(ZipFilePath))
|
||||
{
|
||||
FileInfo fi = new FileInfo(ZipFilePath);
|
||||
@@ -665,6 +709,13 @@ namespace gaseous_server.Classes
|
||||
RetroPie = 1
|
||||
}
|
||||
|
||||
public enum ArchiveTypes
|
||||
{
|
||||
Zip = 0,
|
||||
RAR = 1,
|
||||
SevenZip = 2
|
||||
}
|
||||
|
||||
public class AlwaysIncludeItem
|
||||
{
|
||||
public long PlatformId { get; set; }
|
||||
|
@@ -503,6 +503,14 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
private static int _MaxLibraryScanWorkers
|
||||
{
|
||||
get
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
private static string _HasheousHost
|
||||
{
|
||||
get
|
||||
@@ -522,6 +530,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
||||
|
||||
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
||||
|
||||
public string HasheousHost = _HasheousHost;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO.Compression;
|
||||
using HasheousClient.Models;
|
||||
using NuGet.Common;
|
||||
using SevenZip;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.Rar;
|
||||
@@ -10,11 +12,11 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
public class FileSignature
|
||||
{
|
||||
public static gaseous_server.Models.Signatures_Games GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
public gaseous_server.Models.Signatures_Games GetFileSignature(GameLibrary.LibraryItem library, Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Getting signature for file: " + GameFileImportPath);
|
||||
gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games();
|
||||
discoveredSignature = _GetFileSignature(hash, fi, GameFileImportPath, false);
|
||||
discoveredSignature = _GetFileSignature(hash, fi.Name, fi.Extension, fi.Length, GameFileImportPath, false);
|
||||
|
||||
string[] CompressionExts = { ".zip", ".rar", ".7z" };
|
||||
string ImportedFileExtension = Path.GetExtension(GameFileImportPath);
|
||||
@@ -23,7 +25,8 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
// file is a zip and less than 1 GiB
|
||||
// extract the zip file and search the contents
|
||||
string ExtractPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, Path.GetRandomFileName());
|
||||
|
||||
string ExtractPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, library.Id.ToString(), Path.GetRandomFileName());
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Decompressing " + GameFileImportPath + " to " + ExtractPath + " examine contents");
|
||||
if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); }
|
||||
try
|
||||
@@ -129,7 +132,7 @@ namespace gaseous_server.Classes
|
||||
|
||||
if (signatureFound == false)
|
||||
{
|
||||
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi, file, true);
|
||||
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi.Name, zfi.Extension, zfi.Length, file, true);
|
||||
zDiscoveredSignature.Rom.Name = Path.ChangeExtension(zDiscoveredSignature.Rom.Name, ImportedFileExtension);
|
||||
|
||||
if (zDiscoveredSignature.Score > discoveredSignature.Score)
|
||||
@@ -162,24 +165,20 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
Logging.Log(Logging.LogType.Critical, "Get Signature", "Error processing compressed file: " + GameFileImportPath, ex);
|
||||
}
|
||||
|
||||
if (Directory.Exists(ExtractPath))
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Deleting temporary decompress folder: " + ExtractPath);
|
||||
|
||||
Directory.Delete(ExtractPath, true);
|
||||
}
|
||||
}
|
||||
|
||||
return discoveredSignature;
|
||||
}
|
||||
|
||||
private static gaseous_server.Models.Signatures_Games _GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath, bool IsInZip)
|
||||
private gaseous_server.Models.Signatures_Games _GetFileSignature(Common.hashObject hash, string ImageName, string ImageExtension, long ImageSize, string GameFileImportPath, bool IsInZip)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", "Checking signature for file: " + GameFileImportPath + "\nMD5 hash: " + hash.md5hash + "\nSHA1 hash: " + hash.sha1hash);
|
||||
|
||||
|
||||
gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games();
|
||||
|
||||
// do database search first
|
||||
gaseous_server.Models.Signatures_Games? dbSignature = _GetFileSignatureFromDatabase(hash, fi, GameFileImportPath);
|
||||
gaseous_server.Models.Signatures_Games? dbSignature = _GetFileSignatureFromDatabase(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||
|
||||
if (dbSignature != null)
|
||||
{
|
||||
@@ -190,7 +189,7 @@ namespace gaseous_server.Classes
|
||||
else
|
||||
{
|
||||
// no local signature attempt to pull from Hasheous
|
||||
dbSignature = _GetFileSignatureFromHasheous(hash, fi, GameFileImportPath);
|
||||
dbSignature = _GetFileSignatureFromHasheous(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||
|
||||
if (dbSignature != null)
|
||||
{
|
||||
@@ -202,25 +201,32 @@ namespace gaseous_server.Classes
|
||||
else
|
||||
{
|
||||
// construct a signature from file data
|
||||
dbSignature = _GetFileSignatureFromFileData(hash, fi, GameFileImportPath);
|
||||
dbSignature = _GetFileSignatureFromFileData(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature generated from provided file for game: " + dbSignature.Game.Name);
|
||||
|
||||
discoveredSignature = dbSignature;
|
||||
}
|
||||
}
|
||||
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, ImageExtension, false);
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System);
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " Platform determined to be: " + discoveredSignature.Flags.IGDBPlatformName + " (" + discoveredSignature.Flags.IGDBPlatformId + ")");
|
||||
|
||||
return discoveredSignature;
|
||||
}
|
||||
|
||||
private static gaseous_server.Models.Signatures_Games? _GetFileSignatureFromDatabase(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
private gaseous_server.Models.Signatures_Games? _GetFileSignatureFromDatabase(Common.hashObject hash, string ImageName, string ImageExtension, long ImageSize, string GameFileImportPath)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Checking local database for MD5: " + hash.md5hash);
|
||||
|
||||
// check 1: do we have a signature for it?
|
||||
gaseous_server.Classes.SignatureManagement sc = new SignatureManagement();
|
||||
List<gaseous_server.Models.Signatures_Games> signatures = sc.GetSignature(hash.md5hash);
|
||||
if (signatures.Count == 0)
|
||||
if (signatures == null || signatures.Count == 0)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Checking local database for SHA1: " + hash.sha1hash);
|
||||
|
||||
// no md5 signature found - try sha1
|
||||
signatures = sc.GetSignature("", hash.sha1hash);
|
||||
}
|
||||
@@ -230,19 +236,19 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
// only 1 signature found!
|
||||
discoveredSignature = signatures.ElementAt(0);
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
|
||||
return discoveredSignature;
|
||||
}
|
||||
else if (signatures.Count > 1)
|
||||
{
|
||||
// more than one signature found - find one with highest score
|
||||
// start with first returned element
|
||||
discoveredSignature = signatures.First();
|
||||
foreach (gaseous_server.Models.Signatures_Games Sig in signatures)
|
||||
{
|
||||
if (Sig.Score > discoveredSignature.Score)
|
||||
{
|
||||
discoveredSignature = Sig;
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +258,7 @@ namespace gaseous_server.Classes
|
||||
return null;
|
||||
}
|
||||
|
||||
private static gaseous_server.Models.Signatures_Games? _GetFileSignatureFromHasheous(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
private gaseous_server.Models.Signatures_Games? _GetFileSignatureFromHasheous(Common.hashObject hash, string ImageName, string ImageExtension, long ImageSize, string GameFileImportPath)
|
||||
{
|
||||
// check if hasheous is enabled, and if so use it's signature database
|
||||
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
||||
@@ -286,8 +292,6 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref signature, fi, false);
|
||||
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
@@ -296,20 +300,19 @@ namespace gaseous_server.Classes
|
||||
return null;
|
||||
}
|
||||
|
||||
private static gaseous_server.Models.Signatures_Games _GetFileSignatureFromFileData(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
private gaseous_server.Models.Signatures_Games _GetFileSignatureFromFileData(Common.hashObject hash, string ImageName, string ImageExtension, long ImageSize, string GameFileImportPath)
|
||||
{
|
||||
SignatureManagement signatureManagement = new SignatureManagement();
|
||||
|
||||
gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games();
|
||||
|
||||
// no signature match found - try name search
|
||||
List<gaseous_server.Models.Signatures_Games> signatures = signatureManagement.GetByTosecName(fi.Name);
|
||||
List<gaseous_server.Models.Signatures_Games> signatures = signatureManagement.GetByTosecName(ImageName);
|
||||
|
||||
if (signatures.Count == 1)
|
||||
{
|
||||
// only 1 signature found!
|
||||
discoveredSignature = signatures.ElementAt(0);
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
|
||||
return discoveredSignature;
|
||||
}
|
||||
@@ -321,7 +324,6 @@ namespace gaseous_server.Classes
|
||||
if (Sig.Score > discoveredSignature.Score)
|
||||
{
|
||||
discoveredSignature = Sig;
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,14 +350,11 @@ namespace gaseous_server.Classes
|
||||
// remove special characters like dashes
|
||||
gi.Name = gi.Name.Replace("-", "").Trim();
|
||||
|
||||
// guess platform
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true);
|
||||
|
||||
// get rom data
|
||||
ri.Name = Path.GetFileName(GameFileImportPath);
|
||||
ri.Md5 = hash.md5hash;
|
||||
ri.Sha1 = hash.sha1hash;
|
||||
ri.Size = fi.Length;
|
||||
ri.Size = ImageSize;
|
||||
ri.SignatureSource = gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.None;
|
||||
|
||||
return discoveredSignature;
|
||||
|
@@ -34,6 +34,12 @@ namespace gaseous_server
|
||||
{}
|
||||
}
|
||||
|
||||
public class CannotDeleteLibraryWhileScanIsActive : Exception
|
||||
{
|
||||
public CannotDeleteLibraryWhileScanIsActive() : base("Unable to delete library while a library scan is active. Wait for all scans to complete and try again")
|
||||
{}
|
||||
}
|
||||
|
||||
// code
|
||||
public static LibraryItem GetDefaultLibrary
|
||||
{
|
||||
@@ -110,21 +116,42 @@ namespace gaseous_server
|
||||
|
||||
int newLibraryId = (int)(long)data.Rows[0][0];
|
||||
|
||||
return GetLibrary(newLibraryId);
|
||||
Logging.Log(Logging.LogType.Information, "Library Management", "Created library " + Name + " at directory " + PathName);
|
||||
|
||||
LibraryItem library = GetLibrary(newLibraryId);
|
||||
|
||||
return library;
|
||||
}
|
||||
|
||||
public static void DeleteLibrary(int LibraryId)
|
||||
{
|
||||
if (GetLibrary(LibraryId).IsDefaultLibrary == false)
|
||||
LibraryItem library = GetLibrary(LibraryId);
|
||||
if (library.IsDefaultLibrary == false)
|
||||
{
|
||||
// check for active library scans
|
||||
foreach(ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||
{
|
||||
if (
|
||||
(item.ItemType == ProcessQueue.QueueItemType.LibraryScan && item.ItemState == ProcessQueue.QueueItemState.Running) ||
|
||||
(item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker && item.ItemState == ProcessQueue.QueueItemState.Running)
|
||||
)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Library Management", "Unable to delete libraries while a library scan is running. Wait until the the library scan is completed and try again.");
|
||||
throw new CannotDeleteLibraryWhileScanIsActive();
|
||||
}
|
||||
}
|
||||
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "DELETE FROM Games_Roms WHERE LibraryId=@id; DELETE FROM GameLibraries WHERE Id=@id;";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("id", LibraryId);
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Library Management", "Deleted library " + library.Name + " at path " + library.Path);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Library Management", "Unable to delete the default library.");
|
||||
throw new CannotDeleteDefaultLibrary();
|
||||
}
|
||||
}
|
||||
|
@@ -98,7 +98,8 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
|
||||
|
||||
gaseous_server.Models.Signatures_Games discoveredSignature = GetFileSignature(hash, fi, GameFileImportPath);
|
||||
FileSignature fileSignature = new FileSignature();
|
||||
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, hash, fi, GameFileImportPath);
|
||||
|
||||
// get discovered platform
|
||||
IGDB.Models.Platform? determinedPlatform = null;
|
||||
@@ -117,7 +118,7 @@ namespace gaseous_server.Classes
|
||||
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
|
||||
}
|
||||
|
||||
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId);
|
||||
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
|
||||
|
||||
// add to database
|
||||
StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath);
|
||||
@@ -148,16 +149,16 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId)
|
||||
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
||||
{
|
||||
if (Signature.Flags != null)
|
||||
{
|
||||
if (Signature.Flags.IGDBGameId != null)
|
||||
if (Signature.Flags.IGDBGameId != null && Signature.Flags.IGDBGameId != 0)
|
||||
{
|
||||
// game was determined elsewhere - probably a Hasheous server
|
||||
try
|
||||
{
|
||||
return Games.GetGame(Signature.Flags.IGDBGameId, false, false, false);
|
||||
return Games.GetGame(Signature.Flags.IGDBGameId, false, false, FullDownload);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -482,12 +483,22 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
public void LibraryScan()
|
||||
public void LibraryScan(GameLibrary.LibraryItem? singleLibrary = null)
|
||||
{
|
||||
int maxWorkers = 4;
|
||||
int maxWorkers = Config.MetadataConfiguration.MaxLibraryScanWorkers;
|
||||
|
||||
List<GameLibrary.LibraryItem> libraries = new List<GameLibrary.LibraryItem>();
|
||||
if (singleLibrary == null)
|
||||
{
|
||||
libraries.AddRange(GameLibrary.GetLibraries);
|
||||
}
|
||||
else
|
||||
{
|
||||
libraries.Add(singleLibrary);
|
||||
}
|
||||
|
||||
// setup background tasks for each library
|
||||
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
||||
foreach (GameLibrary.LibraryItem library in libraries)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting worker process for library " + library.Name);
|
||||
ProcessQueue.QueueItem queue = new ProcessQueue.QueueItem(
|
||||
@@ -623,31 +634,28 @@ namespace gaseous_server.Classes
|
||||
Common.hashObject hash = new Common.hashObject(LibraryFile);
|
||||
FileInfo fi = new FileInfo(LibraryFile);
|
||||
|
||||
gaseous_server.Models.Signatures_Games sig = GetFileSignature(hash, fi, LibraryFile);
|
||||
FileSignature fileSignature = new FileSignature();
|
||||
gaseous_server.Models.Signatures_Games sig = fileSignature.GetFileSignature(library, hash, fi, LibraryFile);
|
||||
|
||||
// get discovered platform
|
||||
IGDB.Models.Platform determinedPlatform = Metadata.Platforms.GetPlatform(sig.Flags.IGDBPlatformId);
|
||||
|
||||
IGDB.Models.Game determinedGame = new Game();
|
||||
try
|
||||
{
|
||||
if (determinedPlatform == null)
|
||||
// get discovered platform
|
||||
long PlatformId;
|
||||
IGDB.Models.Platform determinedPlatform;
|
||||
|
||||
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0 )
|
||||
{
|
||||
if (library.DefaultPlatformId == 0)
|
||||
{
|
||||
determinedPlatform = new IGDB.Models.Platform();
|
||||
determinedGame = SearchForGame(sig, sig.Flags.IGDBPlatformId);
|
||||
// no platform discovered in the signature
|
||||
PlatformId = library.DefaultPlatformId;
|
||||
}
|
||||
else
|
||||
{
|
||||
determinedPlatform = Platforms.GetPlatform(library.DefaultPlatformId);
|
||||
determinedGame = SearchForGame(sig, library.DefaultPlatformId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
determinedGame = SearchForGame(sig, (long)determinedPlatform.Id);
|
||||
// use the platform discovered in the signature
|
||||
PlatformId = sig.Flags.IGDBPlatformId;
|
||||
}
|
||||
determinedPlatform = Platforms.GetPlatform(PlatformId);
|
||||
|
||||
IGDB.Models.Game determinedGame = SearchForGame(sig, PlatformId, true);
|
||||
|
||||
StoreROM(library, hash, determinedGame, determinedPlatform, sig, LibraryFile);
|
||||
}
|
||||
@@ -718,26 +726,29 @@ namespace gaseous_server.Classes
|
||||
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan starting");
|
||||
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
|
||||
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch on library " + library.Name);
|
||||
|
||||
string sql = "";
|
||||
if (ForceExecute == false)
|
||||
{
|
||||
sql = "SELECT * FROM Games_Roms WHERE (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) LIMIT 100;";
|
||||
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) AND LibraryId = @libraryid LIMIT 100;";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = "SELECT * FROM Games_Roms WHERE (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0));";
|
||||
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND LibraryId = @libraryid;";
|
||||
}
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
||||
dbDict.Add("libraryid", library.Id);
|
||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||
int StatusCount = -0;
|
||||
foreach (DataRow row in data.Rows)
|
||||
{
|
||||
SetStatus(StatusCount, data.Rows.Count, "Running rematcher");
|
||||
|
||||
// get library
|
||||
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)row["LibraryId"]);
|
||||
|
||||
// get rom info
|
||||
long romId = (long)row["Id"];
|
||||
string romPath = (string)row["Path"];
|
||||
@@ -751,16 +762,26 @@ namespace gaseous_server.Classes
|
||||
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Running rematch against " + romPath);
|
||||
|
||||
// determine rom signature
|
||||
gaseous_server.Models.Signatures_Games sig = GetFileSignature(hash, fi, romPath);
|
||||
FileSignature fileSignature = new FileSignature();
|
||||
gaseous_server.Models.Signatures_Games sig = fileSignature.GetFileSignature(library, hash, fi, romPath);
|
||||
|
||||
// determine rom platform
|
||||
IGDB.Models.Platform determinedPlatform = Metadata.Platforms.GetPlatform(sig.Flags.IGDBPlatformId);
|
||||
if (determinedPlatform == null)
|
||||
// get discovered platform
|
||||
long PlatformId;
|
||||
IGDB.Models.Platform determinedPlatform;
|
||||
|
||||
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0 )
|
||||
{
|
||||
determinedPlatform = new IGDB.Models.Platform();
|
||||
// no platform discovered in the signature
|
||||
PlatformId = library.DefaultPlatformId;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use the platform discovered in the signature
|
||||
PlatformId = sig.Flags.IGDBPlatformId;
|
||||
}
|
||||
determinedPlatform = Platforms.GetPlatform(PlatformId);
|
||||
|
||||
IGDB.Models.Game determinedGame = SearchForGame(sig, sig.Flags.IGDBPlatformId);
|
||||
IGDB.Models.Game determinedGame = SearchForGame(sig, PlatformId, true);
|
||||
|
||||
StoreROM(library, hash, determinedGame, determinedPlatform, sig, romPath, romId);
|
||||
|
||||
@@ -779,4 +800,5 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -127,9 +127,8 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate; INSERT INTO ServerLogs (EventTime, EventType, Process, Message, Exception, CorrelationId, CallingProcess, CallingUser) VALUES (@EventTime, @EventType, @Process, @Message, @Exception, @correlationid, @callingprocess, @callinguser);";
|
||||
string sql = "INSERT INTO ServerLogs (EventTime, EventType, Process, Message, Exception, CorrelationId, CallingProcess, CallingUser) VALUES (@EventTime, @EventType, @Process, @Message, @Exception, @correlationid, @callingprocess, @callinguser);";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||
dbDict.Add("EventTime", logItem.EventTime);
|
||||
dbDict.Add("EventType", logItem.EventType);
|
||||
dbDict.Add("Process", logItem.Process);
|
||||
|
@@ -11,6 +11,32 @@ namespace gaseous_server.Classes
|
||||
|
||||
public void RunMaintenance()
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
|
||||
// remove any entries from the library that have an invalid id
|
||||
string LibraryWhereClause = "";
|
||||
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
||||
{
|
||||
if (LibraryWhereClause.Length > 0)
|
||||
{
|
||||
LibraryWhereClause += ", ";
|
||||
}
|
||||
LibraryWhereClause += library.Id;
|
||||
}
|
||||
string sqlLibraryWhereClause = "";
|
||||
if (LibraryWhereClause.Length > 0)
|
||||
{
|
||||
sqlLibraryWhereClause = "DELETE FROM Games_Roms WHERE LibraryId NOT IN ( " + LibraryWhereClause + " );";
|
||||
db.ExecuteCMD(sqlLibraryWhereClause);
|
||||
}
|
||||
|
||||
// delete old logs
|
||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate;";
|
||||
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
// delete files and directories older than 7 days in PathsToClean
|
||||
List<string> PathsToClean = new List<string>();
|
||||
PathsToClean.Add(Config.LibraryConfiguration.LibraryUploadDirectory);
|
||||
@@ -45,8 +71,7 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Maintenance", "Optimising database tables");
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SHOW TABLES;";
|
||||
sql = "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE';";
|
||||
DataTable tables = db.ExecuteCMD(sql);
|
||||
|
||||
int StatusCounter = 1;
|
||||
|
@@ -67,14 +67,14 @@ namespace gaseous_server.Classes.Metadata
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
try
|
||||
{
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -91,6 +91,8 @@ namespace gaseous_server.Classes.Metadata
|
||||
|
||||
// check for presence of "original" quality file - download if absent or force download is true
|
||||
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||
if (GetImages == true)
|
||||
{
|
||||
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Artwork download forced.");
|
||||
@@ -98,6 +100,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
Communications comms = new Communications();
|
||||
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
@@ -69,14 +69,14 @@ namespace gaseous_server.Classes.Metadata
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
try
|
||||
{
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -92,6 +92,8 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
|
||||
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||
if (GetImages == true)
|
||||
{
|
||||
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Cover download forced.");
|
||||
@@ -113,6 +115,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
@@ -478,7 +478,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
|
||||
// check search cache
|
||||
List<Game>? games = Communications.GetSearchCache<List<Game>>(searchFields, searchBody);
|
||||
Game[]? games = Communications.GetSearchCache<Game[]?>(searchFields, searchBody);
|
||||
|
||||
if (games == null)
|
||||
{
|
||||
@@ -489,6 +489,8 @@ namespace gaseous_server.Classes.Metadata
|
||||
if (allowSearch == true)
|
||||
{
|
||||
results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, searchFields, searchBody);
|
||||
|
||||
Communications.SetSearchCache<Game[]?>(searchFields, searchBody, results);
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -499,6 +501,24 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
}
|
||||
|
||||
public static List<KeyValuePair<long, string>> GetAvailablePlatforms(long GameId)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE Games_Roms.GameId = @gameid ORDER BY Platform.`Name`;";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("gameid", GameId);
|
||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
List<KeyValuePair<long, string>> platforms = new List<KeyValuePair<long, string>>();
|
||||
foreach (DataRow row in data.Rows)
|
||||
{
|
||||
KeyValuePair<long, string> valuePair = new KeyValuePair<long, string>((long)row["PlatformId"], (string)row["Name"]);
|
||||
platforms.Add(valuePair);
|
||||
}
|
||||
|
||||
return platforms;
|
||||
}
|
||||
|
||||
public enum SearchType
|
||||
{
|
||||
where = 0,
|
||||
|
@@ -67,14 +67,14 @@ namespace gaseous_server.Classes.Metadata
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
try
|
||||
{
|
||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
if (GetImages == true) { forceImageDownload = true; }
|
||||
forceImageDownload = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -91,6 +91,8 @@ namespace gaseous_server.Classes.Metadata
|
||||
|
||||
// check for presence of "original" quality file - download if absent or force download is true
|
||||
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||
if (GetImages == true)
|
||||
{
|
||||
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Screenshot download forced.");
|
||||
@@ -98,6 +100,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
Communications comms = new Communications();
|
||||
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
@@ -91,7 +91,7 @@ namespace gaseous_server.Classes
|
||||
mediaGroupItems.Add(BuildMediaGroupFromRow(row));
|
||||
}
|
||||
|
||||
mediaGroupItems.Sort((x, y) => x.PlatformName.CompareTo(y.PlatformName));
|
||||
mediaGroupItems.Sort((x, y) => x.Platform.CompareTo(y.Platform));
|
||||
|
||||
return mediaGroupItems;
|
||||
}
|
||||
@@ -176,6 +176,7 @@ namespace gaseous_server.Classes
|
||||
mediaGroupItem.PlatformId = (long)row["PlatformId"];
|
||||
mediaGroupItem.GameId = (long)row["GameId"];
|
||||
mediaGroupItem.RomIds = new List<long>();
|
||||
mediaGroupItem.Roms = new List<Roms.GameRomItem>();
|
||||
|
||||
// get members
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
@@ -186,6 +187,26 @@ namespace gaseous_server.Classes
|
||||
foreach (DataRow dataRow in data.Rows)
|
||||
{
|
||||
mediaGroupItem.RomIds.Add((long)dataRow["RomId"]);
|
||||
try
|
||||
{
|
||||
mediaGroupItem.Roms.Add(Roms.GetRom((long)dataRow["RomId"]));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Rom Group", "Unable to load ROM data", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// check for a web emulator and update the romItem
|
||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||
{
|
||||
if (platformMapping.IGDBId == mediaGroupItem.PlatformId)
|
||||
{
|
||||
if (platformMapping.WebEmulator != null)
|
||||
{
|
||||
mediaGroupItem.Emulator = platformMapping.WebEmulator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mediaGroupItem;
|
||||
@@ -360,7 +381,7 @@ namespace gaseous_server.Classes
|
||||
public long Id { get; set; }
|
||||
public long GameId { get; set; }
|
||||
public long PlatformId { get; set; }
|
||||
public string PlatformName {
|
||||
public string Platform {
|
||||
get
|
||||
{
|
||||
try
|
||||
@@ -373,7 +394,9 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
}
|
||||
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||
public List<long> RomIds { get; set; }
|
||||
public List<Roms.GameRomItem> Roms { get; set; }
|
||||
private GroupBuildStatus _Status { get; set; }
|
||||
public GroupBuildStatus Status {
|
||||
get
|
||||
|
@@ -71,17 +71,6 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
// get rom media groups
|
||||
GameRoms.MediaGroups = Classes.RomMediaGroup.GetMediaGroupsFromGameId(GameId);
|
||||
|
||||
// sort the platforms
|
||||
GameRoms.Platforms = new List<KeyValuePair<long, string>>();
|
||||
foreach (DataRow platformRow in platformDT.Rows)
|
||||
{
|
||||
KeyValuePair<long, string> valuePair = new KeyValuePair<long, string>((long)platformRow["PlatformId"], (string)platformRow["Name"]);
|
||||
GameRoms.Platforms.Add(valuePair);
|
||||
}
|
||||
|
||||
return GameRoms;
|
||||
}
|
||||
else
|
||||
@@ -190,46 +179,17 @@ namespace gaseous_server.Classes
|
||||
|
||||
public class GameRomObject
|
||||
{
|
||||
public List<GameRomMediaGroupItem> MediaGroups { get; set; } = new List<GameRomMediaGroupItem>();
|
||||
public List<GameRomItem> GameRomItems { get; set; } = new List<GameRomItem>();
|
||||
public int Count { get; set; }
|
||||
public List<KeyValuePair<long, string>> Platforms { get; set; }
|
||||
}
|
||||
|
||||
public class GameRomItem : HasheousClient.Models.LookupResponseModel.RomItem
|
||||
{
|
||||
//public long Id { get; set; }
|
||||
public long PlatformId { get; set; }
|
||||
public string Platform { get; set; }
|
||||
//public Dictionary<string, object>? Emulator { get; set; }
|
||||
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||
public long GameId { get; set; }
|
||||
//public string? Name { get; set; }
|
||||
//public long Size { get; set; }
|
||||
//public string? CRC { get; set; }
|
||||
//public string? MD5 { get; set; }
|
||||
//public string? SHA1 { get; set; }
|
||||
//public string? DevelopmentStatus { get; set; }
|
||||
//public string[]? Flags { get; set; }
|
||||
//public List<KeyValuePair<string, object>>? Attributes { get; set;}
|
||||
//public int RomType { get; set; }
|
||||
//public string? RomTypeMedia { get; set; }
|
||||
// public MediaType? MediaDetail {
|
||||
// get
|
||||
// {
|
||||
// if (RomTypeMedia != null)
|
||||
// {
|
||||
// return new MediaType(Source, RomTypeMedia);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// public string? MediaLabel { get; set; }
|
||||
public string? Path { get; set; }
|
||||
//public SignatureSourceType Source { get; set; }
|
||||
public string? SignatureSourceGameTitle { get; set;}
|
||||
public GameLibrary.LibraryItem Library { get; set; }
|
||||
}
|
||||
|
@@ -288,15 +288,15 @@ namespace gaseous_server.Controllers
|
||||
[ProducesResponseType(typeof(Game), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[ResponseCache(CacheProfileName = "5Minute")]
|
||||
public ActionResult Game(long GameId, bool forceRefresh = false)
|
||||
public ActionResult Game(long GameId)
|
||||
{
|
||||
try
|
||||
{
|
||||
GaseousGame gameObject = new GaseousGame(Classes.Metadata.Games.GetGame(GameId, forceRefresh, false, forceRefresh));
|
||||
Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
if (gameObject != null)
|
||||
if (game != null)
|
||||
{
|
||||
return Ok(gameObject);
|
||||
return Ok(game);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -767,6 +767,24 @@ namespace gaseous_server.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpGet]
|
||||
[Route("{GameId}/platforms")]
|
||||
[ProducesResponseType(typeof(List<KeyValuePair<long, string>>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult GamePlatforms(long GameId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(Games.GetAvailablePlatforms(GameId));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpGet]
|
||||
@@ -1022,6 +1040,35 @@ namespace gaseous_server.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpGet]
|
||||
[Authorize(Roles = "Admin,Gamer")]
|
||||
[Route("{GameId}/romgroup")]
|
||||
[ProducesResponseType(typeof(List<RomMediaGroup.GameRomMediaGroupItem>), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult GetGameRomGroup(long GameId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
try
|
||||
{
|
||||
return Ok(RomMediaGroup.GetMediaGroupsFromGameId(GameId));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Critical, "Rom Group", "An error occurred", ex);
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpPost]
|
||||
@@ -1174,7 +1221,8 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
Classes.Roms.GameRomItem romItem = Classes.Roms.GetRom(RomId);
|
||||
Common.hashObject hash = new Common.hashObject(romItem.Path);
|
||||
gaseous_server.Models.Signatures_Games romSig = FileSignature.GetFileSignature(hash, new FileInfo(romItem.Path), romItem.Path);
|
||||
FileSignature fileSignature = new FileSignature();
|
||||
gaseous_server.Models.Signatures_Games romSig = fileSignature.GetFileSignature(romItem.Library, hash, new FileInfo(romItem.Path), romItem.Path);
|
||||
List<Game> searchResults = Classes.ImportGame.SearchForGame_GetAll(romSig.Game.Name, romSig.Flags.IGDBPlatformId);
|
||||
|
||||
return Ok(searchResults);
|
||||
|
@@ -47,48 +47,48 @@ namespace gaseous_server.Models
|
||||
}
|
||||
}
|
||||
|
||||
public List<IGDB.Models.Artwork>? ArtworksItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Artworks != null)
|
||||
{
|
||||
if (this.Artworks.Ids != null)
|
||||
{
|
||||
List<IGDB.Models.Artwork> artworks = new List<IGDB.Models.Artwork>();
|
||||
foreach (long id in this.Artworks.Ids)
|
||||
{
|
||||
artworks.Add(gaseous_server.Classes.Metadata.Artworks.GetArtwork(id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false));
|
||||
}
|
||||
// public List<IGDB.Models.Artwork>? ArtworksItem
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (this.Artworks != null)
|
||||
// {
|
||||
// if (this.Artworks.Ids != null)
|
||||
// {
|
||||
// List<IGDB.Models.Artwork> artworks = new List<IGDB.Models.Artwork>();
|
||||
// foreach (long id in this.Artworks.Ids)
|
||||
// {
|
||||
// artworks.Add(gaseous_server.Classes.Metadata.Artworks.GetArtwork(id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false));
|
||||
// }
|
||||
|
||||
return artworks;
|
||||
}
|
||||
}
|
||||
// return artworks;
|
||||
// }
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public List<IGDB.Models.Screenshot>? ScreenshotsItem
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.Screenshots != null)
|
||||
{
|
||||
if (this.Screenshots.Ids != null)
|
||||
{
|
||||
List<IGDB.Models.Screenshot> screenshots = new List<IGDB.Models.Screenshot>();
|
||||
foreach (long id in this.Screenshots.Ids)
|
||||
{
|
||||
screenshots.Add(gaseous_server.Classes.Metadata.Screenshots.GetScreenshot(id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false));
|
||||
}
|
||||
// public List<IGDB.Models.Screenshot>? ScreenshotsItem
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// if (this.Screenshots != null)
|
||||
// {
|
||||
// if (this.Screenshots.Ids != null)
|
||||
// {
|
||||
// List<IGDB.Models.Screenshot> screenshots = new List<IGDB.Models.Screenshot>();
|
||||
// foreach (long id in this.Screenshots.Ids)
|
||||
// {
|
||||
// screenshots.Add(gaseous_server.Classes.Metadata.Screenshots.GetScreenshot(id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false));
|
||||
// }
|
||||
|
||||
return screenshots;
|
||||
}
|
||||
}
|
||||
// return screenshots;
|
||||
// }
|
||||
// }
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
@@ -371,14 +371,19 @@ namespace gaseous_server.Models
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void GetIGDBPlatformMapping(ref gaseous_server.Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName)
|
||||
public static void GetIGDBPlatformMapping(ref gaseous_server.Models.Signatures_Games Signature, string ImageExtension, bool SetSystemName)
|
||||
{
|
||||
if (Signature.Game != null)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Platform Mapping", "Determining platform based on extension " + ImageExtension + " or \"" + Signature.Game.System + "\"");
|
||||
}
|
||||
|
||||
bool PlatformFound = false;
|
||||
foreach (Models.PlatformMapping.PlatformMapItem PlatformMapping in Models.PlatformMapping.PlatformMap)
|
||||
{
|
||||
if (PlatformMapping.Extensions != null)
|
||||
{
|
||||
if (PlatformMapping.Extensions.UniqueFileExtensions.Contains(RomFileInfo.Extension, StringComparer.OrdinalIgnoreCase))
|
||||
if (PlatformMapping.Extensions.UniqueFileExtensions.Contains(ImageExtension, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
if (SetSystemName == true)
|
||||
{
|
||||
@@ -388,6 +393,8 @@ namespace gaseous_server.Models
|
||||
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName;
|
||||
|
||||
PlatformFound = true;
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Platform Mapping", "Platform id " + PlatformMapping.IGDBId + " determined from file extension");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -410,10 +417,17 @@ namespace gaseous_server.Models
|
||||
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName;
|
||||
|
||||
PlatformFound = true;
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Platform Mapping", "Platform id " + PlatformMapping.IGDBId + " determined from signature system to platform map");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PlatformFound == false)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Platform Mapping", "Unable to determine platform");
|
||||
}
|
||||
}
|
||||
|
||||
public class PlatformMapItem
|
||||
|
@@ -2,6 +2,8 @@
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Data;
|
||||
using gaseous_server.Classes;
|
||||
using NuGet.Common;
|
||||
using NuGet.Packaging;
|
||||
|
||||
namespace gaseous_server
|
||||
{
|
||||
@@ -239,6 +241,32 @@ namespace gaseous_server
|
||||
maintenance.RunMaintenance();
|
||||
break;
|
||||
|
||||
case QueueItemType.TempCleanup:
|
||||
try
|
||||
{
|
||||
foreach (GameLibrary.LibraryItem libraryItem in GameLibrary.GetLibraries)
|
||||
{
|
||||
string rootPath = Path.Combine(Config.LibraryConfiguration.LibraryTempDirectory, libraryItem.Id.ToString());
|
||||
if (Directory.Exists(rootPath))
|
||||
{
|
||||
foreach (string directory in Directory.GetDirectories(rootPath))
|
||||
{
|
||||
DirectoryInfo info = new DirectoryInfo(directory);
|
||||
if (info.LastWriteTimeUtc.AddMinutes(5) < DateTime.UtcNow)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Deleting temporary decompress folder: " + directory);
|
||||
Directory.Delete(directory, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception tcEx)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "An error occurred while cleaning temporary files", tcEx);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -394,7 +422,12 @@ namespace gaseous_server
|
||||
/// <summary>
|
||||
/// Performs a clean up of old files, and optimises the database
|
||||
/// </summary>
|
||||
Maintainer
|
||||
Maintainer,
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up marked paths in the temporary directory
|
||||
/// </summary>
|
||||
TempCleanup
|
||||
}
|
||||
|
||||
public enum QueueItemState
|
||||
|
@@ -476,6 +476,16 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
})
|
||||
);
|
||||
|
||||
ProcessQueue.QueueItem tempCleanup = new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.TempCleanup,
|
||||
1,
|
||||
new List<ProcessQueue.QueueItemType>(),
|
||||
false,
|
||||
false
|
||||
);
|
||||
tempCleanup.ForceExecute();
|
||||
ProcessQueue.QueueItems.Add(tempCleanup);
|
||||
|
||||
Logging.WriteToDiskOnly = false;
|
||||
|
||||
// start the app
|
||||
|
2
gaseous-server/Support/Database/MySQL/gaseous-1014.sql
Normal file
2
gaseous-server/Support/Database/MySQL/gaseous-1014.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `RomCollections`
|
||||
ADD COLUMN `ArchiveType` INT NULL AFTER `IncludeBIOSFiles`;
|
@@ -188,6 +188,91 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 114,
|
||||
"igdbName": "Amiga CD32",
|
||||
"igdbSlug": "amiga-cd32",
|
||||
"alternateNames": [
|
||||
"Amiga CD32",
|
||||
"Commodore Amiga CD32"
|
||||
],
|
||||
"extensions": {
|
||||
"supportedFileExtensions": [
|
||||
".ZIP"
|
||||
],
|
||||
"uniqueFileExtensions": [
|
||||
]
|
||||
},
|
||||
"retroPieDirectoryName": "amiga",
|
||||
"webEmulator": {
|
||||
"type": "EmulatorJS",
|
||||
"core": "amiga",
|
||||
"availableWebEmulators": [
|
||||
{
|
||||
"emulatorType": "EmulatorJS",
|
||||
"availableWebEmulatorCores": [
|
||||
{
|
||||
"core": "amiga",
|
||||
"alternateCoreName": "puae",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bios": [
|
||||
{
|
||||
"hash": "85ad74194e87c08904327de1a9443b7a",
|
||||
"description": "Kickstart v1.2 rev 33.180",
|
||||
"filename": "kick33180.A500"
|
||||
},
|
||||
{
|
||||
"hash": "82a21c1890cae844b3df741f2762d48d",
|
||||
"description": "Kickstart v1.3 rev 34.005",
|
||||
"filename": "kick34005.A500"
|
||||
},
|
||||
{
|
||||
"hash": "89da1838a24460e4b93f4f0c5d92d48d",
|
||||
"description": "CDTV extended ROM v1.00",
|
||||
"filename": "kick34005.CDTV"
|
||||
},
|
||||
{
|
||||
"hash": "dc10d7bdd1b6f450773dfb558477c230",
|
||||
"description": "Kickstart v2.04 rev 37.175",
|
||||
"filename": "kick37175.A500"
|
||||
},
|
||||
{
|
||||
"hash": "5f8924d013dd57a89cf349f4cdedc6b1",
|
||||
"description": "CD32 Kickstart v3.1 rev 40.060",
|
||||
"filename": "kick40060.CD32"
|
||||
},
|
||||
{
|
||||
"hash": "f2f241bf094168cfb9e7805dc2856433",
|
||||
"description": "CD32 KS + extended v3.1 rev 40.060",
|
||||
"filename": "kick40060.CD32"
|
||||
},
|
||||
{
|
||||
"hash": "bb72565701b1b6faece07d68ea5da639",
|
||||
"description": "CD32 extended ROM rev 40.060",
|
||||
"filename": "kick40060.CD32.ext"
|
||||
},
|
||||
{
|
||||
"hash": "e40a5dfb3d017ba8779faba30cbd1c8e",
|
||||
"description": "Kickstart v3.1 rev 40.063",
|
||||
"filename": "kick40063.A600"
|
||||
},
|
||||
{
|
||||
"hash": "646773759326fbac3b2311fd8c8793ee",
|
||||
"description": "Kickstart v3.1 rev 40.068",
|
||||
"filename": "kick40068.A1200"
|
||||
},
|
||||
{
|
||||
"hash": "9bdedde6a4f33555b4a270c8ca53297d",
|
||||
"description": "Kickstart v3.1 rev 40.068",
|
||||
"filename": "kick40068.A4000"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 25,
|
||||
"igdbName": "Amstrad CPC",
|
||||
@@ -543,6 +628,48 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 68,
|
||||
"igdbName": "ColecoVision",
|
||||
"igdbSlug": "colecovision",
|
||||
"alternateNames": [
|
||||
"ColecoVision"
|
||||
],
|
||||
"extensions": {
|
||||
"supportedFileExtensions": [
|
||||
".BIN",
|
||||
".COL",
|
||||
".ROM",
|
||||
".ZIP"
|
||||
],
|
||||
"uniqueFileExtensions": [
|
||||
]
|
||||
},
|
||||
"retroPieDirectoryName": "coleco",
|
||||
"webEmulator": {
|
||||
"type": "EmulatorJS",
|
||||
"core": "coleco",
|
||||
"availableWebEmulators": [
|
||||
{
|
||||
"emulatorType": "EmulatorJS",
|
||||
"availableWebEmulatorCores": [
|
||||
{
|
||||
"core": "coleco",
|
||||
"alternateCoreName": "coleco",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bios": [
|
||||
{
|
||||
"hash": "2c66f5911e5b42b8ebe113403548eee7",
|
||||
"description": "ColecoVision BIOS - Mandatory",
|
||||
"filename": "colecovision.rom"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 15,
|
||||
"igdbName": "Commodore C64/128/MAX",
|
||||
@@ -620,6 +747,92 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 158,
|
||||
"igdbName": "Commodore CDTV",
|
||||
"igdbSlug": "commodore-cdtv",
|
||||
"alternateNames": [
|
||||
"Commodore CDTV",
|
||||
"Amiga CDTV",
|
||||
"Commodore Amiga CDTV"
|
||||
],
|
||||
"extensions": {
|
||||
"supportedFileExtensions": [
|
||||
".ZIP"
|
||||
],
|
||||
"uniqueFileExtensions": [
|
||||
]
|
||||
},
|
||||
"retroPieDirectoryName": "amiga",
|
||||
"webEmulator": {
|
||||
"type": "EmulatorJS",
|
||||
"core": "amiga",
|
||||
"availableWebEmulators": [
|
||||
{
|
||||
"emulatorType": "EmulatorJS",
|
||||
"availableWebEmulatorCores": [
|
||||
{
|
||||
"core": "amiga",
|
||||
"alternateCoreName": "puae",
|
||||
"default": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"bios": [
|
||||
{
|
||||
"hash": "85ad74194e87c08904327de1a9443b7a",
|
||||
"description": "Kickstart v1.2 rev 33.180",
|
||||
"filename": "kick33180.A500"
|
||||
},
|
||||
{
|
||||
"hash": "82a21c1890cae844b3df741f2762d48d",
|
||||
"description": "Kickstart v1.3 rev 34.005",
|
||||
"filename": "kick34005.A500"
|
||||
},
|
||||
{
|
||||
"hash": "89da1838a24460e4b93f4f0c5d92d48d",
|
||||
"description": "CDTV extended ROM v1.00",
|
||||
"filename": "kick34005.CDTV"
|
||||
},
|
||||
{
|
||||
"hash": "dc10d7bdd1b6f450773dfb558477c230",
|
||||
"description": "Kickstart v2.04 rev 37.175",
|
||||
"filename": "kick37175.A500"
|
||||
},
|
||||
{
|
||||
"hash": "5f8924d013dd57a89cf349f4cdedc6b1",
|
||||
"description": "CD32 Kickstart v3.1 rev 40.060",
|
||||
"filename": "kick40060.CD32"
|
||||
},
|
||||
{
|
||||
"hash": "f2f241bf094168cfb9e7805dc2856433",
|
||||
"description": "CD32 KS + extended v3.1 rev 40.060",
|
||||
"filename": "kick40060.CD32"
|
||||
},
|
||||
{
|
||||
"hash": "bb72565701b1b6faece07d68ea5da639",
|
||||
"description": "CD32 extended ROM rev 40.060",
|
||||
"filename": "kick40060.CD32.ext"
|
||||
},
|
||||
{
|
||||
"hash": "e40a5dfb3d017ba8779faba30cbd1c8e",
|
||||
"description": "Kickstart v3.1 rev 40.063",
|
||||
"filename": "kick40063.A600"
|
||||
},
|
||||
{
|
||||
"hash": "646773759326fbac3b2311fd8c8793ee",
|
||||
"description": "Kickstart v3.1 rev 40.068",
|
||||
"filename": "kick40068.A1200"
|
||||
},
|
||||
{
|
||||
"hash": "9bdedde6a4f33555b4a270c8ca53297d",
|
||||
"description": "Kickstart v3.1 rev 40.068",
|
||||
"filename": "kick40068.A4000"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"igdbId": 33,
|
||||
"igdbName": "Game Boy",
|
||||
|
@@ -58,6 +58,7 @@
|
||||
<None Remove="Support\Database\MySQL\gaseous-1011.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1012.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1013.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1014.sql" />
|
||||
<None Remove="Classes\Metadata\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -93,5 +94,6 @@
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1011.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1012.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1013.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1014.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@@ -42,15 +42,18 @@
|
||||
var statusText = result[i].buildStatus;
|
||||
var downloadLink = '';
|
||||
var packageSize = '-';
|
||||
var inProgress = false;
|
||||
switch (result[i].buildStatus) {
|
||||
case 'NoStatus':
|
||||
statusText = '-';
|
||||
break;
|
||||
case "WaitingForBuild":
|
||||
statusText = 'Build pending';
|
||||
inProgress = true;
|
||||
break;
|
||||
case "Building":
|
||||
statusText = 'Building';
|
||||
inProgress = true;
|
||||
break;
|
||||
case "Completed":
|
||||
statusText = 'Available';
|
||||
@@ -65,6 +68,10 @@
|
||||
break;
|
||||
}
|
||||
|
||||
if (inProgress == true) {
|
||||
setTimeout(GetCollections, 10000);
|
||||
}
|
||||
|
||||
var editButton = '';
|
||||
var deleteButton = '';
|
||||
|
||||
|
@@ -97,6 +97,18 @@
|
||||
BIOS files for each platform will be stored in /BIOS
|
||||
</td>
|
||||
</tr>
|
||||
<!-- <tr>
|
||||
<th>
|
||||
Archive format
|
||||
</th>
|
||||
<td>
|
||||
<select id="collection_archiveformat" style="width: 100%;">
|
||||
<option id="collection_archiveformat_zip" selected="selected" value="Zip">Zip</option>
|
||||
<option id="collection_archiveformat_rar" value="RAR">RAR</option>
|
||||
<option id="collection_archiveformat_7z" value="SevenZip">7z</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr> -->
|
||||
</table>
|
||||
</div>
|
||||
<table style="position: absolute; top: 0px; right: 0px; bottom: 0px; width: 60%;">
|
||||
|
@@ -16,10 +16,12 @@
|
||||
'DELETE',
|
||||
function (result) {
|
||||
loadRoms();
|
||||
loadMediaGroups();
|
||||
closeSubDialog();
|
||||
},
|
||||
function (error) {
|
||||
loadRoms();
|
||||
loadMediaGroups();
|
||||
closeSubDialog();
|
||||
}
|
||||
);
|
||||
|
@@ -71,6 +71,7 @@
|
||||
</div>
|
||||
<div id="gamesummarymediagroups" style="display: none;">
|
||||
<h3>Media Groups</h3>
|
||||
<div id="gamesummarymediagroupscontent"></div>
|
||||
</div>
|
||||
<div id="gamesummaryroms">
|
||||
<span id="rom_edit" class="romlink" onclick="DisplayROMCheckboxes(true);">Edit</span>
|
||||
@@ -85,6 +86,21 @@
|
||||
<button id="rom_edit_creategroup" onclick="createMgGroup();" disabled="disabled">Create Media Group</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="games_library_controls">
|
||||
<div class="games_library_controlblock">
|
||||
<input id="name_filter" type="text" placeholder="Name Search">
|
||||
</div>
|
||||
<div class="games_library_controlblock">
|
||||
<select id="platform_filter"></select>
|
||||
</div>
|
||||
<div class="games_library_controlblock">
|
||||
<button value="Search" onclick="loadRoms();">Search</button>
|
||||
</div>
|
||||
<div class="games_library_controlblock">
|
||||
<span class="games_library_label">0 ROMs</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="gamesummaryromscontent"></div>
|
||||
</div>
|
||||
<div id="gamesummarysimilar" style="display: none;">
|
||||
<h3>Similar Games</h3>
|
||||
@@ -144,9 +160,9 @@
|
||||
var gameSummaryLabel = document.getElementById('gamesummarytext_label');
|
||||
if (result.summary || result.storyline) {
|
||||
if (result.summary) {
|
||||
gameSummaryLabel.innerHTML = result.summary;
|
||||
gameSummaryLabel.innerHTML = result.summary.replaceAll("\n", "<br />");
|
||||
} else {
|
||||
gameSummaryLabel.innerHTML = result.storyline;
|
||||
gameSummaryLabel.innerHTML = result.storyline.replaceAll("\n", "<br />");
|
||||
}
|
||||
|
||||
if (gameSummaryLabel.offsetHeight < gameSummaryLabel.scrollHeight ||
|
||||
@@ -161,21 +177,30 @@
|
||||
gameSummaryLabel.setAttribute('style', 'display: none;');
|
||||
}
|
||||
|
||||
// load artwork
|
||||
if (result.artworksItem) {
|
||||
artworks = result.artworksItem;
|
||||
var startPos = randomIntFromInterval(0, result.artworksItem.length);
|
||||
artworksPosition = startPos;
|
||||
rotateBackground();
|
||||
// load cover
|
||||
var gameSummaryCover = document.getElementById('gamesummary_cover');
|
||||
var gameImage = document.createElement('img');
|
||||
gameImage.className = 'game_cover_image';
|
||||
if (result.cover) {
|
||||
ajaxCall('/api/v1.1/games/' + gameId + '/cover', 'GET', function (coverResult) {
|
||||
if (coverResult) {
|
||||
gameImage.src = '/api/v1.1/Games/' + gameId + '/cover/image/cover_big/' + coverResult.imageId + '.jpg';
|
||||
|
||||
loadArtwork(result, coverResult);
|
||||
} else {
|
||||
var bg = document.getElementById('bgImage');
|
||||
if (result.coverItem) {
|
||||
bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/cover/image/original/' + result.coverItem.imageId + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
|
||||
gameImage.src = '/images/unknowngame.png';
|
||||
gameImage.className = 'game_cover_image unknown';
|
||||
|
||||
loadArtwork(result);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
var randomInt = randomIntFromInterval(1, 3);
|
||||
bg.setAttribute('style', 'background-image: url("/images/gamebg' + randomInt + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
|
||||
}
|
||||
gameImage.src = '/images/unknowngame.png';
|
||||
gameImage.className = 'game_cover_image unknown';
|
||||
|
||||
loadArtwork(result);
|
||||
}
|
||||
gameSummaryCover.appendChild(gameImage);
|
||||
|
||||
// load companies
|
||||
var gameHeaderDeveloperLabel = document.getElementById('gamedeveloper_label');
|
||||
@@ -231,18 +256,6 @@
|
||||
gamePublisherLabel.setAttribute('style', 'display: none;');
|
||||
}
|
||||
|
||||
// load cover
|
||||
var gameSummaryCover = document.getElementById('gamesummary_cover');
|
||||
var gameImage = document.createElement('img');
|
||||
gameImage.className = 'game_cover_image';
|
||||
if (result.cover) {
|
||||
gameImage.src = '/api/v1.1/Games/' + result.id + '/cover/image/cover_big/' + result.coverItem.imageId + '.jpg';
|
||||
} else {
|
||||
gameImage.src = '/images/unknowngame.png';
|
||||
gameImage.className = 'game_cover_image unknown';
|
||||
}
|
||||
gameSummaryCover.appendChild(gameImage);
|
||||
|
||||
// load release date
|
||||
var gameSummaryRelease = document.getElementById('gamesummary_firstrelease');
|
||||
if (result.firstReleaseDate) {
|
||||
@@ -314,6 +327,34 @@
|
||||
gameSummaryGenres.setAttribute('style', 'display: none;');
|
||||
}
|
||||
|
||||
// get platforms
|
||||
var platformFilter = document.getElementById('platform_filter');
|
||||
platformFilter.style.width = "200px";
|
||||
$(platformFilter).select2({
|
||||
minimumResultsForSearch: Infinity
|
||||
});
|
||||
ajaxCall('/api/v1.1/Games/' + gameId + '/platforms', 'GET', function (result) {
|
||||
// add default option
|
||||
var platformFilter_default = document.createElement('option');
|
||||
platformFilter_default.value = "-1";
|
||||
platformFilter_default.innerHTML = "All Platforms";
|
||||
platformFilter_default.selected = "selected";
|
||||
platformFilter.appendChild(platformFilter_default);
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var platformFilter_opt = document.createElement('option');
|
||||
platformFilter_opt.value = result[i].key;
|
||||
platformFilter_opt.innerHTML = result[i].value;
|
||||
platformFilter.appendChild(platformFilter_opt);
|
||||
}
|
||||
|
||||
// load media groups
|
||||
loadMediaGroups();
|
||||
|
||||
// load roms
|
||||
loadRoms(false, 1);
|
||||
});
|
||||
|
||||
// load screenshots
|
||||
var gameScreenshots = document.getElementById('gamescreenshots');
|
||||
if (result.screenshots || result.videos) {
|
||||
@@ -325,12 +366,13 @@
|
||||
if (result.videos) {
|
||||
imageIndex = result.videos.ids.length;
|
||||
}
|
||||
if (result.screenshotsItem) {
|
||||
for (var i = 0; i < result.screenshotsItem.length; i++) {
|
||||
if (result.screenshots) {
|
||||
ajaxCall('/api/v1.1/Games/' + gameId + '/screenshots', 'GET', function (screenshotsItem) {
|
||||
for (var i = 0; i < screenshotsItem.length; i++) {
|
||||
var screenshotItem = document.createElement('div');
|
||||
screenshotItem.id = 'gamescreenshots_gallery_' + imageIndex;
|
||||
screenshotItem.setAttribute('name', 'gamescreenshots_gallery_item');
|
||||
screenshotItem.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/screenshots/' + result.screenshotsItem[i].id + '/image/screenshot_thumb/' + result.screenshotsItem[i].imageId + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: contain;)');
|
||||
screenshotItem.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/screenshots/' + screenshotsItem[i].id + '/image/screenshot_thumb/' + screenshotsItem[i].imageId + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: contain;)');
|
||||
screenshotItem.setAttribute('imageid', imageIndex);
|
||||
screenshotItem.setAttribute('imagetype', 0);
|
||||
screenshotItem.className = 'gamescreenshots_gallery_item';
|
||||
@@ -338,6 +380,9 @@
|
||||
gameScreenshots_Gallery.appendChild(screenshotItem);
|
||||
imageIndex += 1;
|
||||
}
|
||||
|
||||
selectScreenshot(0);
|
||||
});
|
||||
}
|
||||
|
||||
// load videos
|
||||
@@ -387,7 +432,7 @@
|
||||
selectScreenshot(0);
|
||||
});
|
||||
} else {
|
||||
selectScreenshot(0);
|
||||
//selectScreenshot(0);
|
||||
}
|
||||
} else {
|
||||
gamescreenshots.setAttribute('style', 'display: none;');
|
||||
@@ -414,30 +459,125 @@
|
||||
gameSummarySimilar.setAttribute('style', 'display: none;');
|
||||
}
|
||||
});
|
||||
|
||||
// load roms
|
||||
loadRoms(false);
|
||||
});
|
||||
|
||||
function loadRoms(displayCheckboxes, pageNumber, selectedPlatform, nameSearch) {
|
||||
function loadMediaGroups() {
|
||||
ajaxCall('/api/v1.1/Games/' + gameId + '/romgroup', 'GET', function (result) {
|
||||
// display media groups
|
||||
var mediaGroup = document.getElementById('gamesummarymediagroups');
|
||||
var mediaGroupDiv = document.getElementById('gamesummarymediagroupscontent');
|
||||
if (result.length == 0) {
|
||||
mediaGroup.style.display = 'none';
|
||||
} else {
|
||||
console.log(result);
|
||||
mediaGroup.style.display = '';
|
||||
mediaGroupDiv.innerHTML = '';
|
||||
var mgTable = document.createElement('table');
|
||||
mgTable.id = 'mediagrouptable';
|
||||
mgTable.className = 'romtable';
|
||||
mgTable.setAttribute('cellspacing', 0);
|
||||
mgTable.appendChild(createTableRow(true, ['Platform', 'Images', 'Size', '', '', '']));
|
||||
|
||||
lastPlatform = '';
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var mediaGroup = result[i];
|
||||
|
||||
// get rom details including emulator and friendly platform name
|
||||
var launchButton = '';
|
||||
if (mediaGroup.emulator) {
|
||||
if (mediaGroup.emulator.type.length > 0) {
|
||||
launchButton = '<a href="/index.html?page=emulator&engine=' + mediaGroup.emulator.type + '&core=' + mediaGroup.emulator.core + '&platformid=' + mediaGroup.platformId + '&gameid=' + gameId + '&rompath=' + encodeURIComponent('/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '(' + mediaGroup.id + ')' + '.zip') + '" class="romstart">Launch</a>';
|
||||
}
|
||||
}
|
||||
|
||||
var statusText = mediaGroup.status;
|
||||
var downloadLink = '';
|
||||
var packageSize = '-';
|
||||
var launchButtonContent = '';
|
||||
var inProgress = false;
|
||||
switch (mediaGroup.status) {
|
||||
case 'NoStatus':
|
||||
statusText = '-';
|
||||
break;
|
||||
case "WaitingForBuild":
|
||||
statusText = 'Build pending';
|
||||
inProgress = true;
|
||||
break;
|
||||
case "Building":
|
||||
statusText = 'Building';
|
||||
inProgress = true;
|
||||
break;
|
||||
case "Completed":
|
||||
statusText = 'Available';
|
||||
downloadLink = '<a href="/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip" class="romlink"><img src="/images/download.svg" class="banner_button_image" alt="Download" title="Download" /></a>';
|
||||
packageSize = formatBytes(mediaGroup.size);
|
||||
launchButtonContent = launchButton;
|
||||
break;
|
||||
case "Failed":
|
||||
statusText = 'Build error';
|
||||
break;
|
||||
default:
|
||||
statusText = result[i].buildStatus;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inProgress == true) {
|
||||
setTimeout(loadMediaGroups, 10000);
|
||||
}
|
||||
|
||||
var deleteButton = '<a href="#" onclick="showSubDialog(\'mediagroupdelete\', ' + mediaGroup.id + ');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
||||
|
||||
var newRow = [
|
||||
mediaGroup.platform,
|
||||
mediaGroup.romIds.length,
|
||||
packageSize,
|
||||
statusText,
|
||||
launchButtonContent,
|
||||
'<div style="text-align: right;">' + downloadLink + deleteButton + '</div>'
|
||||
]
|
||||
|
||||
mgTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
|
||||
var mgRomRow = document.createElement('tr');
|
||||
var mgRomCell = document.createElement('td');
|
||||
mgRomCell.setAttribute('colspan', 6);
|
||||
mgRomCell.className = 'romGroupTitles';
|
||||
|
||||
|
||||
// iterate the group members
|
||||
var groupMembers = [];
|
||||
for (var r = 0; r < mediaGroup.roms.length; r++) {
|
||||
groupMembers.push(mediaGroup.roms[r]);
|
||||
}
|
||||
|
||||
groupMembers.sort((a, b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
|
||||
var groupMemberNames = [];
|
||||
for (var r = 0; r < groupMembers.length; r++) {
|
||||
groupMemberNames.push(groupMembers[r].name);
|
||||
}
|
||||
mgRomCell.innerHTML = groupMemberNames.join("<br />");
|
||||
mgRomRow.appendChild(mgRomCell);
|
||||
mgTable.appendChild(mgRomRow);
|
||||
}
|
||||
|
||||
mediaGroupDiv.appendChild(mgTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadRoms(displayCheckboxes, pageNumber) {
|
||||
if (!pageNumber) {
|
||||
pageNumber = 1;
|
||||
}
|
||||
|
||||
if (selectedPlatform == undefined) {
|
||||
selectedPlatform = -1;
|
||||
}
|
||||
selectedPlatform = $('#platform_filter').select2('data')[0].id;
|
||||
|
||||
var nameSearchQuery = '';
|
||||
if (nameSearch != undefined) {
|
||||
var nameSearch = document.getElementById('name_filter').value;
|
||||
if (nameSearch != undefined && nameSearch != "") {
|
||||
nameSearchQuery = '&NameSearch=' + encodeURIComponent(nameSearch);
|
||||
}
|
||||
|
||||
var filterControlBlock = document.getElementById('games_library_controls');
|
||||
if (filterControlBlock) {
|
||||
filterControlBlock.remove();
|
||||
}
|
||||
|
||||
var existingTable = document.getElementById('romtable');
|
||||
if (existingTable) {
|
||||
existingTable.remove();
|
||||
@@ -448,11 +588,6 @@
|
||||
romPager.remove();
|
||||
}
|
||||
|
||||
var existingMgTable = document.getElementById('mediagrouptable');
|
||||
if (existingMgTable) {
|
||||
existingMgTable.remove();
|
||||
}
|
||||
|
||||
if (displayCheckboxes == undefined) {
|
||||
if (document.getElementById('rom_edit_panel').style.display == 'none') {
|
||||
displayCheckboxes = false;
|
||||
@@ -461,14 +596,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
var gameRoms = document.getElementById('gamesummaryroms');
|
||||
var gameRomsSection = document.getElementById('gamesummaryroms');
|
||||
var gameRoms = document.getElementById('gamesummaryromscontent');
|
||||
var pageSize = 20;
|
||||
ajaxCall('/api/v1.1/Games/' + gameId + '/roms?pageNumber=' + pageNumber + '&pageSize=' + pageSize + '&platformId=' + selectedPlatform + nameSearchQuery, 'GET', function (result) {
|
||||
drawRomFilterTools(result, gameRoms, displayCheckboxes, pageNumber, selectedPlatform, nameSearch);
|
||||
|
||||
if (result.gameRomItems) {
|
||||
var gameRomItems = result.gameRomItems;
|
||||
var mediaGroups = result.mediaGroups;
|
||||
|
||||
// display roms
|
||||
var newTable = document.createElement('table');
|
||||
@@ -558,193 +691,37 @@
|
||||
romPaginator.appendChild(nextPage);
|
||||
|
||||
gameRoms.appendChild(romPaginator);
|
||||
}
|
||||
|
||||
// display media groups
|
||||
var mediaGroupDiv = document.getElementById('gamesummarymediagroups');
|
||||
if (mediaGroups.length == 0) {
|
||||
mediaGroupDiv.style.display = 'none';
|
||||
} else {
|
||||
mediaGroupDiv.style.display = '';
|
||||
var mgTable = document.createElement('table');
|
||||
mgTable.id = 'mediagrouptable';
|
||||
mgTable.className = 'romtable';
|
||||
mgTable.setAttribute('cellspacing', 0);
|
||||
mgTable.appendChild(createTableRow(true, ['Platform', 'Images', 'Size', '', '', '']));
|
||||
|
||||
lastPlatform = '';
|
||||
for (var i = 0; i < mediaGroups.length; i++) {
|
||||
var mediaGroup = mediaGroups[i];
|
||||
|
||||
// get rom details including emulator and friendly platform name
|
||||
var launchButton = '';
|
||||
for (var r = 0; r < gameRomItems.length; r++) {
|
||||
var gameRomItem = gameRomItems[r];
|
||||
if (gameRomItem.platformId == mediaGroup.platformId) {
|
||||
if (gameRomItem.emulator) {
|
||||
if (gameRomItem.emulator.type.length > 0) {
|
||||
launchButton = '<a href="/index.html?page=emulator&engine=' + gameRomItem.emulator.type + '&core=' + gameRomItem.emulator.core + '&platformid=' + gameRomItem.platformId + '&gameid=' + gameId + '&rompath=' + encodeURIComponent('/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '(' + mediaGroup.id + ')' + '.zip') + '" class="romstart">Launch</a>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var statusText = mediaGroup.status;
|
||||
var downloadLink = '';
|
||||
var packageSize = '-';
|
||||
var launchButtonContent = '';
|
||||
switch (mediaGroup.status) {
|
||||
case 'NoStatus':
|
||||
statusText = '-';
|
||||
break;
|
||||
case "WaitingForBuild":
|
||||
statusText = 'Build pending';
|
||||
break;
|
||||
case "Building":
|
||||
statusText = 'Building';
|
||||
break;
|
||||
case "Completed":
|
||||
statusText = 'Available';
|
||||
downloadLink = '<a href="/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip" class="romlink"><img src="/images/download.svg" class="banner_button_image" alt="Download" title="Download" /></a>';
|
||||
packageSize = formatBytes(mediaGroup.size);
|
||||
launchButtonContent = launchButton;
|
||||
break;
|
||||
case "Failed":
|
||||
statusText = 'Build error';
|
||||
break;
|
||||
default:
|
||||
statusText = result[i].buildStatus;
|
||||
break;
|
||||
}
|
||||
|
||||
var deleteButton = '<a href="#" onclick="showSubDialog(\'mediagroupdelete\', ' + mediaGroup.id + ');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
||||
|
||||
var newRow = [
|
||||
mediaGroup.platformName,
|
||||
mediaGroup.romIds.length,
|
||||
packageSize,
|
||||
statusText,
|
||||
launchButtonContent,
|
||||
'<div style="text-align: right;">' + downloadLink + deleteButton + '</div>'
|
||||
]
|
||||
|
||||
mgTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
|
||||
var mgRomRow = document.createElement('tr');
|
||||
var mgRomCell = document.createElement('td');
|
||||
mgRomCell.setAttribute('colspan', 6);
|
||||
mgRomCell.className = 'romGroupTitles';
|
||||
|
||||
// iterate the group members
|
||||
var groupMembers = [];
|
||||
for (var r = 0; r < mediaGroup.romIds.length; r++) {
|
||||
for (var x = 0; x < gameRomItems.length; x++) {
|
||||
if (mediaGroup.romIds[r] == gameRomItems[x].id) {
|
||||
groupMembers.push(gameRomItems[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupMembers.sort((a, b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
|
||||
var groupMemberNames = [];
|
||||
for (var r = 0; r < groupMembers.length; r++) {
|
||||
groupMemberNames.push(groupMembers[r].name);
|
||||
}
|
||||
mgRomCell.innerHTML = groupMemberNames.join("<br />");
|
||||
|
||||
mgRomRow.appendChild(mgRomCell);
|
||||
mgTable.appendChild(mgRomRow);
|
||||
}
|
||||
|
||||
mediaGroupDiv.appendChild(mgTable);
|
||||
gameRomsSection.appendChild(gameRoms);
|
||||
}
|
||||
} else {
|
||||
gameRoms.setAttribute('style', 'display: none;');
|
||||
gameRomsSection.setAttribute('style', 'display: none;');
|
||||
}
|
||||
},
|
||||
function(error) {
|
||||
drawRomFilterTools(error, gameRoms, displayCheckboxes, pageNumber, selectedPlatform, nameSearch);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
function drawRomFilterTools(result, gameRoms, displayCheckboxes, pageNumber, selectedPlatform, nameSearch) {
|
||||
// display filter tools
|
||||
var filterControls = document.createElement('div');
|
||||
filterControls.id = "games_library_controls";
|
||||
|
||||
var nameSearchFilterBlock = document.createElement('div');
|
||||
nameSearchFilterBlock.className = 'games_library_controlblock';
|
||||
|
||||
var nameSearchbox = document.createElement('input');
|
||||
nameSearchbox.id = 'name_filter';
|
||||
nameSearchbox.type = 'text';
|
||||
if (nameSearch) {
|
||||
nameSearchbox.value = nameSearch;
|
||||
}
|
||||
nameSearchbox.setAttribute('placeholder', "Name Search");
|
||||
nameSearchFilterBlock.appendChild(nameSearchbox);
|
||||
filterControls.appendChild(nameSearchFilterBlock);
|
||||
|
||||
var platformFilterBlock = document.createElement('div');
|
||||
platformFilterBlock.className = 'games_library_controlblock';
|
||||
|
||||
var platformFilterOpt = document.createElement('select');
|
||||
platformFilterOpt.id = "platform_filter";
|
||||
|
||||
var platformFilterOptDefault = document.createElement('option');
|
||||
platformFilterOptDefault.value = '-1';
|
||||
platformFilterOptDefault.innerHTML = 'All Platforms';
|
||||
if (selectedPlatform == -1) {
|
||||
platformFilterOptDefault.selected = 'selected';
|
||||
}
|
||||
platformFilterOpt.appendChild(platformFilterOptDefault);
|
||||
|
||||
if (result.platforms) {
|
||||
for (var i = 0; i < result.platforms.length; i++) {
|
||||
var platformFilterOptValue = document.createElement('option');
|
||||
platformFilterOptValue.value = result.platforms[i].key;
|
||||
platformFilterOptValue.innerHTML = result.platforms[i].value;
|
||||
if (selectedPlatform == Number(result.platforms[i].key)) {
|
||||
platformFilterOptValue.selected = 'selected';
|
||||
}
|
||||
platformFilterOpt.appendChild(platformFilterOptValue);
|
||||
}
|
||||
}
|
||||
platformFilterBlock.appendChild(platformFilterOpt);
|
||||
$(platformFilterOpt).select2({
|
||||
minimumResultsForSearch: Infinity
|
||||
});
|
||||
filterControls.appendChild(platformFilterBlock);
|
||||
|
||||
var searchButtonFilterBlock = document.createElement('div');
|
||||
searchButtonFilterBlock.className = 'games_library_controlblock';
|
||||
|
||||
var searchButton = document.createElement('button');
|
||||
searchButton.value = 'Search';
|
||||
searchButton.innerHTML = 'Search';
|
||||
searchButton.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + 1 + ', Number(document.getElementById("platform_filter").value), document.getElementById("name_filter").value);');
|
||||
searchButtonFilterBlock.appendChild(searchButton);
|
||||
filterControls.appendChild(searchButtonFilterBlock);
|
||||
|
||||
var romCounter = document.createElement('div');
|
||||
romCounter.className = 'games_library_controlblock';
|
||||
|
||||
var romCounterLabel = document.createElement('span');
|
||||
romCounterLabel.className = 'games_library_label';
|
||||
if (result.count) {
|
||||
if (result.count < 1000) {
|
||||
romCounterLabel.innerHTML = result.count + ' ROMs';
|
||||
function loadArtwork(game, cover) {
|
||||
// show default background
|
||||
var bg = document.getElementById('bgImage');
|
||||
if (cover) {
|
||||
bg.setAttribute('style', 'background-image: url("/api/v1.1/Games/' + gameId + '/cover/image/original/' + cover.imageId + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
|
||||
} else {
|
||||
romCounterLabel.innerHTML = 'Maximum of 1000 ROMs';
|
||||
var randomInt = randomIntFromInterval(1, 3);
|
||||
bg.setAttribute('style', 'background-image: url("/images/gamebg' + randomInt + '.jpg"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
|
||||
}
|
||||
} else {
|
||||
romCounterLabel.innerHTML = '0 ROMs';
|
||||
}
|
||||
romCounter.appendChild(romCounterLabel);
|
||||
filterControls.appendChild(romCounter);
|
||||
|
||||
gameRoms.appendChild(filterControls);
|
||||
// // load artwork
|
||||
// if (game.artworks) {
|
||||
// ajaxCall('/api/v1.1/games/' + gameId + '/artwork', 'GET', function (result) {
|
||||
// artworks = result;
|
||||
// var startPos = randomIntFromInterval(0, result.length);
|
||||
// artworksPosition = startPos;
|
||||
// rotateBackground();
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
function rotateBackground() {
|
||||
@@ -778,6 +755,7 @@
|
||||
gameScreenshots_Main.innerHTML = '';
|
||||
switch (gameScreenshots_Selected.getAttribute('imagetype')) {
|
||||
case "0":
|
||||
default:
|
||||
// screenshot
|
||||
gameScreenshots_Main.setAttribute('style', gameScreenshots_Selected.getAttribute('style').replace("/image/screenshot_thumb", "/image/original"));
|
||||
break;
|
||||
@@ -1096,10 +1074,12 @@
|
||||
function (result) {
|
||||
DisplayROMCheckboxes(false);
|
||||
loadRoms();
|
||||
loadMediaGroups();
|
||||
},
|
||||
function (error) {
|
||||
DisplayROMCheckboxes(false);
|
||||
loadRoms();
|
||||
loadMediaGroups();
|
||||
},
|
||||
JSON.stringify(romIds)
|
||||
);
|
||||
|
@@ -3,7 +3,6 @@
|
||||
</div>
|
||||
|
||||
<div id="games_filter_scroller">
|
||||
<div id="games_filter"></div>
|
||||
</div>
|
||||
<div id="games_home">
|
||||
<div id="games_home_box">
|
||||
@@ -38,9 +37,8 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
ajaxCall('/api/v1.1/Filter', 'GET', function (result) {
|
||||
var filterElement = document.getElementById('games_filter');
|
||||
var scrollerElement = document.getElementById('games_filter_scroller');
|
||||
formatFilterPanel(filterElement, scrollerElement, result);
|
||||
formatFilterPanel(scrollerElement, result);
|
||||
|
||||
executeFilter1_1();
|
||||
});
|
||||
|
@@ -149,7 +149,7 @@
|
||||
moment(result[i].eventTime).format("YYYY-MM-DD h:mm:ss a"),
|
||||
result[i].eventType,
|
||||
result[i].process,
|
||||
result[i].message
|
||||
result[i].message.replaceAll("\n", "<br />")
|
||||
];
|
||||
|
||||
surroundingRow.appendChild(createTableRow(false, newRow, '', 'romcell logs_table_cell'));
|
||||
|
@@ -82,7 +82,7 @@
|
||||
var nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||
var startButton = '';
|
||||
if (userProfile.roles.includes("Admin")) {
|
||||
if (result[i].allowManualStart == true && result[i].itemState != "Running") {
|
||||
if (result[i].allowManualStart == true && ![ "Running"].includes(result[i].itemState) && result[i].isBlocked == false) {
|
||||
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,11 @@
|
||||
var existingSearchModel;
|
||||
|
||||
function formatFilterPanel(targetElement, scrollerElement, result) {
|
||||
function formatFilterPanel(containerElement, result) {
|
||||
containerElement.innerHTML = '';
|
||||
|
||||
var targetElement = document.createElement('div');
|
||||
targetElement.id = 'games_filter';
|
||||
|
||||
var panel = document.createElement('div');
|
||||
panel.id = 'filter_panel_box';
|
||||
|
||||
@@ -115,8 +120,6 @@ function formatFilterPanel(targetElement, scrollerElement, result) {
|
||||
|
||||
buttonsDiv.appendChild(resetButton);
|
||||
|
||||
scrollerElement.appendChild(buttonsDiv);
|
||||
|
||||
// set order by values
|
||||
var orderByCookie = getCookie('games_library_orderby_select');
|
||||
if (orderByCookie) {
|
||||
@@ -126,6 +129,10 @@ function formatFilterPanel(targetElement, scrollerElement, result) {
|
||||
if (orderByDirectionCookie) {
|
||||
document.getElementById('games_library_orderby_direction_select').value = orderByDirectionCookie;
|
||||
}
|
||||
|
||||
containerElement.appendChild(targetElement);
|
||||
|
||||
containerElement.appendChild(buttonsDiv);
|
||||
}
|
||||
|
||||
function buildFilterPanel(targetElement, headerString, friendlyHeaderString, valueList, showToggle, initialDisplay) {
|
||||
@@ -422,7 +429,7 @@ function executeFilter1_1(pageNumber, pageSize) {
|
||||
'POST',
|
||||
function (result) {
|
||||
var gameElement = document.getElementById('games_library');
|
||||
formatGamesPanel(gameElement, result, pageNumber, pageSize);
|
||||
formatGamesPanel(gameElement, result, pageNumber, pageSize, true);
|
||||
},
|
||||
function (error) {
|
||||
console.log('An error occurred: ' + JSON.stringify(error));
|
||||
|
@@ -55,7 +55,9 @@ var ClassificationRatings = {
|
||||
"ACB_RC": "Refused Classification"
|
||||
};
|
||||
|
||||
function formatGamesPanel(targetElement, result, pageNumber, pageSize) {
|
||||
var pageReloadInterval;
|
||||
|
||||
function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScrollTop) {
|
||||
console.log("Displaying page: " + pageNumber);
|
||||
console.log("Page size: " + pageSize);
|
||||
|
||||
@@ -66,8 +68,10 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize) {
|
||||
}
|
||||
|
||||
if (pageMode == 'paged') {
|
||||
if (forceScrollTop == true) {
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
var pagerCheck = document.getElementById('games_library_pagerstore');
|
||||
if (pageNumber == 1) {
|
||||
@@ -193,6 +197,18 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// var pageReloadFunction = function() {
|
||||
// formatGamesPanel(targetElement, result, pageNumber, pageSize, false);
|
||||
|
||||
// ajaxCall('/api/v1.1/Filter', 'GET', function (result) {
|
||||
// var scrollerElement = document.getElementById('games_filter_scroller');
|
||||
// formatFilterPanel(scrollerElement, result);
|
||||
// })
|
||||
// };
|
||||
|
||||
// window.clearTimeout(pageReloadInterval);
|
||||
// pageReloadInterval = setTimeout(pageReloadFunction, 10000);
|
||||
}
|
||||
|
||||
function isScrolledIntoView(elem) {
|
||||
|
@@ -415,6 +415,8 @@ function GetTaskFriendlyName(TaskName, options) {
|
||||
return "Compress collection id: " + options;
|
||||
case 'BackgroundDatabaseUpgrade':
|
||||
return "Background database upgrade";
|
||||
case 'TempCleanup':
|
||||
return "Temporary directory cleanup";
|
||||
default:
|
||||
return TaskName;
|
||||
}
|
||||
|
@@ -459,6 +459,7 @@ input[id='filter_panel_userrating_max'] {
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.games_library_label {
|
||||
|
Reference in New Issue
Block a user