Compare commits
22 Commits
v1.1.0
...
branch-v1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
df58fb8817 | ||
![]() |
0e4cfccee0 | ||
![]() |
014c33d46c | ||
![]() |
1dd6a8f71a | ||
![]() |
c396a81c1b | ||
![]() |
59df041cfd | ||
![]() |
2355c5ac97 | ||
![]() |
7891acd218 | ||
![]() |
4ad51e98e2 | ||
![]() |
8a001f9fa4 | ||
![]() |
98fb360483 | ||
![]() |
56cbc441f5 | ||
![]() |
113de6a009 | ||
![]() |
dc2a6b4638 | ||
![]() |
9081b0bed9 | ||
![]() |
d64877543a | ||
![]() |
649fba1bfa | ||
![]() |
7dfb97608f | ||
![]() |
35bb2f18d9 | ||
![]() |
ad84f5ae58 | ||
![]() |
922c429716 | ||
![]() |
a2d634d96f |
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@@ -9,3 +9,9 @@ updates:
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
allow:
|
||||
- dependency-name: "gaseous-server/wwwroot/emulators/EmulatorJS"
|
||||
schedule:
|
||||
interval: "weekly"
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,3 @@
|
||||
[submodule "gaseous-server/wwwroot/EmulatorJS"]
|
||||
path = gaseous-server/wwwroot/EmulatorJS
|
||||
[submodule "gaseous-server/wwwroot/emulators/EmulatorJS"]
|
||||
path = gaseous-server/wwwroot/emulators/EmulatorJS
|
||||
url = https://github.com/EmulatorJS/EmulatorJS.git
|
||||
|
@@ -21,6 +21,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
Dockerfile = Dockerfile
|
||||
README.MD = README.MD
|
||||
LICENSE = LICENSE
|
||||
.gitignore = .gitignore
|
||||
.github\dependabot.yml = .github\dependabot.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "screenshots", "screenshots", "{F1A847C7-57BC-4DA9-8F83-CD060A7F5122}"
|
||||
|
BIN
gaseous-server/.DS_Store
vendored
BIN
gaseous-server/.DS_Store
vendored
Binary file not shown.
120
gaseous-server/Classes/Bios.cs
Normal file
120
gaseous-server/Classes/Bios.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using gaseous_tools;
|
||||
|
||||
namespace gaseous_server.Classes
|
||||
{
|
||||
public class Bios
|
||||
{
|
||||
public Bios()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static Models.PlatformMapping.PlatformMapItem? BiosHashSignatureLookup(string MD5)
|
||||
{
|
||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||
{
|
||||
if (platformMapping.WebEmulator != null)
|
||||
{
|
||||
if (platformMapping.WebEmulator.Bios != null)
|
||||
{
|
||||
foreach (Models.PlatformMapping.PlatformMapItem.WebEmulatorItem.EmulatorBiosItem emulatorBiosItem in platformMapping.WebEmulator.Bios)
|
||||
{
|
||||
if (emulatorBiosItem.hash.ToLower() == MD5.ToLower())
|
||||
{
|
||||
return platformMapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<BiosItem> GetBios()
|
||||
{
|
||||
return BuildBiosList();
|
||||
}
|
||||
|
||||
public static List<BiosItem> GetBios(long PlatformId, bool HideUnavailable)
|
||||
{
|
||||
List<BiosItem> biosItems = new List<BiosItem>();
|
||||
foreach (BiosItem biosItem in BuildBiosList())
|
||||
{
|
||||
if (biosItem.platformid == PlatformId)
|
||||
{
|
||||
if (HideUnavailable == true)
|
||||
{
|
||||
if (biosItem.Available == true)
|
||||
{
|
||||
biosItems.Add(biosItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
biosItems.Add(biosItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return biosItems;
|
||||
}
|
||||
|
||||
private static List<BiosItem> BuildBiosList()
|
||||
{
|
||||
List<BiosItem> biosItems = new List<BiosItem>();
|
||||
|
||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||
{
|
||||
if (platformMapping.WebEmulator != null)
|
||||
{
|
||||
if (platformMapping.WebEmulator.Bios != null)
|
||||
{
|
||||
IGDB.Models.Platform platform = Metadata.Platforms.GetPlatform(platformMapping.IGDBId);
|
||||
|
||||
foreach (Models.PlatformMapping.PlatformMapItem.WebEmulatorItem.EmulatorBiosItem emulatorBios in platformMapping.WebEmulator.Bios)
|
||||
{
|
||||
BiosItem biosItem = new BiosItem
|
||||
{
|
||||
platformid = platformMapping.IGDBId,
|
||||
platformslug = platform.Slug,
|
||||
platformname = platform.Name,
|
||||
description = emulatorBios.description,
|
||||
filename = emulatorBios.filename,
|
||||
region = emulatorBios.region,
|
||||
hash = emulatorBios.hash
|
||||
};
|
||||
biosItems.Add(biosItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return biosItems;
|
||||
}
|
||||
|
||||
public class BiosItem : Models.PlatformMapping.PlatformMapItem.WebEmulatorItem.EmulatorBiosItem
|
||||
{
|
||||
public long platformid { get; set; }
|
||||
public string platformslug { get; set; }
|
||||
public string platformname { get; set; }
|
||||
public string biosPath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(Config.LibraryConfiguration.LibraryBIOSDirectory, platformslug, base.filename);
|
||||
}
|
||||
}
|
||||
public bool Available {
|
||||
get
|
||||
{
|
||||
bool fileExists = File.Exists(biosPath);
|
||||
return fileExists;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Policy;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
@@ -58,42 +59,104 @@ namespace gaseous_server.Classes
|
||||
FileInfo fi = new FileInfo(GameFileImportPath);
|
||||
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
||||
|
||||
// check to make sure we don't already have this file imported
|
||||
sql = "SELECT COUNT(Id) AS count FROM Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
|
||||
dbDict.Add("md5", hash.md5hash);
|
||||
dbDict.Add("sha1", hash.sha1hash);
|
||||
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
||||
if ((Int64)importDB.Rows[0]["count"] > 0)
|
||||
{
|
||||
if (!GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
|
||||
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
|
||||
|
||||
// process as a single file
|
||||
Models.Signatures_Games discoveredSignature = GetFileSignature(hash, fi, GameFileImportPath);
|
||||
if (IsBios == null)
|
||||
{
|
||||
// file is a rom
|
||||
// check to make sure we don't already have this file imported
|
||||
sql = "SELECT COUNT(Id) AS count FROM Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
|
||||
dbDict.Add("md5", hash.md5hash);
|
||||
dbDict.Add("sha1", hash.sha1hash);
|
||||
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
||||
if ((Int64)importDB.Rows[0]["count"] > 0)
|
||||
{
|
||||
if (!GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
|
||||
|
||||
// get discovered platform
|
||||
IGDB.Models.Platform determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
|
||||
if (determinedPlatform == null)
|
||||
{
|
||||
determinedPlatform = new IGDB.Models.Platform();
|
||||
}
|
||||
Models.Signatures_Games discoveredSignature = GetFileSignature(hash, fi, GameFileImportPath);
|
||||
|
||||
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature.Game.Name, discoveredSignature.Flags.IGDBPlatformId);
|
||||
// get discovered platform
|
||||
IGDB.Models.Platform determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
|
||||
if (determinedPlatform == null)
|
||||
{
|
||||
determinedPlatform = new IGDB.Models.Platform();
|
||||
}
|
||||
|
||||
// add to database
|
||||
StoreROM(hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath);
|
||||
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature.Game.Name, discoveredSignature.Flags.IGDBPlatformId);
|
||||
|
||||
// add to database
|
||||
StoreROM(hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// file is a bios
|
||||
if (IsBios.WebEmulator != null)
|
||||
{
|
||||
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
||||
{
|
||||
if (biosItem.Available == false && biosItem.hash == hash.md5hash)
|
||||
{
|
||||
string biosPath = biosItem.biosPath.Replace(biosItem.filename, "");
|
||||
if (!Directory.Exists(biosPath))
|
||||
{
|
||||
Directory.CreateDirectory(biosPath);
|
||||
}
|
||||
|
||||
File.Move(GameFileImportPath, biosItem.biosPath, true);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Models.Signatures_Games GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
public static Models.Signatures_Games GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
{
|
||||
Models.Signatures_Games discoveredSignature = _GetFileSignature(hash, fi, GameFileImportPath);
|
||||
|
||||
if ((Path.GetExtension(GameFileImportPath) == ".zip") && (fi.Length < 1073741824))
|
||||
{
|
||||
// file is a zip and less than 1 GiB
|
||||
// extract the zip file and search the contents
|
||||
string ExtractPath = Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "Temp", Path.GetRandomFileName());
|
||||
if (!Directory.Exists(ExtractPath)) { Directory.CreateDirectory(ExtractPath); }
|
||||
ZipFile.ExtractToDirectory(GameFileImportPath, ExtractPath);
|
||||
|
||||
// loop through contents until we find the first signature match
|
||||
foreach (string file in Directory.GetFiles(ExtractPath))
|
||||
{
|
||||
FileInfo zfi = new FileInfo(file);
|
||||
Common.hashObject zhash = new Common.hashObject(file);
|
||||
|
||||
Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi, file);
|
||||
zDiscoveredSignature.Rom.Name = Path.ChangeExtension(zDiscoveredSignature.Rom.Name, ".zip");
|
||||
|
||||
if (zDiscoveredSignature.Score > discoveredSignature.Score)
|
||||
{
|
||||
discoveredSignature = zDiscoveredSignature;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Directory.Exists(ExtractPath)) { Directory.Delete(ExtractPath, true); }
|
||||
}
|
||||
|
||||
return discoveredSignature;
|
||||
}
|
||||
|
||||
private static Models.Signatures_Games _GetFileSignature(Common.hashObject hash, FileInfo fi, string GameFileImportPath)
|
||||
{
|
||||
// check 1: do we have a signature for it?
|
||||
gaseous_server.Controllers.SignaturesController sc = new Controllers.SignaturesController();
|
||||
@@ -204,7 +267,7 @@ namespace gaseous_server.Classes
|
||||
if (games.Length == 1)
|
||||
{
|
||||
// exact match!
|
||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false);
|
||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
|
||||
GameFound = true;
|
||||
break;
|
||||
@@ -312,7 +375,7 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
||||
dbDict.Add("gameid", Common.ReturnValueIfNull(determinedGame.Id, 0));
|
||||
dbDict.Add("name", Common.ReturnValueIfNull(discoveredSignature.Rom.Name, ""));
|
||||
dbDict.Add("name", Common.ReturnValueIfNull(discoveredSignature.Rom.Name, 0));
|
||||
dbDict.Add("size", Common.ReturnValueIfNull(discoveredSignature.Rom.Size, 0));
|
||||
dbDict.Add("md5", hash.md5hash);
|
||||
dbDict.Add("sha1", hash.sha1hash);
|
||||
@@ -362,7 +425,7 @@ namespace gaseous_server.Classes
|
||||
|
||||
// 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);
|
||||
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false, false);
|
||||
|
||||
// build path
|
||||
string platformSlug = "Unknown Platform";
|
||||
|
@@ -21,7 +21,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static Game? GetGame(long Id, bool followSubGames, bool forceRefresh)
|
||||
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||
{
|
||||
if (Id == 0)
|
||||
{
|
||||
@@ -45,14 +45,14 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.id, Id, followSubGames, forceRefresh);
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.id, Id, getAllMetadata, followSubGames, forceRefresh);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Game GetGame(string Slug, bool followSubGames, bool forceRefresh)
|
||||
public static Game GetGame(string Slug, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||
{
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.slug, Slug, followSubGames, forceRefresh);
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.slug, Slug, getAllMetadata, followSubGames, forceRefresh);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
return Storage.BuildCacheObject<Game>(new Game(), dataRow);
|
||||
}
|
||||
|
||||
private static async Task<Game> _GetGame(SearchUsing searchUsing, object searchValue, bool followSubGames = false, bool forceRefresh = false)
|
||||
private static async Task<Game> _GetGame(SearchUsing searchUsing, object searchValue, bool getAllMetadata = true, bool followSubGames = false, bool forceRefresh = false)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
@@ -99,12 +99,12 @@ namespace gaseous_server.Classes.Metadata
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
UpdateSubClasses(returnValue, followSubGames);
|
||||
UpdateSubClasses(returnValue, getAllMetadata, followSubGames);
|
||||
return returnValue;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
UpdateSubClasses(returnValue, followSubGames);
|
||||
UpdateSubClasses(returnValue, getAllMetadata, followSubGames);
|
||||
return returnValue;
|
||||
case Storage.CacheStatus.Current:
|
||||
return Storage.GetCacheValue<Game>(returnValue, "id", (long)searchValue);
|
||||
@@ -113,117 +113,120 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateSubClasses(Game Game, bool followSubGames)
|
||||
private static void UpdateSubClasses(Game Game, bool getAllMetadata, bool followSubGames)
|
||||
{
|
||||
if (Game.AgeRatings != null)
|
||||
{
|
||||
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
||||
{
|
||||
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.AlternativeNames != null)
|
||||
{
|
||||
foreach (long AlternativeNameId in Game.AlternativeNames.Ids)
|
||||
{
|
||||
AlternativeName GameAlternativeName = AlternativeNames.GetAlternativeNames(AlternativeNameId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Artworks != null)
|
||||
{
|
||||
foreach (long ArtworkId in Game.Artworks.Ids)
|
||||
{
|
||||
Artwork GameArtwork = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
}
|
||||
|
||||
if (followSubGames)
|
||||
{
|
||||
List<long> gamesToFetch = new List<long>();
|
||||
if (Game.Bundles != null) { gamesToFetch.AddRange(Game.Bundles.Ids); }
|
||||
if (Game.Dlcs != null) { gamesToFetch.AddRange(Game.Dlcs.Ids); }
|
||||
if (Game.Expansions != null) { gamesToFetch.AddRange(Game.Expansions.Ids); }
|
||||
if (Game.ParentGame != null) { gamesToFetch.Add((long)Game.ParentGame.Id); }
|
||||
//if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); }
|
||||
if (Game.StandaloneExpansions != null) { gamesToFetch.AddRange(Game.StandaloneExpansions.Ids); }
|
||||
if (Game.VersionParent != null) { gamesToFetch.Add((long)Game.VersionParent.Id); }
|
||||
|
||||
foreach (long gameId in gamesToFetch)
|
||||
{
|
||||
Game relatedGame = GetGame(gameId, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Collection != null)
|
||||
{
|
||||
Collection GameCollection = Collections.GetCollections(Game.Collection.Id);
|
||||
}
|
||||
|
||||
if (Game.Cover != null)
|
||||
{
|
||||
Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
|
||||
if (Game.ExternalGames != null)
|
||||
if (getAllMetadata == true)
|
||||
{
|
||||
foreach (long ExternalGameId in Game.ExternalGames.Ids)
|
||||
if (Game.AgeRatings != null)
|
||||
{
|
||||
ExternalGame GameExternalGame = ExternalGames.GetExternalGames(ExternalGameId);
|
||||
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
||||
{
|
||||
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Franchise != null)
|
||||
{
|
||||
Franchise GameFranchise = Franchises.GetFranchises(Game.Franchise.Id);
|
||||
}
|
||||
|
||||
if (Game.Franchises != null)
|
||||
{
|
||||
foreach (long FranchiseId in Game.Franchises.Ids)
|
||||
if (Game.AlternativeNames != null)
|
||||
{
|
||||
Franchise GameFranchise = Franchises.GetFranchises(FranchiseId);
|
||||
foreach (long AlternativeNameId in Game.AlternativeNames.Ids)
|
||||
{
|
||||
AlternativeName GameAlternativeName = AlternativeNames.GetAlternativeNames(AlternativeNameId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Genres != null)
|
||||
{
|
||||
foreach (long GenreId in Game.Genres.Ids)
|
||||
if (Game.Artworks != null)
|
||||
{
|
||||
Genre GameGenre = Genres.GetGenres(GenreId);
|
||||
foreach (long ArtworkId in Game.Artworks.Ids)
|
||||
{
|
||||
Artwork GameArtwork = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.InvolvedCompanies != null)
|
||||
{
|
||||
foreach (long involvedCompanyId in Game.InvolvedCompanies.Ids)
|
||||
if (followSubGames)
|
||||
{
|
||||
InvolvedCompany involvedCompany = InvolvedCompanies.GetInvolvedCompanies(involvedCompanyId);
|
||||
List<long> gamesToFetch = new List<long>();
|
||||
if (Game.Bundles != null) { gamesToFetch.AddRange(Game.Bundles.Ids); }
|
||||
if (Game.Dlcs != null) { gamesToFetch.AddRange(Game.Dlcs.Ids); }
|
||||
if (Game.Expansions != null) { gamesToFetch.AddRange(Game.Expansions.Ids); }
|
||||
if (Game.ParentGame != null) { gamesToFetch.Add((long)Game.ParentGame.Id); }
|
||||
//if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); }
|
||||
if (Game.StandaloneExpansions != null) { gamesToFetch.AddRange(Game.StandaloneExpansions.Ids); }
|
||||
if (Game.VersionParent != null) { gamesToFetch.Add((long)Game.VersionParent.Id); }
|
||||
|
||||
foreach (long gameId in gamesToFetch)
|
||||
{
|
||||
Game relatedGame = GetGame(gameId, false, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Platforms != null)
|
||||
{
|
||||
foreach (long PlatformId in Game.Platforms.Ids)
|
||||
if (Game.Collection != null)
|
||||
{
|
||||
Platform GamePlatform = Platforms.GetPlatform(PlatformId);
|
||||
Collection GameCollection = Collections.GetCollections(Game.Collection.Id);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Screenshots != null)
|
||||
{
|
||||
foreach (long ScreenshotId in Game.Screenshots.Ids)
|
||||
if (Game.ExternalGames != null)
|
||||
{
|
||||
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
foreach (long ExternalGameId in Game.ExternalGames.Ids)
|
||||
{
|
||||
ExternalGame GameExternalGame = ExternalGames.GetExternalGames(ExternalGameId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Videos != null)
|
||||
{
|
||||
foreach (long GameVideoId in Game.Videos.Ids)
|
||||
if (Game.Franchise != null)
|
||||
{
|
||||
GameVideo gameVideo = GamesVideos.GetGame_Videos(GameVideoId);
|
||||
Franchise GameFranchise = Franchises.GetFranchises(Game.Franchise.Id);
|
||||
}
|
||||
|
||||
if (Game.Franchises != null)
|
||||
{
|
||||
foreach (long FranchiseId in Game.Franchises.Ids)
|
||||
{
|
||||
Franchise GameFranchise = Franchises.GetFranchises(FranchiseId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Genres != null)
|
||||
{
|
||||
foreach (long GenreId in Game.Genres.Ids)
|
||||
{
|
||||
Genre GameGenre = Genres.GetGenres(GenreId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.InvolvedCompanies != null)
|
||||
{
|
||||
foreach (long involvedCompanyId in Game.InvolvedCompanies.Ids)
|
||||
{
|
||||
InvolvedCompany involvedCompany = InvolvedCompanies.GetInvolvedCompanies(involvedCompanyId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Platforms != null)
|
||||
{
|
||||
foreach (long PlatformId in Game.Platforms.Ids)
|
||||
{
|
||||
Platform GamePlatform = Platforms.GetPlatform(PlatformId);
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Screenshots != null)
|
||||
{
|
||||
foreach (long ScreenshotId in Game.Screenshots.Ids)
|
||||
{
|
||||
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
}
|
||||
|
||||
if (Game.Videos != null)
|
||||
{
|
||||
foreach (long GameVideoId in Game.Videos.Ids)
|
||||
{
|
||||
GameVideo gameVideo = GamesVideos.GetGame_Videos(GameVideoId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ namespace gaseous_server.Classes
|
||||
try
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")");
|
||||
Metadata.Games.GetGame((long)dr["id"], true, forceRefresh);
|
||||
Metadata.Games.GetGame((long)dr["id"], true, true, forceRefresh);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@@ -56,7 +56,7 @@ namespace gaseous_server.Classes
|
||||
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);
|
||||
IGDB.Models.Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid WHERE Id = @id";
|
||||
@@ -128,8 +128,9 @@ namespace gaseous_server.Classes
|
||||
public long Id { get; set; }
|
||||
public long PlatformId { get; set; }
|
||||
public IGDB.Models.Platform Platform { get; set; }
|
||||
public Dictionary<string, string>? Emulator { get; set; }
|
||||
public long GameId { get; set; }
|
||||
//public Dictionary<string, object>? Emulator { get; set; }
|
||||
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||
public long GameId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public long Size { get; set; }
|
||||
public string? CRC { get; set; }
|
||||
|
109
gaseous-server/Controllers/BiosController.cs
Normal file
109
gaseous-server/Controllers/BiosController.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v1/[controller]")]
|
||||
public class BiosController : Controller
|
||||
{
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public List<Classes.Bios.BiosItem> GetBios()
|
||||
{
|
||||
return Classes.Bios.GetBios();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("{PlatformId}")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public List<Classes.Bios.BiosItem> GetBios(long PlatformId, bool AvailableOnly = true)
|
||||
{
|
||||
return Classes.Bios.GetBios(PlatformId, AvailableOnly);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpHead]
|
||||
[Route("zip/{PlatformId}")]
|
||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult GetBiosCompressed(long PlatformId)
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Platform platform = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||
|
||||
string biosPath = Path.Combine(gaseous_tools.Config.LibraryConfiguration.LibraryBIOSDirectory, platform.Slug);
|
||||
|
||||
string tempFile = Path.GetTempFileName();
|
||||
|
||||
using (FileStream zipFile = System.IO.File.Create(tempFile))
|
||||
using (var zipArchive = new ZipArchive(zipFile, ZipArchiveMode.Create))
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(biosPath))
|
||||
{
|
||||
zipArchive.CreateEntryFromFile(file, Path.GetFileName(file));
|
||||
}
|
||||
}
|
||||
|
||||
var stream = new FileStream(tempFile, FileMode.Open);
|
||||
return File(stream, "application/zip", platform.Slug + ".zip");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpHead]
|
||||
[Route("{PlatformId}/{BiosName}")]
|
||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult BiosFile(long PlatformId, string BiosName)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios(PlatformId, true))
|
||||
{
|
||||
if (biosItem.filename == BiosName)
|
||||
{
|
||||
if (System.IO.File.Exists(biosItem.biosPath))
|
||||
{
|
||||
string filename = Path.GetFileName(biosItem.biosPath);
|
||||
string filepath = biosItem.biosPath;
|
||||
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||
string contentType = "application/octet-stream";
|
||||
|
||||
var cd = new System.Net.Mime.ContentDisposition
|
||||
{
|
||||
FileName = filename,
|
||||
Inline = false,
|
||||
};
|
||||
|
||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
||||
|
||||
return File(filedata, contentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NotFound();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -136,7 +136,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, forceRefresh);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, forceRefresh, false, forceRefresh);
|
||||
|
||||
if (gameObject != null)
|
||||
{
|
||||
@@ -162,7 +162,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
if (gameObject.AlternativeNames != null)
|
||||
{
|
||||
@@ -193,7 +193,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
if (gameObject.AgeRatings != null)
|
||||
{
|
||||
@@ -303,7 +303,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
List<Artwork> artworks = new List<Artwork>();
|
||||
if (gameObject.Artworks != null)
|
||||
@@ -332,7 +332,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -365,7 +365,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -420,7 +420,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null)
|
||||
{
|
||||
IGDB.Models.Cover coverObject = Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject));
|
||||
@@ -452,7 +452,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Cover.png");
|
||||
if (System.IO.File.Exists(coverFilePath)) {
|
||||
@@ -492,7 +492,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null)
|
||||
{
|
||||
List<IGDB.Models.Genre> genreObjects = new List<Genre>();
|
||||
@@ -528,7 +528,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null)
|
||||
{
|
||||
List<Dictionary<string, object>> icObjects = new List<Dictionary<string, object>>();
|
||||
@@ -571,7 +571,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null)
|
||||
{
|
||||
List<Dictionary<string, object>> icObjects = new List<Dictionary<string, object>>();
|
||||
@@ -611,7 +611,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
InvolvedCompany involvedCompany = Classes.Metadata.InvolvedCompanies.GetInvolvedCompanies(CompanyId);
|
||||
Company company = Classes.Metadata.Companies.GetCompanies(involvedCompany.Company.Id);
|
||||
@@ -655,7 +655,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
List<Classes.Roms.GameRomItem> roms = Classes.Roms.GetRoms(GameId);
|
||||
|
||||
@@ -676,7 +676,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||
if (rom.GameId == GameId)
|
||||
@@ -702,7 +702,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||
if (rom.GameId == GameId)
|
||||
@@ -729,7 +729,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||
if (rom.GameId == GameId)
|
||||
@@ -757,7 +757,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||
if (rom.GameId != GameId)
|
||||
@@ -768,21 +768,44 @@ namespace gaseous_server.Controllers
|
||||
string romFilePath = rom.Path;
|
||||
if (System.IO.File.Exists(romFilePath))
|
||||
{
|
||||
string filename = Path.GetFileName(romFilePath);
|
||||
string filepath = romFilePath;
|
||||
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||
string contentType = "application/octet-stream";
|
||||
FileStream content = new FileStream(romFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
FileStreamResult response = File(content, "application/octet-stream", rom.Name);
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpHead]
|
||||
[Route("{GameId}/roms/{RomId}/{FileName}")]
|
||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult GameRomFile(long GameId, long RomId, string FileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
var cd = new System.Net.Mime.ContentDisposition
|
||||
{
|
||||
FileName = filename,
|
||||
Inline = false,
|
||||
};
|
||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||
if (rom.GameId != GameId || rom.Name != FileName)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
||||
|
||||
return File(filedata, contentType);
|
||||
string romFilePath = rom.Path;
|
||||
if (System.IO.File.Exists(romFilePath))
|
||||
{
|
||||
FileStream content = new FileStream(romFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
FileStreamResult response = File(content, "application/octet-stream", rom.Name);
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -841,7 +864,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
List<Screenshot> screenshots = new List<Screenshot>();
|
||||
if (gameObject.Screenshots != null)
|
||||
@@ -870,7 +893,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null) {
|
||||
IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject));
|
||||
if (screenshotObject != null)
|
||||
@@ -901,7 +924,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject));
|
||||
|
||||
@@ -944,7 +967,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false);
|
||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
|
||||
List<GameVideo> videos = new List<GameVideo>();
|
||||
if (gameObject.Videos != null)
|
||||
|
80
gaseous-server/Controllers/RomsController.cs
Normal file
80
gaseous-server/Controllers/RomsController.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using gaseous_server.Classes.Metadata;
|
||||
using gaseous_tools;
|
||||
using IGDB.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.CodeAnalysis.Scripting;
|
||||
using Org.BouncyCastle.Asn1.X509;
|
||||
using static gaseous_server.Classes.Metadata.AgeRatings;
|
||||
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v1/[controller]")]
|
||||
[ApiController]
|
||||
public class RomsController : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
[ProducesResponseType(typeof(List<IFormFile>), StatusCodes.Status200OK)]
|
||||
[RequestSizeLimit(long.MaxValue)]
|
||||
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue, ValueLengthLimit = int.MaxValue)]
|
||||
public async Task<IActionResult> UploadRom(List<IFormFile> files)
|
||||
{
|
||||
Guid sessionid = Guid.NewGuid();
|
||||
|
||||
string workPath = Path.Combine(Config.LibraryConfiguration.LibraryUploadDirectory, sessionid.ToString());
|
||||
|
||||
long size = files.Sum(f => f.Length);
|
||||
|
||||
List<Dictionary<string, object>> UploadedFiles = new List<Dictionary<string, object>>();
|
||||
|
||||
foreach (IFormFile formFile in files)
|
||||
{
|
||||
if (formFile.Length > 0)
|
||||
{
|
||||
Guid FileId = Guid.NewGuid();
|
||||
|
||||
string filePath = Path.Combine(workPath, Path.GetFileName(formFile.FileName));
|
||||
|
||||
if (!Directory.Exists(workPath))
|
||||
{
|
||||
Directory.CreateDirectory(workPath);
|
||||
}
|
||||
|
||||
using (var stream = System.IO.File.Create(filePath))
|
||||
{
|
||||
await formFile.CopyToAsync(stream);
|
||||
|
||||
Dictionary<string, object> UploadedFile = new Dictionary<string, object>();
|
||||
UploadedFile.Add("id", FileId.ToString());
|
||||
UploadedFile.Add("originalname", Path.GetFileName(formFile.FileName));
|
||||
UploadedFile.Add("fullpath", filePath);
|
||||
UploadedFiles.Add(UploadedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process uploaded files
|
||||
// Don't rely on or trust the FileName property without validation.
|
||||
|
||||
foreach (Dictionary<string, object> UploadedFile in UploadedFiles)
|
||||
{
|
||||
Classes.ImportGame.ImportGameFile((string)UploadedFile["fullpath"]);
|
||||
}
|
||||
|
||||
if (Directory.Exists(workPath))
|
||||
{
|
||||
Directory.Delete(workPath, true);
|
||||
}
|
||||
|
||||
return Ok(new { count = files.Count, size });
|
||||
}
|
||||
}
|
||||
}
|
@@ -14,35 +14,73 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public Dictionary<string, object> GetSystemStatus()
|
||||
public SystemInfo GetSystemStatus()
|
||||
{
|
||||
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
|
||||
Dictionary<string, object> ReturnValue = new Dictionary<string, object>();
|
||||
SystemInfo ReturnValue = new SystemInfo();
|
||||
|
||||
// disk size
|
||||
List<Dictionary<string, object>> Disks = new List<Dictionary<string, object>>();
|
||||
List<SystemInfo.PathItem> Disks = new List<SystemInfo.PathItem>();
|
||||
//Disks.Add(GetDisk(gaseous_tools.Config.ConfigurationPath));
|
||||
Disks.Add(GetDisk(gaseous_tools.Config.LibraryConfiguration.LibraryRootDirectory));
|
||||
ReturnValue.Add("Paths", Disks);
|
||||
ReturnValue.Paths = Disks;
|
||||
|
||||
// database size
|
||||
string sql = "SELECT table_schema, SUM(data_length + index_length) FROM information_schema.tables WHERE table_schema = '" + Config.DatabaseConfiguration.DatabaseName + "'";
|
||||
DataTable dbResponse = db.ExecuteCMD(sql);
|
||||
ReturnValue.Add("DatabaseSize", dbResponse.Rows[0][1]);
|
||||
ReturnValue.DatabaseSize = (long)(System.Decimal)dbResponse.Rows[0][1];
|
||||
|
||||
// platform statistics
|
||||
sql = "SELECT Platform.`name`, grc.Count, grs.Size FROM Platform INNER JOIN (SELECT Platform.`name` AS `Name`, SUM(grs.Size) AS Size FROM Platform JOIN Games_Roms AS grs ON (grs.PlatformId = Platform.Id) GROUP BY Platform.`name`) grs ON (grs.`Name` = Platform.`name`) INNER JOIN (SELECT Platform.`name` AS `Name`, COUNT(grc.Size) AS Count FROM Platform JOIN Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;";
|
||||
dbResponse = db.ExecuteCMD(sql);
|
||||
ReturnValue.PlatformStatistics = new List<SystemInfo.PlatformStatisticsItem>();
|
||||
foreach (DataRow dr in dbResponse.Rows)
|
||||
{
|
||||
SystemInfo.PlatformStatisticsItem platformStatisticsItem = new SystemInfo.PlatformStatisticsItem
|
||||
{
|
||||
Platform = (string)dr["name"],
|
||||
RomCount = (long)dr["Count"],
|
||||
TotalSize = (long)(System.Decimal)dr["Size"]
|
||||
};
|
||||
ReturnValue.PlatformStatistics.Add(platformStatisticsItem);
|
||||
}
|
||||
|
||||
return ReturnValue;
|
||||
}
|
||||
|
||||
private Dictionary<string, object> GetDisk(string Path)
|
||||
private SystemInfo.PathItem GetDisk(string Path)
|
||||
{
|
||||
Dictionary<string, object> DiskValues = new Dictionary<string, object>();
|
||||
DiskValues.Add("LibraryPath", Path);
|
||||
DiskValues.Add("SpaceUsed", gaseous_tools.Common.DirSize(new DirectoryInfo(Path)));
|
||||
DiskValues.Add("SpaceAvailable", new DriveInfo(Path).AvailableFreeSpace);
|
||||
DiskValues.Add("TotalSpace", new DriveInfo(Path).TotalSize);
|
||||
SystemInfo.PathItem pathItem = new SystemInfo.PathItem {
|
||||
LibraryPath = Path,
|
||||
SpaceUsed = gaseous_tools.Common.DirSize(new DirectoryInfo(Path)),
|
||||
SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace,
|
||||
TotalSpace = new DriveInfo(Path).TotalSize
|
||||
};
|
||||
|
||||
return DiskValues;
|
||||
return pathItem;
|
||||
}
|
||||
|
||||
public class SystemInfo
|
||||
{
|
||||
public List<PathItem>? Paths { get; set; }
|
||||
public long DatabaseSize { get; set; }
|
||||
public List<PlatformStatisticsItem>? PlatformStatistics { get; set; }
|
||||
|
||||
public class PathItem
|
||||
{
|
||||
public string LibraryPath { get; set; }
|
||||
public long SpaceUsed { get; set; }
|
||||
public long SpaceAvailable { get; set; }
|
||||
public long TotalSpace { get; set; }
|
||||
}
|
||||
|
||||
public class PlatformStatisticsItem
|
||||
{
|
||||
public string Platform { get; set; }
|
||||
public long RomCount { get; set; }
|
||||
public long TotalSize { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using gaseous_server.Classes;
|
||||
|
||||
namespace gaseous_server.Models
|
||||
{
|
||||
@@ -10,23 +12,21 @@ namespace gaseous_server.Models
|
||||
|
||||
}
|
||||
|
||||
private static List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>();
|
||||
//private static List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>();
|
||||
public static List<PlatformMapItem> PlatformMap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_PlatformMaps.Count == 0)
|
||||
// load platform maps from: gaseous_server.Support.PlatformMap.json
|
||||
List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>();
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var resourceName = "gaseous_server.Support.PlatformMap.json";
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
// load platform maps from: gaseous_server.Support.PlatformMap.json
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var resourceName = "gaseous_server.Support.PlatformMap.json";
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
string rawJson = reader.ReadToEnd();
|
||||
_PlatformMaps.Clear();
|
||||
_PlatformMaps = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
|
||||
}
|
||||
string rawJson = reader.ReadToEnd();
|
||||
_PlatformMaps.Clear();
|
||||
_PlatformMaps = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
|
||||
}
|
||||
|
||||
return _PlatformMaps;
|
||||
@@ -73,13 +73,28 @@ namespace gaseous_server.Models
|
||||
}
|
||||
|
||||
public class PlatformMapItem
|
||||
{
|
||||
{
|
||||
public int IGDBId { get; set; }
|
||||
public string IGDBName { get; set; }
|
||||
public List<string> AlternateNames { get; set; } = new List<string>();
|
||||
public List<string> KnownFileExtensions { get; set; } = new List<string>();
|
||||
public Dictionary<string, string>? WebEmulator { get; set; }
|
||||
//public Dictionary<string, object>? WebEmulator { get; set; }
|
||||
public WebEmulatorItem? WebEmulator { get; set; }
|
||||
|
||||
public class WebEmulatorItem
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public string Core { get; set; }
|
||||
public List<EmulatorBiosItem> Bios { get; set; }
|
||||
|
||||
public class EmulatorBiosItem
|
||||
{
|
||||
public string hash { get; set; }
|
||||
public string description { get; set; }
|
||||
public string filename { get; set; }
|
||||
public string region { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -236,7 +236,7 @@ namespace gaseous_server.Models
|
||||
|
||||
public class SignatureFlags
|
||||
{
|
||||
public int IGDBPlatformId { get; set; }
|
||||
public long IGDBPlatformId { get; set; }
|
||||
public string IGDBPlatformName { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,9 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using gaseous_server;
|
||||
using gaseous_tools;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server");
|
||||
|
||||
@@ -20,6 +22,11 @@ if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")
|
||||
Logging.Log(Logging.LogType.Information, "Startup", "Setting initial API key");
|
||||
Config.SetSetting("API Key", APIKey.ToString());
|
||||
}
|
||||
if (Config.ReadSetting("Emulator: Default BIOS Region", "Default Value") == "Default Value")
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Startup", "Setting default BIOS region to US");
|
||||
Config.SetSetting("Emulator: Default BIOS Region", "US");
|
||||
}
|
||||
|
||||
// set up server
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@@ -32,6 +39,9 @@ builder.Services.AddControllers().AddJsonOptions(x =>
|
||||
|
||||
// suppress nulls
|
||||
x.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
||||
|
||||
// set max depth
|
||||
x.JsonSerializerOptions.MaxDepth = 64;
|
||||
});
|
||||
builder.Services.AddResponseCaching();
|
||||
builder.Services.AddControllers(options =>
|
||||
@@ -55,6 +65,22 @@ builder.Services.AddControllers(options =>
|
||||
});
|
||||
});
|
||||
|
||||
// set max upload size
|
||||
builder.Services.Configure<IISServerOptions>(options =>
|
||||
{
|
||||
options.MaxRequestBodySize = int.MaxValue;
|
||||
});
|
||||
builder.Services.Configure<KestrelServerOptions>(options =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = int.MaxValue;
|
||||
});
|
||||
builder.Services.Configure<FormOptions>(options =>
|
||||
{
|
||||
options.ValueLengthLimit = int.MaxValue;
|
||||
options.MultipartBodyLengthLimit = int.MaxValue;
|
||||
options.MultipartHeadersLengthLimit = int.MaxValue;
|
||||
});
|
||||
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
@@ -88,7 +114,7 @@ app.MapControllers();
|
||||
Config.LibraryConfiguration.InitLibrary();
|
||||
|
||||
// insert unknown platform and game if not present
|
||||
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false);
|
||||
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false);
|
||||
gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
|
||||
|
||||
// organise library
|
||||
|
@@ -44,7 +44,31 @@
|
||||
],
|
||||
"KnownFileExtensions": [
|
||||
".SMS"
|
||||
]
|
||||
],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "segaMS",
|
||||
"Bios": [
|
||||
{
|
||||
"hash": "840481177270d5642a14ca71ee72844c",
|
||||
"description": "MasterSystem EU BIOS",
|
||||
"filename": "bios_E.sms",
|
||||
"region": "EU"
|
||||
},
|
||||
{
|
||||
"hash": "840481177270d5642a14ca71ee72844c",
|
||||
"description": "MasterSystem US BIOS",
|
||||
"filename": "bios_U.sms",
|
||||
"region": "US"
|
||||
},
|
||||
{
|
||||
"hash": "24a519c53f67b00640d0048ef7089105",
|
||||
"description": "MasterSystem JP BIOS",
|
||||
"filename": "bios_J.sms",
|
||||
"region": "JP"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 29,
|
||||
@@ -63,7 +87,15 @@
|
||||
],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "segaMD"
|
||||
"Core": "segaMD",
|
||||
"Bios": [
|
||||
{
|
||||
"hash": "45e298905a08f9cfb38fd504cd6dbc84",
|
||||
"description": "MegaDrive TMSS startup ROM",
|
||||
"filename": "bios_MD.bin",
|
||||
"region": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -74,7 +106,9 @@
|
||||
"N64"
|
||||
],
|
||||
"KnownFileExtensions": [
|
||||
".Z64"
|
||||
".Z64",
|
||||
".V64",
|
||||
".N64"
|
||||
],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
@@ -86,20 +120,147 @@
|
||||
"IGDBName": "Nintendo Entertainment System",
|
||||
"AlternateNames": [
|
||||
"Nintendo Entertainment System",
|
||||
"NES"
|
||||
"NES",
|
||||
"Nintendo Famicom & Entertainment System"
|
||||
],
|
||||
"KnownFileExtensions": [
|
||||
".NES",
|
||||
".FDS",
|
||||
".FIG",
|
||||
".MGD",
|
||||
".SFC",
|
||||
".SMC",
|
||||
".SWC"
|
||||
".NEZ",
|
||||
".UNF",
|
||||
".UNIF"
|
||||
],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "nes"
|
||||
"Core": "nes",
|
||||
"Bios": [
|
||||
{
|
||||
"hash": "ca30b50f880eb660a320674ed365ef7a",
|
||||
"description": "Family Computer Disk System BIOS - Required for Famicom Disk System emulation",
|
||||
"filename": "disksys.rom",
|
||||
"region": ""
|
||||
},
|
||||
{
|
||||
"hash": "7f98d77d7a094ad7d069b74bd553ec98",
|
||||
"description": "Game Genie add-on cartridge - Required for Game Genei Add-on emulation (Only supported on the fceumm core)",
|
||||
"filename": "gamegenie.nes",
|
||||
"region": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 19,
|
||||
"IGDBName": "Super Nintendo Entertainment System",
|
||||
"AlternateNames": [
|
||||
"Nintendo Super Famicom & Super Entertainment System",
|
||||
"Super Nintendo Entertainment System",
|
||||
"Super Nintendo",
|
||||
"SNES"
|
||||
],
|
||||
"KnownFileExtensions": [
|
||||
".SFC",
|
||||
".SMC"
|
||||
],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "snes"
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 7,
|
||||
"IGDBName": "PlayStation",
|
||||
"AlternateNames": [
|
||||
"Sony PlayStation",
|
||||
"PS1",
|
||||
"PSX",
|
||||
"PSOne",
|
||||
"PS"
|
||||
],
|
||||
"KnownFileExtensions": [],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "psx",
|
||||
"Bios": [
|
||||
{
|
||||
"hash": "8dd7d5296a650fac7319bce665a6a53c",
|
||||
"description": "PS1 JP BIOS - Required for JP games",
|
||||
"filename": "scph5500.bin",
|
||||
"region": "JP"
|
||||
},
|
||||
{
|
||||
"hash": "490f666e1afb15b7362b406ed1cea246",
|
||||
"description": "PS1 US BIOS - Required for US games",
|
||||
"filename": "scph5501.bin",
|
||||
"region": "US"
|
||||
},
|
||||
{
|
||||
"hash": "32736f17079d0b2b7024407c39bd3050",
|
||||
"description": "PS1 EU BIOS - Required for EU games",
|
||||
"filename": "scph5502.bin",
|
||||
"region": "EU"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 52,
|
||||
"IGDBName": "Arcade",
|
||||
"AlternateNames": [],
|
||||
"KnownFileExtensions": [],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "arcade",
|
||||
"Bios": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 30,
|
||||
"IGDBName": "Sega 32X",
|
||||
"AlternateNames": [
|
||||
"Sega 32X",
|
||||
"Sega32",
|
||||
"Sega32X"
|
||||
],
|
||||
"KnownFileExtensions": [],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "sega32x",
|
||||
"Bios": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"IGDBId": 78,
|
||||
"IGDBName": "Sega CD",
|
||||
"AlternateNames": [
|
||||
"Sega CD",
|
||||
"Mega CD",
|
||||
"segacd",
|
||||
"Sega Mega-CD & Sega CD"
|
||||
],
|
||||
"KnownFileExtensions": [],
|
||||
"WebEmulator": {
|
||||
"Type": "EmulatorJS",
|
||||
"Core": "segaCD",
|
||||
"Bios": [
|
||||
{
|
||||
"hash": "e66fa1dc5820d254611fdcdba0662372",
|
||||
"description": "MegaCD EU BIOS - Required",
|
||||
"filename": "bios_CD_E.bin",
|
||||
"region": "EU"
|
||||
},
|
||||
{
|
||||
"hash": "2efd74e3232ff260e371b99f84024f7f",
|
||||
"description": "SegaCD US BIOS - Required",
|
||||
"filename": "bios_CD_U.bin",
|
||||
"region": "US"
|
||||
},
|
||||
{
|
||||
"hash": "278a9397d192149e84e820ac621a8edd",
|
||||
"description": "MegaCD JP BIOS - Required",
|
||||
"filename": "bios_CD_J.bin",
|
||||
"region": "JP"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@@ -14,9 +14,9 @@
|
||||
<DocumentationFile>bin\Debug\net7.0\gaseous-server.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.9" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.7" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="7.0.8" />
|
||||
<PackageReference Include="IGDB" Version="2.3.2" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -88,23 +88,21 @@
|
||||
<Folder Include="Classes\" />
|
||||
<Folder Include="Classes\SignatureIngestors\" />
|
||||
<Folder Include="Support\" />
|
||||
<Folder Include="wwwroot\" />
|
||||
<Folder Include="Classes\Metadata\" />
|
||||
<Folder Include="Assets\" />
|
||||
<Folder Include="Assets\Ratings\" />
|
||||
<Folder Include="Assets\Ratings\ESRB\" />
|
||||
<Folder Include="Assets\Ratings\ACB\" />
|
||||
<Folder Include="Assets\Ratings\PEGI\" />
|
||||
<Folder Include="wwwroot\scripts\" />
|
||||
<Folder Include="wwwroot\images\" />
|
||||
<Folder Include="wwwroot\styles\" />
|
||||
<Folder Include="wwwroot\pages\" />
|
||||
<Folder Include="Assets\Ratings\CERO\" />
|
||||
<Folder Include="Assets\Ratings\USK\" />
|
||||
<Folder Include="Assets\Ratings\GRAC\" />
|
||||
<Folder Include="Assets\Ratings\CLASS_IND\" />
|
||||
<Folder Include="wwwroot\fonts\" />
|
||||
<Folder Include="wwwroot\pages\dialogs\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="wwwroot\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj">
|
||||
@@ -119,10 +117,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Remove="Support\PlatformMap.json" />
|
||||
<Content Remove="wwwroot\styles\select2.min.css" />
|
||||
<Content Remove="wwwroot\scripts\select2.min.js" />
|
||||
<Content Remove="wwwroot\scripts\moment.js" />
|
||||
<Content Remove="wwwroot\scripts\jquery-3.6.0.min.js" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Support\PlatformMap.json" Condition="'$(ExcludeConfigFilesFromBuildOutput)'!='true'">
|
||||
@@ -169,9 +163,4 @@
|
||||
<EmbeddedResource Include="Assets\Ratings\CLASS_IND\CLASS_IND_Ten.svg" />
|
||||
<EmbeddedResource Include="Assets\Ratings\CLASS_IND\CLASS_IND_Twelve.svg" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Update="wwwroot\EmulatorJS\data\old\sega-old-wasm.data">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
BIN
gaseous-server/wwwroot/.DS_Store
vendored
BIN
gaseous-server/wwwroot/.DS_Store
vendored
Binary file not shown.
Submodule gaseous-server/wwwroot/EmulatorJS deleted from f7fa5d4148
1
gaseous-server/wwwroot/emulators/EmulatorJS
Submodule
1
gaseous-server/wwwroot/emulators/EmulatorJS
Submodule
Submodule gaseous-server/wwwroot/emulators/EmulatorJS added at 8c5def77a0
BIN
gaseous-server/wwwroot/images/SettingsWallpaper.jpg
Normal file
BIN
gaseous-server/wwwroot/images/SettingsWallpaper.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 607 KiB |
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
15
gaseous-server/wwwroot/images/settings.svg
Normal file
15
gaseous-server/wwwroot/images/settings.svg
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M230.4,358.4V76.8c0-14.13,11.48-25.6,25.6-25.6c14.15,0,25.6,11.47,25.6,25.6v281.6h25.6c14.15,0,25.6,11.48,25.6,25.6
|
||||
c0,14.15-11.45,25.6-25.6,25.6h-25.6v25.6c0,14.15-11.45,25.6-25.6,25.6c-14.13,0-25.6-11.45-25.6-25.6v-25.6h-25.6
|
||||
c-14.13,0-25.6-11.45-25.6-25.6c0-14.13,11.48-25.6,25.6-25.6H230.4z M409.6,102.4V76.8c0-14.13,11.48-25.6,25.6-25.6
|
||||
c14.15,0,25.6,11.47,25.6,25.6v25.6h25.6c14.15,0,25.6,11.47,25.6,25.6c0,14.15-11.45,25.6-25.6,25.6h-25.6v281.6
|
||||
c0,14.15-11.45,25.6-25.6,25.6c-14.13,0-25.6-11.45-25.6-25.6V153.6H384c-14.13,0-25.6-11.45-25.6-25.6
|
||||
c0-14.13,11.48-25.6,25.6-25.6H409.6z M102.4,179.2H128c14.15,0,25.6,11.48,25.6,25.6c0,14.15-11.45,25.6-25.6,25.6h-25.6v204.8
|
||||
c0,14.15-11.45,25.6-25.6,25.6c-14.13,0-25.6-11.45-25.6-25.6V230.4H25.6C11.48,230.4,0,218.95,0,204.8
|
||||
c0-14.13,11.48-25.6,25.6-25.6h25.6V76.8c0-14.13,11.47-25.6,25.6-25.6c14.15,0,25.6,11.47,25.6,25.6V179.2z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
23
gaseous-server/wwwroot/images/upload.svg
Normal file
23
gaseous-server/wwwroot/images/upload.svg
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||
<g>
|
||||
<path d="M509,261.1c-3.3-12.7-9.3-24-16.9-33.4c-5.7-7.1-12.4-13.2-19.6-18.4c-10.8-7.8-22.8-13.6-35-17.7
|
||||
c-7.8-2.5-15.7-4.4-23.5-5.6c-3-18-8.4-34.6-15.7-49.6c-13.6-27.9-34-50.1-58.7-65.3C315,55.8,286.2,47.8,256,47.8
|
||||
c-19,0-36.6,3.2-52.4,8.8c-11.9,4.2-22.7,9.8-32.5,16.4c-14.7,9.9-26.9,22-36.7,35.2c-7.5,10.2-13.6,21.1-18.1,32.2
|
||||
c-12.9,2-25.3,5.3-37.1,10c-11.1,4.5-21.6,10.2-31.1,17.1c-14.3,10.4-26.4,23.7-34.8,39.5c-4.3,8-7.6,16.5-9.9,25.6
|
||||
C1.2,241.7,0,251.4,0,261.4c0,17.9,3.9,34.8,11,49.8c5.3,11.3,12.4,21.5,20.9,30.4c12.7,13.4,28.5,23.9,46.2,31.1
|
||||
c17.7,7.2,37.4,11,57.9,11h56c8.8,0,16-7.2,16-16s-7.2-16-16-16h-56c-14.7,0-28.7-2.4-41.2-6.9c-9.4-3.3-18.1-7.8-25.7-13.2
|
||||
c-11.5-8.1-20.7-18.3-27.1-30.1c-6.4-11.8-9.9-25.2-10-40.2c0-13.4,2.8-25.1,7.6-35.4c3.6-7.8,8.4-14.8,14.3-21
|
||||
c8.8-9.4,20-17.2,32.9-23c12.9-5.8,27.5-9.6,42.7-11c6.4-0.6,11.8-4.9,13.7-11c3.2-9.8,8-19.9,14.4-29.3
|
||||
c4.8-7.1,10.5-13.8,17.1-19.9c9.8-9.1,21.5-16.8,35-22.3c13.5-5.4,28.9-8.7,46.3-8.7c16.4,0,32,2.9,46.4,8.4
|
||||
c21.6,8.2,40.3,22.2,54.6,41.3s24.1,43.5,27.1,72.8c0.8,7.8,7.3,13.9,15.1,14.3c9.2,0.5,19.3,2.3,28.9,5.5
|
||||
c7.2,2.4,14.2,5.6,20.5,9.5c4.7,2.9,9.1,6.2,12.9,9.8c5.8,5.5,10.3,11.6,13.5,18.7c3.2,7,5,14.9,5,24.2c0,5.7-0.6,10.9-1.7,15.7
|
||||
c-1.9,8.4-5.2,15.6-9.8,21.8c-3.4,4.7-7.6,8.9-12.4,12.6c-7.3,5.5-16.2,9.9-26.4,12.9s-21.6,4.6-33.7,4.6h-76c-8.8,0-16,7.2-16,16
|
||||
s7.2,16,16,16h76c15.2,0,29.8-2,43.4-6.1c10.2-3.1,19.8-7.3,28.6-12.8c6.6-4.1,12.6-8.9,18-14.4c8.1-8.3,14.7-18.1,19.1-29.3
|
||||
c4.5-11.2,6.8-23.6,6.8-37C511.9,276.1,510.9,268.4,509,261.1z"/>
|
||||
<path d="M308.7,267.1c6.2,6.2,16.4,6.2,22.6,0c6.3-6.2,6.3-16.4,0-22.6l-64-64c-6.2-6.2-16.4-6.2-22.6,0l-64,64
|
||||
c-6.2,6.2-6.2,16.4,0,22.6c6.2,6.2,16.4,6.2,22.6,0l36.7-36.7v217.8c0,8.8,7.2,16,16,16s16-7.2,16-16V230.4L308.7,267.1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@@ -6,7 +6,11 @@
|
||||
<script src="/scripts/jquery-3.6.0.min.js"></script>
|
||||
<script src="/scripts/moment.js"></script>
|
||||
<link href="/styles/select2.min.css" rel="stylesheet" />
|
||||
<link rel="stylesheet" href="/styles/dropzone.min.css" type="text/css" />
|
||||
<script src="/scripts/jquery.lazy.min.js"></script>
|
||||
<script src="/scripts/jquery.lazy.plugins.min.js"></script>
|
||||
<script src="/scripts/select2.min.js"></script>
|
||||
<script src="/scripts/dropzone.min.js"></script>
|
||||
<script src="/scripts/main.js" type="text/javascript"></script>
|
||||
<script src="/scripts/filterformating.js" type="text/javascript"></script>
|
||||
<script src="/scripts/gamesformating.js" type="text/javascript"></script>
|
||||
@@ -23,8 +27,12 @@
|
||||
<div id="banner_header">
|
||||
<div id="banner_header_label">Gaseous Games</div>
|
||||
</div>
|
||||
<div id="banner_cog" onclick="window.location.href = '/index.html?page=system';">
|
||||
<img src="/images/cog.jpg" alt="System" id="banner_system_image" />
|
||||
<div id="banner_upload" onclick="showDialog('upload');">
|
||||
<img src="/images/upload.svg" alt="Upload" title="Upload" id="banner_upload_image" />
|
||||
<span id="banner_upload_label">Upload Games</span>
|
||||
</div>
|
||||
<div id="banner_cog" onclick="window.location.href = '/index.html?page=settings';">
|
||||
<img src="/images/settings.svg" alt="Settings" title="Settings" id="banner_system_image" />
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
@@ -43,11 +51,21 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- The Modal -->
|
||||
<div id="myModalSub" class="modal">
|
||||
|
||||
<!-- Modal content -->
|
||||
<div class="modal-content-sub">
|
||||
<span id="modal-close-sub" class="close">×</span>
|
||||
<div id="modal-content-sub">Some text in the Modal..</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">var modalVariables = null;
|
||||
|
||||
$(document).ready(function () {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
var myParam = urlParams.get('page');
|
||||
var myParam = getQueryString('page', 'string');
|
||||
|
||||
if (!myParam) {
|
||||
myParam = 'home';
|
||||
|
@@ -6,20 +6,22 @@
|
||||
EJS_player = '#game';
|
||||
|
||||
// Can also be fceumm or nestopia
|
||||
EJS_core = urlParams.get('core');
|
||||
EJS_core = getQueryString('core', 'string');
|
||||
|
||||
// Lightgun
|
||||
EJS_lightgun = false; // can be true or false
|
||||
|
||||
// URL to BIOS file
|
||||
EJS_biosUrl = ''; // example: https://dl.dropboxusercontent.com/s/[random-code]/bios.bin
|
||||
EJS_biosUrl = emuBios;
|
||||
|
||||
// URL to Game rom
|
||||
EJS_gameUrl = decodeURIComponent(urlParams.get('rompath'));
|
||||
EJS_gameUrl = decodeURIComponent(getQueryString('rompath', 'string'));
|
||||
|
||||
// Path to the data directory
|
||||
EJS_pathtodata = '/EmulatorJS/data/';
|
||||
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
||||
|
||||
EJS_DEBUG_XX = false;
|
||||
|
||||
EJS_startOnLoaded = false;
|
||||
</script>
|
||||
<script src='/EmulatorJS/data/loader.js'></script>
|
||||
<script src='/emulators/EmulatorJS/data/loader.js'></script>
|
@@ -1,15 +1,4 @@
|
||||
<!-- The Modal -->
|
||||
<div id="myModalSub" class="modal">
|
||||
|
||||
<!-- Modal content -->
|
||||
<div class="modal-content-sub">
|
||||
<span id="modal-close-sub" class="close">×</span>
|
||||
<div id="modal-content-sub">Some text in the Modal..</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<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_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>-->
|
||||
@@ -85,9 +74,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">document.getElementById('modal-heading').innerHTML = "Properties";
|
||||
<script type="text/javascript">
|
||||
document.getElementById('modal-heading').innerHTML = "Properties";
|
||||
|
||||
var gameId = urlParams.get('id');
|
||||
var gameId = getQueryString('id', 'int');
|
||||
|
||||
var romData;
|
||||
|
||||
@@ -221,27 +211,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
function DropDownRenderGameOption(state) {
|
||||
console.log(JSON.stringify(state));
|
||||
|
||||
if (state.loading) {
|
||||
return state;
|
||||
}
|
||||
|
||||
var response;
|
||||
|
||||
if (state.cover) {
|
||||
response = $(
|
||||
'<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="https://images.igdb.com/igdb/image/upload/t_cover_small/' + state.cover.value.imageId + '.jpg" /></td><td class="dropdown-label"><span>' + state.text + '</span></td></tr></table>'
|
||||
);
|
||||
} else {
|
||||
response = $(
|
||||
'<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="/images/unknowngame.png" /></td><td class="dropdown-label"><span>' + state.text + '</span></td></tr></table>'
|
||||
);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function SaveFixedGame() {
|
||||
var fixplatform = $('#properties_fixplatform').select2('data');
|
||||
var fixgame = $('#properties_fixgame').select2('data');
|
||||
@@ -253,48 +222,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
var subModalVariables;
|
||||
|
||||
function showSubDialog(dialogPage, variables) {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
// Get the button that opens the modal
|
||||
var subbtn = document.getElementById("romDelete");
|
||||
|
||||
// Get the <span> element that closes the modal
|
||||
var subspan = document.getElementById("modal-close-sub");
|
||||
|
||||
// When the user clicks on the button, open the modal
|
||||
submodal.style.display = "block";
|
||||
|
||||
// When the user clicks on <span> (x), close the modal
|
||||
subspan.onclick = function () {
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
|
||||
subModalVariables = modalVariables;
|
||||
|
||||
$('#modal-content-sub').load('/pages/dialogs/' + dialogPage + '.html');
|
||||
}
|
||||
|
||||
function closeSubDialog() {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
|
||||
SelectTab('general');
|
||||
|
||||
document.getElementById('romDelete').setAttribute("onclick", "showSubDialog('romdelete', " + modalVariables + ");");
|
||||
|
10
gaseous-server/wwwroot/pages/dialogs/romsdelete.html
Normal file
10
gaseous-server/wwwroot/pages/dialogs/romsdelete.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<p>Are you sure you want to delete the selected ROMs?</p>
|
||||
<p><strong>Warning:</strong> This cannot be undone!</p>
|
||||
<div style="width: 100%; text-align: center;">
|
||||
<div style="display: inline-block; margin-right: 20px;">
|
||||
<button class="redbutton" value="Delete" onclick="deleteGameRomsCallback(); closeSubDialog();">Delete</button>
|
||||
</div>
|
||||
<div style="display: inline-block; margin-left: 20px;">
|
||||
<button value="Cancel" onclick="closeSubDialog();">Cancel</button>
|
||||
</div>
|
||||
</div>
|
72
gaseous-server/wwwroot/pages/dialogs/upload.html
Normal file
72
gaseous-server/wwwroot/pages/dialogs/upload.html
Normal file
@@ -0,0 +1,72 @@
|
||||
<!-- The Modal -->
|
||||
<div id="myModalSub" class="modal">
|
||||
|
||||
<!-- Modal content -->
|
||||
<div class="modal-content-sub">
|
||||
<span id="modal-close-sub" class="close">×</span>
|
||||
<div id="modal-content-sub">Some text in the Modal..</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div id="upload_target" class="dropzone"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementById('modal-heading').innerHTML = "Upload";
|
||||
|
||||
var myDropzone = new Dropzone("div#upload_target", {
|
||||
url: "/api/v1/Roms",
|
||||
autoProcessQueue: true,
|
||||
uploadMultiple: true,
|
||||
paramName: myParamName,
|
||||
maxFilesize: 60000,
|
||||
createImageThumbnails: false,
|
||||
disablePreviews: false
|
||||
});
|
||||
|
||||
function myParamName() {
|
||||
return "files";
|
||||
}
|
||||
|
||||
function showSubDialog(dialogPage, variables) {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
// Get the button that opens the modal
|
||||
var subbtn = document.getElementById("romDelete");
|
||||
|
||||
// Get the <span> element that closes the modal
|
||||
var subspan = document.getElementById("modal-close-sub");
|
||||
|
||||
// When the user clicks on the button, open the modal
|
||||
submodal.style.display = "block";
|
||||
|
||||
// When the user clicks on <span> (x), close the modal
|
||||
subspan.onclick = function () {
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
|
||||
subModalVariables = modalVariables;
|
||||
|
||||
$('#modal-content-sub').load('/pages/dialogs/' + dialogPage + '.html');
|
||||
}
|
||||
|
||||
function closeSubDialog() {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
</script>
|
@@ -5,13 +5,14 @@
|
||||
<div id="emulator"></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
|
||||
var gameId = urlParams.get('gameid');
|
||||
var gameId = getQueryString('gameid', 'int');
|
||||
var platformId = getQueryString('platformid', 'int');
|
||||
var gameData;
|
||||
var artworks = null;
|
||||
var artworksPosition = 0;
|
||||
|
||||
var emuBios = '';
|
||||
|
||||
ajaxCall('/api/v1/Games/' + gameId, 'GET', function (result) {
|
||||
gameData = result;
|
||||
|
||||
@@ -29,6 +30,20 @@
|
||||
}
|
||||
});
|
||||
|
||||
ajaxCall('/api/v1/Bios/' + platformId, 'GET', function (result) {
|
||||
if (result.length == 0) {
|
||||
emuBios = '';
|
||||
} else {
|
||||
emuBios = '/api/v1/Bios/zip/' + platformId;
|
||||
}
|
||||
|
||||
switch (getQueryString('engine', 'string')) {
|
||||
case 'EmulatorJS':
|
||||
$('#emulator').load('/pages/EmulatorJS.html');
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function rotateBackground() {
|
||||
if (artworks) {
|
||||
artworksPosition += 1;
|
||||
@@ -39,10 +54,4 @@
|
||||
bg.setAttribute('style', 'background-image: url("/api/v1/Games/' + gameId + '/artwork/' + artworks[artworksPosition] + '/image"); background-position: center; background-repeat: no-repeat; background-size: cover; filter: blur(10px); -webkit-filter: blur(10px);');
|
||||
}
|
||||
}
|
||||
|
||||
switch (urlParams.get('engine')) {
|
||||
case 'EmulatorJS':
|
||||
$('#emulator').load('/pages/EmulatorJS.html');
|
||||
break;
|
||||
}
|
||||
</script>
|
||||
|
@@ -2,6 +2,19 @@
|
||||
<div id="bgImage_Opacity"></div>
|
||||
</div>
|
||||
|
||||
<!-- The Modal -->
|
||||
<div id="myModalProgress" class="modal">
|
||||
|
||||
<!-- Modal content -->
|
||||
<div class="modal-content-sub">
|
||||
<div id="modal-content-sub-progress">
|
||||
<h1>In Progress...</h1>
|
||||
<progress style="width: 100%;"></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="gamepage">
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label"></h1>
|
||||
@@ -46,15 +59,23 @@
|
||||
<p id="gamesummarytext_label_button_contract" class="text_link" style="display: none;" onclick="document.querySelector('#gamesummarytext_label').classList.add('line-clamp-4'); document.querySelector('#gamesummarytext_label_button_expand').setAttribute('style', ''); document.querySelector('#gamesummarytext_label_button_contract').setAttribute('style', 'display: none;');">Read less...</p>
|
||||
</div>
|
||||
<div id="gamesummaryroms">
|
||||
<span id="rom_edit" class="romlink" onclick="DisplayROMCheckboxes(true);">Edit</span>
|
||||
<h3>ROM's/Images</h3>
|
||||
<div id="rom_edit_panel" style="display: none;">
|
||||
<div id="rom_edit_panel_center">
|
||||
<button id="rom_edit_delete" class="redbutton" onclick="deleteGameRoms();">Delete</button>
|
||||
|
||||
<select id="rom_edit_fixplatform" style="width: 150px;"></select>
|
||||
<select id="rom_edit_fixgame" style="width: 300px;"></select>
|
||||
<button id="rom_edit_update" onclick="remapTitles();">Update</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
var gameId = urlParams.get('id');
|
||||
<script type="text/javascript">var gameId = getQueryString('id', 'int');
|
||||
var gameData;
|
||||
var artworks = null;
|
||||
var artworksPosition = 0;
|
||||
@@ -95,7 +116,7 @@
|
||||
} else {
|
||||
gameSummaryLabel.innerHTML = result.storyline;
|
||||
}
|
||||
|
||||
|
||||
if (gameSummaryLabel.offsetHeight < gameSummaryLabel.scrollHeight ||
|
||||
gameSummaryLabel.offsetWidth < gameSummaryLabel.scrollWidth) {
|
||||
// your element has overflow and truncated
|
||||
@@ -131,7 +152,7 @@
|
||||
ajaxCall('/api/v1/games/' + gameId + '/companies', 'GET', function (result) {
|
||||
var lstDevelopers = [];
|
||||
var lstPublishers = [];
|
||||
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
var companyLabel = document.createElement('span');
|
||||
companyLabel.className = 'gamegenrelabel';
|
||||
@@ -222,7 +243,7 @@
|
||||
var gameScreenshots = document.getElementById('gamescreenshots');
|
||||
if (result.screenshots || result.videos) {
|
||||
var gameScreenshots_Main = document.getElementById('gamescreenshots_main');
|
||||
|
||||
|
||||
// load static screenshots
|
||||
var gameScreenshots_Gallery = document.getElementById('gamescreenshots_gallery_panel');
|
||||
var imageIndex = 0;
|
||||
@@ -296,15 +317,25 @@
|
||||
}
|
||||
|
||||
// load roms
|
||||
loadRoms();
|
||||
});
|
||||
|
||||
function loadRoms(displayCheckboxes) {
|
||||
var existingTable = document.getElementById('romtable');
|
||||
if (existingTable) {
|
||||
existingTable.remove();
|
||||
}
|
||||
|
||||
var gameRoms = document.getElementById('gamesummaryroms');
|
||||
ajaxCall('/api/v1/Games/' + gameId + '/roms', 'GET', function (result) {
|
||||
if (result) {
|
||||
result.sort((a, b) => a.platform.name.charCodeAt(0) - b.platform.name.charCodeAt(0));
|
||||
|
||||
var newTable = document.createElement('table');
|
||||
newTable.id = 'romtable';
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Name', 'Size', 'Media', '', '', '']));
|
||||
newTable.appendChild(createTableRow(true, [['<input id="rom_mastercheck" type="checkbox" onclick="selectAllChecks();"/>', 'rom_checkbox_box_hidden', 'rom_edit_checkbox'], 'Name', 'Size', 'Media', '', '', '']));
|
||||
|
||||
var lastPlatform = '';
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
@@ -312,7 +343,7 @@
|
||||
lastPlatform = result[i].platform.name;
|
||||
var platformRow = document.createElement('tr');
|
||||
var platformHeader = document.createElement('th');
|
||||
platformHeader.setAttribute('colspan', 4);
|
||||
platformHeader.setAttribute('colspan', 6);
|
||||
platformHeader.innerHTML = result[i].platform.name;
|
||||
platformRow.appendChild(platformHeader);
|
||||
newTable.appendChild(platformRow);
|
||||
@@ -320,26 +351,31 @@
|
||||
|
||||
var launchButton = '';
|
||||
if (result[i].emulator) {
|
||||
launchButton = '<a href="/index.html?page=emulator&engine=' + result[i].emulator.Type + '&core=' + result[i].emulator.Core + '&gameid=' + gameId + '&rompath=' + encodeURIComponent('/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/file') + '" class="romlink">Start</a>';
|
||||
launchButton = '<a href="/index.html?page=emulator&engine=' + result[i].emulator.type + '&core=' + result[i].emulator.core + '&platformid=' + result[i].platform.id + '&gameid=' + gameId + '&rompath=' + encodeURIComponent('/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/' + encodeURIComponent(result[i].name)) + '" class="romstart">Launch</a>';
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
'<a href="/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/file" class="romlink">' + result[i].name + '</a>',
|
||||
['<input type="checkbox" name="rom_checkbox" data-romid="' + result[i].id + '" />', 'rom_checkbox_box_hidden', 'rom_edit_checkbox'],
|
||||
'<a href="/api/v1/Games/' + gameId + '/roms/' + result[i].id + '/' + encodeURIComponent(result[i].name) + '" class="romlink">' + result[i].name + '</a>',
|
||||
formatBytes(result[i].size, 2),
|
||||
result[i].romTypeMedia,
|
||||
result[i].mediaLabel,
|
||||
launchButton,
|
||||
'<span class="romlink" onclick="showDialog(\'rominfo\', ' + result[i].id + ');">...</span>'
|
||||
'<div class="properties_button" onclick="showDialog(\'rominfo\', ' + result[i].id + ');">i</div>'
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
|
||||
gameRoms.appendChild(newTable);
|
||||
|
||||
if (displayCheckboxes == true) {
|
||||
DisplayROMCheckboxes(true);
|
||||
}
|
||||
} else {
|
||||
gameRoms.setAttribute('style', 'display: none;');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function rotateBackground() {
|
||||
if (artworks) {
|
||||
@@ -409,11 +445,203 @@
|
||||
var gameScreenshots_Items = document.getElementsByName('gamescreenshots_gallery_item');
|
||||
|
||||
selectedScreenshot = selectedScreenshot - 1;
|
||||
|
||||
|
||||
if (selectedScreenshot < 0) {
|
||||
selectedScreenshot = gameScreenshots_Items.length - 1;
|
||||
}
|
||||
|
||||
selectScreenshot(selectedScreenshot);
|
||||
}
|
||||
</script>
|
||||
|
||||
function DisplayROMCheckboxes(visible) {
|
||||
var checkbox_boxes = document.getElementsByName('rom_edit_checkbox');
|
||||
|
||||
for (var i = 0; i < checkbox_boxes.length; i++) {
|
||||
if (visible == true) {
|
||||
checkbox_boxes[i].className = 'rom_checkbox_box';
|
||||
} else {
|
||||
checkbox_boxes[i].className = 'rom_checkbox_box_hidden';
|
||||
}
|
||||
}
|
||||
|
||||
var editButton = document.getElementById('rom_edit');
|
||||
var deleteButton = document.getElementById('rom_edit_panel');
|
||||
if (visible == true) {
|
||||
editButton.innerHTML = 'Cancel';
|
||||
deleteButton.style.display = '';
|
||||
} else {
|
||||
editButton.innerHTML = 'Edit';
|
||||
document.getElementById('rom_mastercheck').checked = false;
|
||||
deleteButton.style.display = 'none';
|
||||
selectAllChecks(false);
|
||||
}
|
||||
editButton.setAttribute('onclick', 'DisplayROMCheckboxes(' + !visible + ');');
|
||||
}
|
||||
|
||||
function selectAllChecks(value) {
|
||||
var mastercheckbox = document.getElementById('rom_mastercheck');
|
||||
var checkboxes = document.getElementsByName('rom_checkbox');
|
||||
for (var i = 0; i < checkboxes.length; i++) {
|
||||
if (value) {
|
||||
checkboxes[i].checked = value;
|
||||
} else {
|
||||
checkboxes[i].checked = mastercheckbox.checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$('#rom_edit_fixplatform').select2({
|
||||
minimumInputLength: 3,
|
||||
placeholder: "Platform",
|
||||
ajax: {
|
||||
url: '/api/v1/Search/Platform',
|
||||
data: function (params) {
|
||||
var query = {
|
||||
SearchString: params.term
|
||||
}
|
||||
|
||||
// Query parameters will be ?SearchString=[term]
|
||||
return query;
|
||||
},
|
||||
processResults: function (data) {
|
||||
var arr = [];
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
arr.push({
|
||||
id: data[i].id,
|
||||
text: data[i].name
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
results: arr
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#rom_edit_fixgame').select2({
|
||||
minimumInputLength: 3,
|
||||
templateResult: DropDownRenderGameOption,
|
||||
placeholder: "Game",
|
||||
ajax: {
|
||||
url: '/api/v1/Search/Game',
|
||||
data: function (params) {
|
||||
fixplatform = $('#rom_edit_fixplatform').select2('data');
|
||||
|
||||
var query = {
|
||||
PlatformId: fixplatform[0].id,
|
||||
SearchString: params.term
|
||||
}
|
||||
|
||||
// Query parameters will be ?SearchString=[term]
|
||||
return query;
|
||||
},
|
||||
processResults: function (data) {
|
||||
var arr = [];
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
arr.push({
|
||||
id: data[i].id,
|
||||
text: data[i].name,
|
||||
cover: data[i].cover
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
results: arr
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var remapCallCounter = 0;
|
||||
var remapCallCounterMax = 0;
|
||||
function remapTitles() {
|
||||
var fixplatform = $('#rom_edit_fixplatform').select2('data');
|
||||
var fixgame = $('#rom_edit_fixgame').select2('data');
|
||||
|
||||
if (fixplatform[0] && fixgame[0]) {
|
||||
var rom_checks = document.getElementsByName('rom_checkbox');
|
||||
|
||||
for (var i = 0; i < rom_checks.length; i++) {
|
||||
if (rom_checks[i].checked == true) {
|
||||
remapCallCounterMax += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (remapCallCounterMax > 0) {
|
||||
showProgress();
|
||||
|
||||
for (var i = 0; i < rom_checks.length; i++) {
|
||||
if (rom_checks[i].checked == true) {
|
||||
var romId = rom_checks[i].getAttribute('data-romid');
|
||||
remapCallCounter += 1;
|
||||
|
||||
ajaxCall('/api/v1/Games/' + gameId + '/roms/' + romId + '?NewPlatformId=' + fixplatform[0].id + '&NewGameId=' + fixgame[0].id, 'PATCH', function (result) {
|
||||
remapTitlesCallback();
|
||||
}, function (result) {
|
||||
remapTitlesCallback();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function remapTitlesCallback() {
|
||||
remapCallCounter = remapCallCounter - 1;
|
||||
|
||||
if (remapCallCounter <= 0) {
|
||||
closeProgress();
|
||||
loadRoms(true);
|
||||
remapCallCounter = 0;
|
||||
remapCallCounterMax = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteGameRoms() {
|
||||
var rom_checks = document.getElementsByName('rom_checkbox');
|
||||
var itemsChecked = false;
|
||||
for (var i = 0; i < rom_checks.length; i++) {
|
||||
if (rom_checks[i].checked == true) {
|
||||
itemsChecked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (itemsChecked == true) {
|
||||
showSubDialog('romsdelete');
|
||||
}
|
||||
}
|
||||
|
||||
function deleteGameRomsCallback() {
|
||||
var rom_checks = document.getElementsByName('rom_checkbox');
|
||||
for (var i = 0; i < rom_checks.length; i++) {
|
||||
if (rom_checks[i].checked == true) {
|
||||
remapCallCounterMax += 1;
|
||||
|
||||
var romId = rom_checks[i].getAttribute('data-romid');
|
||||
remapCallCounter += 1;
|
||||
ajaxCall('/api/v1/Games/' + gameId + '/roms/' + romId, 'DELETE', function (result) {
|
||||
remapTitlesCallback();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showProgress() {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalProgress");
|
||||
|
||||
// When the user clicks on the button, open the modal
|
||||
submodal.style.display = "block";
|
||||
}
|
||||
|
||||
function closeProgress() {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalProgress");
|
||||
|
||||
submodal.style.display = "none";
|
||||
}
|
||||
</script>
|
47
gaseous-server/wwwroot/pages/settings.html
Normal file
47
gaseous-server/wwwroot/pages/settings.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<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>
|
||||
|
||||
<div id="gamepage">
|
||||
<div id="properties_toc" class="settings_toc">
|
||||
<div class="filter_header">Settings</div>
|
||||
<div id="properties_toc_system" name="properties_toc_item" onclick="SelectTab('system');">System</div>
|
||||
<div id="properties_toc_bios" name="properties_toc_item" onclick="SelectTab('bios');">Firmware</div>
|
||||
<div id="properties_toc_about" name="properties_toc_item" onclick="SelectTab('about');">About</div>
|
||||
</div>
|
||||
<div id="properties_bodypanel">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
var myParam = getQueryString('sub', 'string');
|
||||
|
||||
var selectedTab = '';
|
||||
|
||||
if (myParam) {
|
||||
selectedTab = myParam;
|
||||
} else {
|
||||
selectedTab = 'system';
|
||||
}
|
||||
|
||||
SelectTab(selectedTab);
|
||||
|
||||
function SelectTab(TabName) {
|
||||
var tocs = document.getElementsByName('properties_toc_item');
|
||||
for (var i = 0; i < tocs.length; i++) {
|
||||
if ((tocs[i].id) == ("properties_toc_" + TabName)) {
|
||||
tocs[i].className = "properties_toc_item_selected";
|
||||
} else {
|
||||
tocs[i].className = '';
|
||||
}
|
||||
}
|
||||
|
||||
$('#properties_bodypanel').load('/pages/settings/' + TabName + '.html');
|
||||
}
|
||||
</script>
|
14
gaseous-server/wwwroot/pages/settings/about.html
Normal file
14
gaseous-server/wwwroot/pages/settings/about.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">About Gaseous</h1>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Home Page</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server" class="romlink">https://github.com/gaseous-project/gaseous-server</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bugs and Feature Requests</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server/issues" class="romlink">https://github.com/gaseous-project/gaseous-server/issues</a></td>
|
||||
</tr>
|
||||
</table>
|
53
gaseous-server/wwwroot/pages/settings/bios.html
Normal file
53
gaseous-server/wwwroot/pages/settings/bios.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">Firmware</h1>
|
||||
</div>
|
||||
|
||||
<h3>Firmware Availablility</h3>
|
||||
<table id="table_firmware" class="romtable" cellspacing="0">
|
||||
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
ajaxCall('/api/v1/Bios', 'GET', function (result) {
|
||||
result.sort((a, b) => a.platformname.charCodeAt(0) - b.platformname.charCodeAt(0));
|
||||
|
||||
var lastPlatform = '';
|
||||
|
||||
var newTable = document.getElementById('table_firmware');
|
||||
newTable.appendChild(createTableRow(true, ['Description', 'File name', 'MD5 Hash', 'Available']));
|
||||
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
if (result[i].platformname != lastPlatform) {
|
||||
lastPlatform = result[i].platformname;
|
||||
var platformRow = document.createElement('tr');
|
||||
var platformHeader = document.createElement('th');
|
||||
platformHeader.setAttribute('colspan', 4);
|
||||
platformHeader.innerHTML = result[i].platformname;
|
||||
platformRow.appendChild(platformHeader);
|
||||
newTable.appendChild(platformRow);
|
||||
}
|
||||
|
||||
var biosFilename = document.createElement('a');
|
||||
biosFilename.href = '/api/v1/Bios/' + result[i].platformid + '/' + result[i].filename;
|
||||
biosFilename.innerHTML = result[i].filename;
|
||||
biosFilename.className = 'romlink';
|
||||
|
||||
var availableText = document.createElement('span');
|
||||
if (result[i].available == true) {
|
||||
availableText.innerHTML = 'Available';
|
||||
availableText.className = 'greentext';
|
||||
} else {
|
||||
availableText.innerHTML = 'Unavailable';
|
||||
availableText.className = 'redtext';
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
result[i].description,
|
||||
biosFilename,
|
||||
result[i].hash,
|
||||
availableText
|
||||
];
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
}
|
||||
});
|
||||
</script>
|
@@ -1,23 +1,31 @@
|
||||
<div id="gamepage">
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">System</h1>
|
||||
</div>
|
||||
|
||||
<h3>Background Tasks</h3>
|
||||
<div id="system_tasks"></div>
|
||||
|
||||
<h3>Usage</h3>
|
||||
<p><strong>Library</strong></p>
|
||||
<div id="system_disks"></div>
|
||||
<p><strong>Database</strong></p>
|
||||
<div id="system_database"></div>
|
||||
|
||||
<h3>Signatures</h3>
|
||||
<div id="system_signatures"></div>
|
||||
<div id="gametitle">
|
||||
<h1 id="gametitle_label">System</h1>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function SystemLoadStatus() {
|
||||
<h3>Background Tasks</h3>
|
||||
<div id="system_tasks"></div>
|
||||
|
||||
<h3>Usage</h3>
|
||||
<p><strong>Disk</strong></p>
|
||||
<div id="system_disks"></div>
|
||||
<p><strong>Library</strong></p>
|
||||
<div>
|
||||
<table cellspacing="0" style="width: 100%;">
|
||||
<tr>
|
||||
<td id="system_platforms"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id="system_platforms_legend"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<p><strong>Database</strong></p>
|
||||
<div id="system_database"></div>
|
||||
|
||||
<h3>Signatures</h3>
|
||||
<div id="system_signatures"></div>
|
||||
|
||||
<script type="text/javascript">function SystemLoadStatus() {
|
||||
ajaxCall('/api/v1/BackgroundTasks', 'GET', function (result) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
@@ -71,7 +79,7 @@
|
||||
|
||||
var startButton = '';
|
||||
if (result[i].itemState != "Running") {
|
||||
startButton = "<span id='startProcess' class='romlink' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||
}
|
||||
|
||||
var newRow = [
|
||||
@@ -95,29 +103,32 @@
|
||||
function SystemLoadSystemStatus() {
|
||||
ajaxCall('/api/v1/System', 'GET', function (result) {
|
||||
if (result) {
|
||||
var totalLibrarySpace = 0;
|
||||
|
||||
// disks
|
||||
var newTable = document.createElement('table');
|
||||
newTable.className = 'romtable';
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.appendChild(createTableRow(true, ['Path', 'Library Size <div id="disk_LibSize" style="width: 10px; height: 10px; background-color: green;"></div>', 'Other <div id="disk_OtherSize" style="width: 10px; height: 10px; background-color: lightgreen;"></div>', 'Total Size <div id="disk_FreeSize" style="width: 10px; height: 10px; background-color: lightgray;"></div>']));
|
||||
|
||||
for (var i = 0; i < result.Paths.length; i++) {
|
||||
var spaceUsedByLibrary = result.Paths[i].SpaceUsed;
|
||||
var spaceUsedByOthers = result.Paths[i].TotalSpace - result.Paths[i].SpaceAvailable;
|
||||
for (var i = 0; i < result.paths.length; i++) {
|
||||
var spaceUsedByLibrary = result.paths[i].spaceUsed;
|
||||
totalLibrarySpace += spaceUsedByLibrary;
|
||||
var spaceUsedByOthers = result.paths[i].totalSpace - result.paths[i].spaceAvailable;
|
||||
|
||||
var newRow = [
|
||||
result.Paths[i].LibraryPath,
|
||||
result.paths[i].libraryPath,
|
||||
formatBytes(spaceUsedByLibrary),
|
||||
formatBytes(spaceUsedByOthers),
|
||||
formatBytes(result.Paths[i].TotalSpace)
|
||||
formatBytes(result.paths[i].totalSpace)
|
||||
];
|
||||
|
||||
|
||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||
|
||||
var spaceRow = document.createElement('tr');
|
||||
var spaceCell = document.createElement('td');
|
||||
spaceCell.setAttribute('colspan', 4);
|
||||
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.Paths[i].TotalSpace));
|
||||
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.paths[i].totalSpace));
|
||||
spaceRow.appendChild(spaceCell);
|
||||
newTable.appendChild(spaceRow);
|
||||
}
|
||||
@@ -126,11 +137,13 @@
|
||||
targetDiv.innerHTML = '';
|
||||
targetDiv.appendChild(newTable);
|
||||
|
||||
BuildLibraryStatisticsBar(document.getElementById('system_platforms'), document.getElementById('system_platforms_legend'), result.platformStatistics, totalLibrarySpace);
|
||||
|
||||
// database
|
||||
var newDbTable = document.createElement('table');
|
||||
newDbTable.className = 'romtable';
|
||||
newDbTable.setAttribute('cellspacing', 0);
|
||||
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.DatabaseSize)]));
|
||||
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.databaseSize)]));
|
||||
|
||||
var targetDbDiv = document.getElementById('system_database');
|
||||
targetDbDiv.innerHTML = '';
|
||||
@@ -168,6 +181,40 @@
|
||||
return newTable;
|
||||
}
|
||||
|
||||
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
||||
var newTable = document.createElement('table');
|
||||
newTable.setAttribute('cellspacing', 0);
|
||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||
|
||||
var newRow = document.createElement('tr');
|
||||
|
||||
for (var i = 0; i < LibraryStatistics.length; i++) {
|
||||
var platformSizePercent = LibraryStatistics[i].totalSize / LibrarySize * 100;
|
||||
var platformSizeColour = intToRGB(hashCode(LibraryStatistics[i].platform));
|
||||
var newCell = document.createElement('td');
|
||||
newCell.setAttribute('style', 'min-width: 2px; width: ' + platformSizePercent + '%; background-color: #' + platformSizeColour);
|
||||
newRow.appendChild(newCell);
|
||||
|
||||
var legend = document.createElement('div');
|
||||
legend.className = 'legend_box';
|
||||
|
||||
var legendColour = document.createElement('div');
|
||||
legendColour.className = 'legend_colour';
|
||||
legendColour.setAttribute('style', 'background-color: #' + platformSizeColour + ';');
|
||||
|
||||
var legendLabel = document.createElement('div');
|
||||
legendLabel.className = 'legend_label';
|
||||
legendLabel.innerHTML = LibraryStatistics[i].platform + '<br />' + formatBytes(LibraryStatistics[i].totalSize);
|
||||
|
||||
legend.appendChild(legendColour);
|
||||
legend.appendChild(legendLabel);
|
||||
TargetObjectLegend.appendChild(legend);
|
||||
}
|
||||
|
||||
newTable.appendChild(newRow);
|
||||
TargetObject.appendChild(newTable);
|
||||
}
|
||||
|
||||
function SystemSignaturesStatus() {
|
||||
ajaxCall('/api/v1/Signatures/Status', 'GET', function (result) {
|
||||
var newTable = document.createElement('table');
|
||||
@@ -202,5 +249,4 @@
|
||||
SystemLoadSystemStatus();
|
||||
setInterval(SystemLoadStatus, 60000);
|
||||
SystemSignaturesStatus();
|
||||
setInterval(SystemSignaturesStatus, 300000);
|
||||
</script>
|
||||
setInterval(SystemSignaturesStatus, 300000);</script>
|
1
gaseous-server/wwwroot/scripts/dropzone.min.js
vendored
Normal file
1
gaseous-server/wwwroot/scripts/dropzone.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -4,6 +4,12 @@
|
||||
var game = renderGameIcon(result[i], true, false);
|
||||
targetElement.appendChild(game);
|
||||
}
|
||||
|
||||
$('.lazy').Lazy({
|
||||
scrollDirection: 'vertical',
|
||||
effect: 'fadeIn',
|
||||
visibleOnly: true
|
||||
});
|
||||
}
|
||||
|
||||
function renderGameIcon(gameObject, showTitle, showRatings) {
|
||||
@@ -12,9 +18,9 @@ function renderGameIcon(gameObject, showTitle, showRatings) {
|
||||
gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";');
|
||||
|
||||
var gameImage = document.createElement('img');
|
||||
gameImage.className = 'game_tile_image';
|
||||
gameImage.className = 'game_tile_image lazy';
|
||||
if (gameObject.cover) {
|
||||
gameImage.src = '/api/v1/Games/' + gameObject.id + '/cover/image';
|
||||
gameImage.setAttribute('data-src', '/api/v1/Games/' + gameObject.id + '/cover/image');
|
||||
} else {
|
||||
gameImage.src = '/images/unknowngame.png';
|
||||
gameImage.className = 'game_tile_image unknown';
|
||||
|
2
gaseous-server/wwwroot/scripts/jquery.lazy.min.js
vendored
Normal file
2
gaseous-server/wwwroot/scripts/jquery.lazy.min.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/*! jQuery & Zepto Lazy v1.7.10 - http://jquery.eisbehr.de/lazy - MIT&GPL-2.0 license - Copyright 2012-2018 Daniel 'Eisbehr' Kern */
|
||||
!function(t,e){"use strict";function r(r,a,i,u,l){function f(){L=t.devicePixelRatio>1,i=c(i),a.delay>=0&&setTimeout(function(){s(!0)},a.delay),(a.delay<0||a.combined)&&(u.e=v(a.throttle,function(t){"resize"===t.type&&(w=B=-1),s(t.all)}),u.a=function(t){t=c(t),i.push.apply(i,t)},u.g=function(){return i=n(i).filter(function(){return!n(this).data(a.loadedName)})},u.f=function(t){for(var e=0;e<t.length;e++){var r=i.filter(function(){return this===t[e]});r.length&&s(!1,r)}},s(),n(a.appendScroll).on("scroll."+l+" resize."+l,u.e))}function c(t){var i=a.defaultImage,o=a.placeholder,u=a.imageBase,l=a.srcsetAttribute,f=a.loaderAttribute,c=a._f||{};t=n(t).filter(function(){var t=n(this),r=m(this);return!t.data(a.handledName)&&(t.attr(a.attribute)||t.attr(l)||t.attr(f)||c[r]!==e)}).data("plugin_"+a.name,r);for(var s=0,d=t.length;s<d;s++){var A=n(t[s]),g=m(t[s]),h=A.attr(a.imageBaseAttribute)||u;g===N&&h&&A.attr(l)&&A.attr(l,b(A.attr(l),h)),c[g]===e||A.attr(f)||A.attr(f,c[g]),g===N&&i&&!A.attr(E)?A.attr(E,i):g===N||!o||A.css(O)&&"none"!==A.css(O)||A.css(O,"url('"+o+"')")}return t}function s(t,e){if(!i.length)return void(a.autoDestroy&&r.destroy());for(var o=e||i,u=!1,l=a.imageBase||"",f=a.srcsetAttribute,c=a.handledName,s=0;s<o.length;s++)if(t||e||A(o[s])){var g=n(o[s]),h=m(o[s]),b=g.attr(a.attribute),v=g.attr(a.imageBaseAttribute)||l,p=g.attr(a.loaderAttribute);g.data(c)||a.visibleOnly&&!g.is(":visible")||!((b||g.attr(f))&&(h===N&&(v+b!==g.attr(E)||g.attr(f)!==g.attr(F))||h!==N&&v+b!==g.css(O))||p)||(u=!0,g.data(c,!0),d(g,h,v,p))}u&&(i=n(i).filter(function(){return!n(this).data(c)}))}function d(t,e,r,i){++z;var o=function(){y("onError",t),p(),o=n.noop};y("beforeLoad",t);var u=a.attribute,l=a.srcsetAttribute,f=a.sizesAttribute,c=a.retinaAttribute,s=a.removeAttribute,d=a.loadedName,A=t.attr(c);if(i){var g=function(){s&&t.removeAttr(a.loaderAttribute),t.data(d,!0),y(T,t),setTimeout(p,1),g=n.noop};t.off(I).one(I,o).one(D,g),y(i,t,function(e){e?(t.off(D),g()):(t.off(I),o())})||t.trigger(I)}else{var h=n(new Image);h.one(I,o).one(D,function(){t.hide(),e===N?t.attr(C,h.attr(C)).attr(F,h.attr(F)).attr(E,h.attr(E)):t.css(O,"url('"+h.attr(E)+"')"),t[a.effect](a.effectTime),s&&(t.removeAttr(u+" "+l+" "+c+" "+a.imageBaseAttribute),f!==C&&t.removeAttr(f)),t.data(d,!0),y(T,t),h.remove(),p()});var m=(L&&A?A:t.attr(u))||"";h.attr(C,t.attr(f)).attr(F,t.attr(l)).attr(E,m?r+m:null),h.complete&&h.trigger(D)}}function A(t){var e=t.getBoundingClientRect(),r=a.scrollDirection,n=a.threshold,i=h()+n>e.top&&-n<e.bottom,o=g()+n>e.left&&-n<e.right;return"vertical"===r?i:"horizontal"===r?o:i&&o}function g(){return w>=0?w:w=n(t).width()}function h(){return B>=0?B:B=n(t).height()}function m(t){return t.tagName.toLowerCase()}function b(t,e){if(e){var r=t.split(",");t="";for(var a=0,n=r.length;a<n;a++)t+=e+r[a].trim()+(a!==n-1?",":"")}return t}function v(t,e){var n,i=0;return function(o,u){function l(){i=+new Date,e.call(r,o)}var f=+new Date-i;n&&clearTimeout(n),f>t||!a.enableThrottle||u?l():n=setTimeout(l,t-f)}}function p(){--z,i.length||z||y("onFinishedAll")}function y(t,e,n){return!!(t=a[t])&&(t.apply(r,[].slice.call(arguments,1)),!0)}var z=0,w=-1,B=-1,L=!1,T="afterLoad",D="load",I="error",N="img",E="src",F="srcset",C="sizes",O="background-image";"event"===a.bind||o?f():n(t).on(D+"."+l,f)}function a(a,o){var u=this,l=n.extend({},u.config,o),f={},c=l.name+"-"+ ++i;return u.config=function(t,r){return r===e?l[t]:(l[t]=r,u)},u.addItems=function(t){return f.a&&f.a("string"===n.type(t)?n(t):t),u},u.getItems=function(){return f.g?f.g():{}},u.update=function(t){return f.e&&f.e({},!t),u},u.force=function(t){return f.f&&f.f("string"===n.type(t)?n(t):t),u},u.loadAll=function(){return f.e&&f.e({all:!0},!0),u},u.destroy=function(){return n(l.appendScroll).off("."+c,f.e),n(t).off("."+c),f={},e},r(u,l,a,f,c),l.chainable?a:u}var n=t.jQuery||t.Zepto,i=0,o=!1;n.fn.Lazy=n.fn.lazy=function(t){return new a(this,t)},n.Lazy=n.lazy=function(t,r,i){if(n.isFunction(r)&&(i=r,r=[]),n.isFunction(i)){t=n.isArray(t)?t:[t],r=n.isArray(r)?r:[r];for(var o=a.prototype.config,u=o._f||(o._f={}),l=0,f=t.length;l<f;l++)(o[t[l]]===e||n.isFunction(o[t[l]]))&&(o[t[l]]=i);for(var c=0,s=r.length;c<s;c++)u[r[c]]=t[0]}},a.prototype.config={name:"lazy",chainable:!0,autoDestroy:!0,bind:"load",threshold:500,visibleOnly:!1,appendScroll:t,scrollDirection:"both",imageBase:null,defaultImage:"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",placeholder:null,delay:-1,combined:!1,attribute:"data-src",srcsetAttribute:"data-srcset",sizesAttribute:"data-sizes",retinaAttribute:"data-retina",loaderAttribute:"data-loader",imageBaseAttribute:"data-imagebase",removeAttribute:!0,handledName:"handled",loadedName:"loaded",effect:"show",effectTime:0,enableThrottle:!0,throttle:250,beforeLoad:e,afterLoad:e,onError:e,onFinishedAll:e},n(t).on("load",function(){o=!0})}(window);
|
2
gaseous-server/wwwroot/scripts/jquery.lazy.plugins.min.js
vendored
Normal file
2
gaseous-server/wwwroot/scripts/jquery.lazy.plugins.min.js
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/*! jQuery & Zepto Lazy - All Plugins v1.7.10 - http://jquery.eisbehr.de/lazy - MIT&GPL-2.0 license - Copyright 2012-2018 Daniel 'Eisbehr' Kern */
|
||||
!function(t){function a(a,e,r,o){o=o?o.toUpperCase():"GET";var i;"POST"!==o&&"PUT"!==o||!a.config("ajaxCreateData")||(i=a.config("ajaxCreateData").apply(a,[e])),t.ajax({url:e.attr("data-src"),type:"POST"===o||"PUT"===o?o:"GET",data:i,dataType:e.attr("data-type")||"html",success:function(t){e.html(t),r(!0),a.config("removeAttribute")&&e.removeAttr("data-src data-method data-type")},error:function(){r(!1)}})}t.lazy("ajax",function(t,e){a(this,t,e,t.attr("data-method"))}),t.lazy("get",function(t,e){a(this,t,e,"GET")}),t.lazy("post",function(t,e){a(this,t,e,"POST")}),t.lazy("put",function(t,e){a(this,t,e,"PUT")})}(window.jQuery||window.Zepto),function(t){t.lazy(["av","audio","video"],["audio","video"],function(a,e){var r=a[0].tagName.toLowerCase();if("audio"===r||"video"===r){var o=a.find("data-src"),i=a.find("data-track"),n=0,c=function(){++n===o.length&&e(!1)},s=function(){var a=t(this),e=a[0].tagName.toLowerCase(),r=a.prop("attributes"),o=t("data-src"===e?"<source>":"<track>");"data-src"===e&&o.one("error",c),t.each(r,function(t,a){o.attr(a.name,a.value)}),a.replaceWith(o)};a.one("loadedmetadata",function(){e(!0)}).off("load error").attr("poster",a.attr("data-poster")),o.length?o.each(s):a.attr("data-src")?(t.each(a.attr("data-src").split(","),function(e,r){var o=r.split("|");a.append(t("<source>").one("error",c).attr({src:o[0].trim(),type:o[1].trim()}))}),this.config("removeAttribute")&&a.removeAttr("data-src")):e(!1),i.length&&i.each(s)}else e(!1)})}(window.jQuery||window.Zepto),function(t){t.lazy(["frame","iframe"],"iframe",function(a,e){var r=this;if("iframe"===a[0].tagName.toLowerCase()){var o=a.attr("data-error-detect");"true"!==o&&"1"!==o?(a.attr("src",a.attr("data-src")),r.config("removeAttribute")&&a.removeAttr("data-src data-error-detect")):t.ajax({url:a.attr("data-src"),dataType:"html",crossDomain:!0,xhrFields:{withCredentials:!0},success:function(t){a.html(t).attr("src",a.attr("data-src")),r.config("removeAttribute")&&a.removeAttr("data-src data-error-detect")},error:function(){e(!1)}})}else e(!1)})}(window.jQuery||window.Zepto),function(t){t.lazy("noop",function(){}),t.lazy("noop-success",function(t,a){a(!0)}),t.lazy("noop-error",function(t,a){a(!1)})}(window.jQuery||window.Zepto),function(t){function a(a,e,i){var n=a.prop("attributes"),c=t("<"+e+">");return t.each(n,function(t,a){"srcset"!==a.name&&a.name!==o||(a.value=r(a.value,i)),c.attr(a.name,a.value)}),a.replaceWith(c),c}function e(a,e,r){var o=t("<img>").one("load",function(){r(!0)}).one("error",function(){r(!1)}).appendTo(a).attr("src",e);o.complete&&o.load()}function r(t,a){if(a){var e=t.split(",");t="";for(var r=0,o=e.length;r<o;r++)t+=a+e[r].trim()+(r!==o-1?",":"")}return t}var o="data-src";t.lazy(["pic","picture"],["picture"],function(i,n){if("picture"===i[0].tagName.toLowerCase()){var c=i.find(o),s=i.find("data-img"),d=this.config("imageBase")||"";c.length?(c.each(function(){a(t(this),"source",d)}),1===s.length?(s=a(s,"img",d),s.on("load",function(){n(!0)}).on("error",function(){n(!1)}),s.attr("src",s.attr(o)),this.config("removeAttribute")&&s.removeAttr(o)):i.attr(o)?(e(i,d+i.attr(o),n),this.config("removeAttribute")&&i.removeAttr(o)):n(!1)):i.attr("data-srcset")?(t("<source>").attr({media:i.attr("data-media"),sizes:i.attr("data-sizes"),type:i.attr("data-type"),srcset:r(i.attr("data-srcset"),d)}).appendTo(i),e(i,d+i.attr(o),n),this.config("removeAttribute")&&i.removeAttr(o+" data-srcset data-media data-sizes data-type")):n(!1)}else n(!1)})}(window.jQuery||window.Zepto),function(t){t.lazy(["js","javascript","script"],"script",function(t,a){"script"===t[0].tagName.toLowerCase()?(t.attr("src",t.attr("data-src")),this.config("removeAttribute")&&t.removeAttr("data-src")):a(!1)})}(window.jQuery||window.Zepto),function(t){t.lazy("vimeo",function(t,a){"iframe"===t[0].tagName.toLowerCase()?(t.attr("src","https://player.vimeo.com/video/"+t.attr("data-src")),this.config("removeAttribute")&&t.removeAttr("data-src")):a(!1)})}(window.jQuery||window.Zepto),function(t){t.lazy(["yt","youtube"],function(t,a){if("iframe"===t[0].tagName.toLowerCase()){var e=/1|true/.test(t.attr("data-nocookie"));t.attr("src","https://www.youtube"+(e?"-nocookie":"")+".com/embed/"+t.attr("data-src")+"?rel=0&showinfo=0"),this.config("removeAttribute")&&t.removeAttr("data-src")}else a(!1)})}(window.jQuery||window.Zepto);
|
@@ -1,4 +1,4 @@
|
||||
function ajaxCall(endpoint, method, successFunction) {
|
||||
function ajaxCall(endpoint, method, successFunction, errorFunction) {
|
||||
$.ajax({
|
||||
|
||||
// Our sample url to make request
|
||||
@@ -11,18 +11,46 @@
|
||||
// Function to call when to
|
||||
// request is ok
|
||||
success: function (data) {
|
||||
var x = JSON.stringify(data);
|
||||
console.log(x);
|
||||
//var x = JSON.stringify(data);
|
||||
//console.log(x);
|
||||
successFunction(data);
|
||||
},
|
||||
|
||||
// Error handling
|
||||
error: function (error) {
|
||||
console.log(`Error ${error}`);
|
||||
|
||||
if (errorFunction) {
|
||||
errorFunction(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getQueryString(stringName, type) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
var myParam = urlParams.get(stringName);
|
||||
|
||||
switch (type) {
|
||||
case "int":
|
||||
if (typeof (Number(myParam)) == 'number') {
|
||||
return Number(myParam);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
if (typeof (myParam) == 'string') {
|
||||
return encodeURIComponent(myParam);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function formatBytes(bytes, decimals = 2) {
|
||||
if (!+bytes) return '0 Bytes'
|
||||
|
||||
@@ -72,6 +100,48 @@ function showDialog(dialogPage, variables) {
|
||||
$('#modal-content').load('/pages/dialogs/' + dialogPage + '.html');
|
||||
}
|
||||
|
||||
var subModalVariables;
|
||||
|
||||
function showSubDialog(dialogPage, variables) {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
// Get the button that opens the modal
|
||||
var subbtn = document.getElementById("romDelete");
|
||||
|
||||
// Get the <span> element that closes the modal
|
||||
var subspan = document.getElementById("modal-close-sub");
|
||||
|
||||
// When the user clicks on the button, open the modal
|
||||
submodal.style.display = "block";
|
||||
|
||||
// When the user clicks on <span> (x), close the modal
|
||||
subspan.onclick = function () {
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
|
||||
subModalVariables = modalVariables;
|
||||
|
||||
$('#modal-content-sub').load('/pages/dialogs/' + dialogPage + '.html');
|
||||
}
|
||||
|
||||
function closeSubDialog() {
|
||||
// Get the modal
|
||||
var submodal = document.getElementById("myModalSub");
|
||||
|
||||
// Get the modal content
|
||||
var subModalContent = document.getElementById("modal-content-sub");
|
||||
|
||||
submodal.style.display = "none";
|
||||
subModalContent.innerHTML = "";
|
||||
subModalVariables = null;
|
||||
}
|
||||
|
||||
function randomIntFromInterval(min, max) { // min and max included
|
||||
var rand = Math.floor(Math.random() * (max - min + 1) + min);
|
||||
return rand;
|
||||
@@ -90,13 +160,62 @@ function createTableRow(isHeader, row, rowClass, cellClass) {
|
||||
var newCell = document.createElement(cellType);
|
||||
if (typeof(row[i]) != "object") {
|
||||
newCell.innerHTML = row[i];
|
||||
newCell.className = cellClass;
|
||||
} else {
|
||||
newCell.appendChild(row[i]);
|
||||
if (Array.isArray(row[i])) {
|
||||
newCell.innerHTML = row[i][0];
|
||||
if (row[i][1]) { newCell.className = row[i][1]; }
|
||||
if (row[i][2]) { newCell.setAttribute('name', row[i][2]); }
|
||||
} else {
|
||||
newCell.appendChild(row[i]);
|
||||
newCell.className = cellClass;
|
||||
}
|
||||
}
|
||||
newCell.className = cellClass;
|
||||
|
||||
newRow.appendChild(newCell);
|
||||
}
|
||||
|
||||
return newRow;
|
||||
}
|
||||
|
||||
function hashCode(str) {
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
function intToRGB(i) {
|
||||
var c = (i & 0x00FFFFFF)
|
||||
.toString(16)
|
||||
.toUpperCase();
|
||||
|
||||
return "00000".substring(0, 6 - c.length) + c;
|
||||
}
|
||||
|
||||
function DropDownRenderGameOption(state) {
|
||||
console.log(JSON.stringify(state));
|
||||
|
||||
if (state.loading) {
|
||||
return state;
|
||||
}
|
||||
|
||||
var response;
|
||||
|
||||
if (state.cover) {
|
||||
response = $(
|
||||
'<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="https://images.igdb.com/igdb/image/upload/t_cover_small/' + state.cover.value.imageId + '.jpg" /></td><td class="dropdown-label"><span>' + state.text + '</span></td></tr></table>'
|
||||
);
|
||||
} else {
|
||||
response = $(
|
||||
'<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="/images/unknowngame.png" /></td><td class="dropdown-label"><span>' + state.text + '</span></td></tr></table>'
|
||||
);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
1
gaseous-server/wwwroot/styles/dropzone.min.css
vendored
Normal file
1
gaseous-server/wwwroot/styles/dropzone.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -105,6 +105,28 @@ h3 {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#banner_upload {
|
||||
background-color: white;
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
right: 41px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 0px;
|
||||
margin: 0px;
|
||||
display: flex;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#banner_upload:hover {
|
||||
cursor: pointer;
|
||||
background-color: lightgrey;
|
||||
}
|
||||
|
||||
#banner_cog {
|
||||
background-color: white;
|
||||
position: fixed;
|
||||
@@ -121,11 +143,18 @@ h3 {
|
||||
|
||||
#banner_cog:hover {
|
||||
cursor: pointer;
|
||||
background-color: lightgrey;
|
||||
}
|
||||
|
||||
#banner_system_image {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
#banner_upload_image {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#banner_header {
|
||||
@@ -168,6 +197,7 @@ h3 {
|
||||
}
|
||||
|
||||
.filter_header {
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
background-color: #2b2b2b;
|
||||
}
|
||||
@@ -267,6 +297,9 @@ input[id='filter_panel_search'] {
|
||||
.game_tile_image {
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
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);
|
||||
}
|
||||
|
||||
.game_tile_image, .unknown {
|
||||
@@ -324,6 +357,9 @@ input[id='filter_panel_search'] {
|
||||
max-width: 250px;
|
||||
max-height: 350px;
|
||||
width: 100%;
|
||||
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);
|
||||
}
|
||||
|
||||
.gamegenrelabel {
|
||||
@@ -337,6 +373,9 @@ input[id='filter_panel_search'] {
|
||||
max-height: 64px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
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);
|
||||
}
|
||||
|
||||
.rating_image_mini {
|
||||
@@ -351,6 +390,9 @@ input[id='filter_panel_search'] {
|
||||
padding: 10px;
|
||||
/*height: 350px;*/
|
||||
margin-bottom: 20px;
|
||||
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);
|
||||
}
|
||||
|
||||
#gamescreenshots_main {
|
||||
@@ -469,7 +511,7 @@ th {
|
||||
|
||||
.romlink {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
/*text-decoration: none;*/
|
||||
}
|
||||
|
||||
.romlink:hover {
|
||||
@@ -478,6 +520,59 @@ th {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.romstart {
|
||||
padding-left: 7px;
|
||||
padding-right: 7px;
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
background-color: #02B01B;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 6px #003506;
|
||||
text-decoration: none;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
-webkit-border-radius: 5px 5px 5px 5px;
|
||||
-moz-border-radius: 5px 5px 5px 5px;
|
||||
border: 1px solid #19d348;
|
||||
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);
|
||||
}
|
||||
|
||||
.romstart:hover {
|
||||
background-color: #003506;
|
||||
border-color: #129834;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.properties_button {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: 15px;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
line-height: 17px;
|
||||
text-align: center;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
border-color: white;
|
||||
background-color: blue;
|
||||
outline-color: blue;
|
||||
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);
|
||||
}
|
||||
|
||||
.properties_button:hover {
|
||||
cursor: pointer;
|
||||
color: blue;
|
||||
border-color: blue;
|
||||
background-color: white;
|
||||
outline-color: white;
|
||||
}
|
||||
|
||||
#gamedev_logo {
|
||||
float: right;
|
||||
max-height: 48px;
|
||||
@@ -492,6 +587,8 @@ th {
|
||||
display: block;
|
||||
width: 150px;
|
||||
min-width: 150px;
|
||||
background-color: #383838;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div[name="properties_toc_item"] {
|
||||
@@ -518,6 +615,10 @@ div[name="properties_toc_item"]:hover {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.settings_toc {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.select2-container--open .select2-dropdown--below,
|
||||
.select2-container--open .select2-dropdown--above {
|
||||
background: #2b2b2b;
|
||||
@@ -546,7 +647,7 @@ div[name="properties_toc_item"]:hover {
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #888;
|
||||
background-color: #555;
|
||||
color: white;
|
||||
border-width: 1px;
|
||||
border-color: #555;
|
||||
@@ -555,10 +656,12 @@ button {
|
||||
padding-bottom: 5px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin-right: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #555;
|
||||
background-color: #888;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -584,4 +687,99 @@ button:disabled {
|
||||
margin: 0 auto;
|
||||
width: 640px;
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
#emulatorbios {
|
||||
margin: 0 auto;
|
||||
width: 640px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.greentext {
|
||||
color: lightgreen;
|
||||
}
|
||||
|
||||
.redtext {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#settings_photocredit {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 20px;
|
||||
background-color: rgba(0, 22, 56, 0.8);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#upload_target {
|
||||
background-color: #383838;
|
||||
color: white;
|
||||
border: none;
|
||||
height: 310px;
|
||||
margin-top: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.legend_box {
|
||||
display: inline-block;
|
||||
width: 145px;
|
||||
height: 50px;
|
||||
vertical-align: top;
|
||||
margin-right: 5px;
|
||||
padding-right: 5px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.legend_colour {
|
||||
float: left;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.legend_label {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.rom_checkbox_box {
|
||||
|
||||
}
|
||||
|
||||
.rom_checkbox_box_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#rom_edit, #rom_edit_delete {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#rom_edit_panel {
|
||||
background-color: rgba(56, 56, 56, 0.3);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#game {
|
||||
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);
|
||||
}
|
||||
|
||||
#rom_edit_progressbar {
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
background-color: lightgray;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#rom_edit_progressbar_progress {
|
||||
height: 10px;
|
||||
background-color: cyan;
|
||||
}
|
@@ -14,7 +14,7 @@
|
||||
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySql.Data" Version="8.0.33" />
|
||||
<PackageReference Include="MySql.Data" Version="8.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@@ -335,6 +335,22 @@ namespace gaseous_tools
|
||||
}
|
||||
}
|
||||
|
||||
public string LibraryBIOSDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(LibraryRootDirectory, "BIOS");
|
||||
}
|
||||
}
|
||||
|
||||
public string LibraryUploadDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
return Path.Combine(LibraryRootDirectory, "Upload");
|
||||
}
|
||||
}
|
||||
|
||||
public string LibraryMetadataDirectory
|
||||
{
|
||||
get
|
||||
@@ -385,6 +401,8 @@ namespace gaseous_tools
|
||||
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
||||
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
|
||||
if (!Directory.Exists(LibraryDataDirectory)) { Directory.CreateDirectory(LibraryDataDirectory); }
|
||||
if (!Directory.Exists(LibraryBIOSDirectory)) { Directory.CreateDirectory(LibraryBIOSDirectory); }
|
||||
if (!Directory.Exists(LibraryUploadDirectory)) { Directory.CreateDirectory(LibraryUploadDirectory); }
|
||||
if (!Directory.Exists(LibraryMetadataDirectory)) { Directory.CreateDirectory(LibraryMetadataDirectory); }
|
||||
if (!Directory.Exists(LibrarySignatureImportDirectory)) { Directory.CreateDirectory(LibrarySignatureImportDirectory); }
|
||||
if (!Directory.Exists(LibrarySignatureImportDirectory_TOSEC)) { Directory.CreateDirectory(LibrarySignatureImportDirectory_TOSEC); }
|
||||
|
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySql.Data" Version="8.0.33" />
|
||||
<PackageReference Include="MySql.Data" Version="8.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="IGDB" Version="2.3.2" />
|
||||
</ItemGroup>
|
||||
|
Reference in New Issue
Block a user