using System; using System.Data; using gaseous_signature_parser.models.RomSignatureObject; using static gaseous_server.Classes.RomMediaGroup; using gaseous_server.Classes.Metadata; using IGDB.Models; using static HasheousClient.Models.FixMatchModel; using NuGet.Protocol.Core.Types; using static gaseous_server.Classes.FileSignature; namespace gaseous_server.Classes { public class Roms { public class InvalidRomId : Exception { public InvalidRomId(long Id) : base("Unable to find ROM by id " + Id) { } } public class InvalidRomHash : Exception { public InvalidRomHash(String Hash) : base("Unable to find ROM by hash " + Hash) { } } public static GameRomObject GetRoms(long GameId, long PlatformId = -1, string NameSearch = "", int pageNumber = 0, int pageSize = 0, string userid = "") { GameRomObject GameRoms = new GameRomObject(); Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = ""; string sqlCount = ""; string sqlPlatform = ""; Dictionary dbDict = new Dictionary(); dbDict.Add("id", GameId); dbDict.Add("userid", userid); string NameSearchWhere = ""; if (NameSearch.Length > 0) { NameSearchWhere = " AND view_Games_Roms.`Name` LIKE @namesearch"; dbDict.Add("namesearch", '%' + NameSearch + '%'); } string UserFields = ""; string UserJoin = ""; if (userid.Length > 0) { UserFields = ", User_RecentPlayedRoms.RomId AS MostRecentRomId, User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup, User_GameFavouriteRoms.RomId AS FavouriteRomId, User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup"; UserJoin = @" LEFT JOIN User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId AND User_RecentPlayedRoms.RomId = view_Games_Roms.Id AND User_RecentPlayedRoms.IsMediaGroup = 0 LEFT JOIN User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId AND User_GameFavouriteRoms.RomId = view_Games_Roms.Id AND User_GameFavouriteRoms.IsMediaGroup = 0 "; } // platform query sqlPlatform = "SELECT DISTINCT view_Games_Roms.PlatformId, Platform.`Name` FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;"; if (PlatformId == -1) { // data query sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;"; // count query sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + ";"; } else { // data query sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;"; // count query sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";"; dbDict.Add("platformid", PlatformId); } DataTable romDT = db.ExecuteCMD(sql, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks)); Dictionary rowCount = db.ExecuteCMDDict(sqlCount, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks))[0]; if (romDT.Rows.Count > 0) { // set count of roms GameRoms.Count = int.Parse((string)rowCount["RomCount"]); int pageOffset = pageSize * (pageNumber - 1); for (int i = 0; i < romDT.Rows.Count; i++) { if ((i >= pageOffset && i < pageOffset + pageSize) || pageSize == 0) { GameRomItem gameRomItem = BuildRom(romDT.Rows[i]); GameRoms.GameRomItems.Add(gameRomItem); } } return GameRoms; } else { throw new Games.InvalidGameId(GameId); } } public static GameRomItem GetRom(long RomId) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.Id = @id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", RomId); DataTable romDT = db.ExecuteCMD(sql, dbDict); if (romDT.Rows.Count > 0) { DataRow romDR = romDT.Rows[0]; GameRomItem romItem = BuildRom(romDR); return romItem; } else { throw new InvalidRomId(RomId); } } public static GameRomItem GetRom(string MD5) { Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.MD5 = @id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", MD5); DataTable romDT = db.ExecuteCMD(sql, dbDict); if (romDT.Rows.Count > 0) { DataRow romDR = romDT.Rows[0]; GameRomItem romItem = BuildRom(romDR); return romItem; } else { throw new InvalidRomHash(MD5); } } public static GameRomItem UpdateRom(long RomId, long PlatformId, long GameId) { // ensure metadata for platformid is present IGDB.Models.Platform platform = Classes.Metadata.Platforms.GetPlatform(PlatformId); // ensure metadata for gameid is present IGDB.Models.Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false); Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid WHERE Id = @id"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", RomId); dbDict.Add("platformid", PlatformId); dbDict.Add("gameid", GameId); db.ExecuteCMD(sql, dbDict); 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 archiveDataValues = Newtonsoft.Json.JsonConvert.DeserializeObject>(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 metadataMatchList = new List(); 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; } public static void DeleteRom(long RomId) { GameRomItem rom = GetRom(RomId); if (rom.Library.IsDefaultLibrary == true) { if (File.Exists(rom.Path)) { File.Delete(rom.Path); } Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); string sql = "DELETE FROM Games_Roms WHERE Id = @id; DELETE FROM GameState WHERE RomId = @id; UPDATE UserTimeTracking SET PlatformId = NULL, IsMediaGroup = NULL, RomId = NULL WHERE RomId = @id AND IsMediaGroup = 0;"; Dictionary dbDict = new Dictionary(); dbDict.Add("id", RomId); db.ExecuteCMD(sql, dbDict); } } private static GameRomItem BuildRom(DataRow romDR) { bool hasSaveStates = false; if (romDR.Table.Columns.Contains("SavedStateRomId")) { if (romDR["SavedStateRomId"] != DBNull.Value) { hasSaveStates = true; } } Dictionary romAttributes = new Dictionary(); if (romDR["attributes"] != DBNull.Value) { try { if ((string)romDR["attributes"] != "[ ]") { romAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject>((string)romDR["attributes"]); } } catch (Exception ex) { Logging.Log(Logging.LogType.Warning, "Roms", "Error parsing rom attributes: " + ex.Message); } } GameRomItem romItem = new GameRomItem { Id = (long)romDR["id"], PlatformId = (long)romDR["platformid"], Platform = (string)romDR["platformname"], GameId = (long)romDR["gameid"], Game = (string)romDR["gamename"], Name = (string)romDR["name"], Size = (long)romDR["size"], Crc = ((string)romDR["crc"]).ToLower(), Md5 = ((string)romDR["md5"]).ToLower(), Sha1 = ((string)romDR["sha1"]).ToLower(), DevelopmentStatus = (string)romDR["developmentstatus"], Attributes = romAttributes, RomType = (HasheousClient.Models.SignatureModel.RomItem.RomTypes)(int)romDR["romtype"], RomTypeMedia = (string)romDR["romtypemedia"], MediaLabel = (string)romDR["medialabel"], Path = (string)romDR["path"], RelativePath = (string)romDR["relativepath"], SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"], SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""), HasSaveStates = hasSaveStates, Library = GameLibrary.GetLibrary((int)romDR["LibraryId"]) }; romItem.RomUserLastUsed = false; if (romDR.Table.Columns.Contains("MostRecentRomId")) { if (romDR["MostRecentRomId"] != DBNull.Value) { romItem.RomUserLastUsed = true; } } romItem.RomUserFavourite = false; if (romDR.Table.Columns.Contains("FavouriteRomId")) { if (romDR["FavouriteRomId"] != DBNull.Value) { romItem.RomUserFavourite = true; } } return romItem; } public class GameRomObject { public List GameRomItems { get; set; } = new List(); public int Count { get; set; } } public class GameRomItem : HasheousClient.Models.SignatureModel.RomItem { public long PlatformId { get; set; } public string Platform { get; set; } public long GameId { get; set; } public string Game { get; set; } public string? Path { get; set; } public string? RelativePath { get; set; } public string? SignatureSourceGameTitle { get; set; } public bool HasSaveStates { get; set; } = false; public GameLibrary.LibraryItem Library { get; set; } public bool RomUserLastUsed { get; set; } public bool RomUserFavourite { get; set; } } } }