Integrate new Hasheous client (#354)
The new Hasheous client has been integrated into Gaseous to take advantage of the new updates to Hasheous that bring improved matching and community contributions.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -405,3 +405,5 @@ ASALocalRun/
|
|||||||
.localhistory/
|
.localhistory/
|
||||||
gaseous-server/.DS_Store
|
gaseous-server/.DS_Store
|
||||||
gaseous-server/wwwroot/emulators/EmulatorJS
|
gaseous-server/wwwroot/emulators/EmulatorJS
|
||||||
|
.devcontainer/.env
|
||||||
|
.mono/
|
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -24,7 +24,8 @@
|
|||||||
},
|
},
|
||||||
"sourceFileMap": {
|
"sourceFileMap": {
|
||||||
"/Views": "${workspaceFolder}/Views"
|
"/Views": "${workspaceFolder}/Views"
|
||||||
}
|
},
|
||||||
|
"enableStepFiltering": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": ".NET Core Attach",
|
"name": ".NET Core Attach",
|
||||||
|
20
Gaseous.sln
20
Gaseous.sln
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 25.0.1704.4
|
VisualStudioVersion = 25.0.1704.4
|
||||||
@@ -27,30 +27,18 @@ Global
|
|||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {979BF092-AFBC-4F19-B55F-32E73959BD1A}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{F1A847C7-57BC-4DA9-8F83-CD060A7F5122} = {17FA6F12-8532-420C-9489-CB8FDE42137C}
|
{F1A847C7-57BC-4DA9-8F83-CD060A7F5122} = {17FA6F12-8532-420C-9489-CB8FDE42137C}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {979BF092-AFBC-4F19-B55F-32E73959BD1A}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
@@ -19,7 +20,8 @@ namespace gaseous_server.Classes
|
|||||||
if (ObjectToCheck == null || ObjectToCheck == System.DBNull.Value)
|
if (ObjectToCheck == null || ObjectToCheck == System.DBNull.Value)
|
||||||
{
|
{
|
||||||
return IfNullValue;
|
return IfNullValue;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return ObjectToCheck;
|
return ObjectToCheck;
|
||||||
}
|
}
|
||||||
@@ -27,10 +29,10 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
static public DateTime ConvertUnixToDateTime(double UnixTimeStamp)
|
static public DateTime ConvertUnixToDateTime(double UnixTimeStamp)
|
||||||
{
|
{
|
||||||
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
|
||||||
dateTime = dateTime.AddSeconds(UnixTimeStamp).ToLocalTime();
|
dateTime = dateTime.AddSeconds(UnixTimeStamp).ToLocalTime();
|
||||||
return dateTime;
|
return dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class hashObject
|
public class hashObject
|
||||||
{
|
{
|
||||||
@@ -41,21 +43,21 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public hashObject(string FileName)
|
public hashObject(string FileName)
|
||||||
{
|
{
|
||||||
var xmlStream = File.OpenRead(FileName);
|
var xmlStream = File.OpenRead(FileName);
|
||||||
|
|
||||||
var md5 = MD5.Create();
|
var md5 = MD5.Create();
|
||||||
byte[] md5HashByte = md5.ComputeHash(xmlStream);
|
byte[] md5HashByte = md5.ComputeHash(xmlStream);
|
||||||
string md5Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
string md5Hash = BitConverter.ToString(md5HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
_md5hash = md5Hash;
|
_md5hash = md5Hash;
|
||||||
|
|
||||||
var sha1 = SHA1.Create();
|
var sha1 = SHA1.Create();
|
||||||
xmlStream.Position = 0;
|
xmlStream.Position = 0;
|
||||||
byte[] sha1HashByte = sha1.ComputeHash(xmlStream);
|
byte[] sha1HashByte = sha1.ComputeHash(xmlStream);
|
||||||
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
|
string sha1Hash = BitConverter.ToString(sha1HashByte).Replace("-", "").ToLowerInvariant();
|
||||||
_sha1hash = sha1Hash;
|
_sha1hash = sha1Hash;
|
||||||
|
|
||||||
xmlStream.Close();
|
xmlStream.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
string _md5hash = "";
|
string _md5hash = "";
|
||||||
string _sha1hash = "";
|
string _sha1hash = "";
|
||||||
@@ -85,29 +87,29 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long DirSize(DirectoryInfo d)
|
public static long DirSize(DirectoryInfo d)
|
||||||
{
|
{
|
||||||
long size = 0;
|
long size = 0;
|
||||||
// Add file sizes.
|
// Add file sizes.
|
||||||
FileInfo[] fis = d.GetFiles();
|
FileInfo[] fis = d.GetFiles();
|
||||||
foreach (FileInfo fi in fis)
|
foreach (FileInfo fi in fis)
|
||||||
{
|
{
|
||||||
size += fi.Length;
|
size += fi.Length;
|
||||||
}
|
}
|
||||||
// Add subdirectory sizes.
|
// Add subdirectory sizes.
|
||||||
DirectoryInfo[] dis = d.GetDirectories();
|
DirectoryInfo[] dis = d.GetDirectories();
|
||||||
foreach (DirectoryInfo di in dis)
|
foreach (DirectoryInfo di in dis)
|
||||||
{
|
{
|
||||||
size += DirSize(di);
|
size += DirSize(di);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string[] SkippableFiles = {
|
public static string[] SkippableFiles = {
|
||||||
".DS_STORE",
|
".DS_STORE",
|
||||||
"desktop.ini"
|
"desktop.ini"
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string NormalizePath(string path)
|
public static string NormalizePath(string path)
|
||||||
{
|
{
|
||||||
return Path.GetFullPath(new Uri(path).LocalPath)
|
return Path.GetFullPath(new Uri(path).LocalPath)
|
||||||
@@ -155,30 +157,74 @@ namespace gaseous_server.Classes
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static int GetLookupByCode(LookupTypes LookupType, string Code)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT Id FROM " + LookupType.ToString() + " WHERE Code = @code";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||||
|
{ "code", Code }
|
||||||
|
};
|
||||||
|
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (data.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (int)data.Rows[0]["Id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetLookupByValue(LookupTypes LookupType, string Value)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT Id FROM " + LookupType.ToString() + " WHERE Value = @value";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||||
|
{ "value", Value }
|
||||||
|
};
|
||||||
|
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (data.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (int)data.Rows[0]["Id"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LookupTypes
|
||||||
|
{
|
||||||
|
Country,
|
||||||
|
Language
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides a way to set contextual data that flows with the call and
|
/// Provides a way to set contextual data that flows with the call and
|
||||||
/// async context of a test or invocation.
|
/// async context of a test or invocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class CallContext
|
public static class CallContext
|
||||||
{
|
{
|
||||||
static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
|
static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores a given object and associates it with the specified name.
|
/// Stores a given object and associates it with the specified name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name with which to associate the new item in the call context.</param>
|
/// <param name="name">The name with which to associate the new item in the call context.</param>
|
||||||
/// <param name="data">The object to store in the call context.</param>
|
/// <param name="data">The object to store in the call context.</param>
|
||||||
public static void SetData(string name, object data) =>
|
public static void SetData(string name, object data) =>
|
||||||
state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
|
state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves an object with the specified name from the <see cref="CallContext"/>.
|
/// Retrieves an object with the specified name from the <see cref="CallContext"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the item in the call context.</param>
|
/// <param name="name">The name of the item in the call context.</param>
|
||||||
/// <returns>The object in the call context associated with the specified name, or <see langword="null"/> if not found.</returns>
|
/// <returns>The object in the call context associated with the specified name, or <see langword="null"/> if not found.</returns>
|
||||||
public static object GetData(string name) =>
|
public static object GetData(string name) =>
|
||||||
state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
|
state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -80,7 +80,8 @@ namespace gaseous_server.Classes
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
string logPath = Path.Combine(ConfigurationPath, "Logs");
|
string logPath = Path.Combine(ConfigurationPath, "Logs");
|
||||||
if (!Directory.Exists(logPath)) {
|
if (!Directory.Exists(logPath))
|
||||||
|
{
|
||||||
Directory.CreateDirectory(logPath);
|
Directory.CreateDirectory(logPath);
|
||||||
}
|
}
|
||||||
return logPath;
|
return logPath;
|
||||||
@@ -92,7 +93,7 @@ namespace gaseous_server.Classes
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
string logFileExtension = "txt";
|
string logFileExtension = "txt";
|
||||||
|
|
||||||
string logPathName = Path.Combine(LogPath, "Server Log " + DateTime.Now.ToUniversalTime().ToString("yyyyMMdd") + "." + logFileExtension);
|
string logPathName = Path.Combine(LogPath, "Server Log " + DateTime.Now.ToUniversalTime().ToString("yyyyMMdd") + "." + logFileExtension);
|
||||||
return logPathName;
|
return logPathName;
|
||||||
}
|
}
|
||||||
@@ -131,7 +132,7 @@ namespace gaseous_server.Classes
|
|||||||
_config.DatabaseConfiguration.DatabaseName = (string)Common.GetEnvVar("dbname", _config.DatabaseConfiguration.DatabaseName);
|
_config.DatabaseConfiguration.DatabaseName = (string)Common.GetEnvVar("dbname", _config.DatabaseConfiguration.DatabaseName);
|
||||||
_config.DatabaseConfiguration.Port = int.Parse((string)Common.GetEnvVar("dbport", _config.DatabaseConfiguration.Port.ToString()));
|
_config.DatabaseConfiguration.Port = int.Parse((string)Common.GetEnvVar("dbport", _config.DatabaseConfiguration.Port.ToString()));
|
||||||
_config.MetadataConfiguration.MetadataSource = (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), (string)Common.GetEnvVar("metadatasource", _config.MetadataConfiguration.MetadataSource.ToString()));
|
_config.MetadataConfiguration.MetadataSource = (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), (string)Common.GetEnvVar("metadatasource", _config.MetadataConfiguration.MetadataSource.ToString()));
|
||||||
_config.MetadataConfiguration.SignatureSource = (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), (string)Common.GetEnvVar("signaturesource", _config.MetadataConfiguration.SignatureSource.ToString()));;
|
_config.MetadataConfiguration.SignatureSource = (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), (string)Common.GetEnvVar("signaturesource", _config.MetadataConfiguration.SignatureSource.ToString())); ;
|
||||||
_config.MetadataConfiguration.MaxLibraryScanWorkers = int.Parse((string)Common.GetEnvVar("maxlibraryscanworkers", _config.MetadataConfiguration.MaxLibraryScanWorkers.ToString()));
|
_config.MetadataConfiguration.MaxLibraryScanWorkers = int.Parse((string)Common.GetEnvVar("maxlibraryscanworkers", _config.MetadataConfiguration.MaxLibraryScanWorkers.ToString()));
|
||||||
_config.MetadataConfiguration.HasheousHost = (string)Common.GetEnvVar("hasheoushost", _config.MetadataConfiguration.HasheousHost);
|
_config.MetadataConfiguration.HasheousHost = (string)Common.GetEnvVar("hasheoushost", _config.MetadataConfiguration.HasheousHost);
|
||||||
_config.IGDBConfiguration.ClientId = (string)Common.GetEnvVar("igdbclientid", _config.IGDBConfiguration.ClientId);
|
_config.IGDBConfiguration.ClientId = (string)Common.GetEnvVar("igdbclientid", _config.IGDBConfiguration.ClientId);
|
||||||
@@ -205,9 +206,9 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
AppSettings.Remove(SettingName);
|
AppSettings.Remove(SettingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Load Settings", "Loading setting " + SettingName + " from database");
|
Logging.Log(Logging.LogType.Information, "Load Settings", "Loading setting " + SettingName + " from database");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Database.schema_version >= 1016)
|
if (Database.schema_version >= 1016)
|
||||||
@@ -275,7 +276,7 @@ namespace gaseous_server.Classes
|
|||||||
if (Database.schema_version >= 1016)
|
if (Database.schema_version >= 1016)
|
||||||
{
|
{
|
||||||
sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName";
|
sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName";
|
||||||
|
|
||||||
dbResponse = db.ExecuteCMD(sql, dbDict);
|
dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
if (dbResponse.Rows.Count == 0)
|
if (dbResponse.Rows.Count == 0)
|
||||||
@@ -301,7 +302,7 @@ namespace gaseous_server.Classes
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "SELECT Value FROM Settings WHERE Setting = @SettingName";
|
sql = "SELECT Value FROM Settings WHERE Setting = @SettingName";
|
||||||
|
|
||||||
dbResponse = db.ExecuteCMD(sql, dbDict);
|
dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
if (dbResponse.Rows.Count == 0)
|
if (dbResponse.Rows.Count == 0)
|
||||||
@@ -355,7 +356,7 @@ namespace gaseous_server.Classes
|
|||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql;
|
string sql;
|
||||||
Dictionary<string, object> dbDict;
|
Dictionary<string, object> dbDict;
|
||||||
|
|
||||||
if (Database.schema_version >= 1016)
|
if (Database.schema_version >= 1016)
|
||||||
{
|
{
|
||||||
sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
||||||
@@ -427,7 +428,8 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public class Database
|
public class Database
|
||||||
{
|
{
|
||||||
private static string _DefaultHostName {
|
private static string _DefaultHostName
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("dbhost")))
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("dbhost")))
|
||||||
@@ -643,7 +645,7 @@ namespace gaseous_server.Classes
|
|||||||
return MetadataPath;
|
return MetadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibrarySignatureImportDirectory
|
public string LibrarySignaturesDirectory
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -651,6 +653,14 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string LibrarySignaturesProcessedDirectory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Path.Combine(LibraryRootDirectory, "Signatures - Processed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void InitLibrary()
|
public void InitLibrary()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
||||||
@@ -660,7 +670,8 @@ namespace gaseous_server.Classes
|
|||||||
if (!Directory.Exists(LibraryMetadataDirectory)) { Directory.CreateDirectory(LibraryMetadataDirectory); }
|
if (!Directory.Exists(LibraryMetadataDirectory)) { Directory.CreateDirectory(LibraryMetadataDirectory); }
|
||||||
if (!Directory.Exists(LibraryTempDirectory)) { Directory.CreateDirectory(LibraryTempDirectory); }
|
if (!Directory.Exists(LibraryTempDirectory)) { Directory.CreateDirectory(LibraryTempDirectory); }
|
||||||
if (!Directory.Exists(LibraryCollectionsDirectory)) { Directory.CreateDirectory(LibraryCollectionsDirectory); }
|
if (!Directory.Exists(LibraryCollectionsDirectory)) { Directory.CreateDirectory(LibraryCollectionsDirectory); }
|
||||||
if (!Directory.Exists(LibrarySignatureImportDirectory)) { Directory.CreateDirectory(LibrarySignatureImportDirectory); }
|
if (!Directory.Exists(LibrarySignaturesDirectory)) { Directory.CreateDirectory(LibrarySignaturesDirectory); }
|
||||||
|
if (!Directory.Exists(LibrarySignaturesProcessedDirectory)) { Directory.CreateDirectory(LibrarySignaturesProcessedDirectory); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,6 +707,10 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool _HasheousSubmitFixes { get; set; } = false;
|
||||||
|
|
||||||
|
private static string _HasheousAPIKey { get; set; } = "";
|
||||||
|
|
||||||
private static int _MaxLibraryScanWorkers
|
private static int _MaxLibraryScanWorkers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -730,6 +745,10 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
||||||
|
|
||||||
|
public bool HasheousSubmitFixes = _HasheousSubmitFixes;
|
||||||
|
|
||||||
|
public string HasheousAPIKey = _HasheousAPIKey;
|
||||||
|
|
||||||
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
||||||
|
|
||||||
public string HasheousHost = _HasheousHost;
|
public string HasheousHost = _HasheousHost;
|
||||||
|
@@ -1,14 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using gaseous_server.Models;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public static class DatabaseMigration
|
public static class DatabaseMigration
|
||||||
{
|
{
|
||||||
public static List<int> BackgroundUpgradeTargetSchemaVersions = new List<int>();
|
public static List<int> BackgroundUpgradeTargetSchemaVersions = new List<int>();
|
||||||
|
|
||||||
public static void PreUpgradeScript(int TargetSchemaVersion, Database.databaseType? DatabaseType)
|
public static void PreUpgradeScript(int TargetSchemaVersion, Database.databaseType? DatabaseType)
|
||||||
{
|
{
|
||||||
// load resources
|
// load resources
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
@@ -20,14 +23,14 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Database", "Checking for pre-upgrade for schema version " + TargetSchemaVersion);
|
Logging.Log(Logging.LogType.Information, "Database", "Checking for pre-upgrade for schema version " + TargetSchemaVersion);
|
||||||
|
|
||||||
switch(DatabaseType)
|
switch (DatabaseType)
|
||||||
{
|
{
|
||||||
case Database.databaseType.MySql:
|
case Database.databaseType.MySql:
|
||||||
switch (TargetSchemaVersion)
|
switch (TargetSchemaVersion)
|
||||||
{
|
{
|
||||||
case 1005:
|
case 1005:
|
||||||
Logging.Log(Logging.LogType.Information, "Database", "Running pre-upgrade for schema version " + TargetSchemaVersion);
|
Logging.Log(Logging.LogType.Information, "Database", "Running pre-upgrade for schema version " + TargetSchemaVersion);
|
||||||
|
|
||||||
// there was a mistake at dbschema version 1004-1005
|
// there was a mistake at dbschema version 1004-1005
|
||||||
// the first preview release of v1.7 reused dbschema version 1004
|
// the first preview release of v1.7 reused dbschema version 1004
|
||||||
// if table "Relation_Game_AgeRatings" exists - then we need to apply the gaseous-fix-1005.sql script before applying the standard 1005 script
|
// if table "Relation_Game_AgeRatings" exists - then we need to apply the gaseous-fix-1005.sql script before applying the standard 1005 script
|
||||||
@@ -62,14 +65,16 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PostUpgradeScript(int TargetSchemaVersion, Database.databaseType? DatabaseType)
|
public static void PostUpgradeScript(int TargetSchemaVersion, Database.databaseType? DatabaseType)
|
||||||
{
|
{
|
||||||
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
DataTable data;
|
DataTable data;
|
||||||
|
|
||||||
switch(DatabaseType)
|
switch (DatabaseType)
|
||||||
{
|
{
|
||||||
case Database.databaseType.MySql:
|
case Database.databaseType.MySql:
|
||||||
switch (TargetSchemaVersion)
|
switch (TargetSchemaVersion)
|
||||||
@@ -78,7 +83,7 @@ namespace gaseous_server.Classes
|
|||||||
// this is a safe background task
|
// this is a safe background task
|
||||||
BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1004:
|
case 1004:
|
||||||
// needs to run on start up
|
// needs to run on start up
|
||||||
|
|
||||||
@@ -103,6 +108,51 @@ namespace gaseous_server.Classes
|
|||||||
sql = "DELETE FROM Settings WHERE Setting LIKE 'LastRun_%';";
|
sql = "DELETE FROM Settings WHERE Setting LIKE 'LastRun_%';";
|
||||||
db.ExecuteNonQuery(sql);
|
db.ExecuteNonQuery(sql);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 1022:
|
||||||
|
// load country list
|
||||||
|
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Adding country look up table contents");
|
||||||
|
|
||||||
|
string countryResourceName = "gaseous_server.Support.Country.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(countryResourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split("|");
|
||||||
|
|
||||||
|
sql = "INSERT INTO Country (Code, Value) VALUES (@code, @value);";
|
||||||
|
dbDict = new Dictionary<string, object>{
|
||||||
|
{ "code", line[0] },
|
||||||
|
{ "value", line[1] }
|
||||||
|
};
|
||||||
|
db.ExecuteNonQuery(sql, dbDict);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load language list
|
||||||
|
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Adding language look up table contents");
|
||||||
|
|
||||||
|
string languageResourceName = "gaseous_server.Support.Language.txt";
|
||||||
|
using (Stream stream = assembly.GetManifestResourceStream(languageResourceName))
|
||||||
|
using (StreamReader reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
string[] line = reader.ReadLine().Split("|");
|
||||||
|
|
||||||
|
sql = "INSERT INTO Language (Code, Value) VALUES (@code, @value);";
|
||||||
|
dbDict = new Dictionary<string, object>{
|
||||||
|
{ "code", line[0] },
|
||||||
|
{ "value", line[1] }
|
||||||
|
};
|
||||||
|
db.ExecuteNonQuery(sql, dbDict);
|
||||||
|
} while (reader.EndOfStream == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is a safe background task
|
||||||
|
BackgroundUpgradeTargetSchemaVersions.Add(1022);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -117,11 +167,16 @@ namespace gaseous_server.Classes
|
|||||||
case 1002:
|
case 1002:
|
||||||
MySql_1002_MigrateMetadataVersion();
|
MySql_1002_MigrateMetadataVersion();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 1022:
|
||||||
|
MySql_1022_MigrateMetadataVersion();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MySql_1002_MigrateMetadataVersion() {
|
public static void MySql_1002_MigrateMetadataVersion()
|
||||||
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
@@ -134,7 +189,7 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - Database Update", "Updating " + data.Rows.Count + " database entries");
|
Logging.Log(Logging.LogType.Information, "Signature Ingestor - Database Update", "Updating " + data.Rows.Count + " database entries");
|
||||||
int Counter = 0;
|
int Counter = 0;
|
||||||
int LastCounterCheck = 0;
|
int LastCounterCheck = 0;
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
List<string> Flags = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>((string)Common.ReturnValueIfNull(row["flags"], "[]"));
|
List<string> Flags = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>((string)Common.ReturnValueIfNull(row["flags"], "[]"));
|
||||||
List<KeyValuePair<string, object>> Attributes = new List<KeyValuePair<string, object>>();
|
List<KeyValuePair<string, object>> Attributes = new List<KeyValuePair<string, object>>();
|
||||||
@@ -207,7 +262,7 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("id", (int)row["Id"]);
|
dbDict.Add("id", (int)row["Id"]);
|
||||||
db.ExecuteCMD(updateSQL, dbDict);
|
db.ExecuteCMD(updateSQL, dbDict);
|
||||||
|
|
||||||
if ((Counter - LastCounterCheck) > 10)
|
if ((Counter - LastCounterCheck) > 10)
|
||||||
{
|
{
|
||||||
LastCounterCheck = Counter;
|
LastCounterCheck = Counter;
|
||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - Database Update", "Updating " + Counter + " / " + data.Rows.Count + " database entries");
|
Logging.Log(Logging.LogType.Information, "Signature Ingestor - Database Update", "Updating " + Counter + " / " + data.Rows.Count + " database entries");
|
||||||
@@ -216,5 +271,36 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void MySql_1022_MigrateMetadataVersion()
|
||||||
|
{
|
||||||
|
FileSignature fileSignature = new FileSignature();
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT * FROM Games_Roms WHERE RomDataVersion = 1;";
|
||||||
|
DataTable data = db.ExecuteCMD(sql);
|
||||||
|
foreach (DataRow row in data.Rows)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Database Migration", "Updating ROM table for ROM: " + (string)row["Name"]);
|
||||||
|
|
||||||
|
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)row["LibraryId"]);
|
||||||
|
Common.hashObject hash = new Common.hashObject()
|
||||||
|
{
|
||||||
|
md5hash = (string)row["MD5"],
|
||||||
|
sha1hash = (string)row["SHA1"]
|
||||||
|
};
|
||||||
|
Signatures_Games signature = fileSignature.GetFileSignature(
|
||||||
|
library,
|
||||||
|
hash,
|
||||||
|
new FileInfo((string)row["Path"]),
|
||||||
|
(string)row["Path"]
|
||||||
|
);
|
||||||
|
|
||||||
|
Platform platform = Platforms.GetPlatform((long)row["PlatformId"], false);
|
||||||
|
Game game = Games.GetGame((long)row["GameId"], false, false, false);
|
||||||
|
|
||||||
|
ImportGame.StoreROM(library, hash, game, platform, signature, (string)row["Path"], (long)row["Id"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,6 +1,8 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
using HasheousClient.Models;
|
using HasheousClient.Models;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
using SevenZip;
|
using SevenZip;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
@@ -31,7 +33,7 @@ namespace gaseous_server.Classes
|
|||||||
if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); }
|
if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); }
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch(ImportedFileExtension)
|
switch (ImportedFileExtension)
|
||||||
{
|
{
|
||||||
case ".zip":
|
case ".zip":
|
||||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Decompressing using zip");
|
Logging.Log(Logging.LogType.Information, "Get Signature", "Decompressing using zip");
|
||||||
@@ -105,31 +107,24 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Processing decompressed files for signature matches");
|
Logging.Log(Logging.LogType.Information, "Get Signature", "Processing decompressed files for signature matches");
|
||||||
// loop through contents until we find the first signature match
|
// loop through contents until we find the first signature match
|
||||||
List<ArchiveData> archiveFiles = new List<ArchiveData>();
|
List<ArchiveData> archiveFiles = new List<ArchiveData>();
|
||||||
bool signatureFound = false;
|
bool signatureFound = false;
|
||||||
|
bool signatureSelectorAlreadyApplied = false;
|
||||||
foreach (string file in Directory.GetFiles(ExtractPath, "*.*", SearchOption.AllDirectories))
|
foreach (string file in Directory.GetFiles(ExtractPath, "*.*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
|
bool signatureSelector = false;
|
||||||
if (File.Exists(file))
|
if (File.Exists(file))
|
||||||
{
|
{
|
||||||
FileInfo zfi = new FileInfo(file);
|
FileInfo zfi = new FileInfo(file);
|
||||||
Common.hashObject zhash = new Common.hashObject(file);
|
Common.hashObject zhash = new Common.hashObject(file);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Checking signature of decompressed file " + file);
|
Logging.Log(Logging.LogType.Information, "Get Signature", "Checking signature of decompressed file " + file);
|
||||||
|
|
||||||
if (zfi != null)
|
if (zfi != null)
|
||||||
{
|
{
|
||||||
ArchiveData archiveData = new ArchiveData{
|
|
||||||
FileName = Path.GetFileName(file),
|
|
||||||
FilePath = zfi.Directory.FullName.Replace(ExtractPath, ""),
|
|
||||||
Size = zfi.Length,
|
|
||||||
MD5 = hash.md5hash,
|
|
||||||
SHA1 = hash.sha1hash
|
|
||||||
};
|
|
||||||
archiveFiles.Add(archiveData);
|
|
||||||
|
|
||||||
if (signatureFound == false)
|
if (signatureFound == false)
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi.Name, zfi.Extension, zfi.Length, file, true);
|
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi.Name, zfi.Extension, zfi.Length, file, true);
|
||||||
@@ -138,7 +133,7 @@ namespace gaseous_server.Classes
|
|||||||
if (zDiscoveredSignature.Score > discoveredSignature.Score)
|
if (zDiscoveredSignature.Score > discoveredSignature.Score)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEArcade ||
|
zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEArcade ||
|
||||||
zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEMess
|
zDiscoveredSignature.Rom.SignatureSource == gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType.MAMEMess
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -151,15 +146,37 @@ namespace gaseous_server.Classes
|
|||||||
discoveredSignature = zDiscoveredSignature;
|
discoveredSignature = zDiscoveredSignature;
|
||||||
|
|
||||||
signatureFound = true;
|
signatureFound = true;
|
||||||
|
|
||||||
|
if (signatureSelectorAlreadyApplied == false)
|
||||||
|
{
|
||||||
|
signatureSelector = true;
|
||||||
|
signatureSelectorAlreadyApplied = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArchiveData archiveData = new ArchiveData
|
||||||
|
{
|
||||||
|
FileName = Path.GetFileName(file),
|
||||||
|
FilePath = zfi.Directory.FullName.Replace(ExtractPath, ""),
|
||||||
|
Size = zfi.Length,
|
||||||
|
MD5 = zhash.md5hash,
|
||||||
|
SHA1 = zhash.sha1hash,
|
||||||
|
isSignatureSelector = signatureSelector
|
||||||
|
};
|
||||||
|
archiveFiles.Add(archiveData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
discoveredSignature.Rom.Attributes.Add(new KeyValuePair<string, object>(
|
if (discoveredSignature.Rom.Attributes == null)
|
||||||
|
{
|
||||||
|
discoveredSignature.Rom.Attributes = new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
discoveredSignature.Rom.Attributes.Add(
|
||||||
"ZipContents", Newtonsoft.Json.JsonConvert.SerializeObject(archiveFiles)
|
"ZipContents", Newtonsoft.Json.JsonConvert.SerializeObject(archiveFiles)
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -195,7 +212,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
// signature retrieved from Hasheous
|
// signature retrieved from Hasheous
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature retrieved from Hasheous for game: " + dbSignature.Game.Name);
|
Logging.Log(Logging.LogType.Information, "Import Game", "Signature retrieved from Hasheous for game: " + dbSignature.Game.Name);
|
||||||
|
|
||||||
discoveredSignature = dbSignature;
|
discoveredSignature = dbSignature;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -203,7 +220,7 @@ namespace gaseous_server.Classes
|
|||||||
// construct a signature from file data
|
// construct a signature from file data
|
||||||
dbSignature = _GetFileSignatureFromFileData(hash, ImageName, ImageExtension, ImageSize, 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);
|
Logging.Log(Logging.LogType.Information, "Import Game", "Signature generated from provided file for game: " + dbSignature.Game.Name);
|
||||||
|
|
||||||
discoveredSignature = dbSignature;
|
discoveredSignature = dbSignature;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -216,8 +233,8 @@ namespace gaseous_server.Classes
|
|||||||
return discoveredSignature;
|
return discoveredSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
private gaseous_server.Models.Signatures_Games? _GetFileSignatureFromDatabase(Common.hashObject hash, string ImageName, string ImageExtension, long ImageSize, 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);
|
Logging.Log(Logging.LogType.Information, "Get Signature", "Checking local database for MD5: " + hash.md5hash);
|
||||||
|
|
||||||
// check 1: do we have a signature for it?
|
// check 1: do we have a signature for it?
|
||||||
@@ -264,29 +281,67 @@ namespace gaseous_server.Classes
|
|||||||
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
||||||
{
|
{
|
||||||
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
||||||
SignatureLookupItem? HasheousResult = hasheous.RetrieveFromHasheousAsync(new HashLookupModel{
|
Console.WriteLine(HasheousClient.WebApp.HttpHelper.BaseUri);
|
||||||
MD5 = hash.md5hash,
|
LookupItemModel? HasheousResult = null;
|
||||||
SHA1 = hash.sha1hash
|
try
|
||||||
});
|
{
|
||||||
|
HasheousResult = hasheous.RetrieveFromHasheous(new HashLookupModel
|
||||||
|
{
|
||||||
|
MD5 = hash.md5hash,
|
||||||
|
SHA1 = hash.sha1hash
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Import Game", "An error occurred while importing " + ImageName, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (HasheousResult != null)
|
if (HasheousResult != null)
|
||||||
{
|
{
|
||||||
if (HasheousResult.Signature != null)
|
if (HasheousResult.Signature != null)
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Signatures_Games signature = new Models.Signatures_Games();
|
gaseous_server.Models.Signatures_Games signature = new Models.Signatures_Games();
|
||||||
signature.Game = HasheousResult.Signature.Game;
|
string gameJson = Newtonsoft.Json.JsonConvert.SerializeObject(HasheousResult.Signature.Game);
|
||||||
signature.Rom = HasheousResult.Signature.Rom;
|
string romJson = Newtonsoft.Json.JsonConvert.SerializeObject(HasheousResult.Signature.Rom);
|
||||||
|
signature.Game = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Signatures_Games.GameItem>(gameJson);
|
||||||
if (HasheousResult.MetadataResults != null)
|
signature.Rom = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Signatures_Games.RomItem>(romJson);
|
||||||
|
|
||||||
|
// get platform metadata
|
||||||
|
if (HasheousResult.Platform != null)
|
||||||
{
|
{
|
||||||
if (HasheousResult.MetadataResults.Count > 0)
|
if (HasheousResult.Platform.metadata.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (SignatureLookupItem.MetadataResult metadataResult in HasheousResult.MetadataResults)
|
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Platform.metadata)
|
||||||
{
|
{
|
||||||
if (metadataResult.Source == MetadataModel.MetadataSources.IGDB)
|
if (metadataResult.Id.Length > 0)
|
||||||
{
|
{
|
||||||
signature.Flags.IGDBPlatformId = (long)metadataResult.PlatformId;
|
switch (metadataResult.Source)
|
||||||
signature.Flags.IGDBGameId = (long)metadataResult.GameId;
|
{
|
||||||
|
case HasheousClient.Models.MetadataSources.IGDB:
|
||||||
|
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id, false).Id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get game metadata
|
||||||
|
if (HasheousResult.Metadata != null)
|
||||||
|
{
|
||||||
|
if (HasheousResult.Metadata.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Metadata)
|
||||||
|
{
|
||||||
|
if (metadataResult.Id.Length > 0)
|
||||||
|
{
|
||||||
|
switch (metadataResult.Source)
|
||||||
|
{
|
||||||
|
case HasheousClient.Models.MetadataSources.IGDB:
|
||||||
|
signature.Flags.IGDBGameId = (long)Games.GetGame(metadataResult.Id, false, false, false).Id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,6 +423,7 @@ namespace gaseous_server.Classes
|
|||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
public string MD5 { get; set; }
|
public string MD5 { get; set; }
|
||||||
public string SHA1 { get; set; }
|
public string SHA1 { get; set; }
|
||||||
|
public bool isSignatureSelector { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -16,48 +16,49 @@ using HasheousClient.Models;
|
|||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class ImportGame : QueueItemStatus
|
public class ImportGame : QueueItemStatus
|
||||||
{
|
{
|
||||||
public void ProcessDirectory(string ImportPath)
|
public void ProcessDirectory(string ImportPath)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(ImportPath))
|
if (Directory.Exists(ImportPath))
|
||||||
{
|
{
|
||||||
string[] importContents = Directory.GetFiles(ImportPath, "*.*", SearchOption.AllDirectories);
|
string[] importContents = Directory.GetFiles(ImportPath, "*.*", SearchOption.AllDirectories);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Games", "Found " + importContents.Length + " files to process in import directory: " + ImportPath);
|
Logging.Log(Logging.LogType.Information, "Import Games", "Found " + importContents.Length + " files to process in import directory: " + ImportPath);
|
||||||
|
|
||||||
// import files first
|
// import files first
|
||||||
int importCount = 1;
|
int importCount = 1;
|
||||||
foreach (string importContent in importContents) {
|
foreach (string importContent in importContents)
|
||||||
|
{
|
||||||
SetStatus(importCount, importContents.Length, "Importing file: " + importContent);
|
SetStatus(importCount, importContents.Length, "Importing file: " + importContent);
|
||||||
|
|
||||||
ImportGameFile(importContent, null);
|
ImportGameFile(importContent, null);
|
||||||
|
|
||||||
importCount += 1;
|
importCount += 1;
|
||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
|
|
||||||
DeleteOrphanedDirectories(ImportPath);
|
DeleteOrphanedDirectories(ImportPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Critical, "Import Games", "The import directory " + ImportPath + " does not exist.");
|
Logging.Log(Logging.LogType.Critical, "Import Games", "The import directory " + ImportPath + " does not exist.");
|
||||||
throw new DirectoryNotFoundException("Invalid path: " + ImportPath);
|
throw new DirectoryNotFoundException("Invalid path: " + ImportPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
public void ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileInfo fi = new FileInfo(GameFileImportPath);
|
FileInfo fi = new FileInfo(GameFileImportPath);
|
||||||
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
||||||
|
|
||||||
@@ -87,7 +88,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
File.Move(GameFileImportPath, targetPathWithFileName, true);
|
File.Move(GameFileImportPath, targetPathWithFileName, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// import source was the upload directory
|
// import source was the upload directory
|
||||||
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
||||||
{
|
{
|
||||||
@@ -146,8 +147,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
||||||
{
|
{
|
||||||
@@ -173,7 +174,7 @@ namespace gaseous_server.Classes
|
|||||||
string GameName = Signature.Game.Name;
|
string GameName = Signature.Game.Name;
|
||||||
|
|
||||||
List<string> SearchCandidates = GetSearchCandidates(GameName);
|
List<string> SearchCandidates = GetSearchCandidates(GameName);
|
||||||
|
|
||||||
foreach (string SearchCandidate in SearchCandidates)
|
foreach (string SearchCandidate in SearchCandidates)
|
||||||
{
|
{
|
||||||
bool GameFound = false;
|
bool GameFound = false;
|
||||||
@@ -197,8 +198,10 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
|
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
|
||||||
|
|
||||||
// quite likely we've found sequels and alternate types
|
// quite likely we've found sequels and alternate types
|
||||||
foreach (Game game in games) {
|
foreach (Game game in games)
|
||||||
if (game.Name == SearchCandidate) {
|
{
|
||||||
|
if (game.Name == SearchCandidate)
|
||||||
|
{
|
||||||
// found game title matches the search candidate
|
// found game title matches the search candidate
|
||||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
|
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
|
||||||
@@ -273,7 +276,8 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// assumption: no games have () in their titles so we'll remove them
|
// assumption: no games have () in their titles so we'll remove them
|
||||||
int idx = GameName.IndexOf('(');
|
int idx = GameName.IndexOf('(');
|
||||||
if (idx >= 0) {
|
if (idx >= 0)
|
||||||
|
{
|
||||||
GameName = GameName.Substring(0, idx);
|
GameName = GameName.Substring(0, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,10 +308,11 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
if (UpdateId == 0)
|
if (UpdateId == 0)
|
||||||
{
|
{
|
||||||
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, Path, MetadataSource, MetadataGameName, MetadataVersion, LibraryId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, Path, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion WHERE Id=@id;";
|
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion WHERE Id=@id;";
|
||||||
dbDict.Add("id", UpdateId);
|
dbDict.Add("id", UpdateId);
|
||||||
}
|
}
|
||||||
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
||||||
@@ -322,6 +327,7 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("metadatagamename", discoveredSignature.Game.Name);
|
dbDict.Add("metadatagamename", discoveredSignature.Game.Name);
|
||||||
dbDict.Add("metadataversion", 2);
|
dbDict.Add("metadataversion", 2);
|
||||||
dbDict.Add("libraryid", library.Id);
|
dbDict.Add("libraryid", library.Id);
|
||||||
|
dbDict.Add("romdataversion", 2);
|
||||||
|
|
||||||
if (discoveredSignature.Rom.Attributes != null)
|
if (discoveredSignature.Rom.Attributes != null)
|
||||||
{
|
{
|
||||||
@@ -348,7 +354,8 @@ namespace gaseous_server.Classes
|
|||||||
if (UpdateId == 0)
|
if (UpdateId == 0)
|
||||||
{
|
{
|
||||||
romId = (long)romInsert.Rows[0][0];
|
romId = (long)romInsert.Rows[0][0];
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
romId = UpdateId;
|
romId = UpdateId;
|
||||||
}
|
}
|
||||||
@@ -362,73 +369,73 @@ namespace gaseous_server.Classes
|
|||||||
return romId;
|
return romId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ComputeROMPath(long RomId)
|
public static string ComputeROMPath(long RomId)
|
||||||
{
|
{
|
||||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
|
||||||
|
|
||||||
// get metadata
|
|
||||||
IGDB.Models.Platform platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId);
|
|
||||||
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false, false);
|
|
||||||
|
|
||||||
// build path
|
|
||||||
string platformSlug = "Unknown Platform";
|
|
||||||
if (platform != null)
|
|
||||||
{
|
|
||||||
platformSlug = platform.Slug;
|
|
||||||
}
|
|
||||||
string gameSlug = "Unknown Title";
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
gameSlug = game.Slug;
|
|
||||||
}
|
|
||||||
string DestinationPath = Path.Combine(GameLibrary.GetDefaultLibrary.Path, gameSlug, platformSlug);
|
|
||||||
if (!Directory.Exists(DestinationPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(DestinationPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
string DestinationPathName = Path.Combine(DestinationPath, rom.Name);
|
|
||||||
|
|
||||||
return DestinationPathName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool MoveGameFile(long RomId)
|
|
||||||
{
|
|
||||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||||
string romPath = rom.Path;
|
|
||||||
|
// get metadata
|
||||||
|
IGDB.Models.Platform platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId);
|
||||||
|
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false, false);
|
||||||
|
|
||||||
|
// build path
|
||||||
|
string platformSlug = "Unknown Platform";
|
||||||
|
if (platform != null)
|
||||||
|
{
|
||||||
|
platformSlug = platform.Slug;
|
||||||
|
}
|
||||||
|
string gameSlug = "Unknown Title";
|
||||||
|
if (game != null)
|
||||||
|
{
|
||||||
|
gameSlug = game.Slug;
|
||||||
|
}
|
||||||
|
string DestinationPath = Path.Combine(GameLibrary.GetDefaultLibrary.Path, gameSlug, platformSlug);
|
||||||
|
if (!Directory.Exists(DestinationPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(DestinationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
string DestinationPathName = Path.Combine(DestinationPath, rom.Name);
|
||||||
|
|
||||||
|
return DestinationPathName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool MoveGameFile(long RomId)
|
||||||
|
{
|
||||||
|
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||||
|
string romPath = rom.Path;
|
||||||
|
|
||||||
if (File.Exists(romPath))
|
if (File.Exists(romPath))
|
||||||
{
|
{
|
||||||
string DestinationPath = ComputeROMPath(RomId);
|
string DestinationPath = ComputeROMPath(RomId);
|
||||||
|
|
||||||
if (romPath == DestinationPath)
|
if (romPath == DestinationPath)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Move Game ROM", "Destination path is the same as the current path - aborting");
|
Logging.Log(Logging.LogType.Debug, "Move Game ROM", "Destination path is the same as the current path - aborting");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "Moving " + romPath + " to " + DestinationPath);
|
Logging.Log(Logging.LogType.Information, "Move Game ROM", "Moving " + romPath + " to " + DestinationPath);
|
||||||
if (File.Exists(DestinationPath))
|
if (File.Exists(DestinationPath))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - aborting");
|
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - aborting");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
File.Move(romPath, DestinationPath);
|
File.Move(romPath, DestinationPath);
|
||||||
|
|
||||||
// update the db
|
// update the db
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "UPDATE Games_Roms SET Path=@path WHERE Id=@id";
|
string sql = "UPDATE Games_Roms SET Path=@path WHERE Id=@id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
dbDict.Add("path", DestinationPath);
|
dbDict.Add("path", DestinationPath);
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -437,8 +444,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OrganiseLibrary()
|
public void OrganiseLibrary()
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Organise Library", "Starting default library organisation");
|
Logging.Log(Logging.LogType.Information, "Organise Library", "Starting default library organisation");
|
||||||
|
|
||||||
GameLibrary.LibraryItem library = GameLibrary.GetDefaultLibrary;
|
GameLibrary.LibraryItem library = GameLibrary.GetDefaultLibrary;
|
||||||
@@ -451,19 +458,19 @@ namespace gaseous_server.Classes
|
|||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < romDT.Rows.Count; i++)
|
for (int i = 0; i < romDT.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
||||||
Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]);
|
Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]);
|
||||||
long RomId = (long)romDT.Rows[i]["id"];
|
long RomId = (long)romDT.Rows[i]["id"];
|
||||||
MoveGameFile(RomId);
|
MoveGameFile(RomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
|
|
||||||
// clean up empty directories
|
// clean up empty directories
|
||||||
DeleteOrphanedDirectories(GameLibrary.GetDefaultLibrary.Path);
|
DeleteOrphanedDirectories(GameLibrary.GetDefaultLibrary.Path);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Organise Library", "Finsihed default library organisation");
|
Logging.Log(Logging.LogType.Information, "Organise Library", "Finsihed default library organisation");
|
||||||
}
|
}
|
||||||
@@ -476,7 +483,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
string[] files = Directory.GetFiles(directory);
|
string[] files = Directory.GetFiles(directory);
|
||||||
string[] directories = Directory.GetDirectories(directory);
|
string[] directories = Directory.GetDirectories(directory);
|
||||||
|
|
||||||
if (files.Length == 0 &&
|
if (files.Length == 0 &&
|
||||||
directories.Length == 0)
|
directories.Length == 0)
|
||||||
{
|
{
|
||||||
@@ -563,7 +570,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public void LibrarySpecificScan(GameLibrary.LibraryItem library)
|
public void LibrarySpecificScan(GameLibrary.LibraryItem library)
|
||||||
{
|
{
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting scan of library: " + library.Name);
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting scan of library: " + library.Name);
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
@@ -632,7 +639,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
// file is not in database - process it
|
// file is not in database - process it
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Orphaned file found in library: " + LibraryFile);
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Orphaned file found in library: " + LibraryFile);
|
||||||
|
|
||||||
Common.hashObject hash = new Common.hashObject(LibraryFile);
|
Common.hashObject hash = new Common.hashObject(LibraryFile);
|
||||||
FileInfo fi = new FileInfo(LibraryFile);
|
FileInfo fi = new FileInfo(LibraryFile);
|
||||||
|
|
||||||
@@ -644,8 +651,8 @@ namespace gaseous_server.Classes
|
|||||||
// get discovered platform
|
// get discovered platform
|
||||||
long PlatformId;
|
long PlatformId;
|
||||||
IGDB.Models.Platform determinedPlatform;
|
IGDB.Models.Platform determinedPlatform;
|
||||||
|
|
||||||
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0 )
|
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0)
|
||||||
{
|
{
|
||||||
// no platform discovered in the signature
|
// no platform discovered in the signature
|
||||||
PlatformId = library.DefaultPlatformId;
|
PlatformId = library.DefaultPlatformId;
|
||||||
@@ -770,8 +777,8 @@ namespace gaseous_server.Classes
|
|||||||
// get discovered platform
|
// get discovered platform
|
||||||
long PlatformId;
|
long PlatformId;
|
||||||
IGDB.Models.Platform determinedPlatform;
|
IGDB.Models.Platform determinedPlatform;
|
||||||
|
|
||||||
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0 )
|
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0)
|
||||||
{
|
{
|
||||||
// no platform discovered in the signature
|
// no platform discovered in the signature
|
||||||
PlatformId = library.DefaultPlatformId;
|
PlatformId = library.DefaultPlatformId;
|
||||||
|
@@ -5,8 +5,8 @@ using IGDB.Models;
|
|||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Games
|
public class Games
|
||||||
{
|
{
|
||||||
const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collection,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collection,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
||||||
|
|
||||||
public Games()
|
public Games()
|
||||||
@@ -15,9 +15,9 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class InvalidGameId : Exception
|
public class InvalidGameId : Exception
|
||||||
{
|
{
|
||||||
public InvalidGameId(long Id) : base("Unable to find Game by id " + Id)
|
public InvalidGameId(long Id) : base("Unable to find Game by id " + Id)
|
||||||
{}
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||||
@@ -78,15 +78,17 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up where clause
|
|
||||||
string WhereClause = "";
|
string WhereClause = "";
|
||||||
|
string searchField = "";
|
||||||
switch (searchUsing)
|
switch (searchUsing)
|
||||||
{
|
{
|
||||||
case SearchUsing.id:
|
case SearchUsing.id:
|
||||||
WhereClause = "where id = " + searchValue;
|
WhereClause = "where id = " + searchValue;
|
||||||
|
searchField = "id";
|
||||||
break;
|
break;
|
||||||
case SearchUsing.slug:
|
case SearchUsing.slug:
|
||||||
WhereClause = "where slug = " + searchValue;
|
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||||
|
searchField = "slug";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid search type");
|
throw new Exception("Invalid search type");
|
||||||
@@ -110,11 +112,11 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
returnValue = Storage.GetCacheValue<Game>(returnValue, "id", (long)searchValue);
|
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||||
}
|
}
|
||||||
return returnValue;
|
return returnValue;
|
||||||
case Storage.CacheStatus.Current:
|
case Storage.CacheStatus.Current:
|
||||||
returnValue = Storage.GetCacheValue<Game>(returnValue, "id", (long)searchValue);
|
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||||
UpdateSubClasses(returnValue, false, false, false);
|
UpdateSubClasses(returnValue, false, false, false);
|
||||||
return returnValue;
|
return returnValue;
|
||||||
default:
|
default:
|
||||||
@@ -285,7 +287,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
|
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -347,7 +349,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
// get missing metadata from parent if this is a port
|
// get missing metadata from parent if this is a port
|
||||||
if (result.Category == Category.Port)
|
if (result.Category == Category.Port)
|
||||||
{
|
{
|
||||||
if (result.Summary == null)
|
if (result.Summary == null)
|
||||||
{
|
{
|
||||||
if (result.ParentGame != null)
|
if (result.ParentGame != null)
|
||||||
@@ -364,7 +366,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AssignAllGamesToPlatformIdZero()
|
public static void AssignAllGamesToPlatformIdZero()
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
@@ -428,7 +430,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
string sql = "SELECT Game.Id, Game.`Name`, Game.Slug, Relation_Game_Platforms.PlatformsId AS PlatformsId, Game.Summary FROM gaseous.Game JOIN Relation_Game_Platforms ON Game.Id = Relation_Game_Platforms.GameId WHERE " + whereClause + ";";
|
string sql = "SELECT Game.Id, Game.`Name`, Game.Slug, Relation_Game_Platforms.PlatformsId AS PlatformsId, Game.Summary FROM gaseous.Game JOIN Relation_Game_Platforms ON Game.Id = Relation_Game_Platforms.GameId WHERE " + whereClause + ";";
|
||||||
|
|
||||||
|
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
Game[]? results = new Game[0];
|
Game[]? results = new Game[0];
|
||||||
@@ -439,7 +441,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
Game game = new Game{
|
Game game = new Game
|
||||||
|
{
|
||||||
Id = (long)row["Id"],
|
Id = (long)row["Id"],
|
||||||
Name = (string)Common.ReturnValueIfNull(row["Name"], ""),
|
Name = (string)Common.ReturnValueIfNull(row["Name"], ""),
|
||||||
Slug = (string)Common.ReturnValueIfNull(row["Slug"], ""),
|
Slug = (string)Common.ReturnValueIfNull(row["Slug"], ""),
|
||||||
@@ -476,12 +479,12 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
searchBody = "where platforms = (" + PlatformId + ") & name ~ \"" + SearchString + "\";";
|
searchBody = "where platforms = (" + PlatformId + ") & name ~ \"" + SearchString + "\";";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check search cache
|
// check search cache
|
||||||
Game[]? games = Communications.GetSearchCache<Game[]?>(searchFields, searchBody);
|
Game[]? games = Communications.GetSearchCache<Game[]?>(searchFields, searchBody);
|
||||||
|
|
||||||
if (games == null)
|
if (games == null)
|
||||||
{
|
{
|
||||||
// cache miss
|
// cache miss
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
@@ -513,7 +516,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
KeyValuePair<long, string> valuePair = new KeyValuePair<long, string>((long)row["PlatformId"], (string)row["Name"]);
|
KeyValuePair<long, string> valuePair = new KeyValuePair<long, string>((long)row["PlatformId"], (string)row["Name"]);
|
||||||
platforms.Add(valuePair);
|
platforms.Add(valuePair);
|
||||||
}
|
}
|
||||||
|
|
||||||
return platforms;
|
return platforms;
|
||||||
@@ -533,7 +536,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MinimalGameItem(Game gameObject)
|
public MinimalGameItem(Game gameObject)
|
||||||
{
|
{
|
||||||
this.Id = gameObject.Id;
|
this.Id = gameObject.Id;
|
||||||
|
@@ -7,16 +7,16 @@ using IGDB.Models;
|
|||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Platforms
|
public class Platforms
|
||||||
{
|
{
|
||||||
const string fieldList = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites;";
|
const string fieldList = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites;";
|
||||||
|
|
||||||
public Platforms()
|
public Platforms()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Platform? GetPlatform(long Id, bool forceRefresh = false)
|
public static Platform? GetPlatform(long Id, bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
if (Id == 0)
|
if (Id == 0)
|
||||||
{
|
{
|
||||||
Platform returnValue = new Platform();
|
Platform returnValue = new Platform();
|
||||||
@@ -44,7 +44,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id, forceRefresh);
|
Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id, forceRefresh);
|
||||||
return RetVal.Result;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata", "An error occurred fetching Platform Id " + Id, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata", "An error occurred fetching Platform Id " + Id, ex);
|
||||||
return null;
|
return null;
|
||||||
@@ -52,14 +52,14 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Platform GetPlatform(string Slug, bool forceRefresh = false)
|
public static Platform GetPlatform(string Slug, bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug, forceRefresh);
|
Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug, forceRefresh);
|
||||||
return RetVal.Result;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue, bool forceRefresh)
|
private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue, bool forceRefresh)
|
||||||
{
|
{
|
||||||
// check database first
|
// check database first
|
||||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
if (searchUsing == SearchUsing.id)
|
if (searchUsing == SearchUsing.id)
|
||||||
@@ -78,13 +78,16 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
// set up where clause
|
// set up where clause
|
||||||
string WhereClause = "";
|
string WhereClause = "";
|
||||||
|
string searchField = "";
|
||||||
switch (searchUsing)
|
switch (searchUsing)
|
||||||
{
|
{
|
||||||
case SearchUsing.id:
|
case SearchUsing.id:
|
||||||
WhereClause = "where id = " + searchValue;
|
WhereClause = "where id = " + searchValue;
|
||||||
|
searchField = "id";
|
||||||
break;
|
break;
|
||||||
case SearchUsing.slug:
|
case SearchUsing.slug:
|
||||||
WhereClause = "where slug = " + searchValue;
|
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||||
|
searchField = "slug";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid search type");
|
throw new Exception("Invalid search type");
|
||||||
@@ -111,10 +114,10 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue);
|
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||||
}
|
}
|
||||||
case Storage.CacheStatus.Current:
|
case Storage.CacheStatus.Current:
|
||||||
return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue);
|
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||||
default:
|
default:
|
||||||
throw new Exception("How did you get here?");
|
throw new Exception("How did you get here?");
|
||||||
}
|
}
|
||||||
@@ -158,11 +161,12 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + platform.Name + " from predefined data.");
|
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + platform.Name + " from predefined data.");
|
||||||
// doesn't exist - add it
|
// doesn't exist - add it
|
||||||
item = new Models.PlatformMapping.PlatformMapItem{
|
item = new Models.PlatformMapping.PlatformMapItem
|
||||||
|
{
|
||||||
IGDBId = (long)platform.Id,
|
IGDBId = (long)platform.Id,
|
||||||
IGDBName = platform.Name,
|
IGDBName = platform.Name,
|
||||||
IGDBSlug = platform.Slug,
|
IGDBSlug = platform.Slug,
|
||||||
AlternateNames = new List<string>{ platform.AlternativeName }
|
AlternateNames = new List<string> { platform.AlternativeName }
|
||||||
};
|
};
|
||||||
Models.PlatformMapping.WritePlatformMap(item, false, true);
|
Models.PlatformMapping.WritePlatformMap(item, false, true);
|
||||||
}
|
}
|
||||||
|
@@ -4,29 +4,32 @@ using gaseous_signature_parser.models.RomSignatureObject;
|
|||||||
using static gaseous_server.Classes.RomMediaGroup;
|
using static gaseous_server.Classes.RomMediaGroup;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
|
using static HasheousClient.Models.FixMatchModel;
|
||||||
|
using NuGet.Protocol.Core.Types;
|
||||||
|
using static gaseous_server.Classes.FileSignature;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class Roms
|
public class Roms
|
||||||
{
|
{
|
||||||
public class InvalidRomId : Exception
|
public class InvalidRomId : Exception
|
||||||
{
|
{
|
||||||
public InvalidRomId(long Id) : base("Unable to find ROM by id " + Id)
|
public InvalidRomId(long Id) : base("Unable to find ROM by id " + Id)
|
||||||
{}
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameRomObject GetRoms(long GameId, long PlatformId = -1, string NameSearch = "", int pageNumber = 0, int pageSize = 0, string userid = "")
|
public static GameRomObject GetRoms(long GameId, long PlatformId = -1, string NameSearch = "", int pageNumber = 0, int pageSize = 0, string userid = "")
|
||||||
{
|
{
|
||||||
GameRomObject GameRoms = new GameRomObject();
|
GameRomObject GameRoms = new GameRomObject();
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
string sqlCount = "";
|
string sqlCount = "";
|
||||||
string sqlPlatform = "";
|
string sqlPlatform = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", GameId);
|
dbDict.Add("id", GameId);
|
||||||
dbDict.Add("userid", userid);
|
dbDict.Add("userid", userid);
|
||||||
|
|
||||||
string NameSearchWhere = "";
|
string NameSearchWhere = "";
|
||||||
if (NameSearch.Length > 0)
|
if (NameSearch.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -37,13 +40,16 @@ namespace gaseous_server.Classes
|
|||||||
// platform query
|
// platform query
|
||||||
sqlPlatform = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
sqlPlatform = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
||||||
|
|
||||||
if (PlatformId == -1) {
|
if (PlatformId == -1)
|
||||||
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
||||||
|
|
||||||
// count query
|
// count query
|
||||||
sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id" + NameSearchWhere + ";";
|
sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id" + NameSearchWhere + ";";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
||||||
|
|
||||||
@@ -52,12 +58,12 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
dbDict.Add("platformid", PlatformId);
|
dbDict.Add("platformid", PlatformId);
|
||||||
}
|
}
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict)[0];
|
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict)[0];
|
||||||
DataTable platformDT = db.ExecuteCMD(sqlPlatform, dbDict);
|
DataTable platformDT = db.ExecuteCMD(sqlPlatform, dbDict);
|
||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
// set count of roms
|
// set count of roms
|
||||||
GameRoms.Count = int.Parse((string)rowCount["RomCount"]);
|
GameRoms.Count = int.Parse((string)rowCount["RomCount"]);
|
||||||
|
|
||||||
@@ -73,12 +79,12 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
return GameRoms;
|
return GameRoms;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Games.InvalidGameId(GameId);
|
throw new Games.InvalidGameId(GameId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameRomItem GetRom(long RomId)
|
public static GameRomItem GetRom(long RomId)
|
||||||
{
|
{
|
||||||
@@ -108,18 +114,65 @@ namespace gaseous_server.Classes
|
|||||||
// ensure metadata for gameid is present
|
// ensure metadata for gameid is present
|
||||||
IGDB.Models.Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
IGDB.Models.Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid WHERE Id = @id";
|
string sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid WHERE Id = @id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
dbDict.Add("platformid", PlatformId);
|
dbDict.Add("platformid", PlatformId);
|
||||||
dbDict.Add("gameid", GameId);
|
dbDict.Add("gameid", GameId);
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
GameRomItem rom = GetRom(RomId);
|
GameRomItem rom = GetRom(RomId);
|
||||||
|
|
||||||
|
// send update to Hasheous if enabled
|
||||||
|
if (PlatformId != 0 && GameId != 0)
|
||||||
|
{
|
||||||
|
if (Config.MetadataConfiguration.HasheousSubmitFixes == true)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous &&
|
||||||
|
(
|
||||||
|
Config.MetadataConfiguration.HasheousAPIKey != null &&
|
||||||
|
Config.MetadataConfiguration.HasheousAPIKey != "")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// find signature used for identifing the rom
|
||||||
|
string md5String = rom.Md5;
|
||||||
|
string sha1String = rom.Sha1;
|
||||||
|
if (rom.Attributes.ContainsKey("ZipContents"))
|
||||||
|
{
|
||||||
|
bool selectorFound = false;
|
||||||
|
List<ArchiveData> archiveDataValues = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ArchiveData>>(rom.Attributes["ZipContents"].ToString());
|
||||||
|
foreach (ArchiveData archiveData in archiveDataValues)
|
||||||
|
{
|
||||||
|
if (archiveData.isSignatureSelector == true)
|
||||||
|
{
|
||||||
|
md5String = archiveData.MD5;
|
||||||
|
sha1String = archiveData.SHA1;
|
||||||
|
selectorFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HasheousClient.WebApp.HttpHelper.AddHeader("X-API-Key", Config.MetadataConfiguration.HasheousAPIKey);
|
||||||
|
HasheousClient.Hasheous hasheousClient = new HasheousClient.Hasheous();
|
||||||
|
List<MetadataMatch> metadataMatchList = new List<MetadataMatch>();
|
||||||
|
metadataMatchList.Add(new MetadataMatch(HasheousClient.Models.MetadataSources.IGDB, platform.Slug, game.Slug));
|
||||||
|
hasheousClient.FixMatch(new HasheousClient.Models.FixMatchModel(md5String, sha1String, metadataMatchList));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Fix Match", "An error occurred while sending a fixed match to Hasheous.", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rom;
|
return rom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteRom(long RomId)
|
public static void DeleteRom(long RomId)
|
||||||
{
|
{
|
||||||
@@ -137,7 +190,7 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GameRomItem BuildRom(DataRow romDR)
|
private static GameRomItem BuildRom(DataRow romDR)
|
||||||
{
|
{
|
||||||
@@ -150,28 +203,44 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Dictionary<string, object> romAttributes = new Dictionary<string, object>();
|
||||||
|
if (romDR["attributes"] != DBNull.Value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((string)romDR["attributes"] != "[ ]")
|
||||||
|
{
|
||||||
|
romAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>((string)romDR["attributes"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Roms", "Error parsing rom attributes: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GameRomItem romItem = new GameRomItem
|
GameRomItem romItem = new GameRomItem
|
||||||
{
|
{
|
||||||
Id = (long)romDR["id"],
|
Id = (long)romDR["id"],
|
||||||
PlatformId = (long)romDR["platformid"],
|
PlatformId = (long)romDR["platformid"],
|
||||||
Platform = (string)romDR["platformname"],
|
Platform = (string)romDR["platformname"],
|
||||||
GameId = (long)romDR["gameid"],
|
GameId = (long)romDR["gameid"],
|
||||||
Name = (string)romDR["name"],
|
Name = (string)romDR["name"],
|
||||||
Size = (long)romDR["size"],
|
Size = (long)romDR["size"],
|
||||||
Crc = ((string)romDR["crc"]).ToLower(),
|
Crc = ((string)romDR["crc"]).ToLower(),
|
||||||
Md5 = ((string)romDR["md5"]).ToLower(),
|
Md5 = ((string)romDR["md5"]).ToLower(),
|
||||||
Sha1 = ((string)romDR["sha1"]).ToLower(),
|
Sha1 = ((string)romDR["sha1"]).ToLower(),
|
||||||
DevelopmentStatus = (string)romDR["developmentstatus"],
|
DevelopmentStatus = (string)romDR["developmentstatus"],
|
||||||
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<KeyValuePair<string, object>>>((string)Common.ReturnValueIfNull(romDR["attributes"], "[ ]")),
|
Attributes = romAttributes,
|
||||||
RomType = (HasheousClient.Models.LookupResponseModel.RomItem.RomTypes)(int)romDR["romtype"],
|
RomType = (HasheousClient.Models.SignatureModel.RomItem.RomTypes)(int)romDR["romtype"],
|
||||||
RomTypeMedia = (string)romDR["romtypemedia"],
|
RomTypeMedia = (string)romDR["romtypemedia"],
|
||||||
MediaLabel = (string)romDR["medialabel"],
|
MediaLabel = (string)romDR["medialabel"],
|
||||||
Path = (string)romDR["path"],
|
Path = (string)romDR["path"],
|
||||||
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"],
|
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"],
|
||||||
SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""),
|
SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""),
|
||||||
HasSaveStates = hasSaveStates,
|
HasSaveStates = hasSaveStates,
|
||||||
Library = GameLibrary.GetLibrary((int)romDR["LibraryId"])
|
Library = GameLibrary.GetLibrary((int)romDR["LibraryId"])
|
||||||
};
|
};
|
||||||
|
|
||||||
// check for a web emulator and update the romItem
|
// check for a web emulator and update the romItem
|
||||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||||
@@ -185,8 +254,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return romItem;
|
return romItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameRomObject
|
public class GameRomObject
|
||||||
{
|
{
|
||||||
@@ -194,17 +263,17 @@ namespace gaseous_server.Classes
|
|||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameRomItem : HasheousClient.Models.LookupResponseModel.RomItem
|
public class GameRomItem : HasheousClient.Models.SignatureModel.RomItem
|
||||||
{
|
{
|
||||||
public long PlatformId { get; set; }
|
public long PlatformId { get; set; }
|
||||||
public string Platform { get; set; }
|
public string Platform { get; set; }
|
||||||
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||||
public long GameId { get; set; }
|
public long GameId { get; set; }
|
||||||
public string? Path { get; set; }
|
public string? Path { get; set; }
|
||||||
public string? SignatureSourceGameTitle { get; set;}
|
public string? SignatureSourceGameTitle { get; set; }
|
||||||
public bool HasSaveStates { get; set; } = false;
|
public bool HasSaveStates { get; set; } = false;
|
||||||
public GameLibrary.LibraryItem Library { get; set; }
|
public GameLibrary.LibraryItem Library { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,21 +8,49 @@ namespace gaseous_server.SignatureIngestors.XML
|
|||||||
{
|
{
|
||||||
public class XMLIngestor : QueueItemStatus
|
public class XMLIngestor : QueueItemStatus
|
||||||
{
|
{
|
||||||
public void Import(string SearchPath, gaseous_signature_parser.parser.SignatureParser XMLType)
|
public void Import(string SearchPath, string ProcessedDirectory, gaseous_signature_parser.parser.SignatureParser XMLType)
|
||||||
{
|
{
|
||||||
// connect to database
|
// connect to database
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
string? XMLDBSearchPath = null;
|
||||||
|
string? XMLDBProcessedDirectory = null;
|
||||||
|
if (XMLType == gaseous_signature_parser.parser.SignatureParser.NoIntro)
|
||||||
|
{
|
||||||
|
XMLDBSearchPath = Path.Combine(SearchPath, "DB");
|
||||||
|
XMLDBProcessedDirectory = Path.Combine(ProcessedDirectory, "DB");
|
||||||
|
SearchPath = Path.Combine(SearchPath, "DAT");
|
||||||
|
ProcessedDirectory = Path.Combine(ProcessedDirectory, "DAT");
|
||||||
|
}
|
||||||
|
|
||||||
// process provided files
|
// process provided files
|
||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing from " + SearchPath);
|
|
||||||
if (!Directory.Exists(SearchPath))
|
if (!Directory.Exists(SearchPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(SearchPath);
|
Directory.CreateDirectory(SearchPath);
|
||||||
}
|
}
|
||||||
|
if (!Directory.Exists(ProcessedDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(ProcessedDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
string[] PathContents = Directory.GetFiles(SearchPath);
|
string[] PathContents = Directory.GetFiles(SearchPath);
|
||||||
Array.Sort(PathContents);
|
Array.Sort(PathContents);
|
||||||
|
|
||||||
|
string[]? DBPathContents = null;
|
||||||
|
if (XMLDBSearchPath != null)
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(XMLDBSearchPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(XMLDBSearchPath);
|
||||||
|
}
|
||||||
|
if (!Directory.Exists(XMLDBProcessedDirectory))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(XMLDBProcessedDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBPathContents = Directory.GetFiles(XMLDBSearchPath);
|
||||||
|
}
|
||||||
|
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
System.Data.DataTable sigDB;
|
System.Data.DataTable sigDB;
|
||||||
@@ -33,226 +61,380 @@ namespace gaseous_server.SignatureIngestors.XML
|
|||||||
|
|
||||||
SetStatus(i + 1, PathContents.Length, "Processing signature file: " + XMLFile);
|
SetStatus(i + 1, PathContents.Length, "Processing signature file: " + XMLFile);
|
||||||
|
|
||||||
if (Common.SkippableFiles.Contains(Path.GetFileName(XMLFile), StringComparer.OrdinalIgnoreCase))
|
Logging.Log(Logging.LogType.Information, "Signature Ingest", "(" + (i + 1) + " / " + PathContents.Length + ") Processing " + XMLType.ToString() + " DAT file: " + XMLFile);
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Skipping file: " + XMLFile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check xml file md5
|
|
||||||
Common.hashObject hashObject = new Common.hashObject(XMLFile);
|
|
||||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
|
||||||
dbDict = new Dictionary<string, object>();
|
|
||||||
dbDict.Add("sourcemd5", hashObject.md5hash);
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (sigDB.Rows.Count == 0)
|
string? DBFile = null;
|
||||||
|
if (XMLDBSearchPath != null)
|
||||||
|
{
|
||||||
|
switch (XMLType)
|
||||||
{
|
{
|
||||||
try
|
case gaseous_signature_parser.parser.SignatureParser.NoIntro:
|
||||||
{
|
for (UInt16 x = 0; x < DBPathContents.Length; x++)
|
||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing file: " + XMLFile);
|
|
||||||
|
|
||||||
// start parsing file
|
|
||||||
gaseous_signature_parser.parser Parser = new gaseous_signature_parser.parser();
|
|
||||||
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, XMLType);
|
|
||||||
|
|
||||||
// store in database
|
|
||||||
string[] flipNameAndDescription = {
|
|
||||||
"MAMEArcade",
|
|
||||||
"MAMEMess"
|
|
||||||
};
|
|
||||||
|
|
||||||
// store source object
|
|
||||||
bool processGames = false;
|
|
||||||
if (Object.SourceMd5 != null)
|
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
string tempDBFileName = Path.GetFileNameWithoutExtension(DBPathContents[x].Replace(" (DB Export)", ""));
|
||||||
dbDict = new Dictionary<string, object>();
|
if (tempDBFileName == Path.GetFileNameWithoutExtension(XMLFile))
|
||||||
string sourceUriStr = "";
|
|
||||||
if (Object.Url != null)
|
|
||||||
{
|
{
|
||||||
sourceUriStr = Object.Url.ToString();
|
DBFile = DBPathContents[x];
|
||||||
|
Logging.Log(Logging.LogType.Information, "Signature Ingest", "Using DB file: " + DBFile);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(Object.Name, ""));
|
}
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(Object.Description, ""));
|
break;
|
||||||
dbDict.Add("category", Common.ReturnValueIfNull(Object.Category, ""));
|
}
|
||||||
dbDict.Add("version", Common.ReturnValueIfNull(Object.Version, ""));
|
}
|
||||||
dbDict.Add("author", Common.ReturnValueIfNull(Object.Author, ""));
|
|
||||||
dbDict.Add("email", Common.ReturnValueIfNull(Object.Email, ""));
|
// check xml file md5
|
||||||
dbDict.Add("homepage", Common.ReturnValueIfNull(Object.Homepage, ""));
|
Common.hashObject hashObject = new Common.hashObject(XMLFile);
|
||||||
dbDict.Add("uri", sourceUriStr);
|
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
||||||
dbDict.Add("sourcetype", Common.ReturnValueIfNull(Object.SourceType, ""));
|
dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("sourcemd5", Object.SourceMd5);
|
dbDict.Add("sourcemd5", hashObject.md5hash);
|
||||||
dbDict.Add("sourcesha1", Object.SourceSHA1);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// start parsing file
|
||||||
|
gaseous_signature_parser.parser Parser = new gaseous_signature_parser.parser();
|
||||||
|
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, DBFile, XMLType);
|
||||||
|
|
||||||
|
// store in database
|
||||||
|
string[] flipNameAndDescription = {
|
||||||
|
"MAMEArcade",
|
||||||
|
"MAMEMess"
|
||||||
|
};
|
||||||
|
|
||||||
|
// store source object
|
||||||
|
bool processGames = false;
|
||||||
|
if (Object.SourceMd5 != null)
|
||||||
|
{
|
||||||
|
int sourceId = 0;
|
||||||
|
|
||||||
|
sql = "SELECT * FROM Signatures_Sources WHERE `SourceMD5`=@sourcemd5";
|
||||||
|
dbDict = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "name", Common.ReturnValueIfNull(Object.Name, "") },
|
||||||
|
{ "description", Common.ReturnValueIfNull(Object.Description, "") },
|
||||||
|
{ "category", Common.ReturnValueIfNull(Object.Category, "") },
|
||||||
|
{ "version", Common.ReturnValueIfNull(Object.Version, "") },
|
||||||
|
{ "author", Common.ReturnValueIfNull(Object.Author, "") },
|
||||||
|
{ "email", Common.ReturnValueIfNull(Object.Email, "") },
|
||||||
|
{ "homepage", Common.ReturnValueIfNull(Object.Homepage, "") }
|
||||||
|
};
|
||||||
|
if (Object.Url == null)
|
||||||
|
{
|
||||||
|
dbDict.Add("uri", "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("uri", Common.ReturnValueIfNull(Object.Url.ToString(), ""));
|
||||||
|
}
|
||||||
|
dbDict.Add("sourcetype", Common.ReturnValueIfNull(Object.SourceType, ""));
|
||||||
|
dbDict.Add("sourcemd5", Object.SourceMd5);
|
||||||
|
dbDict.Add("sourcesha1", Object.SourceSHA1);
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Sources (`Name`, `Description`, `Category`, `Version`, `Author`, `Email`, `Homepage`, `Url`, `SourceType`, `SourceMD5`, `SourceSHA1`) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
|
sourceId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
|
||||||
|
processGames = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (processGames == true)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < Object.Games.Count; ++x)
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
RomSignatureObject.Game gameObject = Object.Games[x];
|
||||||
sql = "INSERT INTO Signatures_Sources (Name, Description, Category, Version, Author, Email, Homepage, Url, SourceType, SourceMD5, SourceSHA1) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1)";
|
|
||||||
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
// set up game dictionary
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
processGames = true;
|
if (flipNameAndDescription.Contains(Object.SourceType))
|
||||||
}
|
|
||||||
|
|
||||||
if (processGames == true)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < Object.Games.Count; ++x)
|
|
||||||
{
|
{
|
||||||
RomSignatureObject.Game gameObject = Object.Games[x];
|
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Description, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Name, ""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Name, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Description, ""));
|
||||||
|
}
|
||||||
|
dbDict.Add("year", Common.ReturnValueIfNull(gameObject.Year, ""));
|
||||||
|
dbDict.Add("publisher", Common.ReturnValueIfNull(gameObject.Publisher, ""));
|
||||||
|
dbDict.Add("demo", (int)gameObject.Demo);
|
||||||
|
dbDict.Add("system", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
||||||
|
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
||||||
|
|
||||||
// set up game dictionary
|
List<int> gameCountries = new List<int>();
|
||||||
dbDict = new Dictionary<string, object>();
|
if (
|
||||||
if (flipNameAndDescription.Contains(Object.SourceType))
|
gameObject.Country != null &&
|
||||||
|
gameObject.Country != "Unknown"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
string[] countries = gameObject.Country.Split(",");
|
||||||
|
foreach (string country in countries)
|
||||||
{
|
{
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Description, ""));
|
int countryId = -1;
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Name, ""));
|
countryId = Common.GetLookupByCode(Common.LookupTypes.Country, (string)Common.ReturnValueIfNull(country.Trim(), ""));
|
||||||
}
|
if (countryId == -1)
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Name, ""));
|
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Description, ""));
|
|
||||||
}
|
|
||||||
dbDict.Add("year", Common.ReturnValueIfNull(gameObject.Year, ""));
|
|
||||||
dbDict.Add("publisher", Common.ReturnValueIfNull(gameObject.Publisher, ""));
|
|
||||||
dbDict.Add("demo", (int)gameObject.Demo);
|
|
||||||
dbDict.Add("system", Common.ReturnValueIfNull(gameObject.System, ""));
|
|
||||||
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
|
||||||
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
|
||||||
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
|
||||||
dbDict.Add("country", Common.ReturnValueIfNull(gameObject.Country, ""));
|
|
||||||
dbDict.Add("language", Common.ReturnValueIfNull(gameObject.Language, ""));
|
|
||||||
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
|
||||||
|
|
||||||
// store platform
|
|
||||||
int gameSystem = 0;
|
|
||||||
if (gameObject.System != null)
|
|
||||||
{
|
|
||||||
sql = "SELECT Id FROM Signatures_Platforms WHERE Platform=@platform";
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
countryId = Common.GetLookupByValue(Common.LookupTypes.Country, (string)Common.ReturnValueIfNull(country.Trim(), ""));
|
||||||
sql = "INSERT INTO Signatures_Platforms (Platform) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
gameSystem = Convert.ToInt32(sigDB.Rows[0][0]);
|
if (countryId == -1)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Unable to locate country id for " + country.Trim());
|
||||||
|
sql = "INSERT INTO Country (`Code`, `Value`) VALUES (@code, @name); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
Dictionary<string, object> countryDict = new Dictionary<string, object>{
|
||||||
|
{ "code", country.Trim() },
|
||||||
|
{ "name", country.Trim() }
|
||||||
|
};
|
||||||
|
countryId = int.Parse(db.ExecuteCMD(sql, countryDict).Rows[0][0].ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (countryId > 0)
|
||||||
{
|
{
|
||||||
gameSystem = (int)sigDB.Rows[0][0];
|
gameCountries.Add(countryId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbDict.Add("systemid", gameSystem);
|
}
|
||||||
|
|
||||||
// store publisher
|
List<int> gameLanguages = new List<int>();
|
||||||
int gamePublisher = 0;
|
if (
|
||||||
if (gameObject.Publisher != null)
|
gameObject.Language != null &&
|
||||||
|
gameObject.Language != "nolang"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
string[] languages = gameObject.Language.Split(",");
|
||||||
|
foreach (string language in languages)
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM Signatures_Publishers WHERE Publisher=@publisher";
|
int languageId = -1;
|
||||||
|
languageId = Common.GetLookupByCode(Common.LookupTypes.Language, (string)Common.ReturnValueIfNull(language.Trim(), ""));
|
||||||
|
if (languageId == -1)
|
||||||
|
{
|
||||||
|
languageId = Common.GetLookupByValue(Common.LookupTypes.Language, (string)Common.ReturnValueIfNull(language.Trim(), ""));
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
if (languageId == -1)
|
||||||
if (sigDB.Rows.Count == 0)
|
{
|
||||||
{
|
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Unable to locate language id for " + language.Trim());
|
||||||
// entry not present, insert it
|
sql = "INSERT INTO Language (`Code`, `Value`) VALUES (@code, @name); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
sql = "INSERT INTO Signatures_Publishers (Publisher) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
Dictionary<string, object> langDict = new Dictionary<string, object>{
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
{ "code", language.Trim() },
|
||||||
gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]);
|
{ "name", language.Trim() }
|
||||||
|
};
|
||||||
|
languageId = int.Parse(db.ExecuteCMD(sql, langDict).Rows[0][0].ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (languageId > 0)
|
||||||
{
|
{
|
||||||
gamePublisher = (int)sigDB.Rows[0][0];
|
gameLanguages.Add(languageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbDict.Add("publisherid", gamePublisher);
|
}
|
||||||
|
|
||||||
// store game
|
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
||||||
int gameId = 0;
|
|
||||||
sql = "SELECT * FROM Signatures_Games WHERE Name=@name AND Year=@year AND Publisherid=@publisher AND Systemid=@systemid AND Country=@country AND Language=@language";
|
// store platform
|
||||||
|
int gameSystem = 0;
|
||||||
|
if (gameObject.System != null)
|
||||||
|
{
|
||||||
|
sql = "SELECT `Id` FROM Signatures_Platforms WHERE `Platform`=@platform";
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
if (sigDB.Rows.Count == 0)
|
if (sigDB.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
// entry not present, insert it
|
||||||
sql = "INSERT INTO Signatures_Games " +
|
sql = "INSERT INTO Signatures_Platforms (`Platform`) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
"(Name, Description, Year, PublisherId, Demo, SystemId, SystemVariant, Video, Country, Language, Copyright) VALUES " +
|
|
||||||
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
gameId = Convert.ToInt32(sigDB.Rows[0][0]);
|
gameSystem = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gameId = (int)sigDB.Rows[0][0];
|
gameSystem = (int)sigDB.Rows[0][0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("systemid", gameSystem);
|
||||||
|
|
||||||
// store rom
|
// store publisher
|
||||||
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
int gamePublisher = 0;
|
||||||
|
if (gameObject.Publisher != null)
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM Signatures_Publishers WHERE `Publisher`=@publisher";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
if (romObject.Md5 != null || romObject.Sha1 != null)
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Publishers (`Publisher`) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gamePublisher = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("publisherid", gamePublisher);
|
||||||
|
|
||||||
|
// store game
|
||||||
|
long gameId = 0;
|
||||||
|
sql = "SELECT * FROM Signatures_Games WHERE `Name`=@name AND `Year`=@year AND `PublisherId`=@publisherid AND `SystemId`=@systemid";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Games " +
|
||||||
|
"(`Name`, `Description`, `Year`, `PublisherId`, `Demo`, `SystemId`, `SystemVariant`, `Video`, `Copyright`) VALUES " +
|
||||||
|
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
gameId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert countries
|
||||||
|
foreach (int gameCountry in gameCountries)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM Signatures_Games_Countries WHERE GameId = @gameid AND CountryId = @Countryid";
|
||||||
|
Dictionary<string, object> countryDict = new Dictionary<string, object>{
|
||||||
|
{ "gameid", gameId },
|
||||||
|
{ "Countryid", gameCountry }
|
||||||
|
};
|
||||||
|
if (db.ExecuteCMD(sql, countryDict).Rows.Count == 0)
|
||||||
{
|
{
|
||||||
int romId = 0;
|
sql = "INSERT INTO Signatures_Games_Countries (GameId, CountryId) VALUES (@gameid, @Countryid)";
|
||||||
sql = "SELECT * FROM Signatures_Roms WHERE GameId=@gameid AND MD5=@md5";
|
db.ExecuteCMD(sql, countryDict);
|
||||||
dbDict = new Dictionary<string, object>();
|
}
|
||||||
dbDict.Add("gameid", gameId);
|
}
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
catch
|
||||||
dbDict.Add("size", Common.ReturnValueIfNull(romObject.Size, ""));
|
{
|
||||||
dbDict.Add("crc", Common.ReturnValueIfNull(romObject.Crc, "").ToString().ToLower());
|
Console.WriteLine("Game id: " + gameId + " with Country " + gameCountry);
|
||||||
dbDict.Add("md5", Common.ReturnValueIfNull(romObject.Md5, "").ToString().ToLower());
|
}
|
||||||
dbDict.Add("sha1", Common.ReturnValueIfNull(romObject.Sha1, "").ToString().ToLower());
|
}
|
||||||
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(romObject.DevelopmentStatus, ""));
|
|
||||||
|
|
||||||
if (romObject.Attributes != null)
|
// insert languages
|
||||||
|
foreach (int gameLanguage in gameLanguages)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM Signatures_Games_Languages WHERE GameId = @gameid AND LanguageId = @languageid";
|
||||||
|
Dictionary<string, object> langDict = new Dictionary<string, object>{
|
||||||
|
{ "gameid", gameId },
|
||||||
|
{ "languageid", gameLanguage }
|
||||||
|
};
|
||||||
|
if (db.ExecuteCMD(sql, langDict).Rows.Count == 0)
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO Signatures_Games_Languages (GameId, LanguageId) VALUES (@gameid, @languageid)";
|
||||||
|
db.ExecuteCMD(sql, langDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine("Game id: " + gameId + " with language " + gameLanguage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store rom
|
||||||
|
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||||
|
{
|
||||||
|
if (romObject.Md5 != null || romObject.Sha1 != null)
|
||||||
|
{
|
||||||
|
long romId = 0;
|
||||||
|
sql = "SELECT * FROM Signatures_Roms WHERE `GameId`=@gameid AND (`MD5`=@md5 OR `SHA1`=@sha1)";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("gameid", gameId);
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
||||||
|
dbDict.Add("size", Common.ReturnValueIfNull(romObject.Size, ""));
|
||||||
|
dbDict.Add("crc", Common.ReturnValueIfNull(romObject.Crc, "").ToString().ToLower());
|
||||||
|
dbDict.Add("md5", Common.ReturnValueIfNull(romObject.Md5, "").ToString().ToLower());
|
||||||
|
dbDict.Add("sha1", Common.ReturnValueIfNull(romObject.Sha1, "").ToString().ToLower());
|
||||||
|
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(romObject.DevelopmentStatus, ""));
|
||||||
|
|
||||||
|
if (romObject.Attributes != null)
|
||||||
|
{
|
||||||
|
if (romObject.Attributes.Count > 0)
|
||||||
{
|
{
|
||||||
if (romObject.Attributes.Count > 0)
|
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(romObject.Attributes));
|
||||||
{
|
|
||||||
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(romObject.Attributes));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", "[ ]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbDict.Add("attributes", "[ ]");
|
dbDict.Add("attributes", "");
|
||||||
}
|
}
|
||||||
dbDict.Add("romtype", (int)romObject.RomType);
|
}
|
||||||
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
else
|
||||||
dbDict.Add("medialabel", Common.ReturnValueIfNull(romObject.MediaLabel, ""));
|
{
|
||||||
dbDict.Add("metadatasource", romObject.SignatureSource);
|
dbDict.Add("attributes", "");
|
||||||
dbDict.Add("ingestorversion", 2);
|
}
|
||||||
|
dbDict.Add("romtype", (int)romObject.RomType);
|
||||||
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
||||||
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(romObject.MediaLabel, ""));
|
||||||
|
dbDict.Add("metadatasource", romObject.SignatureSource);
|
||||||
|
dbDict.Add("ingestorversion", 2);
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Roms (`GameId`, `Name`, `Size`, `CRC`, `MD5`, `SHA1`, `DevelopmentStatus`, `Attributes`, `RomType`, `RomTypeMedia`, `MediaLabel`, `MetadataSource`, `IngestorVersion`) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
{
|
|
||||||
// entry not present, insert it
|
|
||||||
sql = "INSERT INTO Signatures_Roms (GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, MetadataSource, IngestorVersion) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
|
romId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
romId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
romId = Convert.ToInt32(sigDB.Rows[0][0]);
|
// map the rom to the source
|
||||||
}
|
sql = "SELECT * FROM Signatures_RomToSource WHERE SourceId=@sourceid AND RomId=@romid;";
|
||||||
else
|
dbDict.Add("romid", romId);
|
||||||
{
|
dbDict.Add("sourceId", sourceId);
|
||||||
romId = (int)sigDB.Rows[0][0];
|
|
||||||
}
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO Signatures_RomToSource (`SourceId`, `RomId`) VALUES (@sourceid, @romid);";
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
File.Move(XMLFile, Path.Combine(ProcessedDirectory, Path.GetFileName(XMLFile)));
|
||||||
|
if (DBFile != null)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Signature Ingestor - XML", "Invalid import file: " + XMLFile, ex);
|
File.Move(DBFile, Path.Combine(XMLDBProcessedDirectory, Path.GetFileName(DBFile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Ingestor - XML", "Rejecting already imported file: " + XMLFile);
|
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Error ingesting " + XMLType.ToString() + " file: " + XMLFile, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Signature Ingest", "Rejecting already imported " + XMLType.ToString() + " file: " + XMLFile);
|
||||||
|
File.Move(XMLFile, Path.Combine(ProcessedDirectory, Path.GetFileName(XMLFile)));
|
||||||
|
if (DBFile != null)
|
||||||
|
{
|
||||||
|
File.Move(DBFile, Path.Combine(XMLDBProcessedDirectory, Path.GetFileName(DBFile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_signature_parser.models.RomSignatureObject;
|
using gaseous_signature_parser.models.RomSignatureObject;
|
||||||
|
using static gaseous_server.Classes.Common;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -10,7 +11,8 @@ namespace gaseous_server.Classes
|
|||||||
if (md5.Length > 0)
|
if (md5.Length > 0)
|
||||||
{
|
{
|
||||||
return _GetSignature("Signatures_Roms.md5 = @searchstring", md5);
|
return _GetSignature("Signatures_Roms.md5 = @searchstring", md5);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return _GetSignature("Signatures_Roms.sha1 = @searchstring", sha1);
|
return _GetSignature("Signatures_Roms.sha1 = @searchstring", sha1);
|
||||||
}
|
}
|
||||||
@@ -21,7 +23,8 @@ namespace gaseous_server.Classes
|
|||||||
if (TosecName.Length > 0)
|
if (TosecName.Length > 0)
|
||||||
{
|
{
|
||||||
return _GetSignature("Signatures_Roms.name = @searchstring", TosecName);
|
return _GetSignature("Signatures_Roms.name = @searchstring", TosecName);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -44,7 +47,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
Game = new gaseous_server.Models.Signatures_Games.GameItem
|
Game = new gaseous_server.Models.Signatures_Games.GameItem
|
||||||
{
|
{
|
||||||
Id = (Int32)sigDbRow["Id"],
|
Id = (long)(int)sigDbRow["Id"],
|
||||||
Name = (string)sigDbRow["Name"],
|
Name = (string)sigDbRow["Name"],
|
||||||
Description = (string)sigDbRow["Description"],
|
Description = (string)sigDbRow["Description"],
|
||||||
Year = (string)sigDbRow["Year"],
|
Year = (string)sigDbRow["Year"],
|
||||||
@@ -53,20 +56,20 @@ namespace gaseous_server.Classes
|
|||||||
System = (string)sigDbRow["Platform"],
|
System = (string)sigDbRow["Platform"],
|
||||||
SystemVariant = (string)sigDbRow["SystemVariant"],
|
SystemVariant = (string)sigDbRow["SystemVariant"],
|
||||||
Video = (string)sigDbRow["Video"],
|
Video = (string)sigDbRow["Video"],
|
||||||
Country = (string)sigDbRow["Country"],
|
Countries = new Dictionary<string, string>(GetLookup(LookupTypes.Country, (long)(int)sigDbRow["Id"])),
|
||||||
Language = (string)sigDbRow["Language"],
|
Languages = new Dictionary<string, string>(GetLookup(LookupTypes.Language, (long)(int)sigDbRow["Id"])),
|
||||||
Copyright = (string)sigDbRow["Copyright"]
|
Copyright = (string)sigDbRow["Copyright"]
|
||||||
},
|
},
|
||||||
Rom = new gaseous_server.Models.Signatures_Games.RomItem
|
Rom = new gaseous_server.Models.Signatures_Games.RomItem
|
||||||
{
|
{
|
||||||
Id = (Int32)sigDbRow["romid"],
|
Id = (long)(int)sigDbRow["romid"],
|
||||||
Name = (string)sigDbRow["romname"],
|
Name = (string)sigDbRow["romname"],
|
||||||
Size = (Int64)sigDbRow["Size"],
|
Size = (Int64)sigDbRow["Size"],
|
||||||
Crc = (string)sigDbRow["CRC"],
|
Crc = (string)sigDbRow["CRC"],
|
||||||
Md5 = ((string)sigDbRow["MD5"]).ToLower(),
|
Md5 = ((string)sigDbRow["MD5"]).ToLower(),
|
||||||
Sha1 = ((string)sigDbRow["SHA1"]).ToLower(),
|
Sha1 = ((string)sigDbRow["SHA1"]).ToLower(),
|
||||||
DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"],
|
DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"],
|
||||||
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<KeyValuePair<string, object>>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")),
|
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")),
|
||||||
RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"],
|
RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"],
|
||||||
RomTypeMedia = (string)sigDbRow["RomTypeMedia"],
|
RomTypeMedia = (string)sigDbRow["RomTypeMedia"],
|
||||||
MediaLabel = (string)sigDbRow["MediaLabel"],
|
MediaLabel = (string)sigDbRow["MediaLabel"],
|
||||||
@@ -77,5 +80,36 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
return GamesList;
|
return GamesList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dictionary<string, string> GetLookup(LookupTypes LookupType, long GameId)
|
||||||
|
{
|
||||||
|
string tableName = "";
|
||||||
|
switch (LookupType)
|
||||||
|
{
|
||||||
|
case LookupTypes.Country:
|
||||||
|
tableName = "Countries";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LookupTypes.Language:
|
||||||
|
tableName = "Languages";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT " + LookupType.ToString() + ".Code, " + LookupType.ToString() + ".Value FROM Signatures_Games_" + tableName + " JOIN " + LookupType.ToString() + " ON Signatures_Games_" + tableName + "." + LookupType.ToString() + "Id = " + LookupType.ToString() + ".Id WHERE Signatures_Games_" + tableName + ".GameId = @id;";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||||
|
{ "id", GameId }
|
||||||
|
};
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
Dictionary<string, string> returnDict = new Dictionary<string, string>();
|
||||||
|
foreach (DataRow row in data.Rows)
|
||||||
|
{
|
||||||
|
returnDict.Add((string)row["Code"], (string)row["Value"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnDict;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -70,7 +70,8 @@ namespace gaseous_server.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Version")]
|
[Route("Version")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public Version GetSystemVersion() {
|
public Version GetSystemVersion()
|
||||||
|
{
|
||||||
return Assembly.GetExecutingAssembly().GetName().Version;
|
return Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,18 +81,19 @@ namespace gaseous_server.Controllers
|
|||||||
[Route("VersionFile")]
|
[Route("VersionFile")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public FileContentResult GetSystemVersionAsFile() {
|
public FileContentResult GetSystemVersionAsFile()
|
||||||
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
// get age ratings dictionary
|
// get age ratings dictionary
|
||||||
Dictionary<int, string> ClassificationBoardsStrings = new Dictionary<int, string>();
|
Dictionary<int, string> ClassificationBoardsStrings = new Dictionary<int, string>();
|
||||||
foreach(IGDB.Models.AgeRatingCategory ageRatingCategory in Enum.GetValues(typeof(IGDB.Models.AgeRatingCategory)) )
|
foreach (IGDB.Models.AgeRatingCategory ageRatingCategory in Enum.GetValues(typeof(IGDB.Models.AgeRatingCategory)))
|
||||||
{
|
{
|
||||||
ClassificationBoardsStrings.Add((int)ageRatingCategory, ageRatingCategory.ToString());
|
ClassificationBoardsStrings.Add((int)ageRatingCategory, ageRatingCategory.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<int, string> AgeRatingsStrings = new Dictionary<int, string>();
|
Dictionary<int, string> AgeRatingsStrings = new Dictionary<int, string>();
|
||||||
foreach(IGDB.Models.AgeRatingTitle ageRatingTitle in Enum.GetValues(typeof(IGDB.Models.AgeRatingTitle)) )
|
foreach (IGDB.Models.AgeRatingTitle ageRatingTitle in Enum.GetValues(typeof(IGDB.Models.AgeRatingTitle)))
|
||||||
{
|
{
|
||||||
AgeRatingsStrings.Add((int)ageRatingTitle, ageRatingTitle.ToString());
|
AgeRatingsStrings.Add((int)ageRatingTitle, ageRatingTitle.ToString());
|
||||||
}
|
}
|
||||||
@@ -99,13 +101,16 @@ namespace gaseous_server.Controllers
|
|||||||
string ver = "var AppVersion = \"" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\";" + Environment.NewLine +
|
string ver = "var AppVersion = \"" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\";" + Environment.NewLine +
|
||||||
"var DBSchemaVersion = \"" + db.GetDatabaseSchemaVersion() + "\";" + Environment.NewLine +
|
"var DBSchemaVersion = \"" + db.GetDatabaseSchemaVersion() + "\";" + Environment.NewLine +
|
||||||
"var FirstRunStatus = " + Config.ReadSetting<string>("FirstRunStatus", "0") + ";" + Environment.NewLine +
|
"var FirstRunStatus = " + Config.ReadSetting<string>("FirstRunStatus", "0") + ";" + Environment.NewLine +
|
||||||
"var AgeRatingBoardsStrings = " + JsonSerializer.Serialize(ClassificationBoardsStrings, new JsonSerializerOptions{
|
"var AgeRatingBoardsStrings = " + JsonSerializer.Serialize(ClassificationBoardsStrings, new JsonSerializerOptions
|
||||||
|
{
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
}) + ";" + Environment.NewLine +
|
}) + ";" + Environment.NewLine +
|
||||||
"var AgeRatingStrings = " + JsonSerializer.Serialize(AgeRatingsStrings, new JsonSerializerOptions{
|
"var AgeRatingStrings = " + JsonSerializer.Serialize(AgeRatingsStrings, new JsonSerializerOptions
|
||||||
|
{
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
}) + ";" + Environment.NewLine +
|
}) + ";" + Environment.NewLine +
|
||||||
"var AgeRatingGroups = " + JsonSerializer.Serialize(AgeGroups.AgeGroupingsFlat, new JsonSerializerOptions{
|
"var AgeRatingGroups = " + JsonSerializer.Serialize(AgeGroups.AgeGroupingsFlat, new JsonSerializerOptions
|
||||||
|
{
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
}) + ";" + Environment.NewLine +
|
}) + ";" + Environment.NewLine +
|
||||||
"var emulatorDebugMode = " + Config.ReadSetting<string>("emulatorDebugMode", false.ToString()).ToLower() + ";";
|
"var emulatorDebugMode = " + Config.ReadSetting<string>("emulatorDebugMode", false.ToString()).ToLower() + ";";
|
||||||
@@ -159,7 +164,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
// update task enabled
|
// update task enabled
|
||||||
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with enabled value " + TaskConfiguration.Enabled.ToString());
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with enabled value " + TaskConfiguration.Enabled.ToString());
|
||||||
|
|
||||||
Config.SetSetting<string>("Enabled_" + TaskConfiguration.Task, TaskConfiguration.Enabled.ToString());
|
Config.SetSetting<string>("Enabled_" + TaskConfiguration.Task, TaskConfiguration.Enabled.ToString());
|
||||||
|
|
||||||
// update existing process
|
// update existing process
|
||||||
@@ -170,12 +175,12 @@ namespace gaseous_server.Controllers
|
|||||||
item.Enabled(Boolean.Parse(TaskConfiguration.Enabled.ToString()));
|
item.Enabled(Boolean.Parse(TaskConfiguration.Enabled.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update task interval
|
// update task interval
|
||||||
if (TaskConfiguration.Interval >= taskItem.MinimumAllowedInterval)
|
if (TaskConfiguration.Interval >= taskItem.MinimumAllowedInterval)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new interval " + TaskConfiguration.Interval);
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new interval " + TaskConfiguration.Interval);
|
||||||
|
|
||||||
Config.SetSetting<string>("Interval_" + TaskConfiguration.Task, TaskConfiguration.Interval.ToString());
|
Config.SetSetting<string>("Interval_" + TaskConfiguration.Task, TaskConfiguration.Interval.ToString());
|
||||||
|
|
||||||
// update existing process
|
// update existing process
|
||||||
@@ -194,7 +199,7 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
// update task weekdays
|
// update task weekdays
|
||||||
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new weekdays " + String.Join(", ", TaskConfiguration.AllowedDays));
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new weekdays " + String.Join(", ", TaskConfiguration.AllowedDays));
|
||||||
|
|
||||||
Config.SetSetting<string>("AllowedDays_" + TaskConfiguration.Task, Newtonsoft.Json.JsonConvert.SerializeObject(TaskConfiguration.AllowedDays));
|
Config.SetSetting<string>("AllowedDays_" + TaskConfiguration.Task, Newtonsoft.Json.JsonConvert.SerializeObject(TaskConfiguration.AllowedDays));
|
||||||
|
|
||||||
// update existing process
|
// update existing process
|
||||||
@@ -208,7 +213,7 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
// update task hours
|
// update task hours
|
||||||
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new hours " + TaskConfiguration.AllowedStartHours + ":" + TaskConfiguration.AllowedStartMinutes.ToString("00") + " to " + TaskConfiguration.AllowedEndHours + ":" + TaskConfiguration.AllowedEndMinutes.ToString("00"));
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new hours " + TaskConfiguration.AllowedStartHours + ":" + TaskConfiguration.AllowedStartMinutes.ToString("00") + " to " + TaskConfiguration.AllowedEndHours + ":" + TaskConfiguration.AllowedEndMinutes.ToString("00"));
|
||||||
|
|
||||||
Config.SetSetting<string>("AllowedStartHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartHours.ToString());
|
Config.SetSetting<string>("AllowedStartHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartHours.ToString());
|
||||||
Config.SetSetting<string>("AllowedStartMinutes_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartMinutes.ToString());
|
Config.SetSetting<string>("AllowedStartMinutes_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartMinutes.ToString());
|
||||||
Config.SetSetting<string>("AllowedEndHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedEndHours.ToString());
|
Config.SetSetting<string>("AllowedEndHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedEndHours.ToString());
|
||||||
@@ -225,7 +230,7 @@ namespace gaseous_server.Controllers
|
|||||||
item.AllowedEndMinutes = TaskConfiguration.AllowedEndMinutes;
|
item.AllowedEndMinutes = TaskConfiguration.AllowedEndMinutes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -251,10 +256,18 @@ namespace gaseous_server.Controllers
|
|||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult GetSystemSettings()
|
public ActionResult GetSystemSettings()
|
||||||
{
|
{
|
||||||
SystemSettingsModel systemSettingsModel = new SystemSettingsModel{
|
SystemSettingsModel systemSettingsModel = new SystemSettingsModel
|
||||||
|
{
|
||||||
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
||||||
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention,
|
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention,
|
||||||
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString()))
|
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString())),
|
||||||
|
SignatureSource = new SystemSettingsModel.SignatureSourceItem()
|
||||||
|
{
|
||||||
|
Source = Config.MetadataConfiguration.SignatureSource,
|
||||||
|
HasheousHost = Config.MetadataConfiguration.HasheousHost,
|
||||||
|
HasheousSubmitFixes = (bool)Config.MetadataConfiguration.HasheousSubmitFixes,
|
||||||
|
HasheousAPIKey = Config.MetadataConfiguration.HasheousAPIKey
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(systemSettingsModel);
|
return Ok(systemSettingsModel);
|
||||||
@@ -273,6 +286,10 @@ namespace gaseous_server.Controllers
|
|||||||
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
||||||
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
||||||
Config.SetSetting<string>("emulatorDebugMode", model.EmulatorDebugMode.ToString());
|
Config.SetSetting<string>("emulatorDebugMode", model.EmulatorDebugMode.ToString());
|
||||||
|
Config.MetadataConfiguration.SignatureSource = model.SignatureSource.Source;
|
||||||
|
Config.MetadataConfiguration.HasheousHost = model.SignatureSource.HasheousHost;
|
||||||
|
Config.MetadataConfiguration.HasheousAPIKey = model.SignatureSource.HasheousAPIKey;
|
||||||
|
Config.MetadataConfiguration.HasheousSubmitFixes = model.SignatureSource.HasheousSubmitFixes;
|
||||||
Config.UpdateConfig();
|
Config.UpdateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +298,8 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
private SystemInfo.PathItem GetDisk(string Path)
|
private SystemInfo.PathItem GetDisk(string Path)
|
||||||
{
|
{
|
||||||
SystemInfo.PathItem pathItem = new SystemInfo.PathItem {
|
SystemInfo.PathItem pathItem = new SystemInfo.PathItem
|
||||||
|
{
|
||||||
LibraryPath = Path,
|
LibraryPath = Path,
|
||||||
SpaceUsed = Common.DirSize(new DirectoryInfo(Path)),
|
SpaceUsed = Common.DirSize(new DirectoryInfo(Path)),
|
||||||
SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace,
|
SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace,
|
||||||
@@ -293,11 +311,12 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
public class SystemInfo
|
public class SystemInfo
|
||||||
{
|
{
|
||||||
public Version ApplicationVersion {
|
public Version ApplicationVersion
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Assembly.GetExecutingAssembly().GetName().Version;
|
return Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public List<PathItem>? Paths { get; set; }
|
public List<PathItem>? Paths { get; set; }
|
||||||
public long DatabaseSize { get; set; }
|
public long DatabaseSize { get; set; }
|
||||||
@@ -352,7 +371,7 @@ namespace gaseous_server.Controllers
|
|||||||
this.DefaultAllowedEndHours = 23;
|
this.DefaultAllowedEndHours = 23;
|
||||||
this.DefaultAllowedEndMinutes = 59;
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.TitleIngestor:
|
case ProcessQueue.QueueItemType.TitleIngestor:
|
||||||
this._UserManageable = true;
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 1;
|
this.DefaultInterval = 1;
|
||||||
@@ -589,7 +608,8 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
private bool _UserManageable;
|
private bool _UserManageable;
|
||||||
public bool UserManageable => _UserManageable;
|
public bool UserManageable => _UserManageable;
|
||||||
public int Interval {
|
public int Interval
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return int.Parse(Config.ReadSetting<string>("Interval_" + Task, DefaultInterval.ToString()));
|
return int.Parse(Config.ReadSetting<string>("Interval_" + Task, DefaultInterval.ToString()));
|
||||||
@@ -642,7 +662,7 @@ namespace gaseous_server.Controllers
|
|||||||
public List<ProcessQueue.QueueItemType> Blocks
|
public List<ProcessQueue.QueueItemType> Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_Blocks.Contains(ProcessQueue.QueueItemType.All))
|
if (_Blocks.Contains(ProcessQueue.QueueItemType.All))
|
||||||
{
|
{
|
||||||
List<ProcessQueue.QueueItemType> blockList = new List<ProcessQueue.QueueItemType>();
|
List<ProcessQueue.QueueItemType> blockList = new List<ProcessQueue.QueueItemType>();
|
||||||
@@ -710,5 +730,14 @@ namespace gaseous_server.Controllers
|
|||||||
public bool AlwaysLogToDisk { get; set; }
|
public bool AlwaysLogToDisk { get; set; }
|
||||||
public int MinimumLogRetentionPeriod { get; set; }
|
public int MinimumLogRetentionPeriod { get; set; }
|
||||||
public bool EmulatorDebugMode { get; set; }
|
public bool EmulatorDebugMode { get; set; }
|
||||||
|
public SignatureSourceItem SignatureSource { get; set; }
|
||||||
|
|
||||||
|
public class SignatureSourceItem
|
||||||
|
{
|
||||||
|
public HasheousClient.Models.MetadataModel.SignatureSources Source { get; set; }
|
||||||
|
public string HasheousHost { get; set; }
|
||||||
|
public string HasheousAPIKey { get; set; }
|
||||||
|
public bool HasheousSubmitFixes { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -4,12 +4,36 @@ using gaseous_signature_parser.models.RomSignatureObject;
|
|||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
{
|
{
|
||||||
public class Signatures_Games : HasheousClient.Models.LookupResponseModel
|
public class Signatures_Games : HasheousClient.Models.SignatureModel
|
||||||
{
|
{
|
||||||
public Signatures_Games()
|
public Signatures_Games()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public int Score
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int _score = 0;
|
||||||
|
|
||||||
|
if (Game != null)
|
||||||
|
{
|
||||||
|
_score = _score + Game.Score;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Rom != null)
|
||||||
|
{
|
||||||
|
_score = _score + Rom.Score;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameItem Game = new GameItem();
|
||||||
|
public RomItem Rom = new RomItem();
|
||||||
|
|
||||||
public SignatureFlags Flags = new SignatureFlags();
|
public SignatureFlags Flags = new SignatureFlags();
|
||||||
|
|
||||||
public class SignatureFlags
|
public class SignatureFlags
|
||||||
@@ -18,6 +42,213 @@ namespace gaseous_server.Models
|
|||||||
public string IGDBPlatformName { get; set; }
|
public string IGDBPlatformName { get; set; }
|
||||||
public long IGDBGameId { get; set; }
|
public long IGDBGameId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GameItem : HasheousClient.Models.SignatureModel.GameItem
|
||||||
|
{
|
||||||
|
public GameItem()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public int Score
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// calculate a score based on the availablility of data
|
||||||
|
int _score = 0;
|
||||||
|
var properties = this.GetType().GetProperties();
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
if (prop.GetGetMethod() != null)
|
||||||
|
{
|
||||||
|
switch (prop.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "id":
|
||||||
|
case "score":
|
||||||
|
break;
|
||||||
|
case "name":
|
||||||
|
case "year":
|
||||||
|
case "publisher":
|
||||||
|
case "system":
|
||||||
|
if (prop.PropertyType == typeof(string))
|
||||||
|
{
|
||||||
|
if (prop.GetValue(this) != null)
|
||||||
|
{
|
||||||
|
string propVal = prop.GetValue(this).ToString();
|
||||||
|
if (propVal.Length > 0)
|
||||||
|
{
|
||||||
|
_score = _score + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (prop.PropertyType == typeof(string))
|
||||||
|
{
|
||||||
|
if (prop.GetValue(this) != null)
|
||||||
|
{
|
||||||
|
string propVal = prop.GetValue(this).ToString();
|
||||||
|
if (propVal.Length > 0)
|
||||||
|
{
|
||||||
|
_score = _score + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RomItem : HasheousClient.Models.SignatureModel.RomItem
|
||||||
|
{
|
||||||
|
[JsonIgnore]
|
||||||
|
public int Score
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// calculate a score based on the availablility of data
|
||||||
|
int _score = 0;
|
||||||
|
var properties = this.GetType().GetProperties();
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
if (prop.GetGetMethod() != null)
|
||||||
|
{
|
||||||
|
switch (prop.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "name":
|
||||||
|
case "size":
|
||||||
|
case "crc":
|
||||||
|
case "developmentstatus":
|
||||||
|
case "flags":
|
||||||
|
case "attributes":
|
||||||
|
case "romtypemedia":
|
||||||
|
case "medialabel":
|
||||||
|
if (prop.PropertyType == typeof(string) || prop.PropertyType == typeof(Int64) || prop.PropertyType == typeof(List<string>))
|
||||||
|
{
|
||||||
|
if (prop.GetValue(this) != null)
|
||||||
|
{
|
||||||
|
string propVal = prop.GetValue(this).ToString();
|
||||||
|
if (propVal.Length > 0)
|
||||||
|
{
|
||||||
|
_score = _score + 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (prop.PropertyType == typeof(string))
|
||||||
|
{
|
||||||
|
if (prop.GetValue(this) != null)
|
||||||
|
{
|
||||||
|
string propVal = prop.GetValue(this).ToString();
|
||||||
|
if (propVal.Length > 0)
|
||||||
|
{
|
||||||
|
_score = _score + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MediaType
|
||||||
|
{
|
||||||
|
public MediaType(SignatureSourceType Source, string MediaTypeString)
|
||||||
|
{
|
||||||
|
switch (Source)
|
||||||
|
{
|
||||||
|
case RomItem.SignatureSourceType.TOSEC:
|
||||||
|
string[] typeString = MediaTypeString.Split(" ");
|
||||||
|
|
||||||
|
string inType = "";
|
||||||
|
foreach (string typeStringVal in typeString)
|
||||||
|
{
|
||||||
|
if (inType == "")
|
||||||
|
{
|
||||||
|
switch (typeStringVal.ToLower())
|
||||||
|
{
|
||||||
|
case "disk":
|
||||||
|
Media = RomItem.RomTypes.Disk;
|
||||||
|
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "disc":
|
||||||
|
Media = RomItem.RomTypes.Disc;
|
||||||
|
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "file":
|
||||||
|
Media = RomItem.RomTypes.File;
|
||||||
|
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "part":
|
||||||
|
Media = RomItem.RomTypes.Part;
|
||||||
|
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "tape":
|
||||||
|
Media = RomItem.RomTypes.Tape;
|
||||||
|
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "of":
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
case "side":
|
||||||
|
inType = typeStringVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (inType.ToLower())
|
||||||
|
{
|
||||||
|
case "disk":
|
||||||
|
case "disc":
|
||||||
|
case "file":
|
||||||
|
case "part":
|
||||||
|
case "tape":
|
||||||
|
Number = int.Parse(typeStringVal);
|
||||||
|
break;
|
||||||
|
case "of":
|
||||||
|
Count = int.Parse(typeStringVal);
|
||||||
|
break;
|
||||||
|
case "side":
|
||||||
|
Side = typeStringVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inType = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RomItem.RomTypes? Media { get; set; }
|
||||||
|
|
||||||
|
public int? Number { get; set; }
|
||||||
|
|
||||||
|
public int? Count { get; set; }
|
||||||
|
|
||||||
|
public string? Side { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -245,15 +245,33 @@ namespace gaseous_server
|
|||||||
CallingQueueItem = this
|
CallingQueueItem = this
|
||||||
};
|
};
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing TOSEC files");
|
foreach (int i in Enum.GetValues(typeof(gaseous_signature_parser.parser.SignatureParser)))
|
||||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "TOSEC"), gaseous_signature_parser.parser.SignatureParser.TOSEC);
|
{
|
||||||
|
gaseous_signature_parser.parser.SignatureParser parserType = (gaseous_signature_parser.parser.SignatureParser)i;
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing MAME Arcade files");
|
if (
|
||||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "MAME Arcade"), gaseous_signature_parser.parser.SignatureParser.MAMEArcade);
|
parserType != gaseous_signature_parser.parser.SignatureParser.Auto &&
|
||||||
|
parserType != gaseous_signature_parser.parser.SignatureParser.Unknown
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing " + parserType + " files");
|
||||||
|
|
||||||
|
string SignaturePath = Path.Combine(Config.LibraryConfiguration.LibrarySignaturesDirectory, parserType.ToString());
|
||||||
|
string SignatureProcessedPath = Path.Combine(Config.LibraryConfiguration.LibrarySignaturesProcessedDirectory, parserType.ToString());
|
||||||
|
|
||||||
|
if (!Directory.Exists(SignaturePath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(SignaturePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Directory.Exists(SignatureProcessedPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(SignatureProcessedPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
tIngest.Import(SignaturePath, SignatureProcessedPath, parserType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing MAME MESS files");
|
|
||||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "MAME MESS"), gaseous_signature_parser.parser.SignatureParser.MAMEMess);
|
|
||||||
|
|
||||||
_SaveLastRunTime = true;
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@@ -64,6 +64,7 @@ if (Directory.Exists(Config.LibraryConfiguration.LibraryUploadDirectory))
|
|||||||
// kick off any delayed upgrade tasks
|
// kick off any delayed upgrade tasks
|
||||||
// run 1002 background updates in the background on every start
|
// run 1002 background updates in the background on every start
|
||||||
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
||||||
|
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1022);
|
||||||
// start the task
|
// start the task
|
||||||
ProcessQueue.QueueItem queueItem = new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItem queueItem = new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade,
|
ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade,
|
||||||
@@ -273,7 +274,7 @@ using (var scope = app.Services.CreateScope())
|
|||||||
{
|
{
|
||||||
var roleManager = scope.ServiceProvider.GetRequiredService<RoleStore>();
|
var roleManager = scope.ServiceProvider.GetRequiredService<RoleStore>();
|
||||||
var roles = new[] { "Admin", "Gamer", "Player" };
|
var roles = new[] { "Admin", "Gamer", "Player" };
|
||||||
|
|
||||||
foreach (var role in roles)
|
foreach (var role in roles)
|
||||||
{
|
{
|
||||||
if (await roleManager.FindByNameAsync(role, CancellationToken.None) == null)
|
if (await roleManager.FindByNameAsync(role, CancellationToken.None) == null)
|
||||||
@@ -303,11 +304,11 @@ app.Use(async (context, next) =>
|
|||||||
string correlationId = Guid.NewGuid().ToString();
|
string correlationId = Guid.NewGuid().ToString();
|
||||||
CallContext.SetData("CorrelationId", correlationId);
|
CallContext.SetData("CorrelationId", correlationId);
|
||||||
CallContext.SetData("CallingProcess", context.Request.Method + ": " + context.Request.Path);
|
CallContext.SetData("CallingProcess", context.Request.Method + ": " + context.Request.Path);
|
||||||
|
|
||||||
string userIdentity;
|
string userIdentity;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
userIdentity = context.User.Claims.Where(x=>x.Type==System.Security.Claims.ClaimTypes.NameIdentifier).FirstOrDefault().Value;
|
userIdentity = context.User.Claims.Where(x => x.Type == System.Security.Claims.ClaimTypes.NameIdentifier).FirstOrDefault().Value;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -329,7 +330,7 @@ app.Use(async (context, next) =>
|
|||||||
// - the server will not start while the RecoverAccount.txt file exists
|
// - the server will not start while the RecoverAccount.txt file exists
|
||||||
string PasswordRecoveryFile = Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "RecoverAccount.txt");
|
string PasswordRecoveryFile = Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "RecoverAccount.txt");
|
||||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("recoveraccount")))
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("recoveraccount")))
|
||||||
{
|
{
|
||||||
if (File.Exists(PasswordRecoveryFile))
|
if (File.Exists(PasswordRecoveryFile))
|
||||||
{
|
{
|
||||||
// password has already been set - do nothing and just exit
|
// password has already been set - do nothing and just exit
|
||||||
@@ -345,7 +346,7 @@ if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("recoveraccount")))
|
|||||||
string password = new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
string password = new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
||||||
|
|
||||||
File.WriteAllText(PasswordRecoveryFile, password);
|
File.WriteAllText(PasswordRecoveryFile, password);
|
||||||
|
|
||||||
// reset the password
|
// reset the password
|
||||||
using (var scope = app.Services.CreateScope())
|
using (var scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
|
73
gaseous-server/Support/Country.txt
Normal file
73
gaseous-server/Support/Country.txt
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
AE|United Arab Emirates
|
||||||
|
AL|Albania
|
||||||
|
AS|Asia
|
||||||
|
AT|Austria
|
||||||
|
AU|Australia
|
||||||
|
BA|Bosnia and Herzegovina
|
||||||
|
BE|Belgium
|
||||||
|
BG|Bulgaria
|
||||||
|
BR|Brazil
|
||||||
|
CA|Canada
|
||||||
|
CH|Switzerland
|
||||||
|
CL|Chile
|
||||||
|
CN|China
|
||||||
|
CS|Serbia and Montenegro
|
||||||
|
CY|Cyprus
|
||||||
|
CZ|Czech Republic
|
||||||
|
DE|Germany
|
||||||
|
DK|Denmark
|
||||||
|
EE|Estonia
|
||||||
|
EG|Egypt
|
||||||
|
ES|Spain
|
||||||
|
EU|Europe
|
||||||
|
FI|Finland
|
||||||
|
FR|France
|
||||||
|
GB|United Kingdom
|
||||||
|
GR|Greece
|
||||||
|
HK|Hong Kong
|
||||||
|
HR|Croatia
|
||||||
|
HU|Hungary
|
||||||
|
ID|Indonesia
|
||||||
|
IE|Ireland
|
||||||
|
IL|Israel
|
||||||
|
IN|India
|
||||||
|
IR|Iran
|
||||||
|
IS|Iceland
|
||||||
|
IT|Italy
|
||||||
|
JO|Jordan
|
||||||
|
JP|Japan
|
||||||
|
KR|Korea
|
||||||
|
KR|South Korea
|
||||||
|
LT|Lithuania
|
||||||
|
LU|Luxembourg
|
||||||
|
LV|Latvia
|
||||||
|
MN|Mongolia
|
||||||
|
MX|Mexico
|
||||||
|
MY|Malaysia
|
||||||
|
NL|Netherlands
|
||||||
|
NO|Norway
|
||||||
|
NP|Nepal
|
||||||
|
NZ|New Zealand
|
||||||
|
OM|Oman
|
||||||
|
PE|Peru
|
||||||
|
PH|Philippines
|
||||||
|
PL|Poland
|
||||||
|
PT|Portugal
|
||||||
|
QA|Qatar
|
||||||
|
RO|Romania
|
||||||
|
RU|Russia
|
||||||
|
SE|Sweden
|
||||||
|
SG|Singapore
|
||||||
|
SI|Slovenia
|
||||||
|
SK|Slovakia
|
||||||
|
TH|Thailand
|
||||||
|
TR|Turkey
|
||||||
|
TW|Taiwan
|
||||||
|
US|United States
|
||||||
|
USA|United States
|
||||||
|
VN|Vietnam
|
||||||
|
YU|Yugoslavia
|
||||||
|
ZA|South Africa
|
||||||
|
World|World
|
||||||
|
Europe|Europe
|
||||||
|
Asia|Asia
|
40
gaseous-server/Support/Database/MySQL/gaseous-1022.sql
Normal file
40
gaseous-server/Support/Database/MySQL/gaseous-1022.sql
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
CREATE TABLE `Signatures_RomToSource` (
|
||||||
|
`SourceId` int NOT NULL,
|
||||||
|
`RomId` int NOT NULL,
|
||||||
|
PRIMARY KEY (`SourceId`, `RomId`)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Signatures_Games_Countries` (
|
||||||
|
`GameId` INT NOT NULL,
|
||||||
|
`CountryId` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`GameId`, `CountryId`),
|
||||||
|
CONSTRAINT `GameCountry` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Signatures_Games_Languages` (
|
||||||
|
`GameId` INT NOT NULL,
|
||||||
|
`LanguageId` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`GameId`, `LanguageId`),
|
||||||
|
CONSTRAINT `GameLanguage` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Country` (
|
||||||
|
`Id` INT NOT NULL AUTO_INCREMENT,
|
||||||
|
`Code` VARCHAR(20) NULL,
|
||||||
|
`Value` VARCHAR(255) NULL,
|
||||||
|
PRIMARY KEY (`Id`),
|
||||||
|
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
||||||
|
INDEX `id_Value` (`Value` ASC) VISIBLE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Language` (
|
||||||
|
`Id` INT NOT NULL AUTO_INCREMENT,
|
||||||
|
`Code` VARCHAR(20) NULL,
|
||||||
|
`Value` VARCHAR(255) NULL,
|
||||||
|
PRIMARY KEY (`Id`),
|
||||||
|
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
||||||
|
INDEX `id_Value` (`Value` ASC) VISIBLE
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE `Games_Roms`
|
||||||
|
ADD COLUMN `RomDataVersion` INT DEFAULT 1;
|
47
gaseous-server/Support/Language.txt
Normal file
47
gaseous-server/Support/Language.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
ar|Arabic
|
||||||
|
bg|Bulgarian
|
||||||
|
bs|Bosnian
|
||||||
|
cs|Czech
|
||||||
|
cy|Welsh
|
||||||
|
da|Danish
|
||||||
|
de|German
|
||||||
|
el|Greek
|
||||||
|
en|English
|
||||||
|
eo|Esperanto
|
||||||
|
es|Spanish
|
||||||
|
et|Estonian
|
||||||
|
fa|Persian
|
||||||
|
fi|Finnish
|
||||||
|
fr|French
|
||||||
|
fr-ca|French Canadian
|
||||||
|
ga|Irish
|
||||||
|
gd|Gaelic
|
||||||
|
gu|Gujarati
|
||||||
|
he|Hebrew
|
||||||
|
hi|Hindi
|
||||||
|
hr|Croatian
|
||||||
|
hu|Hungarian
|
||||||
|
is|Icelandic
|
||||||
|
it|Italian
|
||||||
|
ja|Japanese
|
||||||
|
ko|Korean
|
||||||
|
lt|Lithuanian
|
||||||
|
lv|Latvian
|
||||||
|
ms|Malay
|
||||||
|
nl|Dutch
|
||||||
|
no|Norwegian
|
||||||
|
pl|Polish
|
||||||
|
pt|Portuguese
|
||||||
|
ro|Romanian
|
||||||
|
ru|Russian
|
||||||
|
sk|Slovakian
|
||||||
|
sl|Slovenian
|
||||||
|
sq|Albanian
|
||||||
|
sr|Serbian
|
||||||
|
sv|Swedish
|
||||||
|
th|Thai
|
||||||
|
tr|Turkish
|
||||||
|
ur|Urdu
|
||||||
|
vi|Vietnamese
|
||||||
|
yi|Yiddish
|
||||||
|
zh|Chinese
|
@@ -16,20 +16,20 @@
|
|||||||
<DocumentationFile>bin\Release\net8.0\gaseous-server.xml</DocumentationFile>
|
<DocumentationFile>bin\Release\net8.0\gaseous-server.xml</DocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.0.0" />
|
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
||||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.0.0" />
|
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||||
<PackageReference Include="gaseous-signature-parser" Version="2.1.0" />
|
<PackageReference Include="gaseous-signature-parser" Version="2.2.1" />
|
||||||
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
||||||
<PackageReference Include="hasheous-client" Version="0.2.0" />
|
<PackageReference Include="hasheous-client" Version="1.0.2" />
|
||||||
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.5.0" />
|
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.7.0" />
|
||||||
<PackageReference Include="sharpcompress" Version="0.36.0" />
|
<PackageReference Include="sharpcompress" Version="0.37.2" />
|
||||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.1.23" />
|
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.1" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.4" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.0" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -39,6 +39,8 @@
|
|||||||
<None Remove="Classes\" />
|
<None Remove="Classes\" />
|
||||||
<None Remove="Classes\SignatureIngestors\" />
|
<None Remove="Classes\SignatureIngestors\" />
|
||||||
<None Remove="Support\" />
|
<None Remove="Support\" />
|
||||||
|
<None Remove="Support\Country.txt" />
|
||||||
|
<None Remove="Support\Language.txt" />
|
||||||
<None Remove="Support\Database\" />
|
<None Remove="Support\Database\" />
|
||||||
<None Remove="Support\Database\MySQL\" />
|
<None Remove="Support\Database\MySQL\" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1000.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1000.sql" />
|
||||||
@@ -64,6 +66,7 @@
|
|||||||
<None Remove="Support\Database\MySQL\gaseous-1019.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1019.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1020.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1020.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1021.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1021.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1022.sql" />
|
||||||
<None Remove="Classes\Metadata\" />
|
<None Remove="Classes\Metadata\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -85,6 +88,8 @@
|
|||||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Support\Country.txt" />
|
||||||
|
<EmbeddedResource Include="Support\Language.txt" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1000.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1000.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1001.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1001.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1002.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1002.sql" />
|
||||||
@@ -108,5 +113,6 @@
|
|||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1019.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1019.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1020.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1020.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1021.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1021.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1022.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@@ -39,7 +39,7 @@
|
|||||||
},
|
},
|
||||||
processResults: function (data) {
|
processResults: function (data) {
|
||||||
var arr = [];
|
var arr = [];
|
||||||
|
|
||||||
arr.push({
|
arr.push({
|
||||||
id: 0,
|
id: 0,
|
||||||
text: 'Any'
|
text: 'Any'
|
||||||
@@ -74,11 +74,11 @@
|
|||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/Library?Name=' + encodeURIComponent(libName) + '&DefaultPlatformId=' + libPlatform[0].id + '&Path=' + encodeURIComponent(libPath),
|
'/api/v1.1/Library?Name=' + encodeURIComponent(libName) + '&DefaultPlatformId=' + libPlatform[0].id + '&Path=' + encodeURIComponent(libPath),
|
||||||
'POST',
|
'POST',
|
||||||
function(result) {
|
function (result) {
|
||||||
drawLibrary();
|
drawLibrary();
|
||||||
closeSubDialog();
|
closeDialog();
|
||||||
},
|
},
|
||||||
function(error) {
|
function (error) {
|
||||||
alert('An error occurred while creating the library:\n\n' + JSON.stringify(error.responseText));
|
alert('An error occurred while creating the library:\n\n' + JSON.stringify(error.responseText));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
<div id="properties_toc">
|
<div id="properties_toc">
|
||||||
<div id="properties_toc_general" name="properties_toc_item" onclick="SelectTab('general');">General</div>
|
<div id="properties_toc_general" name="properties_toc_item" onclick="SelectTab('general');">General</div>
|
||||||
<div id="properties_toc_archive" name="properties_toc_item" onclick="SelectTab('archive');" style="display: none;">Archive Contents</div>
|
<div id="properties_toc_archive" name="properties_toc_item" onclick="SelectTab('archive');" style="display: none;">
|
||||||
<div id="properties_toc_attributes" name="properties_toc_item" onclick="SelectTab('attributes');" style="display: none;">Attributes</div>
|
Archive Contents</div>
|
||||||
|
<div id="properties_toc_attributes" name="properties_toc_item" onclick="SelectTab('attributes');"
|
||||||
|
style="display: none;">Attributes</div>
|
||||||
<div id="properties_toc_match" name="properties_toc_item" onclick="SelectTab('match');">Title Match</div>
|
<div id="properties_toc_match" name="properties_toc_item" onclick="SelectTab('match');">Title Match</div>
|
||||||
<!--<div id="properties_toc_manage" name="properties_toc_item" onclick="SelectTab('manage');">Manage</div>-->
|
<!--<div id="properties_toc_manage" name="properties_toc_item" onclick="SelectTab('manage');">Manage</div>-->
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="properties_bodypanel_attributes" name="properties_tab" style="display: none;">
|
<div id="properties_bodypanel_attributes" name="properties_tab" style="display: none;">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="properties_bodypanel_match" name="properties_tab" style="display: none;">
|
<div id="properties_bodypanel_match" name="properties_tab" style="display: none;">
|
||||||
@@ -78,7 +80,9 @@
|
|||||||
<td style="width: 75%;"><select id="properties_fixgame" style="width: 100%;"></select></td>
|
<td style="width: 75%;"><select id="properties_fixgame" style="width: 100%;"></select></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="text-align: right;"><button id="properties_fixclear" value="Clear Match" onclick="ClearFixedGame();">Clear Match</button><button id="properties_fixsave" value="Save Match" onclick="SaveFixedGame();">Save Match</button></td>
|
<td colspan="2" style="text-align: right;"><button id="properties_fixclear" value="Clear Match"
|
||||||
|
onclick="ClearFixedGame();">Clear Match</button><button id="properties_fixsave"
|
||||||
|
value="Save Match" onclick="SaveFixedGame();">Save Match</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -144,7 +148,7 @@
|
|||||||
document.getElementById('romDelete').style.display = 'none';
|
document.getElementById('romDelete').style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.attributes.length > 0) {
|
if (result.attributes) {
|
||||||
document.getElementById('properties_bodypanel_attributes').appendChild(BuildAttributesTable(result.attributes, result.source));
|
document.getElementById('properties_bodypanel_attributes').appendChild(BuildAttributesTable(result.attributes, result.source));
|
||||||
document.getElementById('properties_bodypanel_archive_content').appendChild(BuildArchiveTable(result.attributes, result.source));
|
document.getElementById('properties_bodypanel_archive_content').appendChild(BuildArchiveTable(result.attributes, result.source));
|
||||||
}
|
}
|
||||||
@@ -276,8 +280,8 @@
|
|||||||
var aTable = document.createElement('table');
|
var aTable = document.createElement('table');
|
||||||
aTable.style.width = '100%';
|
aTable.style.width = '100%';
|
||||||
|
|
||||||
for (var i = 0; i < attributes.length; i++) {
|
for (const [key, value] of Object.entries(attributes)) {
|
||||||
if (attributes[i].key != "ZipContents") {
|
if (key != "ZipContents") {
|
||||||
// show attributes button
|
// show attributes button
|
||||||
document.getElementById('properties_toc_attributes').style.display = '';
|
document.getElementById('properties_toc_attributes').style.display = '';
|
||||||
var aRow = document.createElement('tr');
|
var aRow = document.createElement('tr');
|
||||||
@@ -285,15 +289,15 @@
|
|||||||
var aTitleCell = document.createElement('th');
|
var aTitleCell = document.createElement('th');
|
||||||
aTitleCell.width = "25%";
|
aTitleCell.width = "25%";
|
||||||
if (sourceName == "TOSEC") {
|
if (sourceName == "TOSEC") {
|
||||||
aTitleCell.innerHTML = ConvertTOSECAttributeName(attributes[i].key);
|
aTitleCell.innerHTML = ConvertTOSECAttributeName(key);
|
||||||
} else {
|
} else {
|
||||||
aTitleCell.innerHTML = attributes[i].key;
|
aTitleCell.innerHTML = key;
|
||||||
}
|
}
|
||||||
aRow.appendChild(aTitleCell);
|
aRow.appendChild(aTitleCell);
|
||||||
|
|
||||||
var aValueCell = document.createElement('td');
|
var aValueCell = document.createElement('td');
|
||||||
aValueCell.width = "75%";
|
aValueCell.width = "75%";
|
||||||
aValueCell.innerHTML = attributes[i].value;
|
aValueCell.innerHTML = value;
|
||||||
aRow.appendChild(aValueCell);
|
aRow.appendChild(aValueCell);
|
||||||
|
|
||||||
aTable.appendChild(aRow);
|
aTable.appendChild(aRow);
|
||||||
@@ -304,13 +308,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function BuildArchiveTable(attributes, sourceName) {
|
function BuildArchiveTable(attributes, sourceName) {
|
||||||
for (var i = 0; i < attributes.length; i++) {
|
for (const [key, value] of Object.entries(attributes)) {
|
||||||
if (attributes[i].key == "ZipContents") {
|
if (key == "ZipContents") {
|
||||||
var archiveContent = JSON.parse(attributes[i].value);
|
var archiveContent = JSON.parse(value);
|
||||||
|
|
||||||
// show archive button
|
// show archive button
|
||||||
document.getElementById('properties_toc_archive').style.display = '';
|
document.getElementById('properties_toc_archive').style.display = '';
|
||||||
|
|
||||||
var aTable = document.createElement('table');
|
var aTable = document.createElement('table');
|
||||||
aTable.className = 'romtable';
|
aTable.className = 'romtable';
|
||||||
aTable.setAttribute('cellspacing', 0);
|
aTable.setAttribute('cellspacing', 0);
|
||||||
@@ -343,6 +347,17 @@
|
|||||||
hRow.appendChild(aHashCell);
|
hRow.appendChild(aHashCell);
|
||||||
aBody.appendChild(hRow);
|
aBody.appendChild(hRow);
|
||||||
|
|
||||||
|
if (archiveContent[r].isSignatureSelector == true) {
|
||||||
|
var sigRow = document.createElement('tr');
|
||||||
|
|
||||||
|
var sigCell = document.createElement('td');
|
||||||
|
sigCell.setAttribute('colspan', 2);
|
||||||
|
sigCell.style.paddingLeft = '20px';
|
||||||
|
sigCell.innerHTML = "Hash used to identify this archive";
|
||||||
|
sigRow.appendChild(sigCell);
|
||||||
|
aBody.appendChild(sigRow);
|
||||||
|
}
|
||||||
|
|
||||||
aTable.appendChild(aBody);
|
aTable.appendChild(aBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,18 +369,18 @@
|
|||||||
function ConvertTOSECAttributeName(attributeName) {
|
function ConvertTOSECAttributeName(attributeName) {
|
||||||
var tosecAttributeNames = {
|
var tosecAttributeNames = {
|
||||||
"cr": "Cracked",
|
"cr": "Cracked",
|
||||||
"f" : "Fixed",
|
"f": "Fixed",
|
||||||
"h" : "Hacked",
|
"h": "Hacked",
|
||||||
"m" : "Modified",
|
"m": "Modified",
|
||||||
"p" : "Pirated",
|
"p": "Pirated",
|
||||||
"t" : "Trained",
|
"t": "Trained",
|
||||||
"tr": "Translated",
|
"tr": "Translated",
|
||||||
"o" : "Over Dump",
|
"o": "Over Dump",
|
||||||
"u" : "Under Dump",
|
"u": "Under Dump",
|
||||||
"v" : "Virus",
|
"v": "Virus",
|
||||||
"b" : "Bad Dump",
|
"b": "Bad Dump",
|
||||||
"a" : "Alternate",
|
"a": "Alternate",
|
||||||
"!" : "Known Verified Dump"
|
"!": "Known Verified Dump"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (attributeName in tosecAttributeNames) {
|
if (attributeName in tosecAttributeNames) {
|
||||||
@@ -378,4 +393,4 @@
|
|||||||
SelectTab('general');
|
SelectTab('general');
|
||||||
|
|
||||||
document.getElementById('romDelete').setAttribute("onclick", "showSubDialog('romdelete', " + modalVariables + ");");
|
document.getElementById('romDelete').setAttribute("onclick", "showSubDialog('romdelete', " + modalVariables + ");");
|
||||||
</script>
|
</script>
|
@@ -1,4 +1,5 @@
|
|||||||
<div id="bgImage" style="background-image: url('/images/SettingsWallpaper.jpg'); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);">
|
<div id="bgImage"
|
||||||
|
style="background-image: url('/images/SettingsWallpaper.jpg'); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);">
|
||||||
<div id="bgImage_Opacity"></div>
|
<div id="bgImage_Opacity"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -6,27 +7,40 @@
|
|||||||
<div id="properties_toc" class="settings_toc">
|
<div id="properties_toc" class="settings_toc">
|
||||||
<div class="filter_header">Settings</div>
|
<div class="filter_header">Settings</div>
|
||||||
<div id="properties_toc_system" name="properties_toc_item" onclick="SelectTab('system');">System</div>
|
<div id="properties_toc_system" name="properties_toc_item" onclick="SelectTab('system');">System</div>
|
||||||
<div id="properties_toc_settings" name="properties_toc_item" onclick="SelectTab('settings');" style="display: none;">Settings</div>
|
<div id="properties_toc_settings" name="properties_toc_item" onclick="SelectTab('settings');"
|
||||||
<div id="properties_toc_users" name="properties_toc_item" onclick="SelectTab('users');" style="display: none;">Users</div>
|
style="display: none;">Settings</div>
|
||||||
<div id="properties_toc_mapping" name="properties_toc_item" onclick="SelectTab('mapping');" style="display: none;">Platform Mapping</div>
|
<div id="properties_toc_libraries" name="properties_toc_item" onclick="SelectTab('libraries');"
|
||||||
|
style="display: none;">
|
||||||
|
Libraries</div>
|
||||||
|
<div id="properties_toc_users" name="properties_toc_item" onclick="SelectTab('users');" style="display: none;">
|
||||||
|
Users</div>
|
||||||
|
<div id="properties_toc_services" name="properties_toc_item" onclick="SelectTab('services');"
|
||||||
|
style="display: none;">
|
||||||
|
Services</div>
|
||||||
|
<div id="properties_toc_mapping" name="properties_toc_item" onclick="SelectTab('mapping');"
|
||||||
|
style="display: none;">Platform Mapping</div>
|
||||||
<div id="properties_toc_bios" name="properties_toc_item" onclick="SelectTab('bios');">Firmware</div>
|
<div id="properties_toc_bios" name="properties_toc_item" onclick="SelectTab('bios');">Firmware</div>
|
||||||
<div id="properties_toc_logs" name="properties_toc_item" onclick="SelectTab('logs');" style="display: none;">Logs</div>
|
<div id="properties_toc_logs" name="properties_toc_item" onclick="SelectTab('logs');" style="display: none;">
|
||||||
|
Logs</div>
|
||||||
<div id="properties_toc_about" name="properties_toc_item" onclick="SelectTab('about');">About</div>
|
<div id="properties_toc_about" name="properties_toc_item" onclick="SelectTab('about');">About</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="properties_bodypanel">
|
<div id="properties_bodypanel">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="settings_photocredit">
|
<div id="settings_photocredit">
|
||||||
Wallpaper by <a href="https://unsplash.com/@lorenzoherrera" class="romlink">Lorenzo Herrera</a> / <a href="https://unsplash.com/photos/p0j-mE6mGo4" class="romlink">Unsplash</a>
|
Wallpaper by <a href="https://unsplash.com/@lorenzoherrera" class="romlink">Lorenzo Herrera</a> / <a
|
||||||
|
href="https://unsplash.com/photos/p0j-mE6mGo4" class="romlink">Unsplash</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (userProfile.roles.includes("Admin")) {
|
if (userProfile.roles.includes("Admin")) {
|
||||||
document.getElementById('properties_toc_settings').style.display = '';
|
document.getElementById('properties_toc_settings').style.display = '';
|
||||||
|
document.getElementById('properties_toc_libraries').style.display = '';
|
||||||
document.getElementById('properties_toc_users').style.display = '';
|
document.getElementById('properties_toc_users').style.display = '';
|
||||||
|
document.getElementById('properties_toc_services').style.display = '';
|
||||||
document.getElementById('properties_toc_mapping').style.display = '';
|
document.getElementById('properties_toc_mapping').style.display = '';
|
||||||
document.getElementById('properties_toc_logs').style.display = '';
|
document.getElementById('properties_toc_logs').style.display = '';
|
||||||
}
|
}
|
||||||
@@ -62,4 +76,4 @@
|
|||||||
|
|
||||||
$('#properties_bodypanel').load('/pages/settings/' + TabName + '.html?v=' + AppVersion);
|
$('#properties_bodypanel').load('/pages/settings/' + TabName + '.html?v=' + AppVersion);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
63
gaseous-server/wwwroot/pages/settings/libraries.html
Normal file
63
gaseous-server/wwwroot/pages/settings/libraries.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<div id="gametitle">
|
||||||
|
<h1 id="gametitle_label">Libraries</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="settings_libraries" class="romtable" style="width: 100%;" cellspacing="0">
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showDialog('librarynew');">New
|
||||||
|
Library</button></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function drawLibrary() {
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1.1/Library',
|
||||||
|
'GET',
|
||||||
|
function (result) {
|
||||||
|
var newTable = document.getElementById('settings_libraries');
|
||||||
|
newTable.innerHTML = '';
|
||||||
|
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '']));
|
||||||
|
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var platformName = '';
|
||||||
|
if (result[i].defaultPlatformId == 0) {
|
||||||
|
if (result[i].isDefaultLibrary == true) {
|
||||||
|
platformName = "n/a";
|
||||||
|
} else {
|
||||||
|
platformName = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
platformName = result[i].defaultPlatformName;
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultLibrary = '';
|
||||||
|
if (result[i].isDefaultLibrary == true) {
|
||||||
|
defaultLibrary = "Yes";
|
||||||
|
} else {
|
||||||
|
defaultLibrary = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteButton = '';
|
||||||
|
if (result[i].isDefaultLibrary == false) {
|
||||||
|
var deleteButton = '<a href="#" onclick="showSubDialog(\'librarydelete\', ' + result[i].id + ');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
newTable.appendChild(createTableRow(
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
result[i].name,
|
||||||
|
result[i].path,
|
||||||
|
platformName,
|
||||||
|
defaultLibrary,
|
||||||
|
'<div style="text-align: right;">' + deleteButton + '</div>'
|
||||||
|
],
|
||||||
|
'romrow',
|
||||||
|
'romcell'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLibrary();
|
||||||
|
</script>
|
290
gaseous-server/wwwroot/pages/settings/services.html
Normal file
290
gaseous-server/wwwroot/pages/settings/services.html
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
<div id="gametitle">
|
||||||
|
<h1 id="gametitle_label">Services</h1>
|
||||||
|
</div>
|
||||||
|
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to
|
||||||
|
Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function getBackgroundTaskTimers() {
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||||
|
'GET',
|
||||||
|
function (result) {
|
||||||
|
var targetTable = document.getElementById('settings_tasktimers');
|
||||||
|
targetTable.innerHTML = '';
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(result)) {
|
||||||
|
var newTableRowBody = document.createElement('tbody');
|
||||||
|
newTableRowBody.className = 'romrow';
|
||||||
|
|
||||||
|
var enabledString = "";
|
||||||
|
if (value.enabled == true) {
|
||||||
|
enabledString = 'checked="checked"';
|
||||||
|
}
|
||||||
|
|
||||||
|
var newTableIntervalRow = createTableRow(
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
GetTaskFriendlyName(value.task),
|
||||||
|
'Enabled',
|
||||||
|
'<input id="settings_enabled_' + value.task + '" name="settings_tasktimers_enabled" type="checkbox" ' + enabledString + '/>',
|
||||||
|
],
|
||||||
|
'',
|
||||||
|
'romcell'
|
||||||
|
);
|
||||||
|
newTableRowBody.appendChild(newTableIntervalRow);
|
||||||
|
|
||||||
|
var newTableRow = createTableRow(
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
'Minimum Interval (Minutes):',
|
||||||
|
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="' + value.defaultInterval + '" min="' + value.minimumAllowedInterval + '" value="' + value.interval + '" />'
|
||||||
|
],
|
||||||
|
'',
|
||||||
|
'romcell'
|
||||||
|
);
|
||||||
|
newTableRowBody.appendChild(newTableRow);
|
||||||
|
|
||||||
|
// allowed time periods row
|
||||||
|
var newTableRowTime = document.createElement('tr');
|
||||||
|
var rowTimeSpace = document.createElement('td');
|
||||||
|
newTableRowTime.appendChild(rowTimeSpace);
|
||||||
|
|
||||||
|
var rowTimeContentTitle = document.createElement('td');
|
||||||
|
rowTimeContentTitle.className = 'romcell';
|
||||||
|
rowTimeContentTitle.innerHTML = "Allowed Days:";
|
||||||
|
newTableRowTime.appendChild(rowTimeContentTitle);
|
||||||
|
|
||||||
|
var rowTimeContent = document.createElement('td');
|
||||||
|
// rowTimeContent.setAttribute('colspan', 2);
|
||||||
|
rowTimeContent.className = 'romcell';
|
||||||
|
var daySelector = document.createElement('select');
|
||||||
|
daySelector.id = 'settings_alloweddays_' + value.task;
|
||||||
|
daySelector.name = 'settings_alloweddays';
|
||||||
|
daySelector.multiple = 'multiple';
|
||||||
|
daySelector.setAttribute('data-default', value.defaultAllowedDays.join(","));
|
||||||
|
daySelector.style.width = '95%';
|
||||||
|
var days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
|
||||||
|
for (var d = 0; d < days.length; d++) {
|
||||||
|
var dayOpt = document.createElement('option');
|
||||||
|
dayOpt.value = days[d];
|
||||||
|
dayOpt.innerHTML = days[d];
|
||||||
|
if (value.allowedDays.includes(days[d])) {
|
||||||
|
dayOpt.selected = 'selected';
|
||||||
|
}
|
||||||
|
daySelector.appendChild(dayOpt);
|
||||||
|
}
|
||||||
|
rowTimeContent.appendChild(daySelector);
|
||||||
|
$(daySelector).select2({
|
||||||
|
tags: false
|
||||||
|
});
|
||||||
|
newTableRowTime.appendChild(rowTimeContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowTime);
|
||||||
|
|
||||||
|
// add start and end times
|
||||||
|
var newTableRowClock = document.createElement('tr');
|
||||||
|
var rowClockSpace = document.createElement('td');
|
||||||
|
newTableRowClock.appendChild(rowClockSpace);
|
||||||
|
|
||||||
|
var rowClockContentTitle = document.createElement('td');
|
||||||
|
rowClockContentTitle.className = 'romcell';
|
||||||
|
rowClockContentTitle.innerHTML = "Time Range:";
|
||||||
|
newTableRowClock.appendChild(rowClockContentTitle);
|
||||||
|
|
||||||
|
var rowClockContent = document.createElement('td');
|
||||||
|
rowClockContent.className = 'romcell';
|
||||||
|
// rowClockContent.setAttribute('colspan', 2);
|
||||||
|
|
||||||
|
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'Start', value.defaultAllowedStartHours, value.defaultAllowedStartMinutes, value.allowedStartHours, value.allowedStartMinutes));
|
||||||
|
|
||||||
|
rowClockContentSeparator = document.createElement('span');
|
||||||
|
rowClockContentSeparator.innerHTML = ' - ';
|
||||||
|
rowClockContent.appendChild(rowClockContentSeparator);
|
||||||
|
|
||||||
|
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'End', value.defaultAllowedEndHours, value.defaultAllowedEndMinutes, value.allowedEndHours, value.allowedEndMinutes));
|
||||||
|
|
||||||
|
newTableRowClock.appendChild(rowClockContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowClock);
|
||||||
|
|
||||||
|
// blocks tasks
|
||||||
|
var newTableRowBlocks = document.createElement('tr');
|
||||||
|
var rowBlocksSpace = document.createElement('td');
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksSpace);
|
||||||
|
|
||||||
|
var rowBlocksContentTitle = document.createElement('td');
|
||||||
|
rowBlocksContentTitle.className = 'romcell';
|
||||||
|
rowBlocksContentTitle.innerHTML = "Blocks:";
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksContentTitle);
|
||||||
|
|
||||||
|
var rowBlocksContent = document.createElement('td');
|
||||||
|
rowBlocksContent.className = 'romcell';
|
||||||
|
// rowBlocksContent.setAttribute('colspan', 2);
|
||||||
|
var blocksString = "";
|
||||||
|
for (var i = 0; i < value.blocks.length; i++) {
|
||||||
|
if (blocksString.length > 0) { blocksString += ", "; }
|
||||||
|
blocksString += GetTaskFriendlyName(value.blocks[i]);
|
||||||
|
}
|
||||||
|
if (blocksString.length == 0) { blocksString = 'None'; }
|
||||||
|
rowBlocksContent.innerHTML = blocksString;
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowBlocks);
|
||||||
|
|
||||||
|
// blocked by tasks
|
||||||
|
var newTableRowBlockedBy = document.createElement('tr');
|
||||||
|
var rowBlockedBySpace = document.createElement('td');
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedBySpace);
|
||||||
|
|
||||||
|
var rowBlockedByContentTitle = document.createElement('td');
|
||||||
|
rowBlockedByContentTitle.className = 'romcell';
|
||||||
|
rowBlockedByContentTitle.innerHTML = "Blocked By:";
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedByContentTitle);
|
||||||
|
|
||||||
|
var rowBlockedByContent = document.createElement('td');
|
||||||
|
rowBlockedByContent.className = 'romcell';
|
||||||
|
// rowBlockedByContent.setAttribute('colspan', 2);
|
||||||
|
var BlockedByString = "";
|
||||||
|
for (var i = 0; i < value.blockedBy.length; i++) {
|
||||||
|
if (BlockedByString.length > 0) { BlockedByString += ", "; }
|
||||||
|
BlockedByString += GetTaskFriendlyName(value.blockedBy[i]);
|
||||||
|
}
|
||||||
|
if (BlockedByString.length == 0) { BlockedByString = 'None'; }
|
||||||
|
rowBlockedByContent.innerHTML = BlockedByString;
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedByContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowBlockedBy);
|
||||||
|
|
||||||
|
// complete row
|
||||||
|
targetTable.appendChild(newTableRowBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateTimeDropDowns(taskName, rangeName, defaultHour, defaultMinute, valueHour, valueMinute) {
|
||||||
|
var container = document.createElement('div');
|
||||||
|
container.style.display = 'inline';
|
||||||
|
|
||||||
|
var elementName = 'settings_tasktimers_time';
|
||||||
|
|
||||||
|
var hourSelector = document.createElement('input');
|
||||||
|
hourSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Hour';
|
||||||
|
hourSelector.name = elementName;
|
||||||
|
hourSelector.setAttribute('data-name', taskName);
|
||||||
|
hourSelector.setAttribute('type', 'number');
|
||||||
|
hourSelector.setAttribute('min', '0');
|
||||||
|
hourSelector.setAttribute('max', '23');
|
||||||
|
hourSelector.setAttribute('placeholder', defaultHour);
|
||||||
|
hourSelector.value = valueHour;
|
||||||
|
container.appendChild(hourSelector);
|
||||||
|
|
||||||
|
var separator = document.createElement('span');
|
||||||
|
separator.innerHTML = " : ";
|
||||||
|
container.appendChild(separator);
|
||||||
|
|
||||||
|
var minSelector = document.createElement('input');
|
||||||
|
minSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Minute';
|
||||||
|
minSelector.name = elementName;
|
||||||
|
minSelector.setAttribute('type', 'number');
|
||||||
|
minSelector.setAttribute('min', '0');
|
||||||
|
minSelector.setAttribute('max', '59');
|
||||||
|
minSelector.setAttribute('placeholder', defaultMinute);
|
||||||
|
minSelector.value = valueMinute;
|
||||||
|
container.appendChild(minSelector);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTaskTimers() {
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
|
var model = [];
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
var taskName = timerValues[i].getAttribute('data-name');
|
||||||
|
var taskEnabled = document.getElementById('settings_enabled_' + taskName).checked;
|
||||||
|
var taskIntervalObj = document.getElementById('settings_tasktimers_' + taskName);
|
||||||
|
var taskInterval = function () { if (taskIntervalObj.value) { return taskIntervalObj.value; } else { return taskIntervalObj.getAttribute('placeholder'); } };
|
||||||
|
var taskDaysRaw = $('#settings_alloweddays_' + taskName).select2('data');
|
||||||
|
var taskDays = [];
|
||||||
|
if (taskDaysRaw.length > 0) {
|
||||||
|
for (var d = 0; d < taskDaysRaw.length; d++) {
|
||||||
|
taskDays.push(taskDaysRaw[d].id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
taskDays.push("Monday");
|
||||||
|
}
|
||||||
|
var taskStartHourObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Hour');
|
||||||
|
var taskStartMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Minute');
|
||||||
|
var taskEndHourObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Hour');
|
||||||
|
var taskEndMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Minute');
|
||||||
|
|
||||||
|
var taskStartHour = function () { if (taskStartHourObj.value) { return taskStartHourObj.value; } else { return taskStartHourObj.getAttribute('placeholder'); } };
|
||||||
|
var taskStartMinute = function () { if (taskStartMinuteObj.value) { return taskStartMinuteObj.value; } else { return taskStartMinuteObj.getAttribute('placeholder'); } };
|
||||||
|
var taskEndHour = function () { if (taskEndHourObj.value) { return taskEndHourObj.value; } else { return taskEndHourObj.getAttribute('placeholder'); } };
|
||||||
|
var taskEndMinute = function () { if (taskEndMinuteObj.value) { return taskEndMinuteObj.value; } else { return taskEndMinuteObj.getAttribute('placeholder'); } };
|
||||||
|
|
||||||
|
model.push(
|
||||||
|
{
|
||||||
|
"task": taskName,
|
||||||
|
"enabled": taskEnabled,
|
||||||
|
"interval": taskInterval(),
|
||||||
|
"allowedDays": taskDays,
|
||||||
|
"allowedStartHours": taskStartHour(),
|
||||||
|
"allowedStartMinutes": taskStartMinute(),
|
||||||
|
"allowedEndHours": taskEndHour(),
|
||||||
|
"allowedEndMinutes": taskEndMinute()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||||
|
'POST',
|
||||||
|
function (result) {
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
},
|
||||||
|
JSON.stringify(model)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function defaultTaskTimers() {
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_enabled');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
||||||
|
}
|
||||||
|
|
||||||
|
var timerValues = document.getElementsByName('settings_alloweddays');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
var defaultSelections = timerValues[i].getAttribute('data-default').split(',');
|
||||||
|
$(timerValues[i]).val(defaultSelections);
|
||||||
|
$(timerValues[i]).trigger('change');
|
||||||
|
}
|
||||||
|
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_time');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].value = timerValues[i].getAttribute('placeholder');
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTaskTimers();
|
||||||
|
}
|
||||||
|
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
</script>
|
@@ -2,37 +2,74 @@
|
|||||||
<h1 id="gametitle_label">Settings</h1>
|
<h1 id="gametitle_label">Settings</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Libraries</h3>
|
<table cellspacing="0" style="width: 100%; vertical-align: top;">
|
||||||
<table id="settings_libraries" class="romtable" style="width: 100%;" cellspacing="0">
|
|
||||||
|
|
||||||
</table>
|
|
||||||
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showDialog('librarynew');">New Library</button></div>
|
|
||||||
|
|
||||||
<h2>Advanced Settings</h2>
|
|
||||||
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
|
||||||
<h3>Background Task Timers</h3>
|
|
||||||
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
|
||||||
|
|
||||||
</table>
|
|
||||||
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
|
||||||
|
|
||||||
<h3>System Settings</h3>
|
|
||||||
<table cellspacing="0" style="width: 100%;">
|
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2">Logging</th>
|
<th colspan="2">
|
||||||
|
<h3>Metadata Sources</h3>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 25%;">
|
||||||
|
Signature Source
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_local" value="LocalOnly"
|
||||||
|
onclick="document.getElementById('settings_hasheoushost_row').style.display = 'none';">
|
||||||
|
<label for="settings_signaturesource_local">Local Only</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_hasheous" value="Hasheous"
|
||||||
|
onclick="document.getElementById('settings_hasheoushost_row').style.display = '';">
|
||||||
|
<label for="settings_signaturesource_hasheous">Hasheous</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="settings_hasheoushost_row" style="display: none;">
|
||||||
|
<th>
|
||||||
|
Hasheous Host
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input type="url" id="settings_signaturesource_hasheoushost" style="width: 90%;">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<label for="settings_hasheoussubmit">Submit updates to Hasheous when fixing ROM matches</label>
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="settings_hasheoussubmit" onchange="toggleHasheousAPIKey(this);">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="settings_hasheousapikey_row" style="display: none;">
|
||||||
|
<th>
|
||||||
|
Hasheous API key
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<textarea id="settings_hasheousapikey" rows="2" style="width: 90%;"></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">
|
||||||
|
<h3>Logging</h3>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
Write logs
|
Write logs
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false" checked="checked"><label for="settings_logs_write_db"> To database only (default)</label>
|
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false"
|
||||||
|
checked="checked"><label for="settings_logs_write_db"> To database only
|
||||||
|
(default)</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label for="settings_logs_write_fs"> To database and disk</label>
|
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label
|
||||||
|
for="settings_logs_write_fs"> To database and disk</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -47,10 +84,12 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2">Emulator</th>
|
<th colspan="2">
|
||||||
|
<h3>Emulator</h3>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Enable debug mode</th>
|
<th><label for="settings_emulator_debug">Enable debug mode</label></th>
|
||||||
<td><input type="checkbox" name="settings_emulator" id="settings_emulator_debug" checked="checked" /></td>
|
<td><input type="checkbox" name="settings_emulator" id="settings_emulator_debug" checked="checked" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -61,339 +100,11 @@
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function drawLibrary() {
|
|
||||||
ajaxCall(
|
|
||||||
'/api/v1.1/Library',
|
|
||||||
'GET',
|
|
||||||
function (result) {
|
|
||||||
var newTable = document.getElementById('settings_libraries');
|
|
||||||
newTable.innerHTML = '';
|
|
||||||
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '']));
|
|
||||||
|
|
||||||
for (var i = 0; i < result.length; i++) {
|
|
||||||
var platformName = '';
|
|
||||||
if (result[i].defaultPlatformId == 0) {
|
|
||||||
if (result[i].isDefaultLibrary == true) {
|
|
||||||
platformName = "n/a";
|
|
||||||
} else {
|
|
||||||
platformName = "";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
platformName = result[i].defaultPlatformName;
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultLibrary = '';
|
|
||||||
if (result[i].isDefaultLibrary == true) {
|
|
||||||
defaultLibrary = "Yes";
|
|
||||||
} else {
|
|
||||||
defaultLibrary = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
var deleteButton = '';
|
|
||||||
if (result[i].isDefaultLibrary == false) {
|
|
||||||
var deleteButton = '<a href="#" onclick="showSubDialog(\'librarydelete\', ' + result[i].id + ');" class="romlink"><img src="/images/delete.svg" class="banner_button_image" alt="Delete" title="Delete" /></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
newTable.appendChild(createTableRow(
|
|
||||||
false,
|
|
||||||
[
|
|
||||||
result[i].name,
|
|
||||||
result[i].path,
|
|
||||||
platformName,
|
|
||||||
defaultLibrary,
|
|
||||||
'<div style="text-align: right;">' + deleteButton + '</div>'
|
|
||||||
],
|
|
||||||
'romrow',
|
|
||||||
'romcell'
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBackgroundTaskTimers() {
|
|
||||||
ajaxCall(
|
|
||||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
|
||||||
'GET',
|
|
||||||
function(result) {
|
|
||||||
var targetTable = document.getElementById('settings_tasktimers');
|
|
||||||
targetTable.innerHTML = '';
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(result)) {
|
|
||||||
var newTableRowBody = document.createElement('tbody');
|
|
||||||
newTableRowBody.className = 'romrow';
|
|
||||||
|
|
||||||
var enabledString = "";
|
|
||||||
if (value.enabled == true) {
|
|
||||||
enabledString = 'checked="checked"';
|
|
||||||
}
|
|
||||||
|
|
||||||
var newTableIntervalRow = createTableRow(
|
|
||||||
false,
|
|
||||||
[
|
|
||||||
GetTaskFriendlyName(value.task),
|
|
||||||
'Enabled',
|
|
||||||
'<input id="settings_enabled_' + value.task + '" name="settings_tasktimers_enabled" type="checkbox" ' + enabledString + '/>',
|
|
||||||
],
|
|
||||||
'',
|
|
||||||
'romcell'
|
|
||||||
);
|
|
||||||
newTableRowBody.appendChild(newTableIntervalRow);
|
|
||||||
|
|
||||||
var newTableRow = createTableRow(
|
|
||||||
false,
|
|
||||||
[
|
|
||||||
'',
|
|
||||||
'Minimum Interval (Minutes):',
|
|
||||||
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="' + value.defaultInterval + '" min="' + value.minimumAllowedInterval + '" value="' + value.interval + '" />'
|
|
||||||
],
|
|
||||||
'',
|
|
||||||
'romcell'
|
|
||||||
);
|
|
||||||
newTableRowBody.appendChild(newTableRow);
|
|
||||||
|
|
||||||
// allowed time periods row
|
|
||||||
var newTableRowTime = document.createElement('tr');
|
|
||||||
var rowTimeSpace = document.createElement('td');
|
|
||||||
newTableRowTime.appendChild(rowTimeSpace);
|
|
||||||
|
|
||||||
var rowTimeContentTitle = document.createElement('td');
|
|
||||||
rowTimeContentTitle.className = 'romcell';
|
|
||||||
rowTimeContentTitle.innerHTML = "Allowed Days:";
|
|
||||||
newTableRowTime.appendChild(rowTimeContentTitle);
|
|
||||||
|
|
||||||
var rowTimeContent = document.createElement('td');
|
|
||||||
// rowTimeContent.setAttribute('colspan', 2);
|
|
||||||
rowTimeContent.className = 'romcell';
|
|
||||||
var daySelector = document.createElement('select');
|
|
||||||
daySelector.id = 'settings_alloweddays_' + value.task;
|
|
||||||
daySelector.name = 'settings_alloweddays';
|
|
||||||
daySelector.multiple = 'multiple';
|
|
||||||
daySelector.setAttribute('data-default', value.defaultAllowedDays.join(","));
|
|
||||||
daySelector.style.width = '95%';
|
|
||||||
var days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ];
|
|
||||||
for (var d = 0; d < days.length; d++) {
|
|
||||||
var dayOpt = document.createElement('option');
|
|
||||||
dayOpt.value = days[d];
|
|
||||||
dayOpt.innerHTML = days[d];
|
|
||||||
if (value.allowedDays.includes(days[d])) {
|
|
||||||
dayOpt.selected = 'selected';
|
|
||||||
}
|
|
||||||
daySelector.appendChild(dayOpt);
|
|
||||||
}
|
|
||||||
rowTimeContent.appendChild(daySelector);
|
|
||||||
$(daySelector).select2({
|
|
||||||
tags: false
|
|
||||||
});
|
|
||||||
newTableRowTime.appendChild(rowTimeContent);
|
|
||||||
|
|
||||||
newTableRowBody.appendChild(newTableRowTime);
|
|
||||||
|
|
||||||
// add start and end times
|
|
||||||
var newTableRowClock = document.createElement('tr');
|
|
||||||
var rowClockSpace = document.createElement('td');
|
|
||||||
newTableRowClock.appendChild(rowClockSpace);
|
|
||||||
|
|
||||||
var rowClockContentTitle = document.createElement('td');
|
|
||||||
rowClockContentTitle.className = 'romcell';
|
|
||||||
rowClockContentTitle.innerHTML = "Time Range:";
|
|
||||||
newTableRowClock.appendChild(rowClockContentTitle);
|
|
||||||
|
|
||||||
var rowClockContent = document.createElement('td');
|
|
||||||
rowClockContent.className = 'romcell';
|
|
||||||
// rowClockContent.setAttribute('colspan', 2);
|
|
||||||
|
|
||||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'Start', value.defaultAllowedStartHours, value.defaultAllowedStartMinutes, value.allowedStartHours, value.allowedStartMinutes));
|
|
||||||
|
|
||||||
rowClockContentSeparator = document.createElement('span');
|
|
||||||
rowClockContentSeparator.innerHTML = ' - ';
|
|
||||||
rowClockContent.appendChild(rowClockContentSeparator);
|
|
||||||
|
|
||||||
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'End', value.defaultAllowedEndHours, value.defaultAllowedEndMinutes, value.allowedEndHours, value.allowedEndMinutes));
|
|
||||||
|
|
||||||
newTableRowClock.appendChild(rowClockContent);
|
|
||||||
|
|
||||||
newTableRowBody.appendChild(newTableRowClock);
|
|
||||||
|
|
||||||
// blocks tasks
|
|
||||||
var newTableRowBlocks = document.createElement('tr');
|
|
||||||
var rowBlocksSpace = document.createElement('td');
|
|
||||||
newTableRowBlocks.appendChild(rowBlocksSpace);
|
|
||||||
|
|
||||||
var rowBlocksContentTitle = document.createElement('td');
|
|
||||||
rowBlocksContentTitle.className = 'romcell';
|
|
||||||
rowBlocksContentTitle.innerHTML = "Blocks:";
|
|
||||||
newTableRowBlocks.appendChild(rowBlocksContentTitle);
|
|
||||||
|
|
||||||
var rowBlocksContent = document.createElement('td');
|
|
||||||
rowBlocksContent.className = 'romcell';
|
|
||||||
// rowBlocksContent.setAttribute('colspan', 2);
|
|
||||||
var blocksString = "";
|
|
||||||
for (var i = 0; i < value.blocks.length; i++) {
|
|
||||||
if (blocksString.length > 0) { blocksString += ", "; }
|
|
||||||
blocksString += GetTaskFriendlyName(value.blocks[i]);
|
|
||||||
}
|
|
||||||
if (blocksString.length == 0) { blocksString = 'None'; }
|
|
||||||
rowBlocksContent.innerHTML = blocksString;
|
|
||||||
newTableRowBlocks.appendChild(rowBlocksContent);
|
|
||||||
|
|
||||||
newTableRowBody.appendChild(newTableRowBlocks);
|
|
||||||
|
|
||||||
// blocked by tasks
|
|
||||||
var newTableRowBlockedBy = document.createElement('tr');
|
|
||||||
var rowBlockedBySpace = document.createElement('td');
|
|
||||||
newTableRowBlockedBy.appendChild(rowBlockedBySpace);
|
|
||||||
|
|
||||||
var rowBlockedByContentTitle = document.createElement('td');
|
|
||||||
rowBlockedByContentTitle.className = 'romcell';
|
|
||||||
rowBlockedByContentTitle.innerHTML = "Blocked By:";
|
|
||||||
newTableRowBlockedBy.appendChild(rowBlockedByContentTitle);
|
|
||||||
|
|
||||||
var rowBlockedByContent = document.createElement('td');
|
|
||||||
rowBlockedByContent.className = 'romcell';
|
|
||||||
// rowBlockedByContent.setAttribute('colspan', 2);
|
|
||||||
var BlockedByString = "";
|
|
||||||
for (var i = 0; i < value.blockedBy.length; i++) {
|
|
||||||
if (BlockedByString.length > 0) { BlockedByString += ", "; }
|
|
||||||
BlockedByString += GetTaskFriendlyName(value.blockedBy[i]);
|
|
||||||
}
|
|
||||||
if (BlockedByString.length == 0) { BlockedByString = 'None'; }
|
|
||||||
rowBlockedByContent.innerHTML = BlockedByString;
|
|
||||||
newTableRowBlockedBy.appendChild(rowBlockedByContent);
|
|
||||||
|
|
||||||
newTableRowBody.appendChild(newTableRowBlockedBy);
|
|
||||||
|
|
||||||
// complete row
|
|
||||||
targetTable.appendChild(newTableRowBody);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateTimeDropDowns(taskName, rangeName, defaultHour, defaultMinute, valueHour, valueMinute) {
|
|
||||||
var container = document.createElement('div');
|
|
||||||
container.style.display = 'inline';
|
|
||||||
|
|
||||||
var elementName = 'settings_tasktimers_time';
|
|
||||||
|
|
||||||
var hourSelector = document.createElement('input');
|
|
||||||
hourSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Hour';
|
|
||||||
hourSelector.name = elementName;
|
|
||||||
hourSelector.setAttribute('data-name', taskName);
|
|
||||||
hourSelector.setAttribute('type', 'number');
|
|
||||||
hourSelector.setAttribute('min', '0');
|
|
||||||
hourSelector.setAttribute('max', '23');
|
|
||||||
hourSelector.setAttribute('placeholder', defaultHour);
|
|
||||||
hourSelector.value = valueHour;
|
|
||||||
container.appendChild(hourSelector);
|
|
||||||
|
|
||||||
var separator = document.createElement('span');
|
|
||||||
separator.innerHTML = " : ";
|
|
||||||
container.appendChild(separator);
|
|
||||||
|
|
||||||
var minSelector = document.createElement('input');
|
|
||||||
minSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Minute';
|
|
||||||
minSelector.name = elementName;
|
|
||||||
minSelector.setAttribute('type', 'number');
|
|
||||||
minSelector.setAttribute('min', '0');
|
|
||||||
minSelector.setAttribute('max', '59');
|
|
||||||
minSelector.setAttribute('placeholder', defaultMinute);
|
|
||||||
minSelector.value = valueMinute;
|
|
||||||
container.appendChild(minSelector);
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveTaskTimers() {
|
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
|
||||||
|
|
||||||
var model = [];
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
|
||||||
var taskName = timerValues[i].getAttribute('data-name');
|
|
||||||
var taskEnabled = document.getElementById('settings_enabled_' + taskName).checked;
|
|
||||||
var taskIntervalObj = document.getElementById('settings_tasktimers_' + taskName);
|
|
||||||
var taskInterval = function() { if (taskIntervalObj.value) { return taskIntervalObj.value; } else { return taskIntervalObj.getAttribute('placeholder'); } };
|
|
||||||
var taskDaysRaw = $('#settings_alloweddays_' + taskName).select2('data');
|
|
||||||
var taskDays = [];
|
|
||||||
if (taskDaysRaw.length > 0) {
|
|
||||||
for (var d = 0; d < taskDaysRaw.length; d++) {
|
|
||||||
taskDays.push(taskDaysRaw[d].id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
taskDays.push("Monday");
|
|
||||||
}
|
|
||||||
var taskStartHourObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Hour');
|
|
||||||
var taskStartMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Minute');
|
|
||||||
var taskEndHourObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Hour');
|
|
||||||
var taskEndMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Minute');
|
|
||||||
|
|
||||||
var taskStartHour = function() { if (taskStartHourObj.value) { return taskStartHourObj.value; } else { return taskStartHourObj.getAttribute('placeholder'); } };
|
|
||||||
var taskStartMinute = function() { if (taskStartMinuteObj.value) { return taskStartMinuteObj.value; } else { return taskStartMinuteObj.getAttribute('placeholder'); } };
|
|
||||||
var taskEndHour = function() { if (taskEndHourObj.value) { return taskEndHourObj.value; } else { return taskEndHourObj.getAttribute('placeholder'); } };
|
|
||||||
var taskEndMinute = function() { if (taskEndMinuteObj.value) { return taskEndMinuteObj.value; } else { return taskEndMinuteObj.getAttribute('placeholder'); } };
|
|
||||||
|
|
||||||
model.push(
|
|
||||||
{
|
|
||||||
"task": taskName,
|
|
||||||
"enabled": taskEnabled,
|
|
||||||
"interval": taskInterval(),
|
|
||||||
"allowedDays": taskDays,
|
|
||||||
"allowedStartHours": taskStartHour(),
|
|
||||||
"allowedStartMinutes": taskStartMinute(),
|
|
||||||
"allowedEndHours": taskEndHour(),
|
|
||||||
"allowedEndMinutes": taskEndMinute()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ajaxCall(
|
|
||||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
|
||||||
'POST',
|
|
||||||
function(result) {
|
|
||||||
getBackgroundTaskTimers();
|
|
||||||
},
|
|
||||||
function(error) {
|
|
||||||
getBackgroundTaskTimers();
|
|
||||||
},
|
|
||||||
JSON.stringify(model)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function defaultTaskTimers() {
|
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_enabled');
|
|
||||||
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
|
||||||
timerValues[i].checked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
|
||||||
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
|
||||||
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
|
||||||
}
|
|
||||||
|
|
||||||
var timerValues = document.getElementsByName('settings_alloweddays');
|
|
||||||
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
|
||||||
var defaultSelections = timerValues[i].getAttribute('data-default').split(',');
|
|
||||||
$(timerValues[i]).val(defaultSelections);
|
|
||||||
$(timerValues[i]).trigger('change');
|
|
||||||
}
|
|
||||||
|
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_time');
|
|
||||||
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
|
||||||
timerValues[i].value = timerValues[i].getAttribute('placeholder');
|
|
||||||
}
|
|
||||||
|
|
||||||
saveTaskTimers();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSystemSettings() {
|
function getSystemSettings() {
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1/System/Settings/System',
|
'/api/v1/System/Settings/System',
|
||||||
'GET',
|
'GET',
|
||||||
function(result) {
|
function (result) {
|
||||||
var optionToSelect = 'settings_logs_write_db';
|
var optionToSelect = 'settings_logs_write_db';
|
||||||
if (result.alwaysLogToDisk == true) {
|
if (result.alwaysLogToDisk == true) {
|
||||||
optionToSelect = 'settings_logs_write_fs';
|
optionToSelect = 'settings_logs_write_fs';
|
||||||
@@ -403,6 +114,27 @@
|
|||||||
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
||||||
|
|
||||||
document.getElementById('settings_emulator_debug').checked = result.emulatorDebugMode;
|
document.getElementById('settings_emulator_debug').checked = result.emulatorDebugMode;
|
||||||
|
|
||||||
|
switch (result.signatureSource.source) {
|
||||||
|
case "LocalOnly":
|
||||||
|
document.getElementById('settings_signaturesource_local').checked = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Hasheous":
|
||||||
|
document.getElementById('settings_signaturesource_hasheous').checked = true;
|
||||||
|
document.getElementById('settings_hasheoushost_row').style.display = '';
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('settings_signaturesource_hasheoushost').value = result.signatureSource.hasheousHost;
|
||||||
|
|
||||||
|
let hasheousSubmitCheck = document.getElementById('settings_hasheoussubmit');
|
||||||
|
if (result.signatureSource.hasheousSubmitFixes == true) {
|
||||||
|
hasheousSubmitCheck.checked = true;
|
||||||
|
}
|
||||||
|
document.getElementById('settings_hasheousapikey').innerHTML = result.signatureSource.hasheousAPIKey;
|
||||||
|
toggleHasheousAPIKey(hasheousSubmitCheck);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -423,24 +155,37 @@
|
|||||||
|
|
||||||
var model = {
|
var model = {
|
||||||
"alwaysLogToDisk": alwaysLogToDisk,
|
"alwaysLogToDisk": alwaysLogToDisk,
|
||||||
"minimumLogRetentionPeriod": retentionValue,
|
"minimumLogRetentionPeriod": Number(retentionValue),
|
||||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked
|
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
||||||
|
"signatureSource": {
|
||||||
|
"Source": $("input[type='radio'][name='settings_signaturesource']:checked").val(),
|
||||||
|
"HasheousHost": document.getElementById('settings_signaturesource_hasheoushost').value,
|
||||||
|
"HasheousAPIKey": document.getElementById('settings_hasheousapikey').innerHTML,
|
||||||
|
"HasheousSubmitFixes": document.getElementById('settings_hasheoussubmit').checked
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1/System/Settings/System',
|
'/api/v1/System/Settings/System',
|
||||||
'POST',
|
'POST',
|
||||||
function(result) {
|
function (result) {
|
||||||
getSystemSettings();
|
getSystemSettings();
|
||||||
},
|
},
|
||||||
function(error) {
|
function (error) {
|
||||||
getSystemSettings();
|
getSystemSettings();
|
||||||
},
|
},
|
||||||
JSON.stringify(model)
|
JSON.stringify(model)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawLibrary();
|
function toggleHasheousAPIKey(checkbox) {
|
||||||
getBackgroundTaskTimers();
|
let settings_hasheousapikey_row = document.getElementById('settings_hasheousapikey_row');
|
||||||
|
if (checkbox.checked == true) {
|
||||||
|
settings_hasheousapikey_row.style.display = '';
|
||||||
|
} else {
|
||||||
|
settings_hasheousapikey_row.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getSystemSettings();
|
getSystemSettings();
|
||||||
</script>
|
</script>
|
@@ -22,7 +22,7 @@
|
|||||||
<p><strong>Database</strong></p>
|
<p><strong>Database</strong></p>
|
||||||
<div id="system_database"></div>
|
<div id="system_database"></div>
|
||||||
|
|
||||||
<h3>Signatures</h3>
|
<h3>Local Database Signatures</h3>
|
||||||
<div id="system_signatures"></div>
|
<div id="system_signatures"></div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@@ -37,10 +37,10 @@
|
|||||||
for (var i = 0; i < result.length; i++) {
|
for (var i = 0; i < result.length; i++) {
|
||||||
if (result[i].itemState != "Disabled") {
|
if (result[i].itemState != "Disabled") {
|
||||||
var itemTypeName = GetTaskFriendlyName(result[i].itemType, result[i].options);
|
var itemTypeName = GetTaskFriendlyName(result[i].itemType, result[i].options);
|
||||||
|
|
||||||
var itemStateName;
|
var itemStateName;
|
||||||
var itemLastStart;
|
var itemLastStart;
|
||||||
|
|
||||||
var hasError = "";
|
var hasError = "";
|
||||||
if (result[i].hasErrors) {
|
if (result[i].hasErrors) {
|
||||||
if (result[i].hasErrors.errorType != null) {
|
if (result[i].hasErrors.errorType != null) {
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
var nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
var nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
var startButton = '';
|
var startButton = '';
|
||||||
if (userProfile.roles.includes("Admin")) {
|
if (userProfile.roles.includes("Admin")) {
|
||||||
if (result[i].allowManualStart == true && ![ "Running"].includes(result[i].itemState) && result[i].isBlocked == false) {
|
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>";
|
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,4 +271,4 @@
|
|||||||
setInterval(SystemLoadSystemStatus, 60000);
|
setInterval(SystemLoadSystemStatus, 60000);
|
||||||
SystemSignaturesStatus();
|
SystemSignaturesStatus();
|
||||||
setInterval(SystemSignaturesStatus, 300000);
|
setInterval(SystemSignaturesStatus, 300000);
|
||||||
</script>
|
</script>
|
@@ -23,21 +23,29 @@ h3 {
|
|||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
|
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
|
||||||
|
|
||||||
border-image: linear-gradient(to right, rgba(255,0,0,1) 0%, rgba(251,255,0,1) 16%, rgba(0,255,250,1) 30%, rgba(0,16,255,1) 46%, rgba(250,0,255,1) 62%, rgba(255,0,0,1) 78%, rgba(255,237,0,1) 90%, rgba(20,255,0,1) 100%) 5;
|
border-image: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(251, 255, 0, 1) 16%, rgba(0, 255, 250, 1) 30%, rgba(0, 16, 255, 1) 46%, rgba(250, 0, 255, 1) 62%, rgba(255, 0, 0, 1) 78%, rgba(255, 237, 0, 1) 90%, rgba(20, 255, 0, 1) 100%) 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The Modal (background) */
|
/* The Modal (background) */
|
||||||
.modal {
|
.modal {
|
||||||
display: none; /* Hidden by default */
|
display: none;
|
||||||
position: fixed; /* Stay in place */
|
/* Hidden by default */
|
||||||
z-index: 100; /* Sit on top */
|
position: fixed;
|
||||||
|
/* Stay in place */
|
||||||
|
z-index: 100;
|
||||||
|
/* Sit on top */
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%; /* Full width */
|
width: 100%;
|
||||||
height: 100%; /* Full height */
|
/* Full width */
|
||||||
overflow: none; /* Enable scroll if needed */
|
height: 100%;
|
||||||
background-color: rgb(0,0,0); /* Fallback color */
|
/* Full height */
|
||||||
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
overflow: none;
|
||||||
|
/* Enable scroll if needed */
|
||||||
|
background-color: rgb(0, 0, 0);
|
||||||
|
/* Fallback color */
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
/* Black w/ opacity */
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
-webkit-backdrop-filter: blur(8px);
|
-webkit-backdrop-filter: blur(8px);
|
||||||
filter: drop-shadow(5px 5px 10px #000);
|
filter: drop-shadow(5px 5px 10px #000);
|
||||||
@@ -47,22 +55,28 @@ h3 {
|
|||||||
/* Modal Content/Box */
|
/* Modal Content/Box */
|
||||||
.modal-content {
|
.modal-content {
|
||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
margin: 10% auto; /* 15% from the top and centered */
|
margin: 10% auto;
|
||||||
|
/* 15% from the top and centered */
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 700px; /* Could be more or less, depending on screen size */
|
width: 700px;
|
||||||
|
/* Could be more or less, depending on screen size */
|
||||||
min-height: 358px;
|
min-height: 358px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-content-sub {
|
.modal-content-sub {
|
||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
margin: 20% auto; /* 20% from the top and centered */
|
margin: 20% auto;
|
||||||
|
/* 20% from the top and centered */
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 300px; /* Could be more or less, depending on screen size */
|
width: 300px;
|
||||||
|
/* Could be more or less, depending on screen size */
|
||||||
min-height: 110px;
|
min-height: 110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#modal-heading {
|
#modal-heading {
|
||||||
margin-block: 5px;
|
margin-block: 5px;
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
@@ -70,8 +84,9 @@ h3 {
|
|||||||
border-bottom-width: 3px;
|
border-bottom-width: 3px;
|
||||||
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
|
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
|
||||||
|
|
||||||
border-image: linear-gradient(to right, rgba(255,0,0,1) 0%, rgba(251,255,0,1) 16%, rgba(0,255,250,1) 30%, rgba(0,16,255,1) 46%, rgba(250,0,255,1) 62%, rgba(255,0,0,1) 78%, rgba(255,237,0,1) 90%, rgba(20,255,0,1) 100%) 5;
|
border-image: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(251, 255, 0, 1) 16%, rgba(0, 255, 250, 1) 30%, rgba(0, 16, 255, 1) 46%, rgba(250, 0, 255, 1) 62%, rgba(255, 0, 0, 1) 78%, rgba(255, 237, 0, 1) 90%, rgba(20, 255, 0, 1) 100%) 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#modal-content {
|
#modal-content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -268,7 +283,7 @@ h3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#games_filter {
|
#games_filter {
|
||||||
|
|
||||||
width: 200px;
|
width: 200px;
|
||||||
/* border-style: solid;
|
/* border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@@ -296,7 +311,13 @@ h3 {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='text'], input[type='number'], input[type="email"], input[type="password"], input[type="datetime-local"] {
|
input[type='text'],
|
||||||
|
input[type='number'],
|
||||||
|
input[type="email"],
|
||||||
|
input[type="password"],
|
||||||
|
input[type="datetime-local"],
|
||||||
|
input[type="url"],
|
||||||
|
textarea {
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
@@ -313,10 +334,21 @@ input[type='text'], input[type='number'], input[type="email"], input[type="passw
|
|||||||
height: 21px;
|
height: 21px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='text']:hover, input[type='number']:hover, input[type="email"]:hover, input[type="password"]:hover, input[type="datetime-local"]:hover {
|
input[type='text']:hover,
|
||||||
|
input[type='number']:hover,
|
||||||
|
input[type="email"]:hover,
|
||||||
|
input[type="password"]:hover,
|
||||||
|
input[type="datetime-local"]:hover,
|
||||||
|
input[type="url"]:hover,
|
||||||
|
textarea:hover {
|
||||||
border-color: #939393;
|
border-color: #939393;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
height: unset;
|
||||||
|
font-family: 'Courier New', Courier, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
input[id='filter_panel_search'] {
|
input[id='filter_panel_search'] {
|
||||||
width: 160px;
|
width: 160px;
|
||||||
}
|
}
|
||||||
@@ -351,9 +383,7 @@ input[name='filter_panel_range_max'] {
|
|||||||
background: #555;
|
background: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text_link {
|
.text_link {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.text_link:hover {
|
.text_link:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -390,9 +420,9 @@ input[name='filter_panel_range_max'] {
|
|||||||
background-color: rgba(0, 22, 56, 0.8);
|
background-color: rgba(0, 22, 56, 0.8);
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
-webkit-backdrop-filter: blur(8px);
|
-webkit-backdrop-filter: blur(8px);
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.games_pager_number {
|
.games_pager_number {
|
||||||
@@ -525,13 +555,13 @@ input[name='filter_panel_range_max'] {
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
/* display: flex; */
|
/* display: flex; */
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#games_library_alpha_pager {
|
#games_library_alpha_pager {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.games_library_alpha_pager_letter {
|
.games_library_alpha_pager_letter {
|
||||||
@@ -586,22 +616,22 @@ input[name='filter_panel_range_max'] {
|
|||||||
|
|
||||||
.game_tile:hover {
|
.game_tile:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
/* text-decoration: underline;
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
border-radius: 10px 10px 10px 10px;
|
border-radius: 10px 10px 10px 10px;
|
||||||
-webkit-border-radius: 10px 10px 10px 10px;
|
-webkit-border-radius: 10px 10px 10px 10px;
|
||||||
-moz-border-radius: 10px 10px 10px 10px;
|
-moz-border-radius: 10px 10px 10px 10px;
|
||||||
border: 1px solid #2b2b2b;
|
border: 1px solid #2b2b2b; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_small:hover {
|
.game_tile_small:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
/* text-decoration: underline;
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
border-radius: 10px 10px 10px 10px;
|
border-radius: 10px 10px 10px 10px;
|
||||||
-webkit-border-radius: 10px 10px 10px 10px;
|
-webkit-border-radius: 10px 10px 10px 10px;
|
||||||
-moz-border-radius: 10px 10px 10px 10px;
|
-moz-border-radius: 10px 10px 10px 10px;
|
||||||
border: 1px solid #2b2b2b;
|
border: 1px solid #2b2b2b; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_row {
|
.game_tile_row {
|
||||||
@@ -625,6 +655,19 @@ input[name='filter_panel_range_max'] {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
|
border-radius: 7px;
|
||||||
|
border-width: 2px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game_tile:hover .game_tile_box {
|
||||||
|
border-color: yellow;
|
||||||
|
outline-width: 2px;
|
||||||
|
outline-style: solid;
|
||||||
|
outline-offset: -3px;
|
||||||
|
outline-color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_box_row {
|
.game_tile_box_row {
|
||||||
@@ -706,9 +749,9 @@ input[name='filter_panel_range_max'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image_shadow {
|
.game_tile_image_shadow {
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image_row {
|
.game_tile_image_row {
|
||||||
@@ -720,11 +763,13 @@ input[name='filter_panel_range_max'] {
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image, .unknown {
|
.game_tile_image,
|
||||||
|
.unknown {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image_row, .unknown {
|
.game_tile_image_row,
|
||||||
|
.unknown {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,9 +835,9 @@ input[name='filter_panel_range_max'] {
|
|||||||
max-width: 250px;
|
max-width: 250px;
|
||||||
max-height: 350px;
|
max-height: 350px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gamegenrelabel {
|
.gamegenrelabel {
|
||||||
@@ -842,9 +887,9 @@ input[name='filter_panel_range_max'] {
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
/*height: 350px;*/
|
/*height: 350px;*/
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
#gamescreenshots_main {
|
#gamescreenshots_main {
|
||||||
@@ -903,11 +948,16 @@ iframe {
|
|||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
color: black;
|
color: black;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
user-select: none; /* standard syntax */
|
user-select: none;
|
||||||
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
|
/* standard syntax */
|
||||||
-moz-user-select: none; /* mozilla browsers */
|
-webkit-user-select: none;
|
||||||
-khtml-user-select: none; /* webkit (konqueror) browsers */
|
/* webkit (safari, chrome) browsers */
|
||||||
-ms-user-select: none; /* IE10+ */
|
-moz-user-select: none;
|
||||||
|
/* mozilla browsers */
|
||||||
|
-khtml-user-select: none;
|
||||||
|
/* webkit (konqueror) browsers */
|
||||||
|
-ms-user-select: none;
|
||||||
|
/* IE10+ */
|
||||||
}
|
}
|
||||||
|
|
||||||
.gamescreenshots_arrows:hover {
|
.gamescreenshots_arrows:hover {
|
||||||
@@ -981,9 +1031,7 @@ iframe {
|
|||||||
background-color: rgba(56, 56, 56, 0.9);
|
background-color: rgba(56, 56, 56, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
#gamesummarytext_label {
|
#gamesummarytext_label {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-clamp-4 {
|
.line-clamp-4 {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1057,9 +1105,9 @@ th {
|
|||||||
-webkit-border-radius: 5px 5px 5px 5px;
|
-webkit-border-radius: 5px 5px 5px 5px;
|
||||||
-moz-border-radius: 5px 5px 5px 5px;
|
-moz-border-radius: 5px 5px 5px 5px;
|
||||||
border: 1px solid #19d348;
|
border: 1px solid #19d348;
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.romstart:hover {
|
.romstart:hover {
|
||||||
@@ -1084,9 +1132,9 @@ th {
|
|||||||
border-color: white;
|
border-color: white;
|
||||||
background-color: blue;
|
background-color: blue;
|
||||||
outline-color: blue;
|
outline-color: blue;
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.properties_button:hover {
|
.properties_button:hover {
|
||||||
@@ -1115,14 +1163,18 @@ th {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
div[name="properties_toc_item"],div[name="properties_user_toc_item"],div[name="properties_profile_toc_item"] {
|
div[name="properties_toc_item"],
|
||||||
|
div[name="properties_user_toc_item"],
|
||||||
|
div[name="properties_profile_toc_item"] {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
border-bottom-style: solid;
|
border-bottom-style: solid;
|
||||||
border-bottom-color: #2b2b2b;
|
border-bottom-color: #2b2b2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover,div[name="properties_profile_toc_item"]:hover {
|
div[name="properties_toc_item"]:hover,
|
||||||
|
div[name="properties_user_toc_item"]:hover,
|
||||||
|
div[name="properties_profile_toc_item"]:hover {
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -1150,7 +1202,8 @@ div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select2-container--default:hover, .select2-selection--multiple:hover {
|
.select2-container--default:hover,
|
||||||
|
.select2-selection--multiple:hover {
|
||||||
border-color: #939393;
|
border-color: #939393;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,7 +1250,8 @@ div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select2-selection--single:hover, .select2-selection__rendered:hover {
|
.select2-selection--single:hover,
|
||||||
|
.select2-selection__rendered:hover {
|
||||||
border-color: #939393;
|
border-color: #939393;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1302,9 +1356,7 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
background-color: #555;
|
background-color: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
#emulator {
|
#emulator {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.emulator_partscreen {
|
.emulator_partscreen {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -1377,15 +1429,14 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rom_checkbox_box {
|
.rom_checkbox_box {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.rom_checkbox_box_hidden {
|
.rom_checkbox_box_hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#rom_edit, #rom_edit_delete {
|
#rom_edit,
|
||||||
|
#rom_edit_delete {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1398,9 +1449,9 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#game {
|
#game {
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
#gametitle_criticrating {
|
#gametitle_criticrating {
|
||||||
@@ -1440,7 +1491,7 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
width: 1000px;
|
width: 1000px;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
margin: 25px auto;
|
margin: 25px auto;
|
||||||
/* overflow-x: scroll;*/
|
/* overflow-x: scroll;*/
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1468,7 +1519,8 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bgalt1 {
|
.bgalt1 {
|
||||||
background-color: transparent;;
|
background-color: transparent;
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs_table_cell_150px {
|
.logs_table_cell_150px {
|
||||||
@@ -1520,13 +1572,33 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
}
|
}
|
||||||
|
|
||||||
.string { color: lightblue; }
|
.string {
|
||||||
.number { color: lightblue; }
|
color: lightblue;
|
||||||
.boolean { color: lightblue; }
|
}
|
||||||
.null { color: magenta; }
|
|
||||||
.key { color: greenyellow; }
|
.number {
|
||||||
.brace { color: #888; }
|
color: lightblue;
|
||||||
.square { color: #fff000; }
|
}
|
||||||
|
|
||||||
|
.boolean {
|
||||||
|
color: lightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.null {
|
||||||
|
color: magenta;
|
||||||
|
}
|
||||||
|
|
||||||
|
.key {
|
||||||
|
color: greenyellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.brace {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.square {
|
||||||
|
color: #fff000;
|
||||||
|
}
|
||||||
|
|
||||||
.tagBox {
|
.tagBox {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -1557,12 +1629,16 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.loginwindow {
|
.loginwindow {
|
||||||
position: fixed; /* Stay in place */
|
position: fixed;
|
||||||
|
/* Stay in place */
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%; /* Full width */
|
width: 100%;
|
||||||
height: 100%; /* Full height */
|
/* Full width */
|
||||||
overflow: auto; /* Enable scroll if needed */
|
height: 100%;
|
||||||
|
/* Full height */
|
||||||
|
overflow: auto;
|
||||||
|
/* Enable scroll if needed */
|
||||||
/*background-color: rgb(0,0,0); /* Fallback color */
|
/*background-color: rgb(0,0,0); /* Fallback color */
|
||||||
/*background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
/*background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
|
||||||
/*backdrop-filter: blur(8px);
|
/*backdrop-filter: blur(8px);
|
||||||
@@ -1575,11 +1651,13 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
.loginwindow-content {
|
.loginwindow-content {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: #383838;
|
background-color: #383838;
|
||||||
margin: 15% auto; /* 15% from the top and centered */
|
margin: 15% auto;
|
||||||
|
/* 15% from the top and centered */
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
width: 350px; /* Could be more or less, depending on screen size */
|
width: 350px;
|
||||||
|
/* Could be more or less, depending on screen size */
|
||||||
min-height: 250px;
|
min-height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1615,7 +1693,8 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Links inside the dropdown */
|
/* Links inside the dropdown */
|
||||||
.dropdown-content a, .dropdown-content span {
|
.dropdown-content a,
|
||||||
|
.dropdown-content span {
|
||||||
color: black;
|
color: black;
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@@ -1625,12 +1704,16 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
|
|||||||
.dropdown-content span {
|
.dropdown-content span {
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change color of dropdown links on hover */
|
/* Change color of dropdown links on hover */
|
||||||
.dropdown-content a:hover {background-color: #ddd;}
|
.dropdown-content a:hover {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
|
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
|
||||||
.show {display:block;}
|
.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.dropdownroleitem {
|
.dropdownroleitem {
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
|
Reference in New Issue
Block a user