Compare commits
1 Commits
michael-j-
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2f84a363d |
@@ -1,10 +1,6 @@
|
|||||||
FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm
|
FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm
|
||||||
|
|
||||||
# update apt-get
|
RUN apt-get update && apt-get install -y p7zip-full
|
||||||
RUN apt-get update
|
RUN mkdir -p /workspace/gaseous-server/wwwroot/emulators/EmulatorJS
|
||||||
|
RUN wget https://cdn.emulatorjs.org/releases/4.0.12.7z
|
||||||
# download and unzip EmulatorJS from CDN
|
RUN 7z x -y -o/workspace/gaseous-server/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
||||||
RUN apt-get install -y p7zip-full default-jdk nodejs wget
|
|
||||||
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
|
||||||
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
|
||||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.7z
|
|
||||||
@@ -1,25 +1,27 @@
|
|||||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
|
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
|
||||||
{
|
{
|
||||||
"name": "Gaseous C# (.NET)",
|
"name": "C# (.NET)",
|
||||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||||
//"image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm",
|
//"image": "mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm",
|
||||||
"dockerComposeFile": "docker-compose.yml",
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
"service": "development",
|
"service": "development",
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
|
|
||||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
// "features": {},
|
// "features": {},
|
||||||
|
|
||||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
"forwardPorts": [
|
"forwardPorts": [5198],
|
||||||
5198
|
|
||||||
],
|
|
||||||
"portsAttributes": {
|
"portsAttributes": {
|
||||||
"5198": {
|
"5198": {
|
||||||
"protocol": "http"
|
"protocol": "http"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
"postCreateCommand": "dotnet restore",
|
"postCreateCommand": "dotnet restore",
|
||||||
|
|
||||||
// Configure tool-specific properties.
|
// Configure tool-specific properties.
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
@@ -36,12 +38,11 @@
|
|||||||
"ms-dotnettools.vscodeintellicode-csharp",
|
"ms-dotnettools.vscodeintellicode-csharp",
|
||||||
"Zignd.html-css-class-completion",
|
"Zignd.html-css-class-completion",
|
||||||
"PWABuilder.pwa-studio",
|
"PWABuilder.pwa-studio",
|
||||||
"ms-azuretools.vscode-docker",
|
"ms-azuretools.vscode-docker"
|
||||||
"SonarSource.sonarlint-vscode",
|
|
||||||
"oderwat.indent-rainbow"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
// "remoteUser": "root"
|
// "remoteUser": "root"
|
||||||
}
|
}
|
||||||
61
.github/workflows/BuildNightly.yml
vendored
61
.github/workflows/BuildNightly.yml
vendored
@@ -1,61 +0,0 @@
|
|||||||
name: Build Nightly Docker Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '15 4 * * *'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
docker:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
packages: write
|
|
||||||
contents: read
|
|
||||||
attestations: write
|
|
||||||
id-token: write
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
- name: Install dotnet tool
|
|
||||||
run: dotnet tool install -g dotnetCampus.TagToVersion
|
|
||||||
- name: Set tag to version
|
|
||||||
run: dotnet TagToVersion -t 0.0.0-nightly
|
|
||||||
- name: Sign in to Nuget
|
|
||||||
run: dotnet nuget add source --username michael-j-green --password ${{ secrets.NUGETKEY }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/gaseous-project/index.json"
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
||||||
- name: Login to GitHub Package Registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Build and push standard image
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./build/Dockerfile
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: |
|
|
||||||
gaseousgames/gaseousserver:nightly
|
|
||||||
ghcr.io/gaseous-project/gaseousserver:nightly
|
|
||||||
- name: Build and push image with embedded mariadb
|
|
||||||
uses: docker/build-push-action@v6
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./build/Dockerfile-EmbeddedDB
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: |
|
|
||||||
gaseousgames/gaseousserver:nightly-embeddeddb
|
|
||||||
ghcr.io/gaseous-project/gaseousserver:nightly-embeddeddb
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
[](https://github.com/gaseous-project/gaseous-server/actions/workflows/dotnet.yml) [](https://github.com/gaseous-project/gaseous-server/actions/workflows/BuildNightly.yml) [](https://github.com/gaseous-project/gaseous-server/actions/workflows/BuildDockerOnTag-Release.yml)
|
[](https://github.com/gaseous-project/gaseous-server/actions/workflows/dotnet.yml) [](https://github.com/gaseous-project/gaseous-server/actions/workflows/BuildDockerOnTag-Release.yml)
|
||||||
# <img src="./logo.png" height="28" style="float: right;" /> Gaseous Server
|
# <img src="./logo.png" height="28" style="float: right;" /> Gaseous Server
|
||||||
|
|
||||||
This is the server for the Gaseous system. It offers ROM and title management, as well as some basic in browser emulation of those ROMs.
|
This is the server for the Gaseous system. It offers ROM and title management, as well as some basic in browser emulation of those ROMs.
|
||||||
|
|||||||
@@ -16,14 +16,20 @@ RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
|||||||
# Build and publish a release
|
# Build and publish a release
|
||||||
RUN dotnet publish "gaseous-server/gaseous-server.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
RUN dotnet publish "gaseous-server/gaseous-server.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
||||||
|
|
||||||
|
# Build Gaseous CLI
|
||||||
|
# Restore as distinct layers
|
||||||
|
RUN dotnet restore "gaseous-cli/gaseous-cli.csproj" -a $TARGETARCH
|
||||||
|
# Build and publish a release
|
||||||
|
RUN dotnet publish "gaseous-cli/gaseous-cli.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
||||||
|
|
||||||
# update apt-get
|
# update apt-get
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
|
|
||||||
# download and unzip EmulatorJS from CDN
|
# # download and unzip EmulatorJS from CDN
|
||||||
RUN apt-get install -y p7zip-full
|
RUN apt-get install -y p7zip-full
|
||||||
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
||||||
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
RUN wget https://cdn.emulatorjs.org/releases/4.0.12.7z
|
||||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.7z
|
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
||||||
|
|
||||||
# clean up apt-get
|
# clean up apt-get
|
||||||
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
||||||
|
|||||||
@@ -16,14 +16,20 @@ RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
|||||||
# Build and publish a release
|
# Build and publish a release
|
||||||
RUN dotnet publish "gaseous-server/gaseous-server.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
RUN dotnet publish "gaseous-server/gaseous-server.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
||||||
|
|
||||||
|
# Build Gaseous CLI
|
||||||
|
# Restore as distinct layers
|
||||||
|
RUN dotnet restore "gaseous-cli/gaseous-cli.csproj" -a $TARGETARCH
|
||||||
|
# Build and publish a release
|
||||||
|
RUN dotnet publish "gaseous-cli/gaseous-cli.csproj" --use-current-runtime --self-contained true -c Release -o out -a $TARGETARCH
|
||||||
|
|
||||||
# update apt-get
|
# update apt-get
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
|
|
||||||
# download and unzip EmulatorJS from CDN
|
# # download and unzip EmulatorJS from CDN
|
||||||
RUN apt-get install -y p7zip-full
|
RUN apt-get install -y p7zip-full
|
||||||
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
||||||
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
RUN wget https://cdn.emulatorjs.org/releases/4.0.12.7z
|
||||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.7z
|
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
||||||
|
|
||||||
# Build runtime image
|
# Build runtime image
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -13,37 +11,6 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ImportBiosFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> BiosFileInfo)
|
|
||||||
{
|
|
||||||
BiosFileInfo.Add("type", "bios");
|
|
||||||
BiosFileInfo.Add("status", "notimported");
|
|
||||||
|
|
||||||
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
|
||||||
{
|
|
||||||
if (biosItem.Available == false)
|
|
||||||
{
|
|
||||||
if (biosItem.hash == Hash.md5hash)
|
|
||||||
{
|
|
||||||
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import BIOS File", " " + FilePath + " is a BIOS file - moving to " + biosPath);
|
|
||||||
|
|
||||||
File.Move(FilePath, biosItem.biosPath, true);
|
|
||||||
|
|
||||||
BiosFileInfo.Add("name", biosItem.filename);
|
|
||||||
BiosFileInfo.Add("platform", Platforms.GetPlatform(biosItem.platformid));
|
|
||||||
BiosFileInfo["status"] = "imported";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (biosItem.hash == Hash.md5hash)
|
|
||||||
{
|
|
||||||
BiosFileInfo["status"] = "duplicate";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void MigrateToNewFolderStructure()
|
public static void MigrateToNewFolderStructure()
|
||||||
{
|
{
|
||||||
// migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash
|
// migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash
|
||||||
@@ -127,7 +94,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
if (platformMapping.Bios != null)
|
if (platformMapping.Bios != null)
|
||||||
{
|
{
|
||||||
Platform platform = Metadata.Platforms.GetPlatform(platformMapping.IGDBId);
|
IGDB.Models.Platform platform = Metadata.Platforms.GetPlatform(platformMapping.IGDBId);
|
||||||
|
|
||||||
foreach (Models.PlatformMapping.PlatformMapItem.EmulatorBiosItem emulatorBios in platformMapping.Bios)
|
foreach (Models.PlatformMapping.PlatformMapItem.EmulatorBiosItem emulatorBios in platformMapping.Bios)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using gaseous_server.Classes.Metadata;
|
|||||||
using gaseous_server.Controllers;
|
using gaseous_server.Controllers;
|
||||||
using gaseous_server.Controllers.v1_1;
|
using gaseous_server.Controllers.v1_1;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@@ -18,10 +18,9 @@ using static gaseous_server.Classes.Metadata.Games;
|
|||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class Collections
|
public class Collections
|
||||||
{
|
{
|
||||||
public static List<CollectionItem> GetCollections(string userid)
|
public static List<CollectionItem> GetCollections(string userid) {
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT * FROM RomCollections WHERE OwnedBy=@ownedby ORDER BY `Name`";
|
string sql = "SELECT * FROM RomCollections WHERE OwnedBy=@ownedby ORDER BY `Name`";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||||
@@ -31,18 +30,16 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
List<CollectionItem> collectionItems = new List<CollectionItem>();
|
List<CollectionItem> collectionItems = new List<CollectionItem>();
|
||||||
|
|
||||||
foreach (DataRow row in data.Rows)
|
foreach(DataRow row in data.Rows) {
|
||||||
{
|
|
||||||
collectionItems.Add(BuildCollectionItem(row));
|
collectionItems.Add(BuildCollectionItem(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
return collectionItems;
|
return collectionItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CollectionItem GetCollection(long Id, string userid)
|
public static CollectionItem GetCollection(long Id, string userid) {
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql;
|
string sql;
|
||||||
if (userid == "")
|
if (userid == "")
|
||||||
{
|
{
|
||||||
// reserved for internal operations
|
// reserved for internal operations
|
||||||
@@ -53,24 +50,24 @@ namespace gaseous_server.Classes
|
|||||||
// instigated by a user
|
// instigated by a user
|
||||||
sql = "SELECT * FROM RomCollections WHERE Id = @id AND OwnedBy = @ownedby ORDER BY `Name`";
|
sql = "SELECT * FROM RomCollections WHERE Id = @id AND OwnedBy = @ownedby ORDER BY `Name`";
|
||||||
}
|
}
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "id", Id },
|
{ "id", Id },
|
||||||
{ "ownedby", userid }
|
{ "ownedby", userid }
|
||||||
};
|
};
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
DataRow row = romDT.Rows[0];
|
DataRow row = romDT.Rows[0];
|
||||||
CollectionItem collectionItem = BuildCollectionItem(row);
|
CollectionItem collectionItem = BuildCollectionItem(row);
|
||||||
|
|
||||||
return collectionItem;
|
return collectionItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("Unknown Collection Id");
|
throw new Exception("Unknown Collection Id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CollectionItem NewCollection(CollectionItem item, string userid)
|
public static CollectionItem NewCollection(CollectionItem item, string userid)
|
||||||
@@ -211,8 +208,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CollectionContents GetCollectionContent(CollectionItem collectionItem, string userid)
|
public static CollectionContents GetCollectionContent(CollectionItem collectionItem, string userid) {
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
// get age ratings for specified user
|
// get age ratings for specified user
|
||||||
@@ -255,29 +251,24 @@ namespace gaseous_server.Classes
|
|||||||
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude ||
|
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysInclude ||
|
||||||
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude
|
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude
|
||||||
)
|
)
|
||||||
{
|
|
||||||
if (!platformids.Contains(alwaysIncludeItem.PlatformId))
|
|
||||||
{
|
{
|
||||||
platformids.Add(alwaysIncludeItem.PlatformId);
|
if (!platformids.Contains(alwaysIncludeItem.PlatformId))
|
||||||
}
|
{
|
||||||
|
platformids.Add(alwaysIncludeItem.PlatformId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add dynamic platforms
|
// add dynamic platforms
|
||||||
if (DynamicPlatforms.Count > 0)
|
if (DynamicPlatforms.Count > 0) {
|
||||||
{
|
foreach (long PlatformId in platformids) {
|
||||||
foreach (long PlatformId in platformids)
|
|
||||||
{
|
|
||||||
platforms.Add(Platforms.GetPlatform(PlatformId));
|
platforms.Add(Platforms.GetPlatform(PlatformId));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// get all platforms to pull from
|
// get all platforms to pull from
|
||||||
Dictionary<string, List<Filters.FilterItem>> FilterDict = Filters.Filter(AgeGroups.AgeRestrictionGroupings.Adult, true);
|
Dictionary<string, List<Filters.FilterItem>> FilterDict = Filters.Filter(AgeGroups.AgeRestrictionGroupings.Adult, true);
|
||||||
List<Classes.Filters.FilterItem> filteredPlatforms = (List<Classes.Filters.FilterItem>)FilterDict["platforms"];
|
List<Classes.Filters.FilterItem> filteredPlatforms = (List<Classes.Filters.FilterItem>)FilterDict["platforms"];
|
||||||
foreach (Filters.FilterItem filterItem in filteredPlatforms)
|
foreach (Filters.FilterItem filterItem in filteredPlatforms) {
|
||||||
{
|
|
||||||
platforms.Add(Platforms.GetPlatform(filterItem.Id));
|
platforms.Add(Platforms.GetPlatform(filterItem.Id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,8 +280,7 @@ namespace gaseous_server.Classes
|
|||||||
// build collection
|
// build collection
|
||||||
List<CollectionContents.CollectionPlatformItem> platformItems = new List<CollectionContents.CollectionPlatformItem>();
|
List<CollectionContents.CollectionPlatformItem> platformItems = new List<CollectionContents.CollectionPlatformItem>();
|
||||||
|
|
||||||
foreach (Platform platform in platforms)
|
foreach (Platform platform in platforms) {
|
||||||
{
|
|
||||||
long TotalRomSize = 0;
|
long TotalRomSize = 0;
|
||||||
long TotalGameCount = 0;
|
long TotalGameCount = 0;
|
||||||
|
|
||||||
@@ -307,8 +297,7 @@ namespace gaseous_server.Classes
|
|||||||
Controllers.v1_1.GamesController.GameReturnPackage games = new Controllers.v1_1.GamesController.GameReturnPackage();
|
Controllers.v1_1.GamesController.GameReturnPackage games = new Controllers.v1_1.GamesController.GameReturnPackage();
|
||||||
if (isDynamic == true)
|
if (isDynamic == true)
|
||||||
{
|
{
|
||||||
Controllers.v1_1.GamesController.GameSearchModel searchModel = new Controllers.v1_1.GamesController.GameSearchModel
|
Controllers.v1_1.GamesController.GameSearchModel searchModel = new Controllers.v1_1.GamesController.GameSearchModel{
|
||||||
{
|
|
||||||
Name = "",
|
Name = "",
|
||||||
Platform = new List<string>{
|
Platform = new List<string>{
|
||||||
platform.Id.ToString()
|
platform.Id.ToString()
|
||||||
@@ -317,13 +306,11 @@ namespace gaseous_server.Classes
|
|||||||
GameMode = collectionItem.Players.ConvertAll(s => s.ToString()),
|
GameMode = collectionItem.Players.ConvertAll(s => s.ToString()),
|
||||||
PlayerPerspective = collectionItem.PlayerPerspectives.ConvertAll(s => s.ToString()),
|
PlayerPerspective = collectionItem.PlayerPerspectives.ConvertAll(s => s.ToString()),
|
||||||
Theme = collectionItem.Themes.ConvertAll(s => s.ToString()),
|
Theme = collectionItem.Themes.ConvertAll(s => s.ToString()),
|
||||||
GameRating = new Controllers.v1_1.GamesController.GameSearchModel.GameRatingItem
|
GameRating = new Controllers.v1_1.GamesController.GameSearchModel.GameRatingItem{
|
||||||
{
|
|
||||||
MinimumRating = collectionItem.MinimumRating,
|
MinimumRating = collectionItem.MinimumRating,
|
||||||
MaximumRating = collectionItem.MaximumRating
|
MaximumRating = collectionItem.MaximumRating
|
||||||
},
|
},
|
||||||
GameAgeRating = new Controllers.v1_1.GamesController.GameSearchModel.GameAgeRatingItem
|
GameAgeRating = new Controllers.v1_1.GamesController.GameSearchModel.GameAgeRatingItem{
|
||||||
{
|
|
||||||
AgeGroupings = UserAgeGroupings,
|
AgeGroupings = UserAgeGroupings,
|
||||||
IncludeUnrated = UserAgeGroupIncludeUnrated
|
IncludeUnrated = UserAgeGroupIncludeUnrated
|
||||||
}
|
}
|
||||||
@@ -344,21 +331,20 @@ namespace gaseous_server.Classes
|
|||||||
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude
|
alwaysIncludeItem.InclusionState == CollectionItem.AlwaysIncludeStatus.AlwaysExclude
|
||||||
) && alwaysIncludeItem.PlatformId == platform.Id
|
) && alwaysIncludeItem.PlatformId == platform.Id
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MinimalGameItem AlwaysIncludeGame = new MinimalGameItem(Games.GetGame(HasheousClient.Models.MetadataSources.IGDB, alwaysIncludeItem.GameId));
|
MinimalGameItem AlwaysIncludeGame = new MinimalGameItem(Games.GetGame(alwaysIncludeItem.GameId, false, false, false));
|
||||||
CollectionContents.CollectionPlatformItem.CollectionGameItem gameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(AlwaysIncludeGame);
|
CollectionContents.CollectionPlatformItem.CollectionGameItem gameItem = new CollectionContents.CollectionPlatformItem.CollectionGameItem(AlwaysIncludeGame);
|
||||||
gameItem.InclusionStatus = new CollectionItem.AlwaysIncludeItem();
|
gameItem.InclusionStatus = new CollectionItem.AlwaysIncludeItem();
|
||||||
gameItem.InclusionStatus.PlatformId = alwaysIncludeItem.PlatformId;
|
gameItem.InclusionStatus.PlatformId = alwaysIncludeItem.PlatformId;
|
||||||
gameItem.InclusionStatus.GameId = alwaysIncludeItem.GameId;
|
gameItem.InclusionStatus.GameId = alwaysIncludeItem.GameId;
|
||||||
gameItem.InclusionStatus.InclusionState = alwaysIncludeItem.InclusionState;
|
gameItem.InclusionStatus.InclusionState = alwaysIncludeItem.InclusionState;
|
||||||
gameItem.Roms = Roms.GetRoms((long)gameItem.Id, (long)platform.Id).GameRomItems;
|
gameItem.Roms = Roms.GetRoms((long)gameItem.Id, (long)platform.Id).GameRomItems;
|
||||||
|
|
||||||
collectionPlatformItem.Games.Add(gameItem);
|
collectionPlatformItem.Games.Add(gameItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (MinimalGameItem game in games.Games)
|
foreach (MinimalGameItem game in games.Games) {
|
||||||
{
|
|
||||||
bool gameAlreadyInList = false;
|
bool gameAlreadyInList = false;
|
||||||
foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem existingGame in collectionPlatformItem.Games)
|
foreach (CollectionContents.CollectionPlatformItem.CollectionGameItem existingGame in collectionPlatformItem.Games)
|
||||||
{
|
{
|
||||||
@@ -378,14 +364,11 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// calculate total rom size for the game
|
// calculate total rom size for the game
|
||||||
long GameRomSize = 0;
|
long GameRomSize = 0;
|
||||||
foreach (Roms.GameRomItem gameRom in gameRoms)
|
foreach (Roms.GameRomItem gameRom in gameRoms) {
|
||||||
{
|
|
||||||
GameRomSize += (long)gameRom.Size;
|
GameRomSize += (long)gameRom.Size;
|
||||||
}
|
}
|
||||||
if (collectionItem.MaximumBytesPerPlatform > 0)
|
if (collectionItem.MaximumBytesPerPlatform > 0) {
|
||||||
{
|
if ((TotalRomSize + GameRomSize) < collectionItem.MaximumBytesPerPlatform) {
|
||||||
if ((TotalRomSize + GameRomSize) < collectionItem.MaximumBytesPerPlatform)
|
|
||||||
{
|
|
||||||
AddGame = true;
|
AddGame = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,16 +377,13 @@ namespace gaseous_server.Classes
|
|||||||
AddGame = true;
|
AddGame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddGame == true)
|
if (AddGame == true) {
|
||||||
{
|
|
||||||
TotalRomSize += GameRomSize;
|
TotalRomSize += GameRomSize;
|
||||||
|
|
||||||
bool AddRoms = false;
|
bool AddRoms = false;
|
||||||
|
|
||||||
if (collectionItem.MaximumRomsPerPlatform > 0)
|
if (collectionItem.MaximumRomsPerPlatform > 0) {
|
||||||
{
|
if (TotalGameCount < collectionItem.MaximumRomsPerPlatform) {
|
||||||
if (TotalGameCount < collectionItem.MaximumRomsPerPlatform)
|
|
||||||
{
|
|
||||||
AddRoms = true;
|
AddRoms = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,8 +392,7 @@ namespace gaseous_server.Classes
|
|||||||
AddRoms = true;
|
AddRoms = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddRoms == true)
|
if (AddRoms == true) {
|
||||||
{
|
|
||||||
TotalGameCount += 1;
|
TotalGameCount += 1;
|
||||||
collectionGameItem.Roms = gameRoms;
|
collectionGameItem.Roms = gameRoms;
|
||||||
collectionPlatformItem.Games.Add(collectionGameItem);
|
collectionPlatformItem.Games.Add(collectionGameItem);
|
||||||
@@ -422,8 +401,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handle age grouping
|
// handle age grouping
|
||||||
List<AgeRating> gameAgeRatings = game.AgeRatings.Select(s => (AgeRating)s).ToList();
|
AgeGroups.AgeRestrictionGroupings CurrentAgeGroup = AgeGroups.GetAgeGroupFromAgeRatings(game.AgeRatings);
|
||||||
AgeGroups.AgeRestrictionGroupings CurrentAgeGroup = AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings);
|
|
||||||
if (CurrentAgeGroup > AgeGrouping)
|
if (CurrentAgeGroup > AgeGrouping)
|
||||||
{
|
{
|
||||||
AgeGrouping = CurrentAgeGroup;
|
AgeGrouping = CurrentAgeGroup;
|
||||||
@@ -522,8 +500,7 @@ namespace gaseous_server.Classes
|
|||||||
if (collectionItem.IncludeBIOSFiles == true)
|
if (collectionItem.IncludeBIOSFiles == true)
|
||||||
{
|
{
|
||||||
List<Bios.BiosItem> bios = Bios.GetBios(collectionPlatformItem.Id, true);
|
List<Bios.BiosItem> bios = Bios.GetBios(collectionPlatformItem.Id, true);
|
||||||
if (!Directory.Exists(ZipBiosPath))
|
if (!Directory.Exists(ZipBiosPath)) {
|
||||||
{
|
|
||||||
Directory.CreateDirectory(ZipBiosPath);
|
Directory.CreateDirectory(ZipBiosPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,7 +590,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// compress to zip
|
// compress to zip
|
||||||
Logging.Log(Logging.LogType.Information, "Collections", "Compressing collection");
|
Logging.Log(Logging.LogType.Information, "Collections", "Compressing collection");
|
||||||
switch (collectionItem.ArchiveType)
|
switch(collectionItem.ArchiveType)
|
||||||
{
|
{
|
||||||
case CollectionItem.ArchiveTypes.Zip:
|
case CollectionItem.ArchiveTypes.Zip:
|
||||||
ZipFile.CreateFromDirectory(ZipFileTempPath, ZipFilePath, CompressionLevel.SmallestSize, false);
|
ZipFile.CreateFromDirectory(ZipFileTempPath, ZipFilePath, CompressionLevel.SmallestSize, false);
|
||||||
@@ -662,8 +639,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CollectionItem BuildCollectionItem(DataRow row)
|
private static CollectionItem BuildCollectionItem(DataRow row) {
|
||||||
{
|
|
||||||
string strPlatforms = (string)Common.ReturnValueIfNull(row["Platforms"], "[ ]");
|
string strPlatforms = (string)Common.ReturnValueIfNull(row["Platforms"], "[ ]");
|
||||||
string strGenres = (string)Common.ReturnValueIfNull(row["Genres"], "[ ]");
|
string strGenres = (string)Common.ReturnValueIfNull(row["Genres"], "[ ]");
|
||||||
string strPlayers = (string)Common.ReturnValueIfNull(row["Players"], "[ ]");
|
string strPlayers = (string)Common.ReturnValueIfNull(row["Players"], "[ ]");
|
||||||
@@ -834,8 +810,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CollectionContents
|
public class CollectionContents {
|
||||||
{
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public List<CollectionPlatformItem> Collection { get; set; }
|
public List<CollectionPlatformItem> Collection { get; set; }
|
||||||
|
|
||||||
@@ -865,16 +840,13 @@ namespace gaseous_server.Classes
|
|||||||
public AgeGroups.AgeRestrictionGroupings AgeGroup { get; set; }
|
public AgeGroups.AgeRestrictionGroupings AgeGroup { get; set; }
|
||||||
public bool ContainsUnclassifiedAgeGroup { get; set; }
|
public bool ContainsUnclassifiedAgeGroup { get; set; }
|
||||||
|
|
||||||
public class CollectionPlatformItem
|
public class CollectionPlatformItem {
|
||||||
{
|
public CollectionPlatformItem(IGDB.Models.Platform platform) {
|
||||||
public CollectionPlatformItem(Platform platform)
|
|
||||||
{
|
|
||||||
string[] PropertyWhitelist = new string[] { "Id", "Name", "Slug" };
|
string[] PropertyWhitelist = new string[] { "Id", "Name", "Slug" };
|
||||||
|
|
||||||
PropertyInfo[] srcProperties = typeof(Platform).GetProperties();
|
PropertyInfo[] srcProperties = typeof(IGDB.Models.Platform).GetProperties();
|
||||||
PropertyInfo[] dstProperties = typeof(CollectionPlatformItem).GetProperties();
|
PropertyInfo[] dstProperties = typeof(CollectionPlatformItem).GetProperties();
|
||||||
foreach (PropertyInfo srcProperty in srcProperties)
|
foreach (PropertyInfo srcProperty in srcProperties) {
|
||||||
{
|
|
||||||
if (PropertyWhitelist.Contains<string>(srcProperty.Name))
|
if (PropertyWhitelist.Contains<string>(srcProperty.Name))
|
||||||
{
|
{
|
||||||
foreach (PropertyInfo dstProperty in dstProperties)
|
foreach (PropertyInfo dstProperty in dstProperties)
|
||||||
@@ -894,13 +866,10 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public List<CollectionGameItem> Games { get; set; }
|
public List<CollectionGameItem> Games { get; set; }
|
||||||
|
|
||||||
public int RomCount
|
public int RomCount {
|
||||||
{
|
get {
|
||||||
get
|
|
||||||
{
|
|
||||||
int Counter = 0;
|
int Counter = 0;
|
||||||
foreach (CollectionGameItem Game in Games)
|
foreach (CollectionGameItem Game in Games) {
|
||||||
{
|
|
||||||
Counter += 1;
|
Counter += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -908,15 +877,11 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long RomSize
|
public long RomSize {
|
||||||
{
|
get {
|
||||||
get
|
|
||||||
{
|
|
||||||
long Size = 0;
|
long Size = 0;
|
||||||
foreach (CollectionGameItem Game in Games)
|
foreach (CollectionGameItem Game in Games) {
|
||||||
{
|
foreach (Roms.GameRomItem Rom in Game.Roms) {
|
||||||
foreach (Roms.GameRomItem Rom in Game.Roms)
|
|
||||||
{
|
|
||||||
Size += (long)Rom.Size;
|
Size += (long)Rom.Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -940,12 +905,28 @@ namespace gaseous_server.Classes
|
|||||||
this.AgeRatings = gameObject.AgeRatings;
|
this.AgeRatings = gameObject.AgeRatings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IGDB.Models.Cover? CoverItem
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Cover != null)
|
||||||
|
{
|
||||||
|
IGDB.Models.Cover cover = Covers.GetCover(Cover.Id, Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory, "Games", Slug), false);
|
||||||
|
|
||||||
|
return cover;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public AgeGroups.AgeRestrictionGroupings AgeGrouping
|
public AgeGroups.AgeRestrictionGroupings AgeGrouping
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
List<AgeRating> gameAgeRatings = this.AgeRatings.Select(s => (AgeRating)s).ToList();
|
return AgeGroups.GetAgeGroupFromAgeRatings(this.AgeRatings);
|
||||||
return AgeGroups.GetAgeGroupFromAgeRatings(gameAgeRatings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,20 +934,17 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public List<Roms.GameRomItem> Roms { get; set; }
|
public List<Roms.GameRomItem> Roms { get; set; }
|
||||||
|
|
||||||
public long RomSize
|
public long RomSize {
|
||||||
{
|
get {
|
||||||
get
|
long Size = 0;
|
||||||
{
|
foreach (Roms.GameRomItem Rom in Roms) {
|
||||||
long Size = 0;
|
Size += (long)Rom.Size;
|
||||||
foreach (Roms.GameRomItem Rom in Roms)
|
|
||||||
{
|
|
||||||
Size += (long)Rom.Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Drawing;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using static gaseous_server.Classes.Metadata.Communications;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -128,27 +126,6 @@ namespace gaseous_server.Classes
|
|||||||
typeof(DescriptionAttribute)))?.Description ?? value.ToString();
|
typeof(DescriptionAttribute)))?.Description ?? value.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Point GetResolution(this Enum value)
|
|
||||||
{
|
|
||||||
string width = ((ResolutionAttribute)Attribute.GetCustomAttribute(
|
|
||||||
value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static)
|
|
||||||
.Single(x => x.GetValue(null).Equals(value)),
|
|
||||||
typeof(ResolutionAttribute)))?.width.ToString() ?? value.ToString();
|
|
||||||
|
|
||||||
string height = ((ResolutionAttribute)Attribute.GetCustomAttribute(
|
|
||||||
value.GetType().GetFields(BindingFlags.Public | BindingFlags.Static)
|
|
||||||
.Single(x => x.GetValue(null).Equals(value)),
|
|
||||||
typeof(ResolutionAttribute)))?.height.ToString() ?? value.ToString();
|
|
||||||
|
|
||||||
return new Point(int.Parse(width), int.Parse(height));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsNullableEnum(this Type t)
|
|
||||||
{
|
|
||||||
Type u = Nullable.GetUnderlyingType(t);
|
|
||||||
return u != null && u.IsEnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compression
|
// compression
|
||||||
public static byte[] Compress(byte[] data)
|
public static byte[] Compress(byte[] data)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using IGDB.Models;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
|
|
||||||
@@ -114,12 +115,7 @@ namespace gaseous_server.Classes
|
|||||||
if (File.Exists(ConfigurationFilePath))
|
if (File.Exists(ConfigurationFilePath))
|
||||||
{
|
{
|
||||||
string configRaw = File.ReadAllText(ConfigurationFilePath);
|
string configRaw = File.ReadAllText(ConfigurationFilePath);
|
||||||
Newtonsoft.Json.JsonSerializerSettings serializerSettings = new Newtonsoft.Json.JsonSerializerSettings
|
ConfigFile? _tempConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigFile>(configRaw);
|
||||||
{
|
|
||||||
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
|
|
||||||
MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore
|
|
||||||
};
|
|
||||||
ConfigFile? _tempConfig = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigFile>(configRaw, serializerSettings);
|
|
||||||
if (_tempConfig != null)
|
if (_tempConfig != null)
|
||||||
{
|
{
|
||||||
_config = _tempConfig;
|
_config = _tempConfig;
|
||||||
@@ -135,9 +131,9 @@ namespace gaseous_server.Classes
|
|||||||
_config.DatabaseConfiguration.Password = (string)Common.GetEnvVar("dbpass", _config.DatabaseConfiguration.Password);
|
_config.DatabaseConfiguration.Password = (string)Common.GetEnvVar("dbpass", _config.DatabaseConfiguration.Password);
|
||||||
_config.DatabaseConfiguration.DatabaseName = (string)Common.GetEnvVar("dbname", _config.DatabaseConfiguration.DatabaseName);
|
_config.DatabaseConfiguration.DatabaseName = (string)Common.GetEnvVar("dbname", _config.DatabaseConfiguration.DatabaseName);
|
||||||
_config.DatabaseConfiguration.Port = int.Parse((string)Common.GetEnvVar("dbport", _config.DatabaseConfiguration.Port.ToString()));
|
_config.DatabaseConfiguration.Port = int.Parse((string)Common.GetEnvVar("dbport", _config.DatabaseConfiguration.Port.ToString()));
|
||||||
_config.MetadataConfiguration.DefaultMetadataSource = (HasheousClient.Models.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataSources), (string)Common.GetEnvVar("metadatasource", _config.MetadataConfiguration.DefaultMetadataSource.ToString()));
|
_config.MetadataConfiguration.MetadataSource = (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), (string)Common.GetEnvVar("metadatasource", _config.MetadataConfiguration.MetadataSource.ToString()));
|
||||||
_config.IGDBConfiguration.UseHasheousProxy = bool.Parse((string)Common.GetEnvVar("metadatausehasheousproxy", _config.IGDBConfiguration.UseHasheousProxy.ToString()));
|
|
||||||
_config.MetadataConfiguration.SignatureSource = (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), (string)Common.GetEnvVar("signaturesource", _config.MetadataConfiguration.SignatureSource.ToString())); ;
|
_config.MetadataConfiguration.SignatureSource = (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), (string)Common.GetEnvVar("signaturesource", _config.MetadataConfiguration.SignatureSource.ToString())); ;
|
||||||
|
_config.MetadataConfiguration.MaxLibraryScanWorkers = int.Parse((string)Common.GetEnvVar("maxlibraryscanworkers", _config.MetadataConfiguration.MaxLibraryScanWorkers.ToString()));
|
||||||
_config.MetadataConfiguration.HasheousHost = (string)Common.GetEnvVar("hasheoushost", _config.MetadataConfiguration.HasheousHost);
|
_config.MetadataConfiguration.HasheousHost = (string)Common.GetEnvVar("hasheoushost", _config.MetadataConfiguration.HasheousHost);
|
||||||
_config.IGDBConfiguration.ClientId = (string)Common.GetEnvVar("igdbclientid", _config.IGDBConfiguration.ClientId);
|
_config.IGDBConfiguration.ClientId = (string)Common.GetEnvVar("igdbclientid", _config.IGDBConfiguration.ClientId);
|
||||||
_config.IGDBConfiguration.Secret = (string)Common.GetEnvVar("igdbclientsecret", _config.IGDBConfiguration.Secret);
|
_config.IGDBConfiguration.Secret = (string)Common.GetEnvVar("igdbclientsecret", _config.IGDBConfiguration.Secret);
|
||||||
@@ -627,34 +623,27 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibraryMetadataDirectory_Platform(HasheousClient.Models.Metadata.IGDB.Platform platform)
|
public string LibraryMetadataDirectory_Platform(Platform platform)
|
||||||
{
|
{
|
||||||
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Platforms", platform.Slug);
|
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Platforms", platform.Slug);
|
||||||
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
||||||
return MetadataPath;
|
return MetadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibraryMetadataDirectory_Game(gaseous_server.Models.Game game)
|
public string LibraryMetadataDirectory_Game(Game game)
|
||||||
{
|
{
|
||||||
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Games", game.Slug);
|
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Games", game.Slug);
|
||||||
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
||||||
return MetadataPath;
|
return MetadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibraryMetadataDirectory_Company(HasheousClient.Models.Metadata.IGDB.Company company)
|
public string LibraryMetadataDirectory_Company(Company company)
|
||||||
{
|
{
|
||||||
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Companies", company.Slug);
|
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Companies", company.Slug);
|
||||||
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
||||||
return MetadataPath;
|
return MetadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibraryMetadataDirectory_Hasheous()
|
|
||||||
{
|
|
||||||
string MetadataPath = Path.Combine(LibraryMetadataDirectory, "Hasheous");
|
|
||||||
if (!Directory.Exists(MetadataPath)) { Directory.CreateDirectory(MetadataPath); }
|
|
||||||
return MetadataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LibrarySignaturesDirectory
|
public string LibrarySignaturesDirectory
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -675,6 +664,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
||||||
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
|
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
|
||||||
|
// if (!Directory.Exists(LibraryBIOSDirectory)) { Directory.CreateDirectory(LibraryBIOSDirectory); }
|
||||||
if (!Directory.Exists(LibraryFirmwareDirectory)) { Directory.CreateDirectory(LibraryFirmwareDirectory); }
|
if (!Directory.Exists(LibraryFirmwareDirectory)) { Directory.CreateDirectory(LibraryFirmwareDirectory); }
|
||||||
if (!Directory.Exists(LibraryUploadDirectory)) { Directory.CreateDirectory(LibraryUploadDirectory); }
|
if (!Directory.Exists(LibraryUploadDirectory)) { Directory.CreateDirectory(LibraryUploadDirectory); }
|
||||||
if (!Directory.Exists(LibraryMetadataDirectory)) { Directory.CreateDirectory(LibraryMetadataDirectory); }
|
if (!Directory.Exists(LibraryMetadataDirectory)) { Directory.CreateDirectory(LibraryMetadataDirectory); }
|
||||||
@@ -687,40 +677,17 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public class MetadataAPI
|
public class MetadataAPI
|
||||||
{
|
{
|
||||||
public static string _HasheousClientAPIKey
|
private static HasheousClient.Models.MetadataModel.MetadataSources _MetadataSource
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return "Pna5SRcbJ6R8aasytab_6vZD0aBKDGNZKRz4WY4xArpfZ-3mdZq0hXIGyy0AD43b";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static HasheousClient.Models.MetadataSources _MetadataSource
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatasource")))
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatasource")))
|
||||||
{
|
{
|
||||||
return (HasheousClient.Models.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataSources), Environment.GetEnvironmentVariable("metadatasource"));
|
return (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), Environment.GetEnvironmentVariable("metadatasource"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return HasheousClient.Models.MetadataSources.IGDB;
|
return HasheousClient.Models.MetadataModel.MetadataSources.IGDB;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool _MetadataUseHasheousProxy
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatausehasheousproxy")))
|
|
||||||
{
|
|
||||||
return bool.Parse(Environment.GetEnvironmentVariable("metadatausehasheousproxy"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -744,6 +711,21 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
private static string _HasheousAPIKey { get; set; } = "";
|
private static string _HasheousAPIKey { get; set; } = "";
|
||||||
|
|
||||||
|
private static int _MaxLibraryScanWorkers
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("maxlibraryscanworkers")))
|
||||||
|
{
|
||||||
|
return int.Parse(Environment.GetEnvironmentVariable("maxlibraryscanworkers"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string _HasheousHost
|
private static string _HasheousHost
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -759,7 +741,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HasheousClient.Models.MetadataSources DefaultMetadataSource = _MetadataSource;
|
public HasheousClient.Models.MetadataModel.MetadataSources MetadataSource = _MetadataSource;
|
||||||
|
|
||||||
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
||||||
|
|
||||||
@@ -767,8 +749,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public string HasheousAPIKey = _HasheousAPIKey;
|
public string HasheousAPIKey = _HasheousAPIKey;
|
||||||
|
|
||||||
[JsonIgnore]
|
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
||||||
public string HasheousClientAPIKey = _HasheousClientAPIKey;
|
|
||||||
|
|
||||||
public string HasheousHost = _HasheousHost;
|
public string HasheousHost = _HasheousHost;
|
||||||
}
|
}
|
||||||
@@ -805,24 +786,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool _MetadataUseHasheousProxy
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("igdbusehasheousproxy")))
|
|
||||||
{
|
|
||||||
return bool.Parse(Environment.GetEnvironmentVariable("igdbusehasheousproxy"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ClientId = _DefaultIGDBClientId;
|
public string ClientId = _DefaultIGDBClientId;
|
||||||
public string Secret = _DefaultIGDBSecret;
|
public string Secret = _DefaultIGDBSecret;
|
||||||
public bool UseHasheousProxy = _MetadataUseHasheousProxy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Logging
|
public class Logging
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Data;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -196,11 +197,7 @@ namespace gaseous_server.Classes
|
|||||||
libraryRootPath += Path.DirectorySeparatorChar;
|
libraryRootPath += Path.DirectorySeparatorChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetLastThreeElements = false;
|
bool GetLastThreeElements = (bool)row["DefaultLibrary"];
|
||||||
if ((int)row["DefaultLibrary"] == 1)
|
|
||||||
{
|
|
||||||
GetLastThreeElements = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (DataRow romRow in romData.Rows)
|
foreach (DataRow romRow in romData.Rows)
|
||||||
{
|
{
|
||||||
@@ -246,19 +243,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all tables that have the prefix "Relation_" and drop them
|
|
||||||
sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = @dbname AND table_name LIKE 'Relation_%';";
|
|
||||||
dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "dbname", Config.DatabaseConfiguration.DatabaseName }
|
|
||||||
};
|
|
||||||
data = db.ExecuteCMD(sql, dbDict);
|
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
{
|
|
||||||
sql = "DROP TABLE " + (string)row["table_name"] + ";";
|
|
||||||
db.ExecuteNonQuery(sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
// migrating metadata is a safe background task
|
// migrating metadata is a safe background task
|
||||||
BackgroundUpgradeTargetSchemaVersions.Add(1024);
|
BackgroundUpgradeTargetSchemaVersions.Add(1024);
|
||||||
break;
|
break;
|
||||||
@@ -406,9 +390,10 @@ namespace gaseous_server.Classes
|
|||||||
(string)row["Path"]
|
(string)row["Path"]
|
||||||
);
|
);
|
||||||
|
|
||||||
HasheousClient.Models.Metadata.IGDB.Platform platform = Platforms.GetPlatform((long)row["PlatformId"]);
|
Platform platform = Platforms.GetPlatform((long)row["PlatformId"], false);
|
||||||
|
Game game = Games.GetGame((long)row["GameId"], false, false, false);
|
||||||
|
|
||||||
ImportGame.StoreGame(library, hash, signature, platform, (string)row["Path"], (long)row["Id"]);
|
ImportGame.StoreROM(library, hash, game, platform, signature, (string)row["Path"], (long)row["Id"]);
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Configuration;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using HasheousClient.Models;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
using SevenZip;
|
using SevenZip;
|
||||||
@@ -187,22 +185,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get discovered platform
|
|
||||||
Platform? determinedPlatform = null;
|
|
||||||
if (library.DefaultPlatformId == null || library.DefaultPlatformId == 0)
|
|
||||||
{
|
|
||||||
determinedPlatform = Metadata.Platforms.GetPlatform((long)discoveredSignature.Flags.PlatformId);
|
|
||||||
if (determinedPlatform == null)
|
|
||||||
{
|
|
||||||
determinedPlatform = new Platform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
determinedPlatform = Metadata.Platforms.GetPlatform((long)library.DefaultPlatformId);
|
|
||||||
discoveredSignature.MetadataSources.AddPlatform((long)determinedPlatform.Id, determinedPlatform.Name, HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
return discoveredSignature;
|
return discoveredSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +237,7 @@ namespace gaseous_server.Classes
|
|||||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, ImageExtension, false);
|
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, ImageExtension, false);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System);
|
Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System);
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " Platform determined to be: " + discoveredSignature.Flags.PlatformName + " (" + discoveredSignature.Flags.PlatformId + ")");
|
Logging.Log(Logging.LogType.Information, "Import Game", " Platform determined to be: " + discoveredSignature.Flags.IGDBPlatformName + " (" + discoveredSignature.Flags.IGDBPlatformId + ")");
|
||||||
|
|
||||||
return discoveredSignature;
|
return discoveredSignature;
|
||||||
}
|
}
|
||||||
@@ -309,58 +291,14 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
||||||
Console.WriteLine(HasheousClient.WebApp.HttpHelper.BaseUri);
|
Console.WriteLine(HasheousClient.WebApp.HttpHelper.BaseUri);
|
||||||
HasheousClient.Models.LookupItemModel? HasheousResult = null;
|
LookupItemModel? HasheousResult = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// check the cache first
|
HasheousResult = hasheous.RetrieveFromHasheous(new HashLookupModel
|
||||||
if (!Directory.Exists(Config.LibraryConfiguration.LibraryMetadataDirectory_Hasheous()))
|
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Config.LibraryConfiguration.LibraryMetadataDirectory_Hasheous());
|
MD5 = hash.md5hash,
|
||||||
}
|
SHA1 = hash.sha1hash
|
||||||
// create file name from hash object
|
});
|
||||||
string cacheFileName = hash.md5hash + "_" + hash.sha1hash + ".json";
|
|
||||||
string cacheFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Hasheous(), cacheFileName);
|
|
||||||
// use cache file if it exists and is less than 30 days old, otherwise fetch from hasheous. if the fetch from hasheous is successful, save it to the cache, if it fails, use the cache if it exists even if it's old
|
|
||||||
if (File.Exists(cacheFilePath))
|
|
||||||
{
|
|
||||||
FileInfo cacheFile = new FileInfo(cacheFilePath);
|
|
||||||
if (cacheFile.LastWriteTimeUtc > DateTime.UtcNow.AddDays(-30))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Get Signature", "Using cached signature from Hasheous");
|
|
||||||
HasheousResult = Newtonsoft.Json.JsonConvert.DeserializeObject<HasheousClient.Models.LookupItemModel>(File.ReadAllText(cacheFilePath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (HasheousResult == null)
|
|
||||||
{
|
|
||||||
// fetch from hasheous
|
|
||||||
HasheousResult = hasheous.RetrieveFromHasheous(new HasheousClient.Models.HashLookupModel
|
|
||||||
{
|
|
||||||
MD5 = hash.md5hash,
|
|
||||||
SHA1 = hash.sha1hash
|
|
||||||
});
|
|
||||||
|
|
||||||
if (HasheousResult != null)
|
|
||||||
{
|
|
||||||
// save to cache
|
|
||||||
File.WriteAllText(cacheFilePath, Newtonsoft.Json.JsonConvert.SerializeObject(HasheousResult));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (File.Exists(cacheFilePath))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous - using cached signature", ex);
|
|
||||||
HasheousResult = Newtonsoft.Json.JsonConvert.DeserializeObject<HasheousClient.Models.LookupItemModel>(File.ReadAllText(cacheFilePath));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HasheousResult != null)
|
if (HasheousResult != null)
|
||||||
{
|
{
|
||||||
@@ -379,25 +317,13 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Platform.metadata)
|
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Platform.metadata)
|
||||||
{
|
{
|
||||||
// only IGDB metadata is supported
|
if (metadataResult.Id.Length > 0)
|
||||||
if (metadataResult.Source == HasheousClient.Models.MetadataSources.IGDB)
|
|
||||||
{
|
{
|
||||||
if (metadataResult.ImmutableId.Length > 0)
|
switch (metadataResult.Source)
|
||||||
{
|
{
|
||||||
// use immutable id
|
case HasheousClient.Models.MetadataSources.IGDB:
|
||||||
Platform hasheousPlatform = Platforms.GetPlatform(long.Parse(metadataResult.ImmutableId));
|
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id, false).Id;
|
||||||
signature.MetadataSources.AddPlatform((long)hasheousPlatform.Id, hasheousPlatform.Name, metadataResult.Source);
|
break;
|
||||||
}
|
|
||||||
else if (metadataResult.Id.Length > 0)
|
|
||||||
{
|
|
||||||
// fall back to id
|
|
||||||
Platform hasheousPlatform = Platforms.GetPlatform(metadataResult.Id);
|
|
||||||
signature.MetadataSources.AddPlatform((long)hasheousPlatform.Id, hasheousPlatform.Name, metadataResult.Source);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no id or immutable id - use unknown platform
|
|
||||||
signature.MetadataSources.AddPlatform(0, "Unknown Platform", HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,51 +337,15 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Metadata)
|
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Metadata)
|
||||||
{
|
{
|
||||||
if (metadataResult.ImmutableId.Length > 0)
|
if (metadataResult.Id.Length > 0)
|
||||||
{
|
|
||||||
signature.MetadataSources.AddGame(long.Parse(metadataResult.ImmutableId), HasheousResult.Name, metadataResult.Source);
|
|
||||||
}
|
|
||||||
else if (metadataResult.Id.Length > 0)
|
|
||||||
{
|
{
|
||||||
switch (metadataResult.Source)
|
switch (metadataResult.Source)
|
||||||
{
|
{
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
case HasheousClient.Models.MetadataSources.IGDB:
|
||||||
gaseous_server.Models.Game hasheousGame = Games.GetGame(HasheousClient.Models.MetadataSources.IGDB, metadataResult.Id);
|
signature.Flags.IGDBGameId = (long)Games.GetGame(metadataResult.Id, false, false, false).Id;
|
||||||
signature.MetadataSources.AddGame((long)hasheousGame.Id, hasheousGame.Name, metadataResult.Source);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (long.TryParse(metadataResult.Id, out long id) == true)
|
|
||||||
{
|
|
||||||
signature.MetadataSources.AddGame(id, HasheousResult.Name, metadataResult.Source);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
signature.MetadataSources.AddGame(0, "Unknown Game", HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// no id or immutable id - use unknown game
|
|
||||||
signature.MetadataSources.AddGame(0, "Unknown Game", HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check attributes for a user manual link
|
|
||||||
if (HasheousResult.Attributes != null)
|
|
||||||
{
|
|
||||||
if (HasheousResult.Attributes.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (HasheousClient.Models.AttributeItem attribute in HasheousResult.Attributes)
|
|
||||||
{
|
|
||||||
if (attribute.attributeName == HasheousClient.Models.AttributeItem.AttributeName.VIMMManualId)
|
|
||||||
{
|
|
||||||
signature.Game.UserManual = attribute.GetType().GetProperty("Link").GetValue(attribute).ToString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,20 +368,18 @@ namespace gaseous_server.Classes
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace gaseous_server.Classes
|
|||||||
ageRestriction_Generic += " OR view_Games.AgeGroupId IS NULL";
|
ageRestriction_Generic += " OR view_Games.AgeGroupId IS NULL";
|
||||||
}
|
}
|
||||||
|
|
||||||
string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, view_Games_Roms.PlatformId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id , view_Games_Roms.PlatformId HAVING RomCount > 0) Game JOIN Platform ON Game.PlatformId = Platform.Id AND Platform.SourceId = 0 GROUP BY Platform.`Name`;";
|
string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, view_Games_Roms.PlatformId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id , view_Games_Roms.PlatformId HAVING RomCount > 0) Game JOIN Platform ON Game.PlatformId = Platform.Id GROUP BY Platform.`Name`;";
|
||||||
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300));
|
DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300));
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
//string sql = "SELECT DISTINCT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(view_Games.Id) AS GameCount FROM <ITEMNAME> LEFT JOIN Relation_Game_<ITEMNAME>s ON Relation_Game_<ITEMNAME>s.<ITEMNAME>sId = <ITEMNAME>.Id LEFT JOIN view_Games ON view_Games.Id = Relation_Game_<ITEMNAME>s.GameId WHERE (" + AgeRestriction_Generic + ") GROUP BY <ITEMNAME>.Id HAVING GameCount > 0 ORDER BY <ITEMNAME>.`Name`;";
|
//string sql = "SELECT DISTINCT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(view_Games.Id) AS GameCount FROM <ITEMNAME> LEFT JOIN Relation_Game_<ITEMNAME>s ON Relation_Game_<ITEMNAME>s.<ITEMNAME>sId = <ITEMNAME>.Id LEFT JOIN view_Games ON view_Games.Id = Relation_Game_<ITEMNAME>s.GameId WHERE (" + AgeRestriction_Generic + ") GROUP BY <ITEMNAME>.Id HAVING GameCount > 0 ORDER BY <ITEMNAME>.`Name`;";
|
||||||
|
|
||||||
string sql = "SELECT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT view_Games_Roms.GameIdType, Game.Id, AgeGroup.AgeGroupId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + AgeRestriction + ") GROUP BY Game.Id HAVING RomCount > 0) Game JOIN Relation_Game_<ITEMNAME>s ON Game.Id = Relation_Game_<ITEMNAME>s.GameId AND Game.GameIdType = Relation_Game_<ITEMNAME>s.GameSourceId JOIN <ITEMNAME> ON Relation_Game_<ITEMNAME>s.<ITEMNAME>sId = <ITEMNAME>.Id GROUP BY <ITEMNAME>.`Name` ORDER BY <ITEMNAME>.`Name`;";
|
string sql = "SELECT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(view_Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId WHERE (" + AgeRestriction + ") GROUP BY Game.Id HAVING RomCount > 0) Game JOIN Relation_Game_<ITEMNAME>s ON Game.Id = Relation_Game_<ITEMNAME>s.GameId JOIN <ITEMNAME> ON Relation_Game_<ITEMNAME>s.<ITEMNAME>sId = <ITEMNAME>.Id GROUP BY <ITEMNAME>.`Name` ORDER BY <ITEMNAME>.`Name`;";
|
||||||
sql = sql.Replace("<ITEMNAME>", Name);
|
sql = sql.Replace("<ITEMNAME>", Name);
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300));
|
DataTable dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300));
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow;
|
using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow;
|
||||||
|
|
||||||
namespace gaseous_server
|
namespace gaseous_server
|
||||||
@@ -236,7 +237,7 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
if (_DefaultPlatformId != 0)
|
if (_DefaultPlatformId != 0)
|
||||||
{
|
{
|
||||||
HasheousClient.Models.Metadata.IGDB.Platform platform = Platforms.GetPlatform(_DefaultPlatformId);
|
Platform platform = Platforms.GetPlatform(_DefaultPlatformId);
|
||||||
return platform.Name;
|
return platform.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -7,26 +7,17 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
|
using IGDB.Models;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
using NuGet.LibraryModel;
|
using NuGet.LibraryModel;
|
||||||
using static gaseous_server.Classes.Metadata.Games;
|
using static gaseous_server.Classes.Metadata.Games;
|
||||||
using static gaseous_server.Classes.FileSignature;
|
using static gaseous_server.Classes.FileSignature;
|
||||||
using HasheousClient.Models;
|
using HasheousClient.Models;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class ImportGame : QueueItemStatus
|
public class ImportGame : QueueItemStatus
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Scan the import directory for games and process them
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ImportPath">
|
|
||||||
/// The path to the directory to scan
|
|
||||||
/// </param>
|
|
||||||
/// <exception cref="DirectoryNotFoundException">
|
|
||||||
/// Thrown when the import directory does not exist
|
|
||||||
/// </exception>
|
|
||||||
public void ProcessDirectory(string ImportPath)
|
public void ProcessDirectory(string ImportPath)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(ImportPath))
|
if (Directory.Exists(ImportPath))
|
||||||
@@ -56,29 +47,22 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
||||||
/// Import a single game file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="GameFileImportPath">
|
|
||||||
/// The path to the game file to import
|
|
||||||
/// </param>
|
|
||||||
/// <param name="OverridePlatform">
|
|
||||||
/// The platform to use for the game file
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// A dictionary containing the results of the import
|
|
||||||
/// </returns>
|
|
||||||
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, Platform? OverridePlatform)
|
|
||||||
{
|
{
|
||||||
Dictionary<string, object> RetVal = new Dictionary<string, object>();
|
Dictionary<string, object> RetVal = new Dictionary<string, object>();
|
||||||
RetVal.Add("path", Path.GetFileName(GameFileImportPath));
|
RetVal.Add("path", Path.GetFileName(GameFileImportPath));
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
FileInfo fi = new FileInfo(GameFileImportPath);
|
||||||
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
||||||
|
|
||||||
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
|
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
|
||||||
@@ -86,251 +70,124 @@ namespace gaseous_server.Classes
|
|||||||
if (IsBios == null)
|
if (IsBios == null)
|
||||||
{
|
{
|
||||||
// file is a rom
|
// file is a rom
|
||||||
_ImportGameFile(GameFileImportPath, hash, ref RetVal, OverridePlatform);
|
RetVal.Add("type", "rom");
|
||||||
|
|
||||||
|
// check to make sure we don't already have this file imported
|
||||||
|
sql = "SELECT COUNT(Id) AS count FROM view_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)
|
||||||
|
{
|
||||||
|
// import source was the import directory
|
||||||
|
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
||||||
|
|
||||||
|
string targetPathWithFileName = GameFileImportPath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
||||||
|
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
|
||||||
|
|
||||||
|
if (!Directory.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(targetPath);
|
||||||
|
}
|
||||||
|
File.Move(GameFileImportPath, targetPathWithFileName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// import source was the upload directory
|
||||||
|
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping import");
|
||||||
|
}
|
||||||
|
|
||||||
|
RetVal.Add("status", "duplicate");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
|
||||||
|
|
||||||
|
FileSignature fileSignature = new FileSignature();
|
||||||
|
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, hash, fi, GameFileImportPath);
|
||||||
|
|
||||||
|
// get discovered platform
|
||||||
|
IGDB.Models.Platform? determinedPlatform = null;
|
||||||
|
if (OverridePlatform == null)
|
||||||
|
{
|
||||||
|
determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
|
||||||
|
if (determinedPlatform == null)
|
||||||
|
{
|
||||||
|
determinedPlatform = new IGDB.Models.Platform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
determinedPlatform = OverridePlatform;
|
||||||
|
discoveredSignature.Flags.IGDBPlatformId = (long)determinedPlatform.Id;
|
||||||
|
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
|
||||||
|
|
||||||
|
// add to database
|
||||||
|
long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath, 0, true);
|
||||||
|
|
||||||
|
// build return value
|
||||||
|
RetVal.Add("romid", RomId);
|
||||||
|
RetVal.Add("platform", determinedPlatform);
|
||||||
|
RetVal.Add("game", determinedGame);
|
||||||
|
RetVal.Add("signature", discoveredSignature);
|
||||||
|
RetVal.Add("status", "imported");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// file is a bios
|
// file is a bios
|
||||||
Bios.ImportBiosFile(GameFileImportPath, hash, ref RetVal);
|
RetVal.Add("type", "bios");
|
||||||
|
RetVal.Add("status", "notimported");
|
||||||
|
|
||||||
|
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
||||||
|
{
|
||||||
|
if (biosItem.Available == false)
|
||||||
|
{
|
||||||
|
if (biosItem.hash == hash.md5hash)
|
||||||
|
{
|
||||||
|
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " is a BIOS file - moving to " + biosPath);
|
||||||
|
|
||||||
|
File.Move(GameFileImportPath, biosItem.biosPath, true);
|
||||||
|
|
||||||
|
RetVal.Add("name", biosItem.filename);
|
||||||
|
RetVal.Add("platform", Platforms.GetPlatform(biosItem.platformid, false, false));
|
||||||
|
RetVal["status"] = "imported";
|
||||||
|
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (biosItem.hash == hash.md5hash)
|
||||||
|
{
|
||||||
|
RetVal["status"] = "duplicate";
|
||||||
|
return RetVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RetVal;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
||||||
/// Import a single game file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FilePath">
|
|
||||||
/// The path to the game file to import
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Hash">
|
|
||||||
/// The hash of the game file
|
|
||||||
/// </param>
|
|
||||||
/// <param name="GameFileInfo">
|
|
||||||
/// A dictionary to store the results of the import
|
|
||||||
/// </param>
|
|
||||||
/// <param name="OverridePlatform">
|
|
||||||
/// The platform to use for the game file
|
|
||||||
/// </param>
|
|
||||||
private static void _ImportGameFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> GameFileInfo, Platform? OverridePlatform)
|
|
||||||
{
|
|
||||||
GameFileInfo.Add("type", "rom");
|
|
||||||
|
|
||||||
// check to make sure we don't already have this file imported
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
sql = "SELECT COUNT(Id) AS count FROM view_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)
|
|
||||||
{
|
|
||||||
// import source was the import directory
|
|
||||||
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
|
||||||
|
|
||||||
string targetPathWithFileName = FilePath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
|
||||||
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
|
|
||||||
|
|
||||||
if (!Directory.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(targetPath);
|
|
||||||
}
|
|
||||||
File.Move(FilePath, targetPathWithFileName, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// import source was the upload directory
|
|
||||||
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - skipping import");
|
|
||||||
}
|
|
||||||
|
|
||||||
GameFileInfo.Add("status", "duplicate");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + FilePath + " not in database - processing");
|
|
||||||
|
|
||||||
FileInfo fi = new FileInfo(FilePath);
|
|
||||||
FileSignature fileSignature = new FileSignature();
|
|
||||||
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, Hash, fi, FilePath);
|
|
||||||
|
|
||||||
// add to database
|
|
||||||
Platform? determinedPlatform = Metadata.Platforms.GetPlatform((long)discoveredSignature.Flags.PlatformId);
|
|
||||||
Models.Game? determinedGame = Metadata.Games.GetGame(discoveredSignature.Flags.GameMetadataSource, discoveredSignature.Flags.GameId);
|
|
||||||
long RomId = StoreGame(GameLibrary.GetDefaultLibrary, Hash, discoveredSignature, determinedPlatform, FilePath, 0, true);
|
|
||||||
Roms.GameRomItem romItem = Roms.GetRom(RomId);
|
|
||||||
|
|
||||||
// build return value
|
|
||||||
GameFileInfo.Add("romid", RomId);
|
|
||||||
GameFileInfo.Add("platform", determinedPlatform);
|
|
||||||
GameFileInfo.Add("game", determinedGame);
|
|
||||||
GameFileInfo.Add("signature", discoveredSignature);
|
|
||||||
GameFileInfo.Add("rom", romItem);
|
|
||||||
GameFileInfo.Add("status", "imported");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Store a game in the database and move the file to the library (if required)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="library">
|
|
||||||
/// The library to store the game in
|
|
||||||
/// </param>
|
|
||||||
/// <param name="hash">
|
|
||||||
/// The hash of the game file
|
|
||||||
/// </param>
|
|
||||||
/// <param name="signature">
|
|
||||||
/// The signature of the game file
|
|
||||||
/// </param>
|
|
||||||
/// <param name="filePath">
|
|
||||||
/// The path to the game file
|
|
||||||
/// </param>
|
|
||||||
/// <param name="romId">
|
|
||||||
/// The ID of the ROM in the database (if it already exists, 0 if it doesn't)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="SourceIsExternal">
|
|
||||||
/// Whether the source of the file is external to the library
|
|
||||||
/// </param>
|
|
||||||
public static long StoreGame(GameLibrary.LibraryItem library, Common.hashObject hash, Signatures_Games signature, Platform platform, string filePath, long romId = 0, bool SourceIsExternal = false)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
|
|
||||||
string sql = "";
|
|
||||||
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
// add/get the metadata map
|
|
||||||
MetadataMap? map = MetadataManagement.NewMetadataMap((long)platform.Id, signature.Game.Name);
|
|
||||||
|
|
||||||
// add any metadata attributes that may be supplied as part of the signature
|
|
||||||
if (signature.Game.UserManual != null)
|
|
||||||
{
|
|
||||||
if (signature.Game.UserManual.Length > 0)
|
|
||||||
{
|
|
||||||
MetadataManagement.SetMetadataSupportData((long)map.Id, MetadataManagement.MetadataMapSupportDataTypes.UserManualLink, signature.Game.UserManual);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate map with the sources from the signature if they don't already exist
|
|
||||||
foreach (MetadataSources source in Enum.GetValues(typeof(MetadataSources)))
|
|
||||||
{
|
|
||||||
bool sourceExists = false;
|
|
||||||
|
|
||||||
if (source != MetadataSources.None)
|
|
||||||
{
|
|
||||||
// get the signature that matches this source
|
|
||||||
Signatures_Games.SourceValues.SourceValueItem? signatureSource = signature.MetadataSources.Games.Find(x => x.Source == source);
|
|
||||||
if (signatureSource == null)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " No source found for " + source.ToString());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the metadata map for this source
|
|
||||||
MetadataMap.MetadataMapItem? mapSource = map.MetadataMapItems.Find(x => x.SourceType == source);
|
|
||||||
if (mapSource == null)
|
|
||||||
{
|
|
||||||
// add the source to the map
|
|
||||||
bool preferred = false;
|
|
||||||
if (source == Config.MetadataConfiguration.DefaultMetadataSource)
|
|
||||||
{
|
|
||||||
preferred = true;
|
|
||||||
}
|
|
||||||
MetadataManagement.AddMetadataMapItem((long)map.Id, source, signatureSource.Id, preferred);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// update the source in the map - do not modify the preferred status
|
|
||||||
MetadataManagement.UpdateMetadataMapItem((long)map.Id, source, signatureSource.Id, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reload the map
|
|
||||||
map = MetadataManagement.GetMetadataMap((long)map.Id);
|
|
||||||
|
|
||||||
// add or update the rom
|
|
||||||
dbDict = new Dictionary<string, object>();
|
|
||||||
if (romId == 0)
|
|
||||||
{
|
|
||||||
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, RelativePath, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion, MetadataMapId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion, @metadatamapid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion, MetadataMapId=@metadatamapid WHERE Id=@id;";
|
|
||||||
dbDict.Add("id", romId);
|
|
||||||
}
|
|
||||||
dbDict.Add("platformid", Common.ReturnValueIfNull(platform.Id, 0));
|
|
||||||
dbDict.Add("gameid", 0); // set to 0 - no longer required as game is mapped using the MetadataMapBridge table
|
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(signature.Rom.Name, 0));
|
|
||||||
dbDict.Add("size", Common.ReturnValueIfNull(signature.Rom.Size, 0));
|
|
||||||
dbDict.Add("md5", hash.md5hash);
|
|
||||||
dbDict.Add("sha1", hash.sha1hash);
|
|
||||||
dbDict.Add("crc", Common.ReturnValueIfNull(signature.Rom.Crc, ""));
|
|
||||||
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(signature.Rom.DevelopmentStatus, ""));
|
|
||||||
dbDict.Add("metadatasource", signature.Rom.SignatureSource);
|
|
||||||
dbDict.Add("metadatagamename", signature.Game.Name);
|
|
||||||
dbDict.Add("metadataversion", 2);
|
|
||||||
dbDict.Add("libraryid", library.Id);
|
|
||||||
dbDict.Add("romdataversion", 2);
|
|
||||||
dbDict.Add("metadatamapid", map.Id);
|
|
||||||
|
|
||||||
if (signature.Rom.Attributes != null)
|
|
||||||
{
|
|
||||||
if (signature.Rom.Attributes.Count > 0)
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(signature.Rom.Attributes));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", "[ ]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", "[ ]");
|
|
||||||
}
|
|
||||||
dbDict.Add("romtype", (int)signature.Rom.RomType);
|
|
||||||
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(signature.Rom.RomTypeMedia, ""));
|
|
||||||
dbDict.Add("medialabel", Common.ReturnValueIfNull(signature.Rom.MediaLabel, ""));
|
|
||||||
|
|
||||||
string libraryRootPath = library.Path;
|
|
||||||
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
|
|
||||||
{
|
|
||||||
libraryRootPath += Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
dbDict.Add("path", filePath.Replace(libraryRootPath, ""));
|
|
||||||
|
|
||||||
DataTable romInsert = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (romId == 0)
|
|
||||||
{
|
|
||||||
romId = (long)romInsert.Rows[0][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// move to destination
|
|
||||||
if (library.IsDefaultLibrary == true)
|
|
||||||
{
|
|
||||||
MoveGameFile(romId, SourceIsExternal);
|
|
||||||
}
|
|
||||||
|
|
||||||
return romId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static gaseous_server.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
|
||||||
{
|
{
|
||||||
if (Signature.Flags != null)
|
if (Signature.Flags != null)
|
||||||
{
|
{
|
||||||
if (Signature.Flags.GameId != null && Signature.Flags.GameId != 0)
|
if (Signature.Flags.IGDBGameId != null && Signature.Flags.IGDBGameId != 0)
|
||||||
{
|
{
|
||||||
// game was determined elsewhere - probably a Hasheous server
|
// game was determined elsewhere - probably a Hasheous server
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Games.GetGame(MetadataSources.IGDB, Signature.Flags.GameId);
|
return Games.GetGame(Signature.Flags.IGDBGameId, false, false, FullDownload);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -340,7 +197,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// search discovered game - case insensitive exact match first
|
// search discovered game - case insensitive exact match first
|
||||||
gaseous_server.Models.Game determinedGame = new gaseous_server.Models.Game();
|
IGDB.Models.Game determinedGame = new IGDB.Models.Game();
|
||||||
|
|
||||||
string GameName = Signature.Game.Name;
|
string GameName = Signature.Game.Name;
|
||||||
|
|
||||||
@@ -355,37 +212,30 @@ namespace gaseous_server.Classes
|
|||||||
foreach (Metadata.Games.SearchType searchType in Enum.GetValues(typeof(Metadata.Games.SearchType)))
|
foreach (Metadata.Games.SearchType searchType in Enum.GetValues(typeof(Metadata.Games.SearchType)))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString());
|
Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString());
|
||||||
gaseous_server.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
||||||
if (games != null)
|
if (games.Length == 1)
|
||||||
{
|
{
|
||||||
if (games.Length == 1)
|
// exact match!
|
||||||
{
|
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
||||||
// exact match!
|
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
|
||||||
determinedGame = Metadata.Games.GetGame(MetadataSources.IGDB, (long)games[0].Id);
|
GameFound = true;
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
|
break;
|
||||||
GameFound = true;
|
}
|
||||||
break;
|
else if (games.Length > 0)
|
||||||
}
|
{
|
||||||
else if (games.Length > 0)
|
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
|
|
||||||
|
|
||||||
// quite likely we've found sequels and alternate types
|
// quite likely we've found sequels and alternate types
|
||||||
foreach (gaseous_server.Models.Game game in games)
|
foreach (Game game in games)
|
||||||
{
|
|
||||||
if (game.Name == SearchCandidate)
|
|
||||||
{
|
|
||||||
// found game title matches the search candidate
|
|
||||||
determinedGame = Metadata.Games.GetGame(MetadataSources.IGDB, (long)games[0].Id);
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
|
|
||||||
GameFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " No search results found");
|
if (game.Name == SearchCandidate)
|
||||||
|
{
|
||||||
|
// found game title matches the search candidate
|
||||||
|
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
|
||||||
|
GameFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -397,7 +247,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
if (determinedGame == null)
|
if (determinedGame == null)
|
||||||
{
|
{
|
||||||
determinedGame = new gaseous_server.Models.Game();
|
determinedGame = new IGDB.Models.Game();
|
||||||
}
|
}
|
||||||
|
|
||||||
string destSlug = "";
|
string destSlug = "";
|
||||||
@@ -409,9 +259,9 @@ namespace gaseous_server.Classes
|
|||||||
return determinedGame;
|
return determinedGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<gaseous_server.Models.Game> SearchForGame_GetAll(string GameName, long PlatformId)
|
public static List<IGDB.Models.Game> SearchForGame_GetAll(string GameName, long PlatformId)
|
||||||
{
|
{
|
||||||
List<gaseous_server.Models.Game> searchResults = new List<gaseous_server.Models.Game>();
|
List<IGDB.Models.Game> searchResults = new List<IGDB.Models.Game>();
|
||||||
|
|
||||||
List<string> SearchCandidates = GetSearchCandidates(GameName);
|
List<string> SearchCandidates = GetSearchCandidates(GameName);
|
||||||
|
|
||||||
@@ -421,11 +271,11 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
if ((PlatformId == 0 && searchType == SearchType.searchNoPlatform) || (PlatformId != 0 && searchType != SearchType.searchNoPlatform))
|
if ((PlatformId == 0 && searchType == SearchType.searchNoPlatform) || (PlatformId != 0 && searchType != SearchType.searchNoPlatform))
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
||||||
foreach (gaseous_server.Models.Game foundGame in games)
|
foreach (IGDB.Models.Game foundGame in games)
|
||||||
{
|
{
|
||||||
bool gameInResults = false;
|
bool gameInResults = false;
|
||||||
foreach (gaseous_server.Models.Game searchResult in searchResults)
|
foreach (IGDB.Models.Game searchResult in searchResults)
|
||||||
{
|
{
|
||||||
if (searchResult.Id == foundGame.Id)
|
if (searchResult.Id == foundGame.Id)
|
||||||
{
|
{
|
||||||
@@ -476,14 +326,90 @@ namespace gaseous_server.Classes
|
|||||||
return SearchCandidates;
|
return SearchCandidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long StoreROM(GameLibrary.LibraryItem library, Common.hashObject hash, IGDB.Models.Game determinedGame, IGDB.Models.Platform determinedPlatform, gaseous_server.Models.Signatures_Games discoveredSignature, string GameFileImportPath, long UpdateId = 0, bool SourceIsExternal = false)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
if (UpdateId == 0)
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, RelativePath, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion WHERE Id=@id;";
|
||||||
|
dbDict.Add("id", UpdateId);
|
||||||
|
}
|
||||||
|
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
||||||
|
dbDict.Add("gameid", Common.ReturnValueIfNull(determinedGame.Id, 0));
|
||||||
|
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);
|
||||||
|
dbDict.Add("crc", Common.ReturnValueIfNull(discoveredSignature.Rom.Crc, ""));
|
||||||
|
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(discoveredSignature.Rom.DevelopmentStatus, ""));
|
||||||
|
dbDict.Add("metadatasource", discoveredSignature.Rom.SignatureSource);
|
||||||
|
dbDict.Add("metadatagamename", discoveredSignature.Game.Name);
|
||||||
|
dbDict.Add("metadataversion", 2);
|
||||||
|
dbDict.Add("libraryid", library.Id);
|
||||||
|
dbDict.Add("romdataversion", 2);
|
||||||
|
|
||||||
|
if (discoveredSignature.Rom.Attributes != null)
|
||||||
|
{
|
||||||
|
if (discoveredSignature.Rom.Attributes.Count > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(discoveredSignature.Rom.Attributes));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
dbDict.Add("romtype", (int)discoveredSignature.Rom.RomType);
|
||||||
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(discoveredSignature.Rom.RomTypeMedia, ""));
|
||||||
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(discoveredSignature.Rom.MediaLabel, ""));
|
||||||
|
|
||||||
|
string libraryRootPath = library.Path;
|
||||||
|
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
|
||||||
|
{
|
||||||
|
libraryRootPath += Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
dbDict.Add("path", GameFileImportPath.Replace(libraryRootPath, ""));
|
||||||
|
|
||||||
|
DataTable romInsert = db.ExecuteCMD(sql, dbDict);
|
||||||
|
long romId = 0;
|
||||||
|
if (UpdateId == 0)
|
||||||
|
{
|
||||||
|
romId = (long)romInsert.Rows[0][0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
romId = UpdateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to destination
|
||||||
|
if (library.IsDefaultLibrary == true)
|
||||||
|
{
|
||||||
|
MoveGameFile(romId, SourceIsExternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return romId;
|
||||||
|
}
|
||||||
|
|
||||||
public static string ComputeROMPath(long RomId)
|
public static string ComputeROMPath(long RomId)
|
||||||
{
|
{
|
||||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||||
|
|
||||||
// get metadata
|
// get metadata
|
||||||
MetadataMap.MetadataMapItem metadataMap = Classes.MetadataManagement.GetMetadataMap(rom.MetadataMapId).PreferredMetadataMapItem;
|
IGDB.Models.Platform platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId);
|
||||||
Platform? platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId);
|
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false, false);
|
||||||
gaseous_server.Models.Game? game = Classes.Metadata.Games.GetGame(metadataMap.SourceType, metadataMap.SourceId);
|
|
||||||
|
|
||||||
// build path
|
// build path
|
||||||
string platformSlug = "Unknown Platform";
|
string platformSlug = "Unknown Platform";
|
||||||
@@ -496,7 +422,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
gameSlug = game.Slug;
|
gameSlug = game.Slug;
|
||||||
}
|
}
|
||||||
string DestinationPath = Path.Combine(GameLibrary.GetDefaultLibrary.Path, platformSlug);
|
string DestinationPath = Path.Combine(GameLibrary.GetDefaultLibrary.Path, gameSlug, platformSlug);
|
||||||
if (!Directory.Exists(DestinationPath))
|
if (!Directory.Exists(DestinationPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(DestinationPath);
|
Directory.CreateDirectory(DestinationPath);
|
||||||
@@ -613,7 +539,7 @@ namespace gaseous_server.Classes
|
|||||||
public static List<GameLibrary.LibraryItem> LibrariesToScan = new List<GameLibrary.LibraryItem>();
|
public static List<GameLibrary.LibraryItem> LibrariesToScan = new List<GameLibrary.LibraryItem>();
|
||||||
public void LibraryScan()
|
public void LibraryScan()
|
||||||
{
|
{
|
||||||
int maxWorkers = 4;
|
int maxWorkers = Config.MetadataConfiguration.MaxLibraryScanWorkers;
|
||||||
|
|
||||||
if (LibrariesToScan.Count == 0)
|
if (LibrariesToScan.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -651,7 +577,8 @@ namespace gaseous_server.Classes
|
|||||||
1,
|
1,
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
true)
|
true)
|
||||||
@@ -794,9 +721,9 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
// get discovered platform
|
// get discovered platform
|
||||||
long PlatformId;
|
long PlatformId;
|
||||||
Platform determinedPlatform;
|
IGDB.Models.Platform determinedPlatform;
|
||||||
|
|
||||||
if (sig.Flags.PlatformId == null || sig.Flags.PlatformId == 0)
|
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0)
|
||||||
{
|
{
|
||||||
// no platform discovered in the signature
|
// no platform discovered in the signature
|
||||||
PlatformId = library.DefaultPlatformId;
|
PlatformId = library.DefaultPlatformId;
|
||||||
@@ -804,13 +731,13 @@ namespace gaseous_server.Classes
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// use the platform discovered in the signature
|
// use the platform discovered in the signature
|
||||||
PlatformId = (long)sig.Flags.PlatformId;
|
PlatformId = sig.Flags.IGDBPlatformId;
|
||||||
}
|
}
|
||||||
determinedPlatform = Platforms.GetPlatform(PlatformId);
|
determinedPlatform = Platforms.GetPlatform(PlatformId);
|
||||||
|
|
||||||
gaseous_server.Models.Game determinedGame = SearchForGame(sig, PlatformId, true);
|
IGDB.Models.Game determinedGame = SearchForGame(sig, PlatformId, true);
|
||||||
|
|
||||||
StoreGame(library, hash, sig, determinedPlatform, LibraryFile, 0, false);
|
StoreROM(library, hash, determinedGame, determinedPlatform, sig, LibraryFile);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -872,6 +799,86 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan completed");
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan completed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Rematcher(bool ForceExecute = false)
|
||||||
|
{
|
||||||
|
// rescan all titles with an unknown platform or title and see if we can get a match
|
||||||
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan starting");
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch on library " + library.Name);
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
if (ForceExecute == false)
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM view_Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) AND LibraryId = @libraryid LIMIT 100;";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM view_Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND LibraryId = @libraryid;";
|
||||||
|
}
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
||||||
|
dbDict.Add("libraryid", library.Id);
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
int StatusCount = -0;
|
||||||
|
foreach (DataRow row in data.Rows)
|
||||||
|
{
|
||||||
|
SetStatus(StatusCount, data.Rows.Count, "Running rematcher");
|
||||||
|
|
||||||
|
// get rom info
|
||||||
|
long romId = (long)row["Id"];
|
||||||
|
string romPath = (string)row["Path"];
|
||||||
|
Common.hashObject hash = new Common.hashObject
|
||||||
|
{
|
||||||
|
md5hash = (string)row["MD5"],
|
||||||
|
sha1hash = (string)row["SHA1"]
|
||||||
|
};
|
||||||
|
FileInfo fi = new FileInfo(romPath);
|
||||||
|
|
||||||
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Running rematch against " + romPath);
|
||||||
|
|
||||||
|
// determine rom signature
|
||||||
|
FileSignature fileSignature = new FileSignature();
|
||||||
|
gaseous_server.Models.Signatures_Games sig = fileSignature.GetFileSignature(library, hash, fi, romPath);
|
||||||
|
|
||||||
|
// get discovered platform
|
||||||
|
long PlatformId;
|
||||||
|
IGDB.Models.Platform determinedPlatform;
|
||||||
|
|
||||||
|
if (sig.Flags.IGDBPlatformId == null || sig.Flags.IGDBPlatformId == 0)
|
||||||
|
{
|
||||||
|
// no platform discovered in the signature
|
||||||
|
PlatformId = library.DefaultPlatformId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use the platform discovered in the signature
|
||||||
|
PlatformId = sig.Flags.IGDBPlatformId;
|
||||||
|
}
|
||||||
|
determinedPlatform = Platforms.GetPlatform(PlatformId);
|
||||||
|
|
||||||
|
IGDB.Models.Game determinedGame = SearchForGame(sig, PlatformId, true);
|
||||||
|
|
||||||
|
StoreROM(library, hash, determinedGame, determinedPlatform, sig, romPath, romId);
|
||||||
|
|
||||||
|
string attemptSql = "UPDATE Games_Roms SET LastMatchAttemptDate=@lastmatchattemptdate WHERE Id=@id;";
|
||||||
|
Dictionary<string, object> dbLastAttemptDict = new Dictionary<string, object>();
|
||||||
|
dbLastAttemptDict.Add("id", romId);
|
||||||
|
dbLastAttemptDict.Add("lastmatchattemptdate", DateTime.UtcNow);
|
||||||
|
db.ExecuteCMD(attemptSql, dbLastAttemptDict);
|
||||||
|
|
||||||
|
StatusCount += 1;
|
||||||
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan completed");
|
||||||
|
ClearStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using gaseous_server.Models;
|
using IGDB;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB.Models;
|
||||||
using Microsoft.CodeAnalysis.Classification;
|
using Microsoft.CodeAnalysis.Classification;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
@@ -14,7 +14,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AgeGroup? GetAgeGroup(Models.Game? game)
|
public static AgeGroup? GetAgeGroup(Game? game)
|
||||||
{
|
{
|
||||||
if (game == null)
|
if (game == null)
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
cacheStatus = Storage.GetCacheStatus(HasheousClient.Models.MetadataSources.IGDB, "AgeGroup", (long)game.Id);
|
cacheStatus = Storage.GetCacheStatus("AgeGroup", (long)game.Id);
|
||||||
|
|
||||||
AgeGroup? RetVal = new AgeGroup();
|
AgeGroup? RetVal = new AgeGroup();
|
||||||
|
|
||||||
@@ -31,16 +31,16 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
case Storage.CacheStatus.NotPresent:
|
case Storage.CacheStatus.NotPresent:
|
||||||
RetVal = _GetAgeGroup(game);
|
RetVal = _GetAgeGroup(game);
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.IGDB, RetVal, false);
|
Storage.NewCacheValue(RetVal, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Storage.CacheStatus.Expired:
|
case Storage.CacheStatus.Expired:
|
||||||
RetVal = _GetAgeGroup(game);
|
RetVal = _GetAgeGroup(game);
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.IGDB, RetVal, true);
|
Storage.NewCacheValue(RetVal, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Storage.CacheStatus.Current:
|
case Storage.CacheStatus.Current:
|
||||||
RetVal = Storage.GetCacheValue<AgeGroup>(HasheousClient.Models.MetadataSources.IGDB, RetVal, "Id", game.Id);
|
RetVal = Storage.GetCacheValue<AgeGroup>(RetVal, "Id", game.Id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -51,20 +51,20 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AgeGroup? _GetAgeGroup(Models.Game game)
|
public static AgeGroup? _GetAgeGroup(Game game)
|
||||||
{
|
{
|
||||||
// compile the maximum age group for the given game
|
// compile the maximum age group for the given game
|
||||||
if (game != null)
|
if (game != null)
|
||||||
{
|
{
|
||||||
if (game.AgeRatings != null)
|
if (game.AgeRatings != null)
|
||||||
{
|
{
|
||||||
if (game.AgeRatings != null)
|
if (game.AgeRatings.Ids != null)
|
||||||
{
|
{
|
||||||
// collect ratings values from metadata
|
// collect ratings values from metadata
|
||||||
List<AgeRating> ageRatings = new List<AgeRating>();
|
List<AgeRating> ageRatings = new List<AgeRating>();
|
||||||
foreach (long ratingId in game.AgeRatings)
|
foreach (long ratingId in game.AgeRatings.Ids)
|
||||||
{
|
{
|
||||||
AgeRating? rating = AgeRatings.GetAgeRating(game.MetadataSource, ratingId);
|
AgeRating? rating = AgeRatings.GetAgeRatings(ratingId);
|
||||||
if (rating != null)
|
if (rating != null)
|
||||||
{
|
{
|
||||||
ageRatings.Add(rating);
|
ageRatings.Add(rating);
|
||||||
@@ -262,13 +262,13 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
public class AgeGroupItem
|
public class AgeGroupItem
|
||||||
{
|
{
|
||||||
public List<AgeRatingTitle> ACB { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> ACB { get; set; }
|
||||||
public List<AgeRatingTitle> CERO { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> CERO { get; set; }
|
||||||
public List<AgeRatingTitle> CLASS_IND { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> CLASS_IND { get; set; }
|
||||||
public List<AgeRatingTitle> ESRB { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> ESRB { get; set; }
|
||||||
public List<AgeRatingTitle> GRAC { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> GRAC { get; set; }
|
||||||
public List<AgeRatingTitle> PEGI { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> PEGI { get; set; }
|
||||||
public List<AgeRatingTitle> USK { get; set; }
|
public List<IGDB.Models.AgeRatingTitle> USK { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
[Newtonsoft.Json.JsonIgnore]
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.CodeAnalysis.Classification;
|
using Microsoft.CodeAnalysis.Classification;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class AgeRatings
|
public class AgeRatings
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields category,checksum,content_descriptions,rating,rating_cover_url,synopsis;";
|
const string fieldList = "fields category,checksum,content_descriptions,rating,rating_cover_url,synopsis;";
|
||||||
|
|
||||||
public AgeRatings()
|
public AgeRatings()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AgeRating? GetAgeRating(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static AgeRating? GetAgeRatings(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -23,16 +23,106 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AgeRating? RetVal = Metadata.GetMetadata<AgeRating>(SourceType, (long)Id, false);
|
Task<AgeRating> RetVal = _GetAgeRatings(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameAgeRating GetConsolidatedAgeRating(HasheousClient.Models.MetadataSources SourceType, long RatingId)
|
public static AgeRating GetAgeRatings(string Slug)
|
||||||
|
{
|
||||||
|
Task<AgeRating> RetVal = _GetAgeRatings(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AgeRating> _GetAgeRatings(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AgeRating", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AgeRating", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
AgeRating returnValue = new AgeRating();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
UpdateSubClasses(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<AgeRating>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<AgeRating>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(AgeRating ageRating)
|
||||||
|
{
|
||||||
|
if (ageRating.ContentDescriptions != null)
|
||||||
|
{
|
||||||
|
foreach (long AgeRatingContentDescriptionId in ageRating.ContentDescriptions.Ids)
|
||||||
|
{
|
||||||
|
AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(AgeRatingContentDescriptionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AgeRating> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get AgeRatings metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AgeRating>(IGDBClient.Endpoints.AgeRating, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameAgeRating GetConsolidatedAgeRating(long RatingId)
|
||||||
{
|
{
|
||||||
GameAgeRating gameAgeRating = new GameAgeRating();
|
GameAgeRating gameAgeRating = new GameAgeRating();
|
||||||
|
|
||||||
AgeRating ageRating = GetAgeRating(SourceType, RatingId);
|
AgeRating ageRating = GetAgeRatings(RatingId);
|
||||||
gameAgeRating.Id = (long)ageRating.Id;
|
gameAgeRating.Id = (long)ageRating.Id;
|
||||||
gameAgeRating.RatingBoard = (AgeRatingCategory)ageRating.Category;
|
gameAgeRating.RatingBoard = (AgeRatingCategory)ageRating.Category;
|
||||||
gameAgeRating.RatingTitle = (AgeRatingTitle)ageRating.Rating;
|
gameAgeRating.RatingTitle = (AgeRatingTitle)ageRating.Rating;
|
||||||
@@ -40,9 +130,9 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
List<string> descriptions = new List<string>();
|
List<string> descriptions = new List<string>();
|
||||||
if (ageRating.ContentDescriptions != null)
|
if (ageRating.ContentDescriptions != null)
|
||||||
{
|
{
|
||||||
foreach (long ContentId in ageRating.ContentDescriptions)
|
foreach (long ContentId in ageRating.ContentDescriptions.Ids)
|
||||||
{
|
{
|
||||||
AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(SourceType, ContentId);
|
AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(ContentId);
|
||||||
descriptions.Add(ageRatingContentDescription.Description);
|
descriptions.Add(ageRatingContentDescription.Description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,7 +157,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
db.ExecuteNonQuery(sql);
|
db.ExecuteNonQuery(sql);
|
||||||
|
|
||||||
// loop all age groups
|
// loop all age groups
|
||||||
foreach (KeyValuePair<AgeGroups.AgeRestrictionGroupings, AgeGroups.AgeGroupItem> ageGrouping in AgeGroups.AgeGroupingsFlat)
|
foreach(KeyValuePair<AgeGroups.AgeRestrictionGroupings, AgeGroups.AgeGroupItem> ageGrouping in AgeGroups.AgeGroupingsFlat)
|
||||||
{
|
{
|
||||||
AgeGroups.AgeGroupItem ageGroupItem = ageGrouping.Value;
|
AgeGroups.AgeGroupItem ageGroupItem = ageGrouping.Value;
|
||||||
var properties = ageGroupItem.GetType().GetProperties();
|
var properties = ageGroupItem.GetType().GetProperties();
|
||||||
@@ -96,6 +186,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class AgeRatingContentDescriptions
|
public class AgeRatingContentDescriptions
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields category,checksum,description;";
|
const string fieldList = "fields category,checksum,description;";
|
||||||
|
|
||||||
public AgeRatingContentDescriptions()
|
public AgeRatingContentDescriptions()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AgeRatingContentDescription? RetVal = Metadata.GetMetadata<AgeRatingContentDescription>(SourceType, (long)Id, false);
|
Task<AgeRatingContentDescription> RetVal = _GetAgeRatingContentDescriptions(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static AgeRatingContentDescription GetAgeRatingContentDescriptions(string Slug)
|
||||||
|
{
|
||||||
|
Task<AgeRatingContentDescription> RetVal = _GetAgeRatingContentDescriptions(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AgeRatingContentDescription> _GetAgeRatingContentDescriptions(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
AgeRatingContentDescription returnValue = new AgeRatingContentDescription();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<AgeRatingContentDescription>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<AgeRatingContentDescription>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AgeRatingContentDescription> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get AgeRatingContentDescriptionContentDescriptions metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AgeRatingContentDescription>(IGDBClient.Endpoints.AgeRatingContentDescriptions, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class AlternativeNames
|
public class AlternativeNames
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,comment,game,name;";
|
const string fieldList = "fields checksum,comment,game,name;";
|
||||||
|
|
||||||
public AlternativeNames()
|
public AlternativeNames()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlternativeName? GetAlternativeNames(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static AlternativeName? GetAlternativeNames(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AlternativeName? RetVal = Metadata.GetMetadata<AlternativeName>(SourceType, (long)Id, false);
|
Task<AlternativeName> RetVal = _GetAlternativeNames(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static AlternativeName GetAlternativeNames(string Slug)
|
||||||
|
{
|
||||||
|
Task<AlternativeName> RetVal = _GetAlternativeNames(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AlternativeName> _GetAlternativeNames(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AlternativeName", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("AlternativeName", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
AlternativeName returnValue = new AlternativeName();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<AlternativeName>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<AlternativeName>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<AlternativeName> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get AlternativeNames metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AlternativeName>(IGDBClient.Endpoints.AlternativeNames, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Artworks
|
public class Artworks
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields alpha_channel,animated,checksum,game,height,image_id,url,width;";
|
const string fieldList = "fields alpha_channel,animated,checksum,game,height,image_id,url,width;";
|
||||||
|
|
||||||
public Artworks()
|
public Artworks()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Artwork? GetArtwork(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Artwork? GetArtwork(long? Id, string ImagePath, bool GetImages)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +21,111 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Artwork? RetVal = Metadata.GetMetadata<Artwork>(SourceType, (long)Id, false);
|
Task<Artwork> RetVal = _GetArtwork(SearchUsing.id, Id, ImagePath, GetImages);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Artwork GetArtwork(string Slug, string ImagePath, bool GetImages)
|
||||||
|
{
|
||||||
|
Task<Artwork> RetVal = _GetArtwork(SearchUsing.slug, Slug, ImagePath, GetImages);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Artwork> _GetArtwork(SearchUsing searchUsing, object searchValue, string ImagePath, bool GetImages = true)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Artwork", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Artwork", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Artwork returnValue = new Artwork();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
ImagePath = Path.Combine(ImagePath, "Artwork");
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
|
||||||
|
// check if old value is different from the new value - only download if it's different
|
||||||
|
Artwork oldImage = Storage.GetCacheValue<Artwork>(returnValue, "id", (long)searchValue);
|
||||||
|
if (oldImage.ImageId != returnValue.ImageId)
|
||||||
|
{
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Artwork>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Artwork>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for presence of "original" quality file - download if absent or force download is true
|
||||||
|
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if (GetImages == true)
|
||||||
|
{
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Artwork download forced.");
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Artwork> GetObjectFromServer(string WhereClause, string ImagePath)
|
||||||
|
{
|
||||||
|
// get Artwork metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Artwork>(IGDBClient.Endpoints.Artworks, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Collections
|
public class Collections
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields as_child_relations,as_parent_relations,checksum,created_at,games,name,slug,type,updated_at,url;";
|
const string fieldList = "fields as_child_relations,as_parent_relations,checksum,created_at,games,name,slug,type,updated_at,url;";
|
||||||
|
|
||||||
public Collections()
|
public Collections()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Collection? GetCollections(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Collection? GetCollections(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Collection? RetVal = Metadata.GetMetadata<Collection>(SourceType, (long)Id, false);
|
Task<Collection> RetVal = _GetCollections(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static Collection GetCollections(string Slug)
|
||||||
|
{
|
||||||
|
Task<Collection> RetVal = _GetCollections(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Collection> _GetCollections(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Collection", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Collection", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection returnValue = new Collection();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Collection>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Collection>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Collection> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Collections metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Collection>(IGDBClient.Endpoints.Collections, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Companies
|
public class Companies
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields change_date,change_date_category,changed_company_id,checksum,country,created_at,description,developed,logo,name,parent,published,slug,start_date,start_date_category,updated_at,url,websites;";
|
const string fieldList = "fields change_date,change_date_category,changed_company_id,checksum,country,created_at,description,developed,logo,name,parent,published,slug,start_date,start_date_category,updated_at,url,websites;";
|
||||||
|
|
||||||
public Companies()
|
public Companies()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Company? GetCompanies(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Company? GetCompanies(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +20,105 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Company? RetVal = Metadata.GetMetadata<Company>(SourceType, (long)Id, false);
|
Task<Company> RetVal = _GetCompanies(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Company GetCompanies(string Slug)
|
||||||
|
{
|
||||||
|
Task<Company> RetVal = _GetCompanies(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Company> _GetCompanies(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Company", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Company", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Company returnValue = new Company();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
if (returnValue != null) { Storage.NewCacheValue(returnValue); }
|
||||||
|
UpdateSubClasses(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Company>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Company>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(Company company)
|
||||||
|
{
|
||||||
|
if (company.Logo != null)
|
||||||
|
{
|
||||||
|
CompanyLogo companyLogo = CompanyLogos.GetCompanyLogo(company.Logo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Company(company));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Company> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Companies metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Company>(IGDBClient.Endpoints.Companies, fieldList, WhereClause);
|
||||||
|
if (results.Length > 0)
|
||||||
|
{
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class CompanyLogos
|
public class CompanyLogos
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields alpha_channel,animated,checksum,height,image_id,url,width;";
|
const string fieldList = "fields alpha_channel,animated,checksum,height,image_id,url,width;";
|
||||||
|
|
||||||
public CompanyLogos()
|
public CompanyLogos()
|
||||||
{
|
{
|
||||||
@@ -19,10 +21,110 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CompanyLogo? RetVal = Metadata.GetMetadata<CompanyLogo>((long)Id, false);
|
Task<CompanyLogo> RetVal = _GetCompanyLogo(SearchUsing.id, Id, ImagePath);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CompanyLogo GetCompanyLogo(string Slug, string ImagePath)
|
||||||
|
{
|
||||||
|
Task<CompanyLogo> RetVal = _GetCompanyLogo(SearchUsing.slug, Slug, ImagePath);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<CompanyLogo> _GetCompanyLogo(SearchUsing searchUsing, object searchValue, string ImagePath)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("CompanyLogo", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("CompanyLogo", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
CompanyLogo returnValue = new CompanyLogo();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
if (returnValue != null)
|
||||||
|
{
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
|
||||||
|
// check if old value is different from the new value - only download if it's different
|
||||||
|
CompanyLogo oldImage = Storage.GetCacheValue<CompanyLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
if (oldImage.ImageId != returnValue.ImageId)
|
||||||
|
{
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<CompanyLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<CompanyLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for presence of "original" quality file - download if absent or force download is true
|
||||||
|
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Company logo download forced.");
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<CompanyLogo> GetObjectFromServer(string WhereClause, string ImagePath)
|
||||||
|
{
|
||||||
|
// get Artwork metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<CompanyLogo>(IGDBClient.Endpoints.CompanyLogos, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using System.Net;
|
||||||
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
using Microsoft.CodeAnalysis.Elfie.Model.Strings;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Covers
|
public class Covers
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields alpha_channel,animated,checksum,game,game_localization,height,image_id,url,width;";
|
const string fieldList = "fields alpha_channel,animated,checksum,game,game_localization,height,image_id,url,width;";
|
||||||
|
|
||||||
public Covers()
|
public Covers()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Cover? GetCover(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Cover? GetCover(long? Id, string ImagePath, bool GetImages)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +23,124 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Cover? RetVal = Metadata.GetMetadata<Cover>(SourceType, (long)Id, false);
|
Task<Cover> RetVal = _GetCover(SearchUsing.id, Id, ImagePath, GetImages);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Cover GetCover(string Slug, string ImagePath, bool GetImages)
|
||||||
|
{
|
||||||
|
Task<Cover> RetVal = _GetCover(SearchUsing.slug, Slug, ImagePath, GetImages);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Cover> _GetCover(SearchUsing searchUsing, object searchValue, string ImagePath, bool GetImages = true)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Cover", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Cover", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Cover returnValue = new Cover();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
ImagePath = Path.Combine(ImagePath, "Covers");
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
|
||||||
|
// check if old value is different from the new value - only download if it's different
|
||||||
|
Cover oldCover = Storage.GetCacheValue<Cover>(returnValue, "id", (long)searchValue);
|
||||||
|
if (oldCover.ImageId != returnValue.ImageId)
|
||||||
|
{
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Cover>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Cover>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if (GetImages == true)
|
||||||
|
{
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Cover download forced.");
|
||||||
|
|
||||||
|
// check for presence of image file - download if absent or force download is true
|
||||||
|
List<Communications.IGDBAPI_ImageSize> imageSizes = new List<Communications.IGDBAPI_ImageSize>{
|
||||||
|
Communications.IGDBAPI_ImageSize.cover_big,
|
||||||
|
Communications.IGDBAPI_ImageSize.cover_small,
|
||||||
|
Communications.IGDBAPI_ImageSize.original
|
||||||
|
};
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
foreach (Communications.IGDBAPI_ImageSize size in imageSizes)
|
||||||
|
{
|
||||||
|
localFile = Path.Combine(ImagePath, size.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, size, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Cover> GetObjectFromServer(string WhereClause, string ImagePath)
|
||||||
|
{
|
||||||
|
// get Cover metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Cover>(IGDBClient.Endpoints.Covers, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class ExternalGames
|
public class ExternalGames
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields category,checksum,countries,created_at,game,media,name,platform,uid,updated_at,url,year;";
|
const string fieldList = "fields category,checksum,countries,created_at,game,media,name,platform,uid,updated_at,url,year;";
|
||||||
|
|
||||||
public ExternalGames()
|
public ExternalGames()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ExternalGame? GetExternalGames(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static ExternalGame? GetExternalGames(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +21,98 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExternalGame? RetVal = Metadata.GetMetadata<ExternalGame>(SourceType, (long)Id, false);
|
Task<ExternalGame> RetVal = _GetExternalGames(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static ExternalGame GetExternalGames(string Slug)
|
||||||
|
{
|
||||||
|
Task<ExternalGame> RetVal = _GetExternalGames(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<ExternalGame> _GetExternalGames(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ExternalGame", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ExternalGame", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
ExternalGame returnValue = new ExternalGame();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
if (returnValue != null)
|
||||||
|
{
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<ExternalGame>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<ExternalGame>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<ExternalGame?> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get ExternalGames metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<ExternalGame>(IGDBClient.Endpoints.ExternalGames, fieldList, WhereClause);
|
||||||
|
if (results.Length > 0)
|
||||||
|
{
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Franchises
|
public class Franchises
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;";
|
const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;";
|
||||||
|
|
||||||
public Franchises()
|
public Franchises()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Franchise? GetFranchises(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Franchise? GetFranchises(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -19,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Franchise? RetVal = Metadata.GetMetadata<Franchise>(SourceType, (long)Id, false);
|
Task<Franchise> RetVal = _GetFranchises(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static Franchise GetFranchises(string Slug)
|
||||||
|
{
|
||||||
|
Task<Franchise> RetVal = _GetFranchises(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Franchise> _GetFranchises(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Franchise", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Franchise", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Franchise returnValue = new Franchise();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Franchise>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Franchise>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Franchise> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get FranchiseContentDescriptions metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Franchise>(IGDBClient.Endpoints.Franchies, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class GameModes
|
public class GameModes
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
||||||
|
|
||||||
public GameModes()
|
public GameModes()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameMode? GetGame_Modes(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static GameMode? GetGame_Modes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameMode? RetVal = Metadata.GetMetadata<GameMode>(SourceType, (long)Id, false);
|
Task<GameMode> RetVal = _GetGame_Modes(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GameMode GetGame_Modes(string Slug)
|
||||||
|
{
|
||||||
|
Task<GameMode> RetVal = _GetGame_Modes(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<GameMode> _GetGame_Modes(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("GameMode", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("GameMode", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMode returnValue = new GameMode();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<GameMode>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<GameMode>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<GameMode> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game_Modes metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<GameMode>(IGDBClient.Endpoints.GameModes, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class GamesVideos
|
public class GamesVideos
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,game,name,video_id;";
|
const string fieldList = "fields checksum,game,name,video_id;";
|
||||||
|
|
||||||
public GamesVideos()
|
public GamesVideos()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameVideo? GetGame_Videos(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static GameVideo? GetGame_Videos(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GameVideo? RetVal = Metadata.GetMetadata<GameVideo>(SourceType, (long)Id, false);
|
Task<GameVideo> RetVal = _GetGame_Videos(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static GameVideo GetGame_Videos(string Slug)
|
||||||
|
{
|
||||||
|
Task<GameVideo> RetVal = _GetGame_Videos(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<GameVideo> _GetGame_Videos(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("GameVideo", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("GameVideo", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
GameVideo returnValue = new GameVideo();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<GameVideo>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<GameVideo>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<GameVideo> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game_Videos metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<GameVideo>(IGDBClient.Endpoints.GameVideos, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Games
|
public class Games
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
||||||
|
|
||||||
public Games()
|
public Games()
|
||||||
{
|
{
|
||||||
@@ -20,32 +21,39 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Game? GetGame(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if (Id == 0)
|
||||||
{
|
{
|
||||||
return null;
|
Game returnValue = new Game();
|
||||||
|
if (Storage.GetCacheStatus("Game", 0) == Storage.CacheStatus.NotPresent)
|
||||||
|
{
|
||||||
|
returnValue = new Game
|
||||||
|
{
|
||||||
|
Id = 0,
|
||||||
|
Name = "Unknown Title",
|
||||||
|
Slug = "Unknown"
|
||||||
|
};
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Storage.GetCacheValue<Game>(returnValue, "id", 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Game? RetVal = Metadata.GetMetadata<Game>(SourceType, (long)Id, false);
|
Task<Game> RetVal = _GetGame(SearchUsing.id, Id, getAllMetadata, followSubGames, forceRefresh);
|
||||||
RetVal.MetadataSource = SourceType;
|
return RetVal.Result;
|
||||||
long? metadataMap = MetadataManagement.GetMetadataMapIdFromSourceId(SourceType, (long)Id);
|
|
||||||
if (metadataMap != null)
|
|
||||||
{
|
|
||||||
RetVal.MetadataMapId = (long)metadataMap;
|
|
||||||
}
|
|
||||||
RetVal = MassageResult(RetVal);
|
|
||||||
return RetVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Game? GetGame(HasheousClient.Models.MetadataSources SourceType, string? Slug)
|
public static Game GetGame(string Slug, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||||
{
|
{
|
||||||
Game? RetVal = Metadata.GetMetadata<Game>(SourceType, Slug, false);
|
Task<Game> RetVal = _GetGame(SearchUsing.slug, Slug, getAllMetadata, followSubGames, forceRefresh);
|
||||||
RetVal.MetadataSource = SourceType;
|
return RetVal.Result;
|
||||||
RetVal = MassageResult(RetVal);
|
|
||||||
return RetVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Game GetGame(DataRow dataRow)
|
public static Game GetGame(DataRow dataRow)
|
||||||
@@ -53,43 +61,327 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
return Storage.BuildCacheObject<Game>(new Game(), dataRow);
|
return Storage.BuildCacheObject<Game>(new Game(), dataRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Game MassageResult(Game result)
|
private static async Task<Game> _GetGame(SearchUsing searchUsing, object searchValue, bool getAllMetadata = true, bool followSubGames = false, bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
Game? parentGame = null;
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Game", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Game", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceRefresh == true)
|
||||||
|
{
|
||||||
|
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
||||||
|
}
|
||||||
|
|
||||||
|
string WhereClause = "";
|
||||||
|
string searchField = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
searchField = "id";
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||||
|
searchField = "slug";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Game returnValue = new Game();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
UpdateSubClasses(returnValue, getAllMetadata, followSubGames, forceRefresh);
|
||||||
|
return returnValue;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
UpdateSubClasses(returnValue, getAllMetadata, followSubGames, forceRefresh);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||||
|
UpdateSubClasses(returnValue, false, false, false);
|
||||||
|
return returnValue;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(Game Game, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||||
|
{
|
||||||
|
// required metadata
|
||||||
|
// if (Game.Cover != null)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// Logging.Log(Logging.LogType.Critical, "Game Metadata", "Unable to fetch cover artwork.", ex);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (Game.Genres != null)
|
||||||
|
{
|
||||||
|
foreach (long GenreId in Game.Genres.Ids)
|
||||||
|
{
|
||||||
|
Genre GameGenre = Genres.GetGenres(GenreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.GameModes != null)
|
||||||
|
{
|
||||||
|
foreach (long gameModeId in Game.GameModes.Ids)
|
||||||
|
{
|
||||||
|
GameMode gameMode = GameModes.GetGame_Modes(gameModeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.MultiplayerModes != null)
|
||||||
|
{
|
||||||
|
foreach (long multiplayerModeId in Game.MultiplayerModes.Ids)
|
||||||
|
{
|
||||||
|
MultiplayerMode multiplayerMode = MultiplayerModes.GetGame_MultiplayerModes(multiplayerModeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.PlayerPerspectives != null)
|
||||||
|
{
|
||||||
|
foreach (long PerspectiveId in Game.PlayerPerspectives.Ids)
|
||||||
|
{
|
||||||
|
PlayerPerspective GamePlayPerspective = PlayerPerspectives.GetGame_PlayerPerspectives(PerspectiveId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.Themes != null)
|
||||||
|
{
|
||||||
|
foreach (long ThemeId in Game.Themes.Ids)
|
||||||
|
{
|
||||||
|
Theme GameTheme = Themes.GetGame_Themes(ThemeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.AgeRatings != null)
|
||||||
|
{
|
||||||
|
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
||||||
|
{
|
||||||
|
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AgeGroups.GetAgeGroup(Game);
|
||||||
|
|
||||||
|
if (Game.ReleaseDates != null)
|
||||||
|
{
|
||||||
|
foreach (long ReleaseDateId in Game.ReleaseDates.Ids)
|
||||||
|
{
|
||||||
|
ReleaseDate GameReleaseDate = ReleaseDates.GetReleaseDates(ReleaseDateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// optional metadata - usually downloaded as needed
|
||||||
|
if (getAllMetadata == true)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Artwork GameArtwork = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Game Metadata", "Unable to fetch artwork id: " + ArtworkId, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.Collection != null)
|
||||||
|
{
|
||||||
|
Collection GameCollection = Collections.GetCollections(Game.Collection.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.ExternalGames != null)
|
||||||
|
{
|
||||||
|
foreach (long ExternalGameId in Game.ExternalGames.Ids)
|
||||||
|
{
|
||||||
|
ExternalGame GameExternalGame = ExternalGames.GetExternalGames(ExternalGameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.Franchise != null)
|
||||||
|
{
|
||||||
|
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.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)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Game Metadata", "Unable to fetch screenshot id: " + ScreenshotId, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.Videos != null)
|
||||||
|
{
|
||||||
|
foreach (long GameVideoId in Game.Videos.Ids)
|
||||||
|
{
|
||||||
|
GameVideo gameVideo = GamesVideos.GetGame_Videos(GameVideoId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Game> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
// add artificial unknown platform mapping
|
||||||
|
List<long> platformIds = new List<long>();
|
||||||
|
platformIds.Add(0);
|
||||||
|
if (result.Platforms != null)
|
||||||
|
{
|
||||||
|
if (result.Platforms.Ids != null)
|
||||||
|
{
|
||||||
|
platformIds.AddRange(result.Platforms.Ids.ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Platforms = new IdentitiesOrValues<Platform>(
|
||||||
|
ids: platformIds.ToArray<long>()
|
||||||
|
);
|
||||||
|
|
||||||
// get cover art from parent if this has no cover
|
// get cover art from parent if this has no cover
|
||||||
if (result.Cover == null)
|
if (result.Cover == null)
|
||||||
{
|
{
|
||||||
if (result.ParentGame != null)
|
if (result.ParentGame != null)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Game Metadata", "Game has no cover art, fetching cover art from parent game");
|
if (result.ParentGame.Id != null)
|
||||||
parentGame = GetGame(result.MetadataSource, (long)result.ParentGame);
|
{
|
||||||
result.Cover = parentGame.Cover;
|
Logging.Log(Logging.LogType.Information, "Game Metadata", "Game has no cover art, fetching cover art from parent game");
|
||||||
|
Game parentGame = GetGame((long)result.ParentGame.Id, false, false, false);
|
||||||
|
result.Cover = parentGame.Cover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get missing metadata from parent if this is a port
|
// get missing metadata from parent if this is a port
|
||||||
if (result.Category == HasheousClient.Models.Metadata.IGDB.Category.Port)
|
if (result.Category == Category.Port)
|
||||||
{
|
{
|
||||||
if (result.Summary == null)
|
if (result.Summary == null)
|
||||||
{
|
{
|
||||||
if (result.ParentGame != null)
|
if (result.ParentGame != null)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Game Metadata", "Game has no summary, fetching summary from parent game");
|
if (result.ParentGame.Id != null)
|
||||||
result.Summary = parentGame.Summary;
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Game Metadata", "Game has no summary, fetching summary from parent game");
|
||||||
|
Game parentGame = GetGame((long)result.ParentGame.Id, false, false, false);
|
||||||
|
result.Summary = parentGame.Summary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate age group data
|
|
||||||
if (result.MetadataSource == HasheousClient.Models.MetadataSources.IGDB)
|
|
||||||
{
|
|
||||||
AgeGroups.GetAgeGroup(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AssignAllGamesToPlatformIdZero()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT * FROM Game;";
|
||||||
|
DataTable gamesTable = db.ExecuteCMD(sql);
|
||||||
|
foreach (DataRow gameRow in gamesTable.Rows)
|
||||||
|
{
|
||||||
|
sql = "DELETE FROM Relation_Game_Platforms WHERE PlatformsId = 0 AND GameId = @Id; INSERT INTO Relation_Game_Platforms (GameId, PlatformsId) VALUES (@Id, 0);";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("Id", (long)gameRow["Id"]);
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool AllowNoPlatformSearch = false;
|
private static bool AllowNoPlatformSearch = false;
|
||||||
|
|
||||||
public static Game[] SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
public static Game[] SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
||||||
@@ -138,7 +430,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
string sql = "SELECT Game.Id, Game.`Name`, Game.Slug, Relation_Game_Platforms.PlatformsId AS PlatformsId, Game.Summary FROM gaseous.Game JOIN Relation_Game_Platforms ON Game.Id = Relation_Game_Platforms.GameId AND Game.SourceId = Relation_Game_Platforms.GameSourceId WHERE " + whereClause + ";";
|
string sql = "SELECT Game.Id, Game.`Name`, Game.Slug, Relation_Game_Platforms.PlatformsId AS PlatformsId, Game.Summary FROM gaseous.Game JOIN Relation_Game_Platforms ON Game.Id = Relation_Game_Platforms.GameId WHERE " + whereClause + ";";
|
||||||
|
|
||||||
|
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
@@ -168,90 +460,64 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
private static async Task<Game[]> _SearchForGameRemote(string SearchString, long PlatformId, SearchType searchType)
|
private static async Task<Game[]> _SearchForGameRemote(string SearchString, long PlatformId, SearchType searchType)
|
||||||
{
|
{
|
||||||
switch (Config.MetadataConfiguration.DefaultMetadataSource)
|
string searchBody = "";
|
||||||
|
string searchFields = "fields id,name,slug,platforms,summary; ";
|
||||||
|
bool allowSearch = true;
|
||||||
|
switch (searchType)
|
||||||
{
|
{
|
||||||
case HasheousClient.Models.MetadataSources.None:
|
case SearchType.searchNoPlatform:
|
||||||
return new Game[0];
|
searchBody = "search \"" + SearchString + "\"; ";
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
if (Config.IGDB.UseHasheousProxy == false)
|
|
||||||
{
|
|
||||||
string searchBody = "";
|
|
||||||
string searchFields = "fields id,name,slug,platforms,summary; ";
|
|
||||||
bool allowSearch = true;
|
|
||||||
switch (searchType)
|
|
||||||
{
|
|
||||||
case SearchType.searchNoPlatform:
|
|
||||||
searchBody = "search \"" + SearchString + "\"; ";
|
|
||||||
|
|
||||||
allowSearch = AllowNoPlatformSearch;
|
allowSearch = AllowNoPlatformSearch;
|
||||||
break;
|
break;
|
||||||
case SearchType.search:
|
case SearchType.search:
|
||||||
searchBody = "search \"" + SearchString + "\"; where platforms = (" + PlatformId + ");";
|
searchBody = "search \"" + SearchString + "\"; where platforms = (" + PlatformId + ");";
|
||||||
break;
|
break;
|
||||||
case SearchType.wherefuzzy:
|
case SearchType.wherefuzzy:
|
||||||
searchBody = "where platforms = (" + PlatformId + ") & name ~ *\"" + SearchString + "\"*;";
|
searchBody = "where platforms = (" + PlatformId + ") & name ~ *\"" + SearchString + "\"*;";
|
||||||
break;
|
break;
|
||||||
case SearchType.where:
|
case SearchType.where:
|
||||||
searchBody = "where platforms = (" + PlatformId + ") & name ~ \"" + SearchString + "\";";
|
searchBody = "where platforms = (" + PlatformId + ") & name ~ \"" + SearchString + "\";";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check search cache
|
// check search cache
|
||||||
Game[]? games = Communications.GetSearchCache<Game[]?>(searchFields, searchBody);
|
Game[]? games = Communications.GetSearchCache<Game[]?>(searchFields, searchBody);
|
||||||
|
|
||||||
if (games == null)
|
if (games == null)
|
||||||
{
|
{
|
||||||
// cache miss
|
// cache miss
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
Game[]? results = new Game[0];
|
Game[]? results = new Game[0];
|
||||||
if (allowSearch == true)
|
if (allowSearch == true)
|
||||||
{
|
{
|
||||||
results = await comms.APIComm<Game>(IGDB.IGDBClient.Endpoints.Games, searchFields, searchBody);
|
results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, searchFields, searchBody);
|
||||||
|
|
||||||
Communications.SetSearchCache<Game[]?>(searchFields, searchBody, results);
|
Communications.SetSearchCache<Game[]?>(searchFields, searchBody, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return games.ToArray();
|
return games.ToArray();
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
|
||||||
HasheousClient.Models.Metadata.IGDB.Game[] hResults = hasheous.GetMetadataProxy_SearchGame<HasheousClient.Models.Metadata.IGDB.Game>(HasheousClient.Hasheous.MetadataProvider.IGDB, PlatformId.ToString(), SearchString);
|
|
||||||
|
|
||||||
List<Game> hGames = new List<Game>();
|
|
||||||
foreach (HasheousClient.Models.Metadata.IGDB.Game hResult in hResults)
|
|
||||||
{
|
|
||||||
hGames.Add(Communications.ConvertToIGDBModel<Game>(hResult));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hGames.ToArray();
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return new Game[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<AvailablePlatformItem> GetAvailablePlatforms(string UserId, HasheousClient.Models.MetadataSources SourceType, long GameId)
|
public static List<AvailablePlatformItem> GetAvailablePlatforms(string UserId, long GameId)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = @"
|
string sql = @"
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
view_Games_Roms.MetadataMapId,
|
|
||||||
view_Games_Roms.GameId,
|
view_Games_Roms.GameId,
|
||||||
view_Games_Roms.PlatformId,
|
view_Games_Roms.PlatformId,
|
||||||
view_Games_Roms.UserManualLink,
|
|
||||||
Platform.`Name`,
|
Platform.`Name`,
|
||||||
User_RecentPlayedRoms.UserId AS MostRecentUserId,
|
User_RecentPlayedRoms.UserId AS MostRecentUserId,
|
||||||
User_RecentPlayedRoms.RomId AS MostRecentRomId,
|
User_RecentPlayedRoms.RomId AS MostRecentRomId,
|
||||||
CASE User_RecentPlayedRoms.IsMediaGroup
|
CASE User_RecentPlayedRoms.IsMediaGroup
|
||||||
WHEN 0 THEN GMR.`Name`
|
WHEN 0 THEN GMR.`Name`
|
||||||
WHEN 1 THEN view_Games_Roms.`MetadataGameName`
|
WHEN 1 THEN 'Media Group'
|
||||||
ELSE NULL
|
ELSE NULL
|
||||||
END AS `MostRecentRomName`,
|
END AS `MostRecentRomName`,
|
||||||
User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup,
|
User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup,
|
||||||
@@ -259,32 +525,31 @@ SELECT DISTINCT
|
|||||||
User_GameFavouriteRoms.RomId AS FavouriteRomId,
|
User_GameFavouriteRoms.RomId AS FavouriteRomId,
|
||||||
CASE User_GameFavouriteRoms.IsMediaGroup
|
CASE User_GameFavouriteRoms.IsMediaGroup
|
||||||
WHEN 0 THEN GFV.`Name`
|
WHEN 0 THEN GFV.`Name`
|
||||||
WHEN 1 THEN view_Games_Roms.`MetadataGameName`
|
WHEN 1 THEN 'Media Group'
|
||||||
ELSE NULL
|
ELSE NULL
|
||||||
END AS `FavouriteRomName`,
|
END AS `FavouriteRomName`,
|
||||||
User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup
|
User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup
|
||||||
FROM
|
FROM
|
||||||
view_Games_Roms
|
view_Games_Roms
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Platform ON view_Games_Roms.PlatformId = Platform.Id AND Platform.SourceId = view_Games_Roms.GameIdType
|
Platform ON view_Games_Roms.PlatformId = Platform.Id
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
||||||
AND User_RecentPlayedRoms.GameId = view_Games_Roms.MetadataMapId
|
AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId
|
||||||
AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId
|
AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
||||||
AND User_GameFavouriteRoms.GameId = view_Games_Roms.MetadataMapId
|
AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId
|
||||||
AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId
|
AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
view_Games_Roms AS GMR ON GMR.Id = User_RecentPlayedRoms.RomId
|
view_Games_Roms AS GMR ON GMR.Id = User_RecentPlayedRoms.RomId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
view_Games_Roms AS GFV ON GFV.Id = User_GameFavouriteRoms.RomId
|
view_Games_Roms AS GFV ON GFV.Id = User_GameFavouriteRoms.RomId
|
||||||
WHERE
|
WHERE
|
||||||
view_Games_Roms.GameIdType = @sourcetype AND view_Games_Roms.GameId = @gameid
|
view_Games_Roms.GameId = @gameid
|
||||||
ORDER BY Platform.`Name`;";
|
ORDER BY Platform.`Name`;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "sourcetype", (int)SourceType },
|
|
||||||
{ "gameid", GameId },
|
{ "gameid", GameId },
|
||||||
{ "userid", UserId }
|
{ "userid", UserId }
|
||||||
};
|
};
|
||||||
@@ -294,40 +559,23 @@ ORDER BY Platform.`Name`;";
|
|||||||
List<AvailablePlatformItem> platforms = new List<AvailablePlatformItem>();
|
List<AvailablePlatformItem> platforms = new List<AvailablePlatformItem>();
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
HasheousClient.Models.Metadata.IGDB.Platform platform = Platforms.GetPlatform((long)row["PlatformId"]);
|
IGDB.Models.Platform platform = Platforms.GetPlatform((long)row["PlatformId"]);
|
||||||
|
|
||||||
// get the user emulator configuration
|
|
||||||
PlatformMapping.UserEmulatorConfiguration? emulatorConfiguration = platformMapping.GetUserEmulator(UserId, GameId, (long)platform.Id);
|
PlatformMapping.UserEmulatorConfiguration? emulatorConfiguration = platformMapping.GetUserEmulator(UserId, GameId, (long)platform.Id);
|
||||||
|
|
||||||
// if no user configuration, get the platform emulator configuration
|
|
||||||
if (emulatorConfiguration == null)
|
if (emulatorConfiguration == null)
|
||||||
{
|
{
|
||||||
if (platform.Id != 0)
|
if (platform.Id != 0)
|
||||||
{
|
{
|
||||||
Models.PlatformMapping.PlatformMapItem platformMap = PlatformMapping.GetPlatformMap((long)platform.Id);
|
Models.PlatformMapping.PlatformMapItem platformMap = PlatformMapping.GetPlatformMap((long)platform.Id);
|
||||||
if (platformMap != null)
|
emulatorConfiguration = new PlatformMapping.UserEmulatorConfiguration
|
||||||
{
|
{
|
||||||
emulatorConfiguration = new PlatformMapping.UserEmulatorConfiguration
|
EmulatorType = platformMap.WebEmulator.Type,
|
||||||
{
|
Core = platformMap.WebEmulator.Core,
|
||||||
EmulatorType = platformMap.WebEmulator.Type,
|
EnableBIOSFiles = platformMap.EnabledBIOSHashes
|
||||||
Core = platformMap.WebEmulator.Core,
|
};
|
||||||
EnableBIOSFiles = platformMap.EnabledBIOSHashes
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if still no emulator configuration, create a blank one
|
|
||||||
if (emulatorConfiguration == null)
|
|
||||||
{
|
|
||||||
emulatorConfiguration = new PlatformMapping.UserEmulatorConfiguration
|
|
||||||
{
|
|
||||||
EmulatorType = "",
|
|
||||||
Core = "",
|
|
||||||
EnableBIOSFiles = new List<string>()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
long? LastPlayedRomId = null;
|
long? LastPlayedRomId = null;
|
||||||
bool? LastPlayedIsMediagroup = false;
|
bool? LastPlayedIsMediagroup = false;
|
||||||
string? LastPlayedRomName = null;
|
string? LastPlayedRomName = null;
|
||||||
@@ -348,23 +596,16 @@ ORDER BY Platform.`Name`;";
|
|||||||
{
|
{
|
||||||
FavouriteRomId = (long?)row["FavouriteRomId"];
|
FavouriteRomId = (long?)row["FavouriteRomId"];
|
||||||
FavouriteRomIsMediagroup = (bool)row["FavouriteRomIsMediaGroup"];
|
FavouriteRomIsMediagroup = (bool)row["FavouriteRomIsMediaGroup"];
|
||||||
if (row["FavouriteRomName"] != System.DBNull.Value)
|
if (row["MostRecentRomName"] != System.DBNull.Value)
|
||||||
{
|
{
|
||||||
FavouriteRomName = string.IsNullOrEmpty((string?)row["FavouriteRomName"]) ? "" : (string)row["FavouriteRomName"];
|
FavouriteRomName = string.IsNullOrEmpty((string?)row["MostRecentRomName"]) ? "" : (string)row["MostRecentRomName"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string? UserManualLink = null;
|
|
||||||
if (row["UserManualLink"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
UserManualLink = string.IsNullOrEmpty((string?)row["UserManualLink"]) ? "" : (string)row["UserManualLink"];
|
|
||||||
}
|
|
||||||
|
|
||||||
AvailablePlatformItem valuePair = new AvailablePlatformItem
|
AvailablePlatformItem valuePair = new AvailablePlatformItem
|
||||||
{
|
{
|
||||||
Id = platform.Id,
|
Id = platform.Id,
|
||||||
Name = platform.Name,
|
Name = platform.Name,
|
||||||
MetadataMapId = (long)row["MetadataMapId"],
|
|
||||||
Category = platform.Category,
|
Category = platform.Category,
|
||||||
emulatorConfiguration = emulatorConfiguration,
|
emulatorConfiguration = emulatorConfiguration,
|
||||||
LastPlayedRomId = LastPlayedRomId,
|
LastPlayedRomId = LastPlayedRomId,
|
||||||
@@ -372,15 +613,11 @@ ORDER BY Platform.`Name`;";
|
|||||||
LastPlayedRomName = LastPlayedRomName,
|
LastPlayedRomName = LastPlayedRomName,
|
||||||
FavouriteRomId = FavouriteRomId,
|
FavouriteRomId = FavouriteRomId,
|
||||||
FavouriteRomIsMediagroup = FavouriteRomIsMediagroup,
|
FavouriteRomIsMediagroup = FavouriteRomIsMediagroup,
|
||||||
FavouriteRomName = FavouriteRomName,
|
FavouriteRomName = FavouriteRomName
|
||||||
UserManualLink = UserManualLink
|
|
||||||
};
|
};
|
||||||
platforms.Add(valuePair);
|
platforms.Add(valuePair);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort platforms by the Name attribute
|
|
||||||
platforms.Sort((x, y) => x.Name.CompareTo(y.Name));
|
|
||||||
|
|
||||||
return platforms;
|
return platforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,9 +649,8 @@ ORDER BY Platform.`Name`;";
|
|||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AvailablePlatformItem : HasheousClient.Models.Metadata.IGDB.Platform
|
public class AvailablePlatformItem : IGDB.Models.Platform
|
||||||
{
|
{
|
||||||
public long MetadataMapId { get; set; }
|
|
||||||
public PlatformMapping.UserEmulatorConfiguration emulatorConfiguration { get; set; }
|
public PlatformMapping.UserEmulatorConfiguration emulatorConfiguration { get; set; }
|
||||||
public long? LastPlayedRomId { get; set; }
|
public long? LastPlayedRomId { get; set; }
|
||||||
public bool? LastPlayedRomIsMediagroup { get; set; }
|
public bool? LastPlayedRomIsMediagroup { get; set; }
|
||||||
@@ -422,7 +658,6 @@ ORDER BY Platform.`Name`;";
|
|||||||
public long? FavouriteRomId { get; set; }
|
public long? FavouriteRomId { get; set; }
|
||||||
public bool? FavouriteRomIsMediagroup { get; set; }
|
public bool? FavouriteRomIsMediagroup { get; set; }
|
||||||
public string? FavouriteRomName { get; set; }
|
public string? FavouriteRomName { get; set; }
|
||||||
public string? UserManualLink { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SearchType
|
public enum SearchType
|
||||||
@@ -443,7 +678,6 @@ ORDER BY Platform.`Name`;";
|
|||||||
public MinimalGameItem(Game gameObject)
|
public MinimalGameItem(Game gameObject)
|
||||||
{
|
{
|
||||||
this.Id = gameObject.Id;
|
this.Id = gameObject.Id;
|
||||||
this.MetadataMapId = gameObject.MetadataMapId;
|
|
||||||
this.Name = gameObject.Name;
|
this.Name = gameObject.Name;
|
||||||
this.Slug = gameObject.Slug;
|
this.Slug = gameObject.Slug;
|
||||||
this.Summary = gameObject.Summary;
|
this.Summary = gameObject.Summary;
|
||||||
@@ -454,12 +688,12 @@ ORDER BY Platform.`Name`;";
|
|||||||
this.FirstReleaseDate = gameObject.FirstReleaseDate;
|
this.FirstReleaseDate = gameObject.FirstReleaseDate;
|
||||||
|
|
||||||
// compile age ratings
|
// compile age ratings
|
||||||
this.AgeRatings = new List<object>();
|
this.AgeRatings = new List<AgeRating>();
|
||||||
if (gameObject.AgeRatings != null)
|
if (gameObject.AgeRatings != null)
|
||||||
{
|
{
|
||||||
foreach (long ageRatingId in gameObject.AgeRatings)
|
foreach (long ageRatingId in gameObject.AgeRatings.Ids)
|
||||||
{
|
{
|
||||||
HasheousClient.Models.Metadata.IGDB.AgeRating? rating = Classes.Metadata.AgeRatings.GetAgeRating(gameObject.MetadataSource, ageRatingId);
|
AgeRating? rating = Classes.Metadata.AgeRatings.GetAgeRatings(ageRatingId);
|
||||||
if (rating != null)
|
if (rating != null)
|
||||||
{
|
{
|
||||||
this.AgeRatings.Add(rating);
|
this.AgeRatings.Add(rating);
|
||||||
@@ -469,7 +703,6 @@ ORDER BY Platform.`Name`;";
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long? Id { get; set; }
|
public long? Id { get; set; }
|
||||||
public long? MetadataMapId { get; set; }
|
|
||||||
public long Index { get; set; }
|
public long Index { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
@@ -479,9 +712,9 @@ ORDER BY Platform.`Name`;";
|
|||||||
public bool HasSavedGame { get; set; } = false;
|
public bool HasSavedGame { get; set; } = false;
|
||||||
public bool IsFavourite { get; set; } = false;
|
public bool IsFavourite { get; set; } = false;
|
||||||
public DateTimeOffset? FirstReleaseDate { get; set; }
|
public DateTimeOffset? FirstReleaseDate { get; set; }
|
||||||
public object Cover { get; set; }
|
public IGDB.IdentityOrValue<IGDB.Models.Cover> Cover { get; set; }
|
||||||
public List<long> Artworks { get; set; }
|
public IGDB.IdentitiesOrValues<IGDB.Models.Artwork> Artworks { get; set; }
|
||||||
public List<object> AgeRatings { get; set; }
|
public List<IGDB.Models.AgeRating> AgeRatings { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Genres
|
public class Genres
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
||||||
|
|
||||||
public Genres()
|
public Genres()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Genre? GetGenres(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Genre? GetGenres(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Genre? RetVal = Metadata.GetMetadata<Genre>(SourceType, (long)Id, false);
|
Task<Genre> RetVal = _GetGenres(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static Genre GetGenres(string Slug)
|
||||||
|
{
|
||||||
|
Task<Genre> RetVal = _GetGenres(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Genre> _GetGenres(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Genre", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Genre", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Genre returnValue = new Genre();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Genre>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Genre>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Genre> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Genres metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Genre>(IGDBClient.Endpoints.Genres, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class InvolvedCompanies
|
public class InvolvedCompanies
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields *;";
|
const string fieldList = "fields *;";
|
||||||
|
|
||||||
public InvolvedCompanies()
|
public InvolvedCompanies()
|
||||||
{
|
{
|
||||||
@@ -19,8 +20,106 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InvolvedCompany? RetVal = Metadata.GetMetadata<InvolvedCompany>(HasheousClient.Models.MetadataSources.IGDB, (long)Id, false);
|
Task<InvolvedCompany> RetVal = _GetInvolvedCompanies(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InvolvedCompany GetInvolvedCompanies(string Slug)
|
||||||
|
{
|
||||||
|
Task<InvolvedCompany> RetVal = _GetInvolvedCompanies(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<InvolvedCompany> _GetInvolvedCompanies(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("InvolvedCompany", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("InvolvedCompany", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
InvolvedCompany returnValue = new InvolvedCompany();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
UpdateSubClasses(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<InvolvedCompany>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<InvolvedCompany>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(InvolvedCompany involvedCompany)
|
||||||
|
{
|
||||||
|
if (involvedCompany.Company != null)
|
||||||
|
{
|
||||||
|
Company company = Companies.GetCompanies(involvedCompany.Company.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<InvolvedCompany> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get InvolvedCompanies metadata
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<InvolvedCompany>(IGDBClient.Endpoints.InvolvedCompanies, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Involved Companies", "Failure when requesting involved companies.");
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Involved Companies", "Field list: " + fieldList);
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Involved Companies", "Where clause: " + WhereClause);
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Involved Companies", "Error", ex);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,262 +0,0 @@
|
|||||||
using System.Data;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
|
||||||
{
|
|
||||||
public class Metadata
|
|
||||||
{
|
|
||||||
#region Exception Handling
|
|
||||||
public class InvalidMetadataId : Exception
|
|
||||||
{
|
|
||||||
public InvalidMetadataId(long Id) : base("Invalid Metadata id: " + Id + " from source: " + HasheousClient.Models.MetadataSources.IGDB + " (default)")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidMetadataId(HasheousClient.Models.MetadataSources SourceType, long Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidMetadataId(string Id) : base("Invalid Metadata id: " + Id + " from source: " + HasheousClient.Models.MetadataSources.IGDB + " (default)")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public InvalidMetadataId(HasheousClient.Models.MetadataSources SourceType, string Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get Metadata
|
|
||||||
/// <summary>
|
|
||||||
/// Get metadata from the default source
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">
|
|
||||||
/// The type of metadata to get
|
|
||||||
/// </typeparam>
|
|
||||||
/// <param name="Id">
|
|
||||||
/// The id of the metadata to get
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The metadata object
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="InvalidMetadataId">
|
|
||||||
/// Thrown when the id is invalid
|
|
||||||
/// </exception>
|
|
||||||
public static T? GetMetadata<T>(long Id, Boolean ForceRefresh = false) where T : class
|
|
||||||
{
|
|
||||||
if (Id < 0)
|
|
||||||
{
|
|
||||||
throw new InvalidMetadataId(Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _GetMetadata<T>(HasheousClient.Models.MetadataSources.IGDB, Id, ForceRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get metadata from the specified source
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">
|
|
||||||
/// The type of metadata to get
|
|
||||||
/// </typeparam>
|
|
||||||
/// <param name="SourceType">
|
|
||||||
/// The source of the metadata
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Id">
|
|
||||||
/// The id of the metadata to get
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The metadata object
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="InvalidMetadataId">
|
|
||||||
/// Thrown when the id is invalid
|
|
||||||
/// </exception>
|
|
||||||
public static T? GetMetadata<T>(HasheousClient.Models.MetadataSources SourceType, long Id, Boolean ForceRefresh = false) where T : class
|
|
||||||
{
|
|
||||||
if (Id < 0)
|
|
||||||
{
|
|
||||||
throw new InvalidMetadataId(SourceType, Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _GetMetadata<T>(SourceType, Id, ForceRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T? GetMetadata<T>(HasheousClient.Models.MetadataSources SourceType, string Slug, Boolean ForceRefresh = false) where T : class
|
|
||||||
{
|
|
||||||
return _GetMetadata<T>(SourceType, Slug, ForceRefresh);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static T? _GetMetadata<T>(HasheousClient.Models.MetadataSources SourceType, object Id, Boolean ForceRefresh) where T : class
|
|
||||||
{
|
|
||||||
// get T type as string
|
|
||||||
string type = typeof(T).Name;
|
|
||||||
|
|
||||||
// get type of Id as string
|
|
||||||
IdType idType = Id.GetType() == typeof(long) ? IdType.Long : IdType.String;
|
|
||||||
|
|
||||||
// check cached metadata status
|
|
||||||
// if metadata is not cached or expired, get it from the source. Otherwise, return the cached metadata
|
|
||||||
Storage.CacheStatus? cacheStatus;
|
|
||||||
if (idType == IdType.Long)
|
|
||||||
{
|
|
||||||
cacheStatus = Storage.GetCacheStatus(SourceType, type, (long)Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cacheStatus = Storage.GetCacheStatus(SourceType, type, (string)Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if ForceRefresh is true, set cache status to expired if it is current
|
|
||||||
if (ForceRefresh == true)
|
|
||||||
{
|
|
||||||
if (cacheStatus == Storage.CacheStatus.Current)
|
|
||||||
{
|
|
||||||
cacheStatus = Storage.CacheStatus.Expired;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the source is "none", cache status should be "current" or "not present"
|
|
||||||
if (SourceType == HasheousClient.Models.MetadataSources.None)
|
|
||||||
{
|
|
||||||
if (cacheStatus == Storage.CacheStatus.Expired)
|
|
||||||
{
|
|
||||||
cacheStatus = Storage.CacheStatus.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T? metadata = (T)Activator.CreateInstance(typeof(T));
|
|
||||||
|
|
||||||
switch (cacheStatus)
|
|
||||||
{
|
|
||||||
case Storage.CacheStatus.Current:
|
|
||||||
if (idType == IdType.Long)
|
|
||||||
{
|
|
||||||
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Id", (long)Id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Slug", (string)Id);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Storage.CacheStatus.Expired:
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (idType == IdType.Long)
|
|
||||||
{
|
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
|
|
||||||
}
|
|
||||||
Storage.NewCacheValue<T>(SourceType, metadata, true);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Fetch Metadata", "Failed to fetch metadata from source: " + SourceType + " for id: " + Id + " of type: " + type + ". Error: " + e.Message);
|
|
||||||
metadata = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Storage.CacheStatus.NotPresent:
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (idType == IdType.Long)
|
|
||||||
{
|
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
|
|
||||||
}
|
|
||||||
Storage.NewCacheValue<T>(SourceType, metadata, false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Fetch Metadata", "Failed to fetch metadata from source: " + SourceType + " for id: " + Id + " of type: " + type + ". Error: " + e.Message);
|
|
||||||
metadata = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum IdType
|
|
||||||
{
|
|
||||||
Long,
|
|
||||||
String
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataSources SourceType, long Id) where T : class
|
|
||||||
{
|
|
||||||
// get T type as string
|
|
||||||
string type = typeof(T).Name;
|
|
||||||
|
|
||||||
if (SourceType == HasheousClient.Models.MetadataSources.None)
|
|
||||||
{
|
|
||||||
// generate a dummy object
|
|
||||||
var returnObject = (T)Activator.CreateInstance(typeof(T));
|
|
||||||
returnObject.GetType().GetProperty("Id").SetValue(returnObject, Id);
|
|
||||||
|
|
||||||
// if returnObject has a property called "name", query the metadatamap view for the name
|
|
||||||
if (returnObject.GetType().GetProperty("Name") != null)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "SELECT * FROM MetadataMap JOIN MetadataMapBridge ON MetadataMap.Id = MetadataMapBridge.ParentMapId WHERE MetadataSourceId = @id AND MetadataSourceType = 0;";
|
|
||||||
DataTable dataTable = db.ExecuteCMD(sql, new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "@id", Id }
|
|
||||||
});
|
|
||||||
if (dataTable.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
returnObject.GetType().GetProperty("Name").SetValue(returnObject, dataTable.Rows[0]["SignatureGameName"].ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnObject;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get metadata from the server
|
|
||||||
Communications comms = new Communications();
|
|
||||||
var results = await comms.APIComm<T>(SourceType, (Communications.MetadataEndpoint)Enum.Parse(typeof(Communications.MetadataEndpoint), type, true), Id);
|
|
||||||
|
|
||||||
// check for errors
|
|
||||||
if (results == null)
|
|
||||||
{
|
|
||||||
throw new InvalidMetadataId(SourceType, Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.FirstOrDefault<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataSources SourceType, string Id) where T : class
|
|
||||||
{
|
|
||||||
// get T type as string
|
|
||||||
string type = typeof(T).Name;
|
|
||||||
|
|
||||||
if (SourceType == HasheousClient.Models.MetadataSources.None)
|
|
||||||
{
|
|
||||||
// generate a dummy object
|
|
||||||
return (T)Activator.CreateInstance(typeof(T));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get metadata from the server
|
|
||||||
Communications comms = new Communications();
|
|
||||||
var results = await comms.APIComm<T>(SourceType, (Communications.MetadataEndpoint)Enum.Parse(typeof(Communications.MetadataEndpoint), type, true), Id);
|
|
||||||
|
|
||||||
// check for errors
|
|
||||||
if (results == null)
|
|
||||||
{
|
|
||||||
throw new InvalidMetadataId(SourceType, Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.FirstOrDefault<T>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class MultiplayerModes
|
public class MultiplayerModes
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields campaigncoop,checksum,dropin,game,lancoop,offlinecoop,offlinecoopmax,offlinemax,onlinecoop,onlinecoopmax,onlinemax,platform,splitscreen,splitscreenonline;";
|
const string fieldList = "fields campaigncoop,checksum,dropin,game,lancoop,offlinecoop,offlinecoopmax,offlinemax,onlinecoop,onlinecoopmax,onlinemax,platform,splitscreen,splitscreenonline;";
|
||||||
|
|
||||||
public MultiplayerModes()
|
public MultiplayerModes()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MultiplayerMode? GetGame_MultiplayerModes(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static MultiplayerMode? GetGame_MultiplayerModes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MultiplayerMode? RetVal = Metadata.GetMetadata<MultiplayerMode>(SourceType, (long)Id, false);
|
Task<MultiplayerMode> RetVal = _GetGame_MultiplayerModes(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MultiplayerMode GetGame_MultiplayerModes(string Slug)
|
||||||
|
{
|
||||||
|
Task<MultiplayerMode> RetVal = _GetGame_MultiplayerModes(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<MultiplayerMode> _GetGame_MultiplayerModes(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("MultiplayerMode", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("MultiplayerMode", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiplayerMode returnValue = new MultiplayerMode();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<MultiplayerMode>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<MultiplayerMode>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<MultiplayerMode> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game_MultiplayerModes metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<MultiplayerMode>(IGDBClient.Endpoints.MultiplayerModes, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
using static gaseous_server.Models.PlatformMapping;
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class PlatformLogos
|
public class PlatformLogos
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields alpha_channel,animated,checksum,height,image_id,url,width;";
|
const string fieldList = "fields alpha_channel,animated,checksum,height,image_id,url,width;";
|
||||||
|
|
||||||
public PlatformLogos()
|
public PlatformLogos()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlatformLogo? GetPlatformLogo(long? Id, HasheousClient.Models.MetadataSources SourceType = HasheousClient.Models.MetadataSources.IGDB)
|
public static PlatformLogo? GetPlatformLogo(long? Id, string ImagePath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -21,10 +21,113 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PlatformLogo? RetVal = Metadata.GetMetadata<PlatformLogo>(SourceType, (long)Id, false);
|
Task<PlatformLogo> RetVal = _GetPlatformLogo(SearchUsing.id, Id, ImagePath);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static PlatformLogo GetPlatformLogo(string Slug, string ImagePath)
|
||||||
|
{
|
||||||
|
Task<PlatformLogo> RetVal = _GetPlatformLogo(SearchUsing.slug, Slug, ImagePath);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlatformLogo> _GetPlatformLogo(SearchUsing searchUsing, object searchValue, string ImagePath)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlatformLogo", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlatformLogo", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformLogo returnValue = new PlatformLogo();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
if (returnValue != null)
|
||||||
|
{
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
|
||||||
|
// check if old value is different from the new value - only download if it's different
|
||||||
|
PlatformLogo oldImage = Storage.GetCacheValue<PlatformLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
if (oldImage.ImageId != returnValue.ImageId)
|
||||||
|
{
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<PlatformLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<PlatformLogo>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnValue != null)
|
||||||
|
{
|
||||||
|
// check for presence of "original" quality file - download if absent or force download is true
|
||||||
|
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Platform logo download forced.");
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlatformLogo> GetObjectFromServer(string WhereClause, string ImagePath)
|
||||||
|
{
|
||||||
|
// get Artwork metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlatformLogo>(IGDBClient.Endpoints.PlatformLogos, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class PlatformVersions
|
public class PlatformVersions
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,companies,connectivity,cpu,graphics,main_manufacturer,media,memory,name,online,os,output,platform_logo,platform_version_release_dates,resolutions,slug,sound,storage,summary,url;";
|
const string fieldList = "fields checksum,companies,connectivity,cpu,graphics,main_manufacturer,media,memory,name,online,os,output,platform_logo,platform_version_release_dates,resolutions,slug,sound,storage,summary,url;";
|
||||||
|
|
||||||
public PlatformVersions()
|
public PlatformVersions()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlatformVersion? GetPlatformVersion(HasheousClient.Models.MetadataSources SourceType, long Id)
|
public static PlatformVersion? GetPlatformVersion(long Id, Platform ParentPlatform, bool GetImages = false)
|
||||||
{
|
{
|
||||||
if (Id == 0)
|
if (Id == 0)
|
||||||
{
|
{
|
||||||
@@ -20,8 +21,113 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PlatformVersion? RetVal = Metadata.GetMetadata<PlatformVersion>(SourceType, Id, false);
|
Task<PlatformVersion> RetVal = _GetPlatformVersion(SearchUsing.id, Id, ParentPlatform, GetImages);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlatformVersion GetPlatformVersion(string Slug, Platform ParentPlatform, bool GetImages = false)
|
||||||
|
{
|
||||||
|
Task<PlatformVersion> RetVal = _GetPlatformVersion(SearchUsing.slug, Slug, ParentPlatform, GetImages);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlatformVersion> _GetPlatformVersion(SearchUsing searchUsing, object searchValue, Platform ParentPlatform, bool GetImages)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlatformVersion", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlatformVersion", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformVersion returnValue = new PlatformVersion();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
if (returnValue != null)
|
||||||
|
{
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
UpdateSubClasses(ParentPlatform, returnValue, GetImages);
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
UpdateSubClasses(ParentPlatform, returnValue, GetImages);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<PlatformVersion>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
return Storage.GetCacheValue<PlatformVersion>(returnValue, "id", (long)searchValue);
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(Platform ParentPlatform, PlatformVersion platformVersion, bool GetImages)
|
||||||
|
{
|
||||||
|
if (GetImages == true)
|
||||||
|
{
|
||||||
|
if (platformVersion.PlatformLogo != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PlatformLogo platformLogo = PlatformLogos.GetPlatformLogo(platformVersion.PlatformLogo.Id, Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(ParentPlatform), "Versions", platformVersion.Slug));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Platform Update", "Unable to fetch platform logo", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlatformVersion?> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get PlatformVersion metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlatformVersion>(IGDBClient.Endpoints.PlatformVersions, fieldList, WhereClause);
|
||||||
|
if (results.Length > 0)
|
||||||
|
{
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,152 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Platforms
|
public class Platforms
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites;";
|
const string fieldList = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites;";
|
||||||
|
|
||||||
public Platforms()
|
public Platforms()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Platform? GetPlatform(long Id, HasheousClient.Models.MetadataSources? SourceType = null)
|
public static Platform? GetPlatform(long Id, bool forceRefresh = false, bool GetImages = false)
|
||||||
{
|
{
|
||||||
HasheousClient.Models.MetadataSources Source = SourceType ?? Communications.MetadataSource;
|
if (Id == 0)
|
||||||
|
|
||||||
if ((Id == 0) || (Id == null))
|
|
||||||
{
|
{
|
||||||
Platform returnValue = new Platform();
|
Platform returnValue = new Platform();
|
||||||
if (Storage.GetCacheStatus(Source, "Platform", 0) == Storage.CacheStatus.NotPresent)
|
if (Storage.GetCacheStatus("Platform", 0) == Storage.CacheStatus.NotPresent)
|
||||||
{
|
{
|
||||||
returnValue = new Platform
|
returnValue = new Platform
|
||||||
{
|
{
|
||||||
Id = 0,
|
Id = 0,
|
||||||
Name = "Unknown Platform",
|
Name = "Unknown Platform",
|
||||||
Slug = "unknown"
|
Slug = "Unknown"
|
||||||
};
|
};
|
||||||
Storage.NewCacheValue(Source, returnValue);
|
Storage.NewCacheValue(returnValue);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Storage.GetCacheValue<Platform>(Source, returnValue, "id", 0);
|
return Storage.GetCacheValue<Platform>(returnValue, "id", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Platform? RetVal = new Platform();
|
try
|
||||||
RetVal = (Platform?)Storage.GetCacheValue<Platform>(HasheousClient.Models.MetadataSources.None, RetVal, "Id", (long)Id);
|
|
||||||
if (Source != HasheousClient.Models.MetadataSources.None)
|
|
||||||
{
|
{
|
||||||
if (RetVal == null)
|
Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id, forceRefresh, GetImages);
|
||||||
{
|
return RetVal.Result;
|
||||||
RetVal = Metadata.GetMetadata<Platform>(Source, (long)Id, false);
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata", "An error occurred fetching Platform Id " + Id, ex);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return RetVal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Platform GetPlatform(string Slug)
|
public static Platform GetPlatform(string Slug, bool forceRefresh = false, bool GetImages = false)
|
||||||
{
|
{
|
||||||
// get platform id from slug - query Platform table
|
Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug, forceRefresh, GetImages);
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
return RetVal.Result;
|
||||||
string query = "SELECT Id FROM Platform WHERE slug = @slug AND SourceId = @sourceid;";
|
}
|
||||||
DataTable result = db.ExecuteCMD(query, new Dictionary<string, object> { { "@slug", Slug }, { "@sourceid", HasheousClient.Models.MetadataSources.IGDB } });
|
|
||||||
if (result.Rows.Count == 0)
|
private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue, bool forceRefresh, bool GetImages)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
{
|
{
|
||||||
throw new Metadata.InvalidMetadataId(Slug);
|
cacheStatus = Storage.GetCacheStatus("Platform", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Platform", (string)searchValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
long Id = (long)result.Rows[0]["Id"];
|
if (forceRefresh == true)
|
||||||
return GetPlatform(Id);
|
{
|
||||||
|
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
string searchField = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
searchField = "id";
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||||
|
searchField = "slug";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform returnValue = new Platform();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
UpdateSubClasses(returnValue, GetImages);
|
||||||
|
AddPlatformMapping(returnValue);
|
||||||
|
return returnValue;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
UpdateSubClasses(returnValue, GetImages);
|
||||||
|
AddPlatformMapping(returnValue);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||||
|
}
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSubClasses(Platform platform, bool GetImages)
|
||||||
|
{
|
||||||
|
if (platform.Versions != null)
|
||||||
|
{
|
||||||
|
foreach (long PlatformVersionId in platform.Versions.Ids)
|
||||||
|
{
|
||||||
|
PlatformVersion platformVersion = PlatformVersions.GetPlatformVersion(PlatformVersionId, platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetImages == true)
|
||||||
|
{
|
||||||
|
if (platform.PlatformLogo != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PlatformLogo platformLogo = PlatformLogos.GetPlatformLogo(platform.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platform));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Platform Update", "Unable to fetch platform logo", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddPlatformMapping(Platform platform)
|
private static void AddPlatformMapping(Platform platform)
|
||||||
@@ -93,6 +174,36 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
Models.PlatformMapping.WritePlatformMap(item, false, true);
|
Models.PlatformMapping.WritePlatformMap(item, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Platform> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get platform metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Platform>(IGDBClient.Endpoints.Platforms, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AssignAllPlatformsToGameIdZero()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT * FROM Platform;";
|
||||||
|
DataTable platformsTable = db.ExecuteCMD(sql);
|
||||||
|
foreach (DataRow platformRow in platformsTable.Rows)
|
||||||
|
{
|
||||||
|
sql = "DELETE FROM Relation_Game_Platforms WHERE GameId = 0 AND PlatformsId = @Id; INSERT INTO Relation_Game_Platforms (GameId, PlatformsId) VALUES (0, @Id);";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("Id", (long)platformRow["Id"]);
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class PlayerPerspectives
|
public class PlayerPerspectives
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
||||||
|
|
||||||
public PlayerPerspectives()
|
public PlayerPerspectives()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerPerspective? GetGame_PlayerPerspectives(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static PlayerPerspective? GetGame_PlayerPerspectives(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,90 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PlayerPerspective? RetVal = Metadata.GetMetadata<PlayerPerspective>(SourceType, (long)Id, false);
|
Task<PlayerPerspective> RetVal = _GetGame_PlayerPerspectives(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PlayerPerspective GetGame_PlayerPerspectives(string Slug)
|
||||||
|
{
|
||||||
|
Task<PlayerPerspective> RetVal = _GetGame_PlayerPerspectives(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlayerPerspective> _GetGame_PlayerPerspectives(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlayerPerspective", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("PlayerPerspective", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerPerspective returnValue = new PlayerPerspective();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<PlayerPerspective>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<PlayerPerspective>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<PlayerPerspective> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game_PlayerPerspectives metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlayerPerspective>(IGDBClient.Endpoints.PlayerPerspectives, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class ReleaseDates
|
public class ReleaseDates
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields category,checksum,created_at,date,game,human,m,platform,region,status,updated_at,y;";
|
const string fieldList = "fields category,checksum,created_at,date,game,human,m,platform,region,status,updated_at,y;";
|
||||||
|
|
||||||
public ReleaseDates()
|
public ReleaseDates()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReleaseDate? GetReleaseDates(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static ReleaseDate? GetReleaseDates(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,88 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ReleaseDate? RetVal = Metadata.GetMetadata<ReleaseDate>(SourceType, (long)Id, false);
|
Task<ReleaseDate> RetVal = _GetReleaseDates(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static ReleaseDate GetReleaseDates(string Slug)
|
||||||
|
{
|
||||||
|
Task<ReleaseDate> RetVal = _GetReleaseDates(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<ReleaseDate> _GetReleaseDates(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ReleaseDate", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ReleaseDate", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDate returnValue = new ReleaseDate();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<ReleaseDate>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<ReleaseDate>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<ReleaseDate> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get ReleaseDates metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<ReleaseDate>(IGDBClient.Endpoints.ReleaseDates, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Screenshots
|
public class Screenshots
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields alpha_channel,animated,checksum,game,height,image_id,url,width;";
|
const string fieldList = "fields alpha_channel,animated,checksum,game,height,image_id,url,width;";
|
||||||
|
|
||||||
public Screenshots()
|
public Screenshots()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Screenshot? GetScreenshot(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Screenshot? GetScreenshot(long? Id, string ImagePath, bool GetImages)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,111 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Screenshot? RetVal = Metadata.GetMetadata<Screenshot>(SourceType, (long)Id, false);
|
Task<Screenshot> RetVal = _GetScreenshot(SearchUsing.id, Id, ImagePath, GetImages);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Screenshot GetScreenshot(string Slug, string ImagePath, bool GetImages)
|
||||||
|
{
|
||||||
|
Task<Screenshot> RetVal = _GetScreenshot(SearchUsing.slug, Slug, ImagePath, GetImages);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Screenshot> _GetScreenshot(SearchUsing searchUsing, object searchValue, string ImagePath, bool GetImages = true)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Screenshot", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Screenshot", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Screenshot returnValue = new Screenshot();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
ImagePath = Path.Combine(ImagePath, "Screenshots");
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
|
||||||
|
// check if old value is different from the new value - only download if it's different
|
||||||
|
Screenshot oldImage = Storage.GetCacheValue<Screenshot>(returnValue, "id", (long)searchValue);
|
||||||
|
if (oldImage.ImageId != returnValue.ImageId)
|
||||||
|
{
|
||||||
|
forceImageDownload = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<Screenshot>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Screenshot>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for presence of "original" quality file - download if absent or force download is true
|
||||||
|
string localFile = Path.Combine(ImagePath, Communications.IGDBAPI_ImageSize.original.ToString(), returnValue.ImageId + ".jpg");
|
||||||
|
if (GetImages == true)
|
||||||
|
{
|
||||||
|
if ((!File.Exists(localFile)) || forceImageDownload == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Metadata: " + returnValue.GetType().Name, "Screenshot download forced.");
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
comms.GetSpecificImageFromServer(ImagePath, returnValue.ImageId, Communications.IGDBAPI_ImageSize.original, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Screenshot> GetObjectFromServer(string WhereClause, string ImagePath)
|
||||||
|
{
|
||||||
|
// get Screenshot metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Screenshot>(IGDBClient.Endpoints.Screenshots, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,79 +9,23 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
public class Storage
|
public class Storage
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Cache status of a record
|
|
||||||
/// </summary>
|
|
||||||
public enum CacheStatus
|
public enum CacheStatus
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The record is not present in the database
|
|
||||||
/// </summary>
|
|
||||||
NotPresent,
|
NotPresent,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The record is present in the database and is current
|
|
||||||
/// </summary>
|
|
||||||
Current,
|
Current,
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The record is present in the database but is expired
|
|
||||||
/// </summary>
|
|
||||||
Expired
|
Expired
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static CacheStatus GetCacheStatus(string Endpoint, string Slug)
|
||||||
/// Get the cache status of a record in the database
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="SourceType">
|
|
||||||
/// The source of the metadata (IGDB, RAWG, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Endpoint">
|
|
||||||
/// The endpoint of the metadata (games, companies, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Slug">
|
|
||||||
/// The slug of the metadata record
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The cache status of the record
|
|
||||||
/// </returns>
|
|
||||||
public static CacheStatus GetCacheStatus(HasheousClient.Models.MetadataSources SourceType, string Endpoint, string Slug)
|
|
||||||
{
|
{
|
||||||
return _GetCacheStatus(SourceType, Endpoint, "slug", Slug);
|
return _GetCacheStatus(Endpoint, "slug", Slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static CacheStatus GetCacheStatus(string Endpoint, long Id)
|
||||||
/// Get the cache status of a record in the database
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="SourceType">
|
|
||||||
/// The source of the metadata (IGDB, RAWG, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Endpoint">
|
|
||||||
/// The endpoint of the metadata (games, companies, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="Id">
|
|
||||||
/// The ID of the metadata record
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The cache status of the record
|
|
||||||
/// </returns>
|
|
||||||
public static CacheStatus GetCacheStatus(HasheousClient.Models.MetadataSources SourceType, string Endpoint, long Id)
|
|
||||||
{
|
{
|
||||||
return _GetCacheStatus(SourceType, Endpoint, "id", Id);
|
return _GetCacheStatus(Endpoint, "id", Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the cache status of a record in the database
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="Row">
|
|
||||||
/// The DataRow object to check
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The cache status of the record
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="Exception">
|
|
||||||
/// Thrown when the DataRow object does not contain a "lastUpdated" column
|
|
||||||
/// </exception>
|
|
||||||
public static CacheStatus GetCacheStatus(DataRow Row)
|
public static CacheStatus GetCacheStatus(DataRow Row)
|
||||||
{
|
{
|
||||||
if (Row.Table.Columns.Contains("lastUpdated"))
|
if (Row.Table.Columns.Contains("lastUpdated"))
|
||||||
@@ -102,14 +46,13 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CacheStatus _GetCacheStatus(HasheousClient.Models.MetadataSources SourceType, string Endpoint, string SearchField, object SearchValue)
|
private static CacheStatus _GetCacheStatus(string Endpoint, string SearchField, object SearchValue)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
string sql = "SELECT lastUpdated FROM " + Endpoint + " WHERE SourceId = @SourceType AND " + SearchField + " = @" + SearchField;
|
string sql = "SELECT lastUpdated FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField;
|
||||||
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("SourceType", SourceType);
|
|
||||||
dbDict.Add("Endpoint", Endpoint);
|
dbDict.Add("Endpoint", Endpoint);
|
||||||
dbDict.Add(SearchField, SearchValue);
|
dbDict.Add(SearchField, SearchValue);
|
||||||
|
|
||||||
@@ -133,41 +76,16 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static void NewCacheValue(object ObjectToCache, bool UpdateRecord = false)
|
||||||
/// Add a new record to the cache
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="SourceType">
|
|
||||||
/// The source of the metadata (IGDB, RAWG, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="ObjectToCache">
|
|
||||||
/// The object to cache
|
|
||||||
/// </param>
|
|
||||||
/// <param name="UpdateRecord">
|
|
||||||
/// Whether to update the record if it already exists
|
|
||||||
/// </param>
|
|
||||||
public static void NewCacheValue<T>(HasheousClient.Models.MetadataSources SourceType, T ObjectToCache, bool UpdateRecord = false)
|
|
||||||
{
|
{
|
||||||
// get the object type name
|
// get the object type name
|
||||||
string ObjectTypeName = ObjectToCache.GetType().Name;
|
string ObjectTypeName = ObjectToCache.GetType().Name;
|
||||||
|
|
||||||
// build dictionary
|
// build dictionary
|
||||||
Dictionary<string, object?> objectDict = new Dictionary<string, object?>
|
string objectJson = Newtonsoft.Json.JsonConvert.SerializeObject(ObjectToCache);
|
||||||
{
|
Dictionary<string, object?> objectDict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object?>>(objectJson);
|
||||||
{ "SourceId", SourceType },
|
objectDict.Add("dateAdded", DateTime.UtcNow);
|
||||||
{ "dateAdded", DateTime.UtcNow },
|
objectDict.Add("lastUpdated", DateTime.UtcNow);
|
||||||
{ "lastUpdated", DateTime.UtcNow }
|
|
||||||
};
|
|
||||||
foreach (PropertyInfo property in ObjectToCache.GetType().GetProperties())
|
|
||||||
{
|
|
||||||
if (property.GetCustomAttribute<Models.NoDatabaseAttribute>() == null)
|
|
||||||
{
|
|
||||||
object? propertyValue = property.GetValue(ObjectToCache);
|
|
||||||
if (propertyValue != null)
|
|
||||||
{
|
|
||||||
objectDict.Add(property.Name, propertyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate sql
|
// generate sql
|
||||||
string fieldList = "";
|
string fieldList = "";
|
||||||
@@ -182,7 +100,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
fieldList = fieldList + key.Key;
|
fieldList = fieldList + key.Key;
|
||||||
valueList = valueList + "@" + key.Key;
|
valueList = valueList + "@" + key.Key;
|
||||||
if ((key.Key != "id") && (key.Key != "dateAdded") && (key.Key != "SourceId"))
|
if ((key.Key != "id") && (key.Key != "dateAdded"))
|
||||||
{
|
{
|
||||||
if (updateFieldValueList.Length > 0)
|
if (updateFieldValueList.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -217,13 +135,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
newObjectValue = Newtonsoft.Json.JsonConvert.SerializeObject(newDict["Ids"]);
|
newObjectValue = Newtonsoft.Json.JsonConvert.SerializeObject(newDict["Ids"]);
|
||||||
objectDict[key.Key] = newObjectValue;
|
objectDict[key.Key] = newObjectValue;
|
||||||
|
|
||||||
StoreRelations(SourceType, ObjectTypeName, key.Key, (long)objectDict["Id"], newObjectValue);
|
StoreRelations(ObjectTypeName, key.Key, (long)objectDict["Id"], newObjectValue);
|
||||||
break;
|
|
||||||
case "list":
|
|
||||||
newObjectValue = Newtonsoft.Json.JsonConvert.SerializeObject(objectValue);
|
|
||||||
objectDict[key.Key] = newObjectValue;
|
|
||||||
|
|
||||||
StoreRelations(SourceType, ObjectTypeName, key.Key, (long)objectDict["Id"], newObjectValue);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "int32[]":
|
case "int32[]":
|
||||||
@@ -239,11 +151,11 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
string sql = "";
|
string sql = "";
|
||||||
if (UpdateRecord == false)
|
if (UpdateRecord == false)
|
||||||
{
|
{
|
||||||
sql = "INSERT INTO " + ObjectTypeName + " (" + fieldList + ") VALUES (" + valueList + ");";
|
sql = "INSERT INTO " + ObjectTypeName + " (" + fieldList + ") VALUES (" + valueList + ")";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "UPDATE " + ObjectTypeName + " SET " + updateFieldValueList + " WHERE Id = @Id AND SourceId = @SourceId;";
|
sql = "UPDATE " + ObjectTypeName + " SET " + updateFieldValueList + " WHERE Id = @Id";
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute sql
|
// execute sql
|
||||||
@@ -251,40 +163,15 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
db.ExecuteCMD(sql, objectDict);
|
db.ExecuteCMD(sql, objectDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static T GetCacheValue<T>(T EndpointType, string SearchField, object SearchValue)
|
||||||
/// Get a record from the cache
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">
|
|
||||||
/// The type of the object to return
|
|
||||||
/// </typeparam>
|
|
||||||
/// <param name="SourceType">
|
|
||||||
/// The source of the metadata (IGDB, RAWG, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="EndpointType">
|
|
||||||
/// The type of the endpoint (games, companies, etc.)
|
|
||||||
/// </param>
|
|
||||||
/// <param name="SearchField">
|
|
||||||
/// The field to search for the record by
|
|
||||||
/// </param>
|
|
||||||
/// <param name="SearchValue">
|
|
||||||
/// The value to search for
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The object from the cache
|
|
||||||
/// </returns>
|
|
||||||
/// <exception cref="Exception">
|
|
||||||
/// Thrown when no record is found that matches the search criteria
|
|
||||||
/// </exception>
|
|
||||||
public static T GetCacheValue<T>(HasheousClient.Models.MetadataSources SourceType, T? EndpointType, string SearchField, object SearchValue)
|
|
||||||
{
|
{
|
||||||
string Endpoint = EndpointType.GetType().Name;
|
string Endpoint = EndpointType.GetType().Name;
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
string sql = "SELECT * FROM " + Endpoint + " WHERE SourceId = @SourceType AND " + SearchField + " = @" + SearchField;
|
string sql = "SELECT * FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField;
|
||||||
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("SourceType", SourceType);
|
|
||||||
dbDict.Add("Endpoint", Endpoint);
|
dbDict.Add("Endpoint", Endpoint);
|
||||||
dbDict.Add(SearchField, SearchValue);
|
dbDict.Add(SearchField, SearchValue);
|
||||||
|
|
||||||
@@ -305,66 +192,202 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
public static T BuildCacheObject<T>(T EndpointType, DataRow dataRow)
|
public static T BuildCacheObject<T>(T EndpointType, DataRow dataRow)
|
||||||
{
|
{
|
||||||
// copy the DataRow to EndpointType
|
|
||||||
foreach (PropertyInfo property in EndpointType.GetType().GetProperties())
|
foreach (PropertyInfo property in EndpointType.GetType().GetProperties())
|
||||||
{
|
{
|
||||||
if (property.GetCustomAttribute<Models.NoDatabaseAttribute>() == null)
|
if (dataRow.Table.Columns.Contains(property.Name))
|
||||||
{
|
{
|
||||||
// get the value from the DataRow with the same name as the property
|
if (dataRow[property.Name] != DBNull.Value)
|
||||||
if (dataRow.Table.Columns.Contains(property.Name) == true)
|
|
||||||
{
|
{
|
||||||
object? value = dataRow[property.Name];
|
string objectTypeName = property.PropertyType.Name.ToLower().Split("`")[0];
|
||||||
|
string subObjectTypeName = "";
|
||||||
if (value != null && value != DBNull.Value)
|
object? objectToStore = null;
|
||||||
|
if (objectTypeName == "nullable")
|
||||||
{
|
{
|
||||||
// check the property type - if it's a list or array, deserialize it. Otherwise, just set the value
|
objectTypeName = property.PropertyType.UnderlyingSystemType.ToString().Split("`1")[1].Replace("[System.", "").Replace("]", "").ToLower();
|
||||||
Type objectType = EndpointType.GetType();
|
}
|
||||||
if (objectType != null)
|
try
|
||||||
|
{
|
||||||
|
switch (objectTypeName)
|
||||||
{
|
{
|
||||||
// fullname = System.Nullable`1[[System.DateTimeOffset,
|
//case "boolean":
|
||||||
string propertyTypeName = property.PropertyType.FullName.Split(",")[0];
|
// Boolean storedBool = Convert.ToBoolean((int)dataRow[property.Name]);
|
||||||
bool isNullable = false;
|
// property.SetValue(EndpointType, storedBool);
|
||||||
if (propertyTypeName.StartsWith("System.Nullable"))
|
// break;
|
||||||
{
|
case "datetimeoffset":
|
||||||
isNullable = true;
|
DateTimeOffset? storedDate = (DateTime?)dataRow[property.Name];
|
||||||
propertyTypeName = propertyTypeName.Split("[[")[1];
|
property.SetValue(EndpointType, storedDate);
|
||||||
}
|
break;
|
||||||
propertyTypeName = propertyTypeName.Split("`")[0];
|
//case "nullable":
|
||||||
|
// Console.WriteLine("Nullable: " + property.PropertyType.UnderlyingSystemType);
|
||||||
|
// break;
|
||||||
|
case "identityorvalue":
|
||||||
|
subObjectTypeName = property.PropertyType.UnderlyingSystemType.ToString().Split("`1")[1].Replace("[IGDB.Models.", "").Replace("]", "").ToLower();
|
||||||
|
|
||||||
switch (propertyTypeName.ToLower())
|
switch (subObjectTypeName)
|
||||||
{
|
{
|
||||||
case "system.collections.generic.list":
|
case "collection":
|
||||||
var listArray = Newtonsoft.Json.JsonConvert.DeserializeObject<List<long>>(value.ToString());
|
objectToStore = new IdentityOrValue<Collection>(id: (long)dataRow[property.Name]);
|
||||||
property.SetValue(EndpointType, listArray);
|
break;
|
||||||
break;
|
case "company":
|
||||||
|
objectToStore = new IdentityOrValue<Company>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "cover":
|
||||||
|
objectToStore = new IdentityOrValue<Cover>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "franchise":
|
||||||
|
objectToStore = new IdentityOrValue<Franchise>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "game":
|
||||||
|
objectToStore = new IdentityOrValue<Game>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "platformfamily":
|
||||||
|
objectToStore = new IdentityOrValue<PlatformFamily>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "platformlogo":
|
||||||
|
objectToStore = new IdentityOrValue<PlatformLogo>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "platformversioncompany":
|
||||||
|
objectToStore = new IdentityOrValue<PlatformVersionCompany>(id: (long)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "system.int32[]":
|
if (objectToStore != null)
|
||||||
var int32array = Newtonsoft.Json.JsonConvert.DeserializeObject<int[]>(value.ToString());
|
{
|
||||||
property.SetValue(EndpointType, int32array);
|
property.SetValue(EndpointType, objectToStore);
|
||||||
break;
|
}
|
||||||
|
|
||||||
case "system.datetimeoffset":
|
break;
|
||||||
property.SetValue(EndpointType, (DateTimeOffset)(DateTime?)value);
|
case "identitiesorvalues":
|
||||||
break;
|
subObjectTypeName = property.PropertyType.UnderlyingSystemType.ToString().Split("`1")[1].Replace("[IGDB.Models.", "").Replace("]", "").ToLower();
|
||||||
|
|
||||||
default:
|
long[] fromJsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<long[]>((string)dataRow[property.Name]);
|
||||||
// check if property is an enum
|
|
||||||
if (property.PropertyType.IsEnum)
|
switch (subObjectTypeName)
|
||||||
{
|
{
|
||||||
property.SetValue(EndpointType, Enum.Parse(property.PropertyType, value.ToString()));
|
case "agerating":
|
||||||
}
|
objectToStore = new IdentitiesOrValues<AgeRating>(ids: fromJsonObject);
|
||||||
else if (Common.IsNullableEnum(property.PropertyType))
|
break;
|
||||||
{
|
case "alternativename":
|
||||||
property.SetValue(EndpointType, Enum.Parse(Nullable.GetUnderlyingType(property.PropertyType), value.ToString()));
|
objectToStore = new IdentitiesOrValues<AlternativeName>(ids: fromJsonObject);
|
||||||
}
|
break;
|
||||||
else
|
case "artwork":
|
||||||
{
|
objectToStore = new IdentitiesOrValues<Artwork>(ids: fromJsonObject);
|
||||||
property.SetValue(EndpointType, value);
|
break;
|
||||||
}
|
case "ageratingcontentdescription":
|
||||||
break;
|
objectToStore = new IdentitiesOrValues<AgeRatingContentDescription>(ids: fromJsonObject);
|
||||||
}
|
break;
|
||||||
|
case "game":
|
||||||
|
objectToStore = new IdentitiesOrValues<Game>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "externalgame":
|
||||||
|
objectToStore = new IdentitiesOrValues<ExternalGame>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "franchise":
|
||||||
|
objectToStore = new IdentitiesOrValues<Franchise>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "gameengine":
|
||||||
|
objectToStore = new IdentitiesOrValues<GameEngine>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "gamemode":
|
||||||
|
objectToStore = new IdentitiesOrValues<GameMode>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "gamevideo":
|
||||||
|
objectToStore = new IdentitiesOrValues<GameVideo>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "genre":
|
||||||
|
objectToStore = new IdentitiesOrValues<Genre>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "involvedcompany":
|
||||||
|
objectToStore = new IdentitiesOrValues<InvolvedCompany>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "multiplayermode":
|
||||||
|
objectToStore = new IdentitiesOrValues<MultiplayerMode>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "platform":
|
||||||
|
objectToStore = new IdentitiesOrValues<Platform>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "platformversion":
|
||||||
|
objectToStore = new IdentitiesOrValues<PlatformVersion>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "platformwebsite":
|
||||||
|
objectToStore = new IdentitiesOrValues<PlatformWebsite>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "platformversioncompany":
|
||||||
|
objectToStore = new IdentitiesOrValues<PlatformVersionCompany>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "platformversionreleasedate":
|
||||||
|
objectToStore = new IdentitiesOrValues<PlatformVersionReleaseDate>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "playerperspective":
|
||||||
|
objectToStore = new IdentitiesOrValues<PlayerPerspective>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "releasedate":
|
||||||
|
objectToStore = new IdentitiesOrValues<ReleaseDate>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "screenshot":
|
||||||
|
objectToStore = new IdentitiesOrValues<Screenshot>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "theme":
|
||||||
|
objectToStore = new IdentitiesOrValues<Theme>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
case "website":
|
||||||
|
objectToStore = new IdentitiesOrValues<Website>(ids: fromJsonObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (objectToStore != null)
|
||||||
|
{
|
||||||
|
property.SetValue(EndpointType, objectToStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "int32[]":
|
||||||
|
Int32[] fromJsonObject_int32Array = Newtonsoft.Json.JsonConvert.DeserializeObject<Int32[]>((string)dataRow[property.Name]);
|
||||||
|
if (fromJsonObject_int32Array != null)
|
||||||
|
{
|
||||||
|
property.SetValue(EndpointType, fromJsonObject_int32Array);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "[igdb.models.category":
|
||||||
|
property.SetValue(EndpointType, (Category)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.gamestatus":
|
||||||
|
property.SetValue(EndpointType, (GameStatus)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.ageratingcategory":
|
||||||
|
property.SetValue(EndpointType, (AgeRatingCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.ageratingcontentdescriptioncategory":
|
||||||
|
property.SetValue(EndpointType, (AgeRatingContentDescriptionCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.ageratingtitle":
|
||||||
|
property.SetValue(EndpointType, (AgeRatingTitle)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.externalcategory":
|
||||||
|
property.SetValue(EndpointType, (ExternalCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.startdatecategory":
|
||||||
|
property.SetValue(EndpointType, (StartDateCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.releasedateregion":
|
||||||
|
property.SetValue(EndpointType, (ReleaseDateRegion)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.releasedatecategory":
|
||||||
|
property.SetValue(EndpointType, (ReleaseDateCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[gaseous_server.classes.metadata.agegroups+agerestrictiongroupings":
|
||||||
|
property.SetValue(EndpointType, (AgeGroups.AgeRestrictionGroupings)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
property.SetValue(EndpointType, dataRow[property.Name]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error occurred in column " + property.Name);
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -372,7 +395,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
return EndpointType;
|
return EndpointType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void StoreRelations(HasheousClient.Models.MetadataSources SourceType, string PrimaryTable, string SecondaryTable, long ObjectId, string Relations)
|
private static void StoreRelations(string PrimaryTable, string SecondaryTable, long ObjectId, string Relations)
|
||||||
{
|
{
|
||||||
string TableName = "Relation_" + PrimaryTable + "_" + SecondaryTable;
|
string TableName = "Relation_" + PrimaryTable + "_" + SecondaryTable;
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
@@ -381,13 +404,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
if (data.Rows.Count == 0)
|
if (data.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// table doesn't exist, create it
|
// table doesn't exist, create it
|
||||||
sql = @"
|
sql = "CREATE TABLE `" + Config.DatabaseConfiguration.DatabaseName + "`.`" + TableName + "` (`" + PrimaryTable + "Id` BIGINT NOT NULL, `" + SecondaryTable + "Id` BIGINT NOT NULL, PRIMARY KEY (`" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`), INDEX `idx_PrimaryColumn` (`" + PrimaryTable + "Id` ASC) VISIBLE);";
|
||||||
CREATE TABLE
|
|
||||||
`" + Config.DatabaseConfiguration.DatabaseName + "`.`" + TableName + @"`
|
|
||||||
(`" + PrimaryTable + @"SourceId` INT NOT NULL,
|
|
||||||
`" + PrimaryTable + @"Id` BIGINT NOT NULL,
|
|
||||||
`" + SecondaryTable + @"Id` BIGINT NOT NULL,
|
|
||||||
PRIMARY KEY (`" + PrimaryTable + "SourceId`, `" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`), INDEX `idx_PrimaryColumn` (`" + PrimaryTable + "Id` ASC) VISIBLE);";
|
|
||||||
db.ExecuteCMD(sql);
|
db.ExecuteCMD(sql);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -403,13 +420,10 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
long[] RelationValues = Newtonsoft.Json.JsonConvert.DeserializeObject<long[]>(Relations);
|
long[] RelationValues = Newtonsoft.Json.JsonConvert.DeserializeObject<long[]>(Relations);
|
||||||
foreach (long RelationValue in RelationValues)
|
foreach (long RelationValue in RelationValues)
|
||||||
{
|
{
|
||||||
sql = "INSERT INTO " + TableName + " (`" + PrimaryTable + "SourceId`, `" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`) VALUES (@sourceid, @objectid, @relationvalue);";
|
sql = "INSERT INTO " + TableName + " (`" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`) VALUES (@objectid, @relationvalue);";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
{
|
dbDict.Add("objectid", ObjectId);
|
||||||
{ "sourceid", SourceType },
|
dbDict.Add("relationvalue", RelationValue);
|
||||||
{ "objectid", ObjectId },
|
|
||||||
{ "relationvalue", RelationValue }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -431,13 +445,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
if (data.Rows.Count == 0)
|
if (data.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// table doesn't exist, create it
|
// table doesn't exist, create it
|
||||||
sql = @"
|
sql = "CREATE TABLE `" + Config.DatabaseConfiguration.DatabaseName + "`.`" + TableName + "` (`" + PrimaryTable + "Id` BIGINT NOT NULL, `" + SecondaryTable + "Id` BIGINT NOT NULL, PRIMARY KEY (`" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`), INDEX `idx_PrimaryColumn` (`" + PrimaryTable + "Id` ASC) VISIBLE);";
|
||||||
CREATE TABLE
|
|
||||||
`" + Config.DatabaseConfiguration.DatabaseName + "`.`" + TableName + @"`
|
|
||||||
(`" + PrimaryTable + @"SourceId` INT NOT NULL,
|
|
||||||
`" + PrimaryTable + @"Id` BIGINT NOT NULL,
|
|
||||||
`" + SecondaryTable + @"Id` BIGINT NOT NULL,
|
|
||||||
PRIMARY KEY (`" + PrimaryTable + "SourceId`, `" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`), INDEX `idx_PrimaryColumn` (`" + PrimaryTable + "Id` ASC) VISIBLE);";
|
|
||||||
db.ExecuteCMD(sql);
|
db.ExecuteCMD(sql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
public class Themes
|
public class Themes
|
||||||
{
|
{
|
||||||
public const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
||||||
|
|
||||||
public Themes()
|
public Themes()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Theme? GetGame_Themes(HasheousClient.Models.MetadataSources SourceType, long? Id)
|
public static Theme? GetGame_Themes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
{
|
{
|
||||||
@@ -20,10 +21,90 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Theme? RetVal = Metadata.GetMetadata<Theme>(SourceType, (long)Id, false);
|
Task<Theme> RetVal = _GetGame_Themes(SearchUsing.id, Id);
|
||||||
return RetVal;
|
return RetVal.Result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Theme GetGame_Themes(string Slug)
|
||||||
|
{
|
||||||
|
Task<Theme> RetVal = _GetGame_Themes(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Theme> _GetGame_Themes(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Theme", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("Theme", (string)searchValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up where clause
|
||||||
|
string WhereClause = "";
|
||||||
|
switch (searchUsing)
|
||||||
|
{
|
||||||
|
case SearchUsing.id:
|
||||||
|
WhereClause = "where id = " + searchValue;
|
||||||
|
break;
|
||||||
|
case SearchUsing.slug:
|
||||||
|
WhereClause = "where slug = " + searchValue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid search type");
|
||||||
|
}
|
||||||
|
|
||||||
|
Theme returnValue = new Theme();
|
||||||
|
bool forceImageDownload = false;
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
forceImageDownload = true;
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
return Storage.GetCacheValue<Theme>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<Theme>(returnValue, "id", (long)searchValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("How did you get here?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SearchUsing
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<Theme> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get Game_Themes metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Theme>(IGDBClient.Endpoints.Themes, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,364 +1,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using HasheousClient.Models;
|
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class MetadataManagement : QueueItemStatus
|
public class MetadataManagement : QueueItemStatus
|
||||||
{
|
{
|
||||||
private static bool Processing = false;
|
|
||||||
|
|
||||||
public enum MetadataMapSupportDataTypes
|
|
||||||
{
|
|
||||||
UserManualLink
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new metadata map, if one with the same platformId and name does not already exist.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="platformId">
|
|
||||||
/// The ID of the platform to which the metadata map belongs.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="name">
|
|
||||||
/// The name of the metadata map.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The ID of the new metadata map, or the ID of the existing metadata map if one already exists.
|
|
||||||
/// </returns>
|
|
||||||
public static MetadataMap? NewMetadataMap(long platformId, string name)
|
|
||||||
{
|
|
||||||
if (Processing == true)
|
|
||||||
{
|
|
||||||
// loop until processing = false
|
|
||||||
while (Processing == true)
|
|
||||||
{
|
|
||||||
System.Threading.Thread.Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Processing = true;
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@platformId", platformId },
|
|
||||||
{ "@name", name }
|
|
||||||
};
|
|
||||||
DataTable dt = new DataTable();
|
|
||||||
|
|
||||||
// check if the metadata map already exists
|
|
||||||
MetadataMap? existingMetadataMap = GetMetadataMap(platformId, name);
|
|
||||||
if (existingMetadataMap != null)
|
|
||||||
{
|
|
||||||
Processing = false;
|
|
||||||
return existingMetadataMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the metadata map
|
|
||||||
sql = "INSERT INTO MetadataMap (PlatformId, SignatureGameName) VALUES (@platformId, @name); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
long metadataMapId = (long)dt.Rows[0][0];
|
|
||||||
|
|
||||||
// create dummy game metadata item and capture id
|
|
||||||
sql = "INSERT INTO Game (SourceId, Name, dateAdded, lastUpdated) VALUES (@sourceid, @name, @dateadded, @lastupdated); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@sourceid", HasheousClient.Models.MetadataSources.None },
|
|
||||||
{ "@name", name },
|
|
||||||
{ "@dateadded", DateTime.UtcNow },
|
|
||||||
{ "@lastupdated", DateTime.UtcNow }
|
|
||||||
};
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
long gameId = (long)dt.Rows[0][0];
|
|
||||||
|
|
||||||
// add default metadata sources
|
|
||||||
AddMetadataMapItem(metadataMapId, HasheousClient.Models.MetadataSources.None, gameId, true);
|
|
||||||
|
|
||||||
// return the new metadata map
|
|
||||||
MetadataMap RetVal = GetMetadataMap(metadataMapId);
|
|
||||||
Processing = false;
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a metadata map item to the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="metadataMapId">
|
|
||||||
/// The ID of the metadata map to which the item belongs.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="sourceType">
|
|
||||||
/// The type of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="sourceId">
|
|
||||||
/// The ID of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="preferred">
|
|
||||||
/// Whether the metadata source is preferred.
|
|
||||||
/// </param>
|
|
||||||
/// <remarks>
|
|
||||||
/// If the metadata source is preferred, all other metadata sources for the same metadata map will be set to not preferred.
|
|
||||||
/// </remarks>
|
|
||||||
public static void AddMetadataMapItem(long metadataMapId, HasheousClient.Models.MetadataSources sourceType, long sourceId, bool preferred)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@metadataMapId", metadataMapId },
|
|
||||||
{ "@sourceType", sourceType },
|
|
||||||
{ "@sourceId", sourceId },
|
|
||||||
{ "@preferred", preferred },
|
|
||||||
{ "@processedatimport", false }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (preferred == true)
|
|
||||||
{
|
|
||||||
// set all other items to not preferred
|
|
||||||
sql = "UPDATE MetadataMapBridge SET Preferred = 0 WHERE ParentMapId = @metadataMapId;";
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = "INSERT INTO MetadataMapBridge (ParentMapId, MetadataSourceType, MetadataSourceId, Preferred, ProcessedAtImport) VALUES (@metadataMapId, @sourceType, @sourceId, @preferred, @processedatimport);";
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UpdateMetadataMapItem(long metadataMapId, HasheousClient.Models.MetadataSources SourceType, long sourceId, bool? preferred = null)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@metadataMapId", metadataMapId },
|
|
||||||
{ "@sourceType", SourceType },
|
|
||||||
{ "@sourceId", sourceId },
|
|
||||||
{ "@preferred", preferred }
|
|
||||||
};
|
|
||||||
|
|
||||||
if (preferred == true)
|
|
||||||
{
|
|
||||||
// set all other items to not preferred
|
|
||||||
sql = "UPDATE MetadataMapBridge SET Preferred = 0 WHERE ParentMapId = @metadataMapId; UPDATE MetadataMapBridge SET MetadataSourceId = @sourceId, Preferred = @preferred WHERE ParentMapId = @metadataMapId AND MetadataSourceType = @sourceType;";
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sql = "UPDATE MetadataMapBridge SET MetadataSourceId = @sourceId WHERE ParentMapId = @metadataMapId AND MetadataSourceType = @sourceType;";
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a metadata map from the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="platformId">
|
|
||||||
/// The ID of the platform to which the metadata map belongs.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="name">
|
|
||||||
/// The name of the metadata map.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The metadata map, or null if it does not exist.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// This method will return the first metadata map found with the given platformId and name.
|
|
||||||
/// </remarks>
|
|
||||||
public static MetadataMap? GetMetadataMap(long platformId, string name)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@platformId", platformId },
|
|
||||||
{ "@name", name.Trim() }
|
|
||||||
};
|
|
||||||
DataTable dt = new DataTable();
|
|
||||||
|
|
||||||
sql = "SELECT Id FROM MetadataMap WHERE PlatformId = @platformId AND SignatureGameName = @name;";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (dt.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
return GetMetadataMap((long)dt.Rows[0]["Id"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a metadata map from the database.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="metadataMapId">
|
|
||||||
/// The ID of the metadata map.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The metadata map, or null if it does not exist.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// This method will return the metadata map with the given ID.
|
|
||||||
/// </remarks>
|
|
||||||
public static MetadataMap? GetMetadataMap(long metadataMapId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@metadataMapId", metadataMapId }
|
|
||||||
};
|
|
||||||
DataTable dt = new DataTable();
|
|
||||||
|
|
||||||
sql = "SELECT * FROM MetadataMap WHERE Id = @metadataMapId;";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (dt.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
MetadataMap metadataMap = new MetadataMap()
|
|
||||||
{
|
|
||||||
Id = (long)dt.Rows[0]["Id"],
|
|
||||||
PlatformId = (long)dt.Rows[0]["PlatformId"],
|
|
||||||
SignatureGameName = dt.Rows[0]["SignatureGameName"].ToString(),
|
|
||||||
MetadataMapItems = new List<MetadataMap.MetadataMapItem>()
|
|
||||||
};
|
|
||||||
|
|
||||||
sql = "SELECT * FROM MetadataMapBridge WHERE ParentMapId = @metadataMapId;";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dt.Rows)
|
|
||||||
{
|
|
||||||
MetadataMap.MetadataMapItem metadataMapItem = new MetadataMap.MetadataMapItem()
|
|
||||||
{
|
|
||||||
SourceType = (HasheousClient.Models.MetadataSources)dr["MetadataSourceType"],
|
|
||||||
SourceId = (long)dr["MetadataSourceId"],
|
|
||||||
Preferred = (bool)dr["Preferred"]
|
|
||||||
};
|
|
||||||
|
|
||||||
metadataMap.MetadataMapItems.Add(metadataMapItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
return metadataMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetMetadataSupportData(long metadataMapId, MetadataMapSupportDataTypes dataType, string data)
|
|
||||||
{
|
|
||||||
// verify the metadata map exists
|
|
||||||
MetadataMap? metadataMap = GetMetadataMap(metadataMapId);
|
|
||||||
if (metadataMap == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@metadataMapId", metadataMapId },
|
|
||||||
{ "@data", data }
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (dataType)
|
|
||||||
{
|
|
||||||
case MetadataMapSupportDataTypes.UserManualLink:
|
|
||||||
sql = "UPDATE MetadataMap SET UserManualLink = @data WHERE Id = @metadataMapId;";
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the MetadataMapItem for the provided metadata source, and source id
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sourceType">
|
|
||||||
/// The type of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="sourceId">
|
|
||||||
/// The ID of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The MetadataMapItem, or null if it does not exist.
|
|
||||||
/// </returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// This method will return the MetadataMapItem with the given sourceType and sourceId.
|
|
||||||
/// </remarks>
|
|
||||||
public static MetadataMap.MetadataMapItem? GetMetadataMapFromSourceId(HasheousClient.Models.MetadataSources sourceType, long sourceId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@sourceType", sourceType },
|
|
||||||
{ "@sourceId", sourceId }
|
|
||||||
};
|
|
||||||
DataTable dt = new DataTable();
|
|
||||||
|
|
||||||
sql = "SELECT * FROM MetadataMapBridge WHERE MetadataSourceType = @sourceType AND MetadataSourceId = @sourceId;";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (dt.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
MetadataMap.MetadataMapItem metadataMapItem = new MetadataMap.MetadataMapItem()
|
|
||||||
{
|
|
||||||
SourceType = (HasheousClient.Models.MetadataSources)dt.Rows[0]["MetadataSourceType"],
|
|
||||||
SourceId = (long)dt.Rows[0]["MetadataSourceId"],
|
|
||||||
Preferred = (bool)dt.Rows[0]["Preferred"]
|
|
||||||
};
|
|
||||||
|
|
||||||
return metadataMapItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the Id of the MetadataMap for the provided metadata source, and source id
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sourceType">
|
|
||||||
/// The type of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <param name="sourceId">
|
|
||||||
/// The ID of the metadata source.
|
|
||||||
/// </param>
|
|
||||||
/// <returns>
|
|
||||||
/// The ID of the MetadataMap, or null if it does not exist.
|
|
||||||
/// </returns>
|
|
||||||
public static long? GetMetadataMapIdFromSourceId(HasheousClient.Models.MetadataSources sourceType, long sourceId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>()
|
|
||||||
{
|
|
||||||
{ "@sourceType", sourceType },
|
|
||||||
{ "@sourceId", sourceId }
|
|
||||||
};
|
|
||||||
DataTable dt = new DataTable();
|
|
||||||
|
|
||||||
sql = "SELECT * FROM MetadataMapBridge WHERE MetadataSourceType = @sourceType AND MetadataSourceId = @sourceId;";
|
|
||||||
dt = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (dt.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
return (long)dt.Rows[0]["ParentMapId"];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RefreshMetadata(bool forceRefresh = false)
|
public void RefreshMetadata(bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
DataTable dt = new DataTable();
|
DataTable dt = new DataTable();
|
||||||
|
|
||||||
// disabling forceRefresh
|
// disabling forceRefresh
|
||||||
forceRefresh = false;
|
forceRefresh = false;
|
||||||
|
|
||||||
// update platform metadata
|
// update platforms
|
||||||
sql = "SELECT Id, `Name` FROM Platform;";
|
sql = "SELECT Id, `Name` FROM Platform;";
|
||||||
dt = db.ExecuteCMD(sql);
|
dt = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
@@ -370,23 +27,7 @@ namespace gaseous_server.Classes
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for platform " + dr["name"] + " (" + dr["id"] + ")");
|
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for platform " + dr["name"] + " (" + dr["id"] + ")");
|
||||||
|
Metadata.Platforms.GetPlatform((long)dr["id"], true);
|
||||||
HasheousClient.Models.MetadataSources metadataSource = HasheousClient.Models.MetadataSources.None;
|
|
||||||
|
|
||||||
// fetch the platform metadata
|
|
||||||
Platform platform = Metadata.Platforms.GetPlatform((long)dr["id"], metadataSource);
|
|
||||||
|
|
||||||
// fetch the platform metadata from Hasheous
|
|
||||||
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
|
||||||
{
|
|
||||||
Communications.PopulateHasheousPlatformData((long)dr["id"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// force platformLogo refresh
|
|
||||||
if (platform.PlatformLogo != null)
|
|
||||||
{
|
|
||||||
Metadata.PlatformLogos.GetPlatformLogo(platform.PlatformLogo, metadataSource);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -397,68 +38,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
|
|
||||||
// update rom signatures - only valid if Haseheous is enabled
|
// update games
|
||||||
if (Config.MetadataConfiguration.SignatureSource == MetadataModel.SignatureSources.Hasheous)
|
|
||||||
{
|
|
||||||
// get all ROMs in the database
|
|
||||||
sql = "SELECT * FROM view_Games_Roms;";
|
|
||||||
dt = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
StatusCounter = 1;
|
|
||||||
foreach (DataRow dr in dt.Rows)
|
|
||||||
{
|
|
||||||
SetStatus(StatusCounter, dt.Rows.Count, "Refreshing signature for ROM " + dr["Name"]);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing signature for ROM " + dr["Name"] + " (" + dr["Id"] + ")");
|
|
||||||
|
|
||||||
// get the hash of the ROM from the datarow
|
|
||||||
string? md5 = dr["MD5"] == DBNull.Value ? null : dr["MD5"].ToString();
|
|
||||||
string? sha1 = dr["SHA1"] == DBNull.Value ? null : dr["SHA1"].ToString();
|
|
||||||
Common.hashObject hash = new Common.hashObject();
|
|
||||||
if (md5 != null)
|
|
||||||
{
|
|
||||||
hash.md5hash = md5;
|
|
||||||
}
|
|
||||||
if (sha1 != null)
|
|
||||||
{
|
|
||||||
hash.sha1hash = sha1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the library for the ROM
|
|
||||||
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)dr["LibraryId"]);
|
|
||||||
|
|
||||||
// get the signature for the ROM
|
|
||||||
FileInfo fi = new FileInfo(dr["Path"].ToString());
|
|
||||||
FileSignature fileSignature = new FileSignature();
|
|
||||||
gaseous_server.Models.Signatures_Games signature = fileSignature.GetFileSignature(library, hash, fi, fi.FullName);
|
|
||||||
|
|
||||||
// validate the signature - if it is invalid, skip the rest of the loop
|
|
||||||
// validation rules: 1) signature must not be null, 2) signature must have a platform ID
|
|
||||||
if (signature == null || signature.Flags.PlatformId == null)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Signature for " + dr["RomName"] + " is invalid - skipping metadata refresh");
|
|
||||||
StatusCounter += 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the signature in the database
|
|
||||||
Platform? signaturePlatform = Metadata.Platforms.GetPlatform((long)signature.Flags.PlatformId);
|
|
||||||
ImportGame.StoreGame(library, hash, signature, signaturePlatform, fi.FullName, (long)dr["Id"], false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["RomName"], ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusCounter += 1;
|
|
||||||
}
|
|
||||||
ClearStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// update game metadata
|
|
||||||
if (forceRefresh == true)
|
if (forceRefresh == true)
|
||||||
{
|
{
|
||||||
// when forced, only update games with ROMs for
|
// when forced, only update games with ROMs for
|
||||||
@@ -467,7 +47,7 @@ namespace gaseous_server.Classes
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// when run normally, update all games (since this will honour cache timeouts)
|
// when run normally, update all games (since this will honour cache timeouts)
|
||||||
sql = "SELECT DISTINCT MetadataSourceId AS `Id`, MetadataSourceType AS `GameIdType`, SignatureGameName AS `Name` FROM gaseous.view_MetadataMap;";
|
sql = "SELECT Id, `Name` FROM Game;";
|
||||||
}
|
}
|
||||||
dt = db.ExecuteCMD(sql);
|
dt = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
@@ -478,111 +58,8 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
MetadataSources metadataSource;
|
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")");
|
||||||
if (dr["GameIdType"] == DBNull.Value)
|
Metadata.Games.GetGame((long)dr["id"], true, false, true);
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Unable to refresh metadata for game " + dr["name"] + " (" + dr["id"] + ") - no source type specified");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
metadataSource = (MetadataSources)Enum.Parse(typeof(MetadataSources), dr["GameIdType"].ToString());
|
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ") using source " + metadataSource.ToString());
|
|
||||||
HasheousClient.Models.Metadata.IGDB.Game game = Metadata.Games.GetGame(metadataSource, (long)dr["id"]);
|
|
||||||
|
|
||||||
// get supporting metadata
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
if (game.AgeRatings != null)
|
|
||||||
{
|
|
||||||
foreach (long ageRatingId in game.AgeRatings)
|
|
||||||
{
|
|
||||||
AgeRating ageRating = Metadata.AgeRatings.GetAgeRating(metadataSource, ageRatingId);
|
|
||||||
if (ageRating.ContentDescriptions != null)
|
|
||||||
{
|
|
||||||
foreach (long ageRatingContentDescriptionId in ageRating.ContentDescriptions)
|
|
||||||
{
|
|
||||||
Metadata.AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(metadataSource, ageRatingContentDescriptionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.AlternativeNames != null)
|
|
||||||
{
|
|
||||||
foreach (long alternateNameId in game.AlternativeNames)
|
|
||||||
{
|
|
||||||
Metadata.AlternativeNames.GetAlternativeNames(metadataSource, alternateNameId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Artworks != null)
|
|
||||||
{
|
|
||||||
foreach (long artworkId in game.Artworks)
|
|
||||||
{
|
|
||||||
Metadata.Artworks.GetArtwork(metadataSource, artworkId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Cover != null)
|
|
||||||
{
|
|
||||||
Metadata.Covers.GetCover(metadataSource, (long?)game.Cover);
|
|
||||||
}
|
|
||||||
if (game.GameModes != null)
|
|
||||||
{
|
|
||||||
foreach (long gameModeId in game.GameModes)
|
|
||||||
{
|
|
||||||
Metadata.GameModes.GetGame_Modes(metadataSource, gameModeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Genres != null)
|
|
||||||
{
|
|
||||||
foreach (long genreId in game.Genres)
|
|
||||||
{
|
|
||||||
Metadata.Genres.GetGenres(metadataSource, genreId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Videos != null)
|
|
||||||
{
|
|
||||||
foreach (long gameVideoId in game.Videos)
|
|
||||||
{
|
|
||||||
Metadata.GamesVideos.GetGame_Videos(metadataSource, gameVideoId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.MultiplayerModes != null)
|
|
||||||
{
|
|
||||||
foreach (long multiplayerModeId in game.MultiplayerModes)
|
|
||||||
{
|
|
||||||
Metadata.MultiplayerModes.GetGame_MultiplayerModes(metadataSource, multiplayerModeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.PlayerPerspectives != null)
|
|
||||||
{
|
|
||||||
foreach (long playerPerspectiveId in game.PlayerPerspectives)
|
|
||||||
{
|
|
||||||
Metadata.PlayerPerspectives.GetGame_PlayerPerspectives(metadataSource, playerPerspectiveId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.ReleaseDates != null)
|
|
||||||
{
|
|
||||||
foreach (long releaseDateId in game.ReleaseDates)
|
|
||||||
{
|
|
||||||
Metadata.ReleaseDates.GetReleaseDates(metadataSource, releaseDateId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Screenshots != null)
|
|
||||||
{
|
|
||||||
foreach (long screenshotId in game.Screenshots)
|
|
||||||
{
|
|
||||||
Metadata.Screenshots.GetScreenshot(metadataSource, screenshotId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (game.Themes != null)
|
|
||||||
{
|
|
||||||
foreach (long themeId in game.Themes)
|
|
||||||
{
|
|
||||||
Metadata.Themes.GetGame_Themes(metadataSource, themeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -592,7 +69,7 @@ namespace gaseous_server.Classes
|
|||||||
StatusCounter += 1;
|
StatusCounter += 1;
|
||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ using System;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_signature_parser.models.RomSignatureObject;
|
using gaseous_signature_parser.models.RomSignatureObject;
|
||||||
using Microsoft.VisualBasic;
|
using Microsoft.VisualBasic;
|
||||||
|
using IGDB.Models;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
using SharpCompress.Common;
|
using SharpCompress.Common;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -193,7 +193,7 @@ namespace gaseous_server.Classes
|
|||||||
public static void DeleteMediaGroup(long Id)
|
public static void DeleteMediaGroup(long Id)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "DELETE FROM RomMediaGroup WHERE Id=@id; DELETE FROM GameState WHERE RomId=@id AND IsMediaGroup=1; DELETE FROM User_GameFavouriteRoms WHERE RomId = @id AND IsMediaGroup = 1; DELETE FROM User_RecentPlayedRoms WHERE RomId = @id AND IsMediaGroup = 1; UPDATE UserTimeTracking SET PlatformId = NULL, IsMediaGroup = NULL, RomId = NULL WHERE RomId=@id AND IsMediaGroup = 1;";
|
string sql = "DELETE FROM RomMediaGroup WHERE Id=@id; DELETE FROM GameState WHERE RomId=@id AND IsMediaGroup=1; UPDATE UserTimeTracking SET PlatformId = NULL, IsMediaGroup = NULL, RomId = NULL WHERE RomId=@id AND IsMediaGroup = 1;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", Id);
|
dbDict.Add("id", Id);
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -296,9 +296,8 @@ namespace gaseous_server.Classes
|
|||||||
GameRomMediaGroupItem mediaGroupItem = GetMediaGroup(Id);
|
GameRomMediaGroupItem mediaGroupItem = GetMediaGroup(Id);
|
||||||
if (mediaGroupItem.Status == GameRomMediaGroupItem.GroupBuildStatus.WaitingForBuild)
|
if (mediaGroupItem.Status == GameRomMediaGroupItem.GroupBuildStatus.WaitingForBuild)
|
||||||
{
|
{
|
||||||
MetadataMap.MetadataMapItem metadataMap = Classes.MetadataManagement.GetMetadataMap(mediaGroupItem.GameId).PreferredMetadataMapItem;
|
Game GameObject = Games.GetGame(mediaGroupItem.GameId, false, false, false);
|
||||||
Models.Game GameObject = Games.GetGame(metadataMap.SourceType, metadataMap.SourceId);
|
Platform PlatformObject = Platforms.GetPlatform(mediaGroupItem.PlatformId, false);
|
||||||
Platform PlatformObject = Platforms.GetPlatform(mediaGroupItem.PlatformId);
|
|
||||||
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(mediaGroupItem.PlatformId);
|
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(mediaGroupItem.PlatformId);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Media Group", "Beginning build of media group: " + GameObject.Name + " for platform " + PlatformObject.Name);
|
Logging.Log(Logging.LogType.Information, "Media Group", "Beginning build of media group: " + GameObject.Name + " for platform " + PlatformObject.Name);
|
||||||
@@ -558,7 +557,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Platforms.GetPlatform(PlatformId).Name;
|
return Platforms.GetPlatform(PlatformId, false).Name;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Data;
|
|||||||
using gaseous_signature_parser.models.RomSignatureObject;
|
using gaseous_signature_parser.models.RomSignatureObject;
|
||||||
using static gaseous_server.Classes.RomMediaGroup;
|
using static gaseous_server.Classes.RomMediaGroup;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using IGDB.Models;
|
||||||
using static HasheousClient.Models.FixMatchModel;
|
using static HasheousClient.Models.FixMatchModel;
|
||||||
using NuGet.Protocol.Core.Types;
|
using NuGet.Protocol.Core.Types;
|
||||||
using static gaseous_server.Classes.FileSignature;
|
using static gaseous_server.Classes.FileSignature;
|
||||||
@@ -38,7 +39,7 @@ namespace gaseous_server.Classes
|
|||||||
string NameSearchWhere = "";
|
string NameSearchWhere = "";
|
||||||
if (NameSearch.Length > 0)
|
if (NameSearch.Length > 0)
|
||||||
{
|
{
|
||||||
NameSearchWhere = " AND Games_Roms.`Name` LIKE @namesearch";
|
NameSearchWhere = " AND view_Games_Roms.`Name` LIKE @namesearch";
|
||||||
dbDict.Add("namesearch", '%' + NameSearch + '%');
|
dbDict.Add("namesearch", '%' + NameSearch + '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,72 +51,46 @@ namespace gaseous_server.Classes
|
|||||||
UserJoin = @"
|
UserJoin = @"
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
||||||
AND User_RecentPlayedRoms.GameId = Games_Roms.MetadataMapId
|
AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId
|
||||||
AND User_RecentPlayedRoms.PlatformId = Games_Roms.PlatformId
|
AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId
|
||||||
AND User_RecentPlayedRoms.RomId = Games_Roms.Id
|
AND User_RecentPlayedRoms.RomId = view_Games_Roms.Id
|
||||||
AND User_RecentPlayedRoms.IsMediaGroup = 0
|
AND User_RecentPlayedRoms.IsMediaGroup = 0
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
||||||
AND User_GameFavouriteRoms.GameId = Games_Roms.MetadataMapId
|
AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId
|
||||||
AND User_GameFavouriteRoms.PlatformId = Games_Roms.PlatformId
|
AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId
|
||||||
AND User_GameFavouriteRoms.RomId = Games_Roms.Id
|
AND User_GameFavouriteRoms.RomId = view_Games_Roms.Id
|
||||||
AND User_GameFavouriteRoms.IsMediaGroup = 0
|
AND User_GameFavouriteRoms.IsMediaGroup = 0
|
||||||
";
|
";
|
||||||
}
|
}
|
||||||
|
|
||||||
// platform query
|
// platform query
|
||||||
sqlPlatform = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
sqlPlatform = "SELECT DISTINCT view_Games_Roms.PlatformId, Platform.`Name` FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
||||||
|
|
||||||
if (PlatformId == -1)
|
if (PlatformId == -1)
|
||||||
{
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.MetadataMapId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name`;";
|
sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;";
|
||||||
|
|
||||||
// count query
|
// count query
|
||||||
sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.MetadataMapId = @id" + NameSearchWhere + ";";
|
sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + ";";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = @"
|
sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename, GameState.RomId AS SavedStateRomId" + UserFields + " FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id LEFT JOIN GameState ON (view_Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + " WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, view_Games_Roms.`Name` LIMIT 1000;";
|
||||||
SELECT DISTINCT
|
|
||||||
Games_Roms.*,
|
|
||||||
Platform.`Name` AS platformname,
|
|
||||||
view_GamesWithRoms.`Name` AS gamename,
|
|
||||||
GameState.RomId AS SavedStateRomId,
|
|
||||||
CONCAT(`GameLibraries`.`Path`,
|
|
||||||
'/',
|
|
||||||
`Games_Roms`.`RelativePath`) AS `Path`,
|
|
||||||
`GameLibraries`.`Name` AS `LibraryName`
|
|
||||||
" + UserFields + @"
|
|
||||||
FROM
|
|
||||||
Games_Roms
|
|
||||||
JOIN
|
|
||||||
GameLibraries ON Games_Roms.LibraryId = GameLibraries.Id
|
|
||||||
LEFT JOIN
|
|
||||||
Platform ON Games_Roms.PlatformId = Platform.Id AND Platform.SourceId = @platformsource
|
|
||||||
LEFT JOIN
|
|
||||||
view_GamesWithRoms ON view_GamesWithRoms.MetadataMapId = Games_Roms.MetadataMapId
|
|
||||||
LEFT JOIN
|
|
||||||
GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) " + UserJoin + @"
|
|
||||||
WHERE
|
|
||||||
Games_Roms.MetadataMapId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + @"
|
|
||||||
ORDER BY
|
|
||||||
Platform.`Name`, Games_Roms.`Name`;
|
|
||||||
";
|
|
||||||
|
|
||||||
// count query
|
// count query
|
||||||
sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.MetadataMapId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";";
|
sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";";
|
||||||
|
|
||||||
dbDict.Add("platformid", PlatformId);
|
dbDict.Add("platformid", PlatformId);
|
||||||
dbDict.Add("platformsource", (int)HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
}
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks));
|
DataTable romDT = db.ExecuteCMD(sql, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks));
|
||||||
|
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks))[0];
|
||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
// set count of roms
|
// set count of roms
|
||||||
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks))[0];
|
|
||||||
GameRoms.Count = int.Parse((string)rowCount["RomCount"]);
|
GameRoms.Count = int.Parse((string)rowCount["RomCount"]);
|
||||||
|
|
||||||
int pageOffset = pageSize * (pageNumber - 1);
|
int pageOffset = pageSize * (pageNumber - 1);
|
||||||
@@ -139,7 +114,7 @@ namespace gaseous_server.Classes
|
|||||||
public static GameRomItem GetRom(long RomId)
|
public static GameRomItem GetRom(long RomId)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, view_GamesWithRoms.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN view_GamesWithRoms ON view_Games_Roms.MetadataMapId = view_GamesWithRoms.MetadataMapId WHERE view_Games_Roms.Id = @id";
|
string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.Id = @id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -159,7 +134,7 @@ namespace gaseous_server.Classes
|
|||||||
public static GameRomItem GetRom(string MD5)
|
public static GameRomItem GetRom(string MD5)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT DISTINCT view_Games_Roms.*, Platform.`Name` AS platformname, view_GamesWithRoms.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN view_GamesWithRoms ON view_Games_Roms.MetadataMapId = view_GamesWithRoms.MetadataMapId WHERE view_Games_Roms.MD5 = @id";
|
string sql = "SELECT view_Games_Roms.*, Platform.`Name` AS platformname, Game.`Name` AS gamename FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id LEFT JOIN Game ON view_Games_Roms.GameId = Game.Id WHERE view_Games_Roms.MD5 = @id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", MD5);
|
dbDict.Add("id", MD5);
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -179,13 +154,13 @@ namespace gaseous_server.Classes
|
|||||||
public static GameRomItem UpdateRom(long RomId, long PlatformId, long GameId)
|
public static GameRomItem UpdateRom(long RomId, long PlatformId, long GameId)
|
||||||
{
|
{
|
||||||
// ensure metadata for platformid is present
|
// ensure metadata for platformid is present
|
||||||
HasheousClient.Models.Metadata.IGDB.Platform platform = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
IGDB.Models.Platform platform = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
|
|
||||||
// ensure metadata for gameid is present
|
// ensure metadata for gameid is present
|
||||||
Models.Game game = Classes.Metadata.Games.GetGame(HasheousClient.Models.MetadataSources.IGDB, GameId);
|
IGDB.Models.Game game = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "UPDATE Games_Roms SET PlatformId=@platformid, MetadataMapId=@gameid WHERE Id = @id";
|
string sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid WHERE Id = @id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
dbDict.Add("platformid", PlatformId);
|
dbDict.Add("platformid", PlatformId);
|
||||||
@@ -227,8 +202,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HasheousClient.WebApp.HttpHelper.APIKey = Config.MetadataConfiguration.HasheousAPIKey;
|
HasheousClient.WebApp.HttpHelper.AddHeader("X-API-Key", Config.MetadataConfiguration.HasheousAPIKey);
|
||||||
HasheousClient.WebApp.HttpHelper.ClientKey = Config.MetadataConfiguration.HasheousClientAPIKey;
|
|
||||||
HasheousClient.Hasheous hasheousClient = new HasheousClient.Hasheous();
|
HasheousClient.Hasheous hasheousClient = new HasheousClient.Hasheous();
|
||||||
List<MetadataMatch> metadataMatchList = new List<MetadataMatch>();
|
List<MetadataMatch> metadataMatchList = new List<MetadataMatch>();
|
||||||
metadataMatchList.Add(new MetadataMatch(HasheousClient.Models.MetadataSources.IGDB, platform.Slug, game.Slug));
|
metadataMatchList.Add(new MetadataMatch(HasheousClient.Models.MetadataSources.IGDB, platform.Slug, game.Slug));
|
||||||
@@ -256,7 +230,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "DELETE FROM Games_Roms WHERE Id = @id; DELETE FROM GameState WHERE RomId = @id; DELETE FROM User_GameFavouriteRoms WHERE RomId = @id AND IsMediaGroup = 0; DELETE FROM User_RecentPlayedRoms WHERE RomId = @id AND IsMediaGroup = 0; UPDATE UserTimeTracking SET PlatformId = NULL, IsMediaGroup = NULL, RomId = NULL WHERE RomId = @id AND IsMediaGroup = 0;";
|
string sql = "DELETE FROM Games_Roms WHERE Id = @id; DELETE FROM GameState WHERE RomId = @id; UPDATE UserTimeTracking SET PlatformId = NULL, IsMediaGroup = NULL, RomId = NULL WHERE RomId = @id AND IsMediaGroup = 0;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -295,10 +269,8 @@ namespace gaseous_server.Classes
|
|||||||
Id = (long)romDR["id"],
|
Id = (long)romDR["id"],
|
||||||
PlatformId = (long)romDR["platformid"],
|
PlatformId = (long)romDR["platformid"],
|
||||||
Platform = (string)romDR["platformname"],
|
Platform = (string)romDR["platformname"],
|
||||||
MetadataMapId = (long)romDR["metadatamapid"],
|
|
||||||
MetadataSource = (HasheousClient.Models.MetadataSources)(int)romDR["metadatasource"],
|
|
||||||
GameId = (long)romDR["gameid"],
|
GameId = (long)romDR["gameid"],
|
||||||
Game = (string)Common.ReturnValueIfNull(romDR["gamename"], ""),
|
Game = (string)romDR["gamename"],
|
||||||
Name = (string)romDR["name"],
|
Name = (string)romDR["name"],
|
||||||
Size = (long)romDR["size"],
|
Size = (long)romDR["size"],
|
||||||
Crc = ((string)romDR["crc"]).ToLower(),
|
Crc = ((string)romDR["crc"]).ToLower(),
|
||||||
@@ -348,8 +320,6 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
public long PlatformId { get; set; }
|
public long PlatformId { get; set; }
|
||||||
public string Platform { get; set; }
|
public string Platform { get; set; }
|
||||||
public long MetadataMapId { get; set; }
|
|
||||||
public HasheousClient.Models.MetadataSources MetadataSource { get; set; }
|
|
||||||
public long GameId { get; set; }
|
public long GameId { get; set; }
|
||||||
public string Game { get; set; }
|
public string Game { get; set; }
|
||||||
public string? Path { get; set; }
|
public string? Path { get; set; }
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using IGDB.Models;
|
||||||
using HasheousClient.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -61,20 +60,12 @@ namespace gaseous_server.Classes
|
|||||||
DataTable nowPlayingData = db.ExecuteCMD(sql, dbDict);
|
DataTable nowPlayingData = db.ExecuteCMD(sql, dbDict);
|
||||||
if (nowPlayingData.Rows.Count > 0)
|
if (nowPlayingData.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
try
|
NowPlaying = new Models.UserProfile.NowPlayingItem
|
||||||
{
|
{
|
||||||
gaseous_server.Models.MetadataMap.MetadataMapItem metadataMap = Classes.MetadataManagement.GetMetadataMap((long)nowPlayingData.Rows[0]["GameId"]).PreferredMetadataMapItem;
|
Game = Games.GetGame((long)nowPlayingData.Rows[0]["GameId"], false, false, false),
|
||||||
NowPlaying = new Models.UserProfile.NowPlayingItem
|
Platform = Platforms.GetPlatform((long)nowPlayingData.Rows[0]["PlatformId"], false, false),
|
||||||
{
|
Duration = Convert.ToInt64(nowPlayingData.Rows[0]["SessionLength"])
|
||||||
Game = Games.GetGame(metadataMap.SourceType, metadataMap.SourceId),
|
};
|
||||||
Platform = Platforms.GetPlatform((long)nowPlayingData.Rows[0]["PlatformId"]),
|
|
||||||
Duration = Convert.ToInt64(nowPlayingData.Rows[0]["SessionLength"])
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the user profile object
|
// return the user profile object
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ using Asp.Versioning;
|
|||||||
using Authentication;
|
using Authentication;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
|
using IGDB.Models;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
@@ -99,11 +99,7 @@ namespace gaseous_server.Controllers
|
|||||||
if (bios.hash == hash)
|
if (bios.hash == hash)
|
||||||
{
|
{
|
||||||
// add the bios file to the zip
|
// add the bios file to the zip
|
||||||
string biosFilePath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, hash + ".bios");
|
zipArchive.CreateEntryFromFile(Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, hash + ".bios"), bios.filename);
|
||||||
if (System.IO.File.Exists(biosFilePath))
|
|
||||||
{
|
|
||||||
zipArchive.CreateEntryFromFile(biosFilePath, bios.filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -8,12 +8,12 @@ using System.Threading.Tasks;
|
|||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.CodeAnalysis.Scripting;
|
using Microsoft.CodeAnalysis.Scripting;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
|
|
||||||
if (platformObject != null)
|
if (platformObject != null)
|
||||||
{
|
{
|
||||||
@@ -77,45 +77,43 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
// [MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
// [HttpGet]
|
[HttpGet]
|
||||||
// [Route("{PlatformId}/platformlogo")]
|
[Route("{PlatformId}/platformlogo")]
|
||||||
// [ProducesResponseType(typeof(PlatformLogo), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(PlatformLogo), StatusCodes.Status200OK)]
|
||||||
// [ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
// public ActionResult PlatformLogo(long PlatformId)
|
public ActionResult PlatformLogo(long PlatformId)
|
||||||
// {
|
{
|
||||||
// try
|
try
|
||||||
// {
|
{
|
||||||
// Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
// if (platformObject != null)
|
if (platformObject != null)
|
||||||
// {
|
{
|
||||||
// PlatformLogo logoObjectParent = (PlatformLogo)platformObject.PlatformLogo;
|
IGDB.Models.PlatformLogo logoObject = PlatformLogos.GetPlatformLogo(platformObject.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
||||||
// PlatformLogo logoObject = PlatformLogos.GetPlatformLogo(logoObjectParent.Id);
|
if (logoObject != null)
|
||||||
// if (logoObject != null)
|
{
|
||||||
// {
|
return Ok(logoObject);
|
||||||
// return Ok(logoObject);
|
}
|
||||||
// }
|
else
|
||||||
// else
|
{
|
||||||
// {
|
return NotFound();
|
||||||
// return NotFound();
|
}
|
||||||
// }
|
}
|
||||||
// }
|
else
|
||||||
// else
|
{
|
||||||
// {
|
return NotFound();
|
||||||
// return NotFound();
|
}
|
||||||
// }
|
}
|
||||||
// }
|
catch
|
||||||
// catch
|
{
|
||||||
// {
|
return NotFound();
|
||||||
// return NotFound();
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{PlatformId}/platformlogo/{size}/")]
|
|
||||||
[Route("{PlatformId}/platformlogo/{size}/logo.png")]
|
[Route("{PlatformId}/platformlogo/{size}/logo.png")]
|
||||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
@@ -123,41 +121,40 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HasheousClient.Models.MetadataSources metadataSources = HasheousClient.Models.MetadataSources.None;
|
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
|
IGDB.Models.PlatformLogo? logoObject = null;
|
||||||
Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId, metadataSources);
|
try
|
||||||
PlatformLogo? logoObject = null;
|
{
|
||||||
|
logoObject = PlatformLogos.GetPlatformLogo(platformObject.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
||||||
logoObject = PlatformLogos.GetPlatformLogo((long)platformObject.PlatformLogo, metadataSources);
|
}
|
||||||
|
catch
|
||||||
if (logoObject == null)
|
|
||||||
{
|
{
|
||||||
// getting the logo failed, so we'll try a platform variant if available
|
// getting the logo failed, so we'll try a platform variant if available
|
||||||
if (platformObject.Versions != null)
|
if (platformObject.Versions != null)
|
||||||
{
|
{
|
||||||
if (platformObject.Versions.Count > 0)
|
if (platformObject.Versions.Ids.Length > 0)
|
||||||
{
|
{
|
||||||
PlatformVersion platformVersion = Classes.Metadata.PlatformVersions.GetPlatformVersion(metadataSources, (long)platformObject.Versions[0]);
|
IGDB.Models.PlatformVersion platformVersion = Classes.Metadata.PlatformVersions.GetPlatformVersion(platformObject.Versions.Ids[0], platformObject);
|
||||||
logoObject = PlatformLogos.GetPlatformLogo((long)platformVersion.PlatformLogo);
|
logoObject = PlatformLogos.GetPlatformLogo(platformVersion.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return GetDummyImage();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return GetDummyImage();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject), metadataSources.ToString());
|
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
||||||
string imagePath = Path.Combine(basePath, size.ToString(), logoObject.ImageId);
|
string imagePath = Path.Combine(basePath, size.ToString(), logoObject.ImageId + ".jpg");
|
||||||
|
|
||||||
if (!System.IO.File.Exists(imagePath))
|
if (!System.IO.File.Exists(imagePath))
|
||||||
{
|
{
|
||||||
Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
Task<string> ImgFetch = comms.GetSpecificImageFromServer(metadataSources, Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject)), logoObject.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
Task<string> ImgFetch = comms.GetSpecificImageFromServer(Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject)), logoObject.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
||||||
|
|
||||||
imagePath = ImgFetch.Result;
|
imagePath = ImgFetch.Result;
|
||||||
}
|
}
|
||||||
@@ -165,78 +162,16 @@ namespace gaseous_server.Controllers
|
|||||||
if (!System.IO.File.Exists(imagePath))
|
if (!System.IO.File.Exists(imagePath))
|
||||||
{
|
{
|
||||||
Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
Task<string> ImgFetch = comms.GetSpecificImageFromServer(metadataSources, basePath, logoObject.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, logoObject.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
||||||
|
|
||||||
imagePath = ImgFetch.Result;
|
imagePath = ImgFetch.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.IO.File.Exists(imagePath))
|
if (System.IO.File.Exists(imagePath))
|
||||||
{
|
{
|
||||||
// get image info
|
string filename = logoObject.ImageId + ".jpg";
|
||||||
var info = new ImageMagick.MagickImageInfo(imagePath);
|
|
||||||
string extension = ".jpg";
|
|
||||||
string mimeType = "image/jpg";
|
|
||||||
switch (info.Format)
|
|
||||||
{
|
|
||||||
case ImageMagick.MagickFormat.Jpeg:
|
|
||||||
extension = ".jpg";
|
|
||||||
mimeType = "image/jpg";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Png:
|
|
||||||
extension = ".png";
|
|
||||||
mimeType = "image/png";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Gif:
|
|
||||||
extension = ".gif";
|
|
||||||
mimeType = "image/gif";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Bmp:
|
|
||||||
extension = ".bmp";
|
|
||||||
mimeType = "image/bmp";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Tiff:
|
|
||||||
extension = ".tiff";
|
|
||||||
mimeType = "image/tiff";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Unknown:
|
|
||||||
extension = ".jpg";
|
|
||||||
mimeType = "image/jpg";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.WebP:
|
|
||||||
extension = ".webp";
|
|
||||||
mimeType = "image/webp";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Heic:
|
|
||||||
extension = ".heic";
|
|
||||||
mimeType = "image/heic";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Heif:
|
|
||||||
extension = ".heif";
|
|
||||||
mimeType = "image/heif";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ImageMagick.MagickFormat.Svg:
|
|
||||||
extension = ".svg";
|
|
||||||
mimeType = "image/svg+xml";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
extension = ".jpg";
|
|
||||||
mimeType = "image/jpg";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
string filename = logoObject.ImageId + extension;
|
|
||||||
string filepath = imagePath;
|
string filepath = imagePath;
|
||||||
string contentType = mimeType;
|
string contentType = "image/jpg";
|
||||||
|
|
||||||
var cd = new System.Net.Mime.ContentDisposition
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
{
|
{
|
||||||
@@ -258,56 +193,10 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
return File(filedata, contentType);
|
return File(filedata, contentType);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
catch
|
||||||
|
|
||||||
private ActionResult GetDummyImage()
|
|
||||||
{
|
|
||||||
// return resource named DefaultPlatformLogo.svg
|
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
|
||||||
string resourceName = "gaseous_server.Support.DefaultPlatformLogo.svg";
|
|
||||||
string[] resources = Assembly.GetExecutingAssembly().GetManifestResourceNames();
|
|
||||||
if (resources.Contains(resourceName))
|
|
||||||
{
|
|
||||||
string svgData = "";
|
|
||||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
|
||||||
using (StreamReader reader = new StreamReader(stream))
|
|
||||||
{
|
|
||||||
svgData = reader.ReadToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
var cd = new System.Net.Mime.ContentDisposition
|
|
||||||
{
|
|
||||||
FileName = "DefaultPlatformLogo.svg",
|
|
||||||
Inline = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
|
||||||
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
|
||||||
|
|
||||||
byte[] filedata = null;
|
|
||||||
using (MemoryStream ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (StreamWriter writer = new StreamWriter(ms))
|
|
||||||
{
|
|
||||||
writer.Write(svgData);
|
|
||||||
writer.Flush();
|
|
||||||
ms.Position = 0;
|
|
||||||
filedata = ms.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return File(filedata, "image/svg+xml");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ using System.Reflection;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.CodeAnalysis.Scripting;
|
using Microsoft.CodeAnalysis.Scripting;
|
||||||
using static gaseous_server.Classes.Metadata.AgeRatings;
|
using static gaseous_server.Classes.Metadata.AgeRatings;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
@@ -62,7 +62,7 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get override platform if specified
|
// get override platform if specified
|
||||||
Platform? OverridePlatform = null;
|
IGDB.Models.Platform? OverridePlatform = null;
|
||||||
if (OverridePlatformId != null)
|
if (OverridePlatformId != null)
|
||||||
{
|
{
|
||||||
OverridePlatform = Platforms.GetPlatform((long)OverridePlatformId);
|
OverridePlatform = Platforms.GetPlatform((long)OverridePlatformId);
|
||||||
@@ -76,10 +76,10 @@ namespace gaseous_server.Controllers
|
|||||||
case "rom":
|
case "rom":
|
||||||
if (RetVal["status"] == "imported")
|
if (RetVal["status"] == "imported")
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Game? game = (gaseous_server.Models.Game)RetVal["game"];
|
IGDB.Models.Game? game = (IGDB.Models.Game)RetVal["game"];
|
||||||
if (game == null || game.Id == null)
|
if (game.Id == null)
|
||||||
{
|
{
|
||||||
RetVal["game"] = Games.GetGame(HasheousClient.Models.MetadataSources.IGDB, 0);
|
RetVal["game"] = Games.GetGame(0, false, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ using System.Threading.Tasks;
|
|||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
@@ -35,112 +36,92 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
private static async Task<List<Platform>> _SearchForPlatform(string SearchString)
|
private static async Task<List<Platform>> _SearchForPlatform(string SearchString)
|
||||||
{
|
{
|
||||||
// search the database for the requested platforms
|
string searchBody = "";
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
string searchFields = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; ";
|
||||||
string query = "SELECT `Id` FROM Platform WHERE `Name` LIKE '%" + SearchString + "%';";
|
searchBody += "where name ~ *\"" + SearchString + "\"*;";
|
||||||
DataTable data = db.ExecuteCMD(query);
|
|
||||||
|
|
||||||
List<Platform> platforms = new List<Platform>();
|
List<Platform>? searchCache = Communications.GetSearchCache<List<Platform>>(searchFields, searchBody);
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
|
if (searchCache == null)
|
||||||
{
|
{
|
||||||
Platform platform = Platforms.GetPlatform((long)row["Id"]);
|
// cache miss
|
||||||
|
// get Platform metadata from data source
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Platform>(IGDBClient.Endpoints.Platforms, searchFields, searchBody);
|
||||||
|
|
||||||
platforms.Add(platform);
|
Communications.SetSearchCache<List<Platform>>(searchFields, searchBody, results.ToList());
|
||||||
|
|
||||||
|
return results.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return searchCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
return platforms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Game")]
|
[Route("Game")]
|
||||||
[ProducesResponseType(typeof(List<gaseous_server.Models.Game>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(List<GaseousGame>), StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult> SearchGame(long PlatformId, string SearchString)
|
public async Task<ActionResult> SearchGame(long PlatformId, string SearchString)
|
||||||
{
|
{
|
||||||
List<gaseous_server.Models.Game> RetVal = await _SearchForGame(PlatformId, SearchString);
|
List<GaseousGame> RetVal = await _SearchForGame(PlatformId, SearchString);
|
||||||
return Ok(RetVal);
|
return Ok(RetVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<List<gaseous_server.Models.Game>> _SearchForGame(long PlatformId, string SearchString)
|
private static async Task<List<GaseousGame>> _SearchForGame(long PlatformId, string SearchString)
|
||||||
{
|
{
|
||||||
switch (Config.MetadataConfiguration.DefaultMetadataSource)
|
string searchBody = "";
|
||||||
|
string searchFields = "fields *; ";
|
||||||
|
searchBody += "search \"" + SearchString + "\";";
|
||||||
|
searchBody += "where platforms = (" + PlatformId + ");";
|
||||||
|
searchBody += "limit 100;";
|
||||||
|
|
||||||
|
List<GaseousGame>? searchCache = Communications.GetSearchCache<List<GaseousGame>>(searchFields, searchBody);
|
||||||
|
|
||||||
|
if (searchCache == null)
|
||||||
{
|
{
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
// cache miss
|
||||||
if (Config.IGDB.UseHasheousProxy == false)
|
// get Game metadata from data source
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, searchFields, searchBody);
|
||||||
|
|
||||||
|
List<GaseousGame> games = new List<GaseousGame>();
|
||||||
|
foreach (Game game in results.ToList())
|
||||||
|
{
|
||||||
|
Storage.CacheStatus cacheStatus = Storage.GetCacheStatus("Game", (long)game.Id);
|
||||||
|
switch (cacheStatus)
|
||||||
{
|
{
|
||||||
string searchBody = "";
|
case Storage.CacheStatus.NotPresent:
|
||||||
string searchFields = "fields *; ";
|
Storage.NewCacheValue(game, false);
|
||||||
searchBody += "search \"" + SearchString + "\";";
|
break;
|
||||||
searchBody += "where platforms = (" + PlatformId + ");";
|
|
||||||
searchBody += "limit 100;";
|
|
||||||
|
|
||||||
List<gaseous_server.Models.Game>? searchCache = Communications.GetSearchCache<List<gaseous_server.Models.Game>>(searchFields, searchBody);
|
case Storage.CacheStatus.Expired:
|
||||||
|
Storage.NewCacheValue(game, true);
|
||||||
|
break;
|
||||||
|
|
||||||
if (searchCache == null)
|
|
||||||
{
|
|
||||||
// cache miss
|
|
||||||
// get Game metadata from data source
|
|
||||||
Communications comms = new Communications();
|
|
||||||
var results = await comms.APIComm<gaseous_server.Models.Game>("Game", searchFields, searchBody);
|
|
||||||
|
|
||||||
List<gaseous_server.Models.Game> games = new List<gaseous_server.Models.Game>();
|
|
||||||
foreach (gaseous_server.Models.Game game in results.ToList())
|
|
||||||
{
|
|
||||||
Storage.CacheStatus cacheStatus = Storage.GetCacheStatus(HasheousClient.Models.MetadataSources.IGDB, "Game", (long)game.Id);
|
|
||||||
switch (cacheStatus)
|
|
||||||
{
|
|
||||||
case Storage.CacheStatus.NotPresent:
|
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.IGDB, game, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Storage.CacheStatus.Expired:
|
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.IGDB, game, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
games.Add(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
Communications.SetSearchCache<List<gaseous_server.Models.Game>>(searchFields, searchBody, games);
|
|
||||||
|
|
||||||
return games;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get full version of results from database
|
|
||||||
// this is a hacky workaround due to the readonly nature of IGDB.Model.Game IdentityOrValue fields
|
|
||||||
List<gaseous_server.Models.Game> gamesToReturn = new List<gaseous_server.Models.Game>();
|
|
||||||
foreach (gaseous_server.Models.Game game in searchCache)
|
|
||||||
{
|
|
||||||
gaseous_server.Models.Game? tempGame = Games.GetGame(Communications.MetadataSource, (long)game.Id);
|
|
||||||
if (tempGame != null)
|
|
||||||
{
|
|
||||||
gamesToReturn.Add(tempGame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gamesToReturn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
|
||||||
Communications.ConfigureHasheousClient(ref hasheous);
|
|
||||||
List<gaseous_server.Models.Game> hSearch = hasheous.GetMetadataProxy_SearchGame<gaseous_server.Models.Game>(HasheousClient.Hasheous.MetadataProvider.IGDB, PlatformId.ToString(), SearchString).ToList<gaseous_server.Models.Game>();
|
|
||||||
|
|
||||||
List<gaseous_server.Models.Game> hGamesToReturn = new List<gaseous_server.Models.Game>();
|
|
||||||
foreach (gaseous_server.Models.Game game in hSearch)
|
|
||||||
{
|
|
||||||
hGamesToReturn.Add(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
return hGamesToReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
games.Add(new GaseousGame(game));
|
||||||
return new List<gaseous_server.Models.Game>();
|
}
|
||||||
|
|
||||||
|
Communications.SetSearchCache<List<GaseousGame>>(searchFields, searchBody, games);
|
||||||
|
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get full version of results from database
|
||||||
|
// this is a hacky workaround due to the readonly nature of IGDB.Model.Game IdentityOrValue fields
|
||||||
|
List<GaseousGame> gamesToReturn = new List<GaseousGame>();
|
||||||
|
foreach (GaseousGame game in searchCache)
|
||||||
|
{
|
||||||
|
Game tempGame = Games.GetGame((long)game.Id, false, false, false);
|
||||||
|
gamesToReturn.Add(new GaseousGame(tempGame));
|
||||||
|
}
|
||||||
|
|
||||||
|
return gamesToReturn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,19 +51,7 @@ namespace gaseous_server.Controllers
|
|||||||
ReturnValue.DatabaseSize = (long)(System.Decimal)dbResponse.Rows[0][1];
|
ReturnValue.DatabaseSize = (long)(System.Decimal)dbResponse.Rows[0][1];
|
||||||
|
|
||||||
// platform statistics
|
// platform statistics
|
||||||
sql = @"
|
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 view_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 view_Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;";
|
||||||
SELECT
|
|
||||||
view_Games_Roms.PlatformId,
|
|
||||||
Platform.`Name`,
|
|
||||||
SUM(view_Games_Roms.Size) AS Size,
|
|
||||||
COUNT(view_Games_Roms.`Id`) AS Count
|
|
||||||
FROM
|
|
||||||
view_Games_Roms
|
|
||||||
LEFT JOIN
|
|
||||||
Platform ON view_Games_Roms.PlatformId = Platform.`Id`
|
|
||||||
AND Platform.SourceId = 0
|
|
||||||
GROUP BY Platform.`Name`
|
|
||||||
ORDER BY Platform.`Name`; ";
|
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
dbResponse = db.ExecuteCMD(sql);
|
||||||
ReturnValue.PlatformStatistics = new List<SystemInfo.PlatformStatisticsItem>();
|
ReturnValue.PlatformStatistics = new List<SystemInfo.PlatformStatisticsItem>();
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
@@ -84,51 +72,10 @@ ORDER BY Platform.`Name`; ";
|
|||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Version")]
|
[Route("Version")]
|
||||||
[ProducesResponseType(typeof(Dictionary<string, object>), StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[AllowAnonymous]
|
public Version GetSystemVersion()
|
||||||
public ActionResult GetSystemVersion()
|
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
return Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
|
|
||||||
// get age ratings dictionary
|
|
||||||
Dictionary<int, string> ClassificationBoardsStrings = new Dictionary<int, string>();
|
|
||||||
foreach (IGDB.Models.AgeRatingCategory ageRatingCategory in Enum.GetValues(typeof(IGDB.Models.AgeRatingCategory)))
|
|
||||||
{
|
|
||||||
ClassificationBoardsStrings.Add((int)ageRatingCategory, ageRatingCategory.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<int, string> AgeRatingsStrings = new Dictionary<int, string>();
|
|
||||||
foreach (IGDB.Models.AgeRatingTitle ageRatingTitle in Enum.GetValues(typeof(IGDB.Models.AgeRatingTitle)))
|
|
||||||
{
|
|
||||||
AgeRatingsStrings.Add((int)ageRatingTitle, ageRatingTitle.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<string, object> retVal = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{
|
|
||||||
"AppVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"DBSchemaVersion", db.GetDatabaseSchemaVersion().ToString()
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"FirstRunStatus", Config.ReadSetting<string>("FirstRunStatus", "0")
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"AgeRatingBoardsStrings", ClassificationBoardsStrings
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"AgeRatingStrings", AgeRatingsStrings
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"AgeRatingGroups", AgeGroups.AgeGroupingsFlat
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"emulatorDebugMode", Config.ReadSetting<string>("emulatorDebugMode", false.ToString()).ToLower()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return Ok(retVal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
@@ -323,11 +270,6 @@ ORDER BY Platform.`Name`; ";
|
|||||||
HasheousHost = Config.MetadataConfiguration.HasheousHost,
|
HasheousHost = Config.MetadataConfiguration.HasheousHost,
|
||||||
HasheousSubmitFixes = (bool)Config.MetadataConfiguration.HasheousSubmitFixes,
|
HasheousSubmitFixes = (bool)Config.MetadataConfiguration.HasheousSubmitFixes,
|
||||||
HasheousAPIKey = Config.MetadataConfiguration.HasheousAPIKey
|
HasheousAPIKey = Config.MetadataConfiguration.HasheousAPIKey
|
||||||
},
|
|
||||||
MetadataSources = new List<SystemSettingsModel.MetadataSourceItem>
|
|
||||||
{
|
|
||||||
new SystemSettingsModel.MetadataSourceItem(HasheousClient.Models.MetadataSources.None, false, "", "", Config.MetadataConfiguration.DefaultMetadataSource),
|
|
||||||
new SystemSettingsModel.MetadataSourceItem(HasheousClient.Models.MetadataSources.IGDB, Config.IGDB.UseHasheousProxy, Config.IGDB.ClientId, Config.IGDB.Secret, Config.MetadataConfiguration.DefaultMetadataSource)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -351,34 +293,6 @@ ORDER BY Platform.`Name`; ";
|
|||||||
Config.MetadataConfiguration.HasheousHost = model.SignatureSource.HasheousHost;
|
Config.MetadataConfiguration.HasheousHost = model.SignatureSource.HasheousHost;
|
||||||
Config.MetadataConfiguration.HasheousAPIKey = model.SignatureSource.HasheousAPIKey;
|
Config.MetadataConfiguration.HasheousAPIKey = model.SignatureSource.HasheousAPIKey;
|
||||||
Config.MetadataConfiguration.HasheousSubmitFixes = model.SignatureSource.HasheousSubmitFixes;
|
Config.MetadataConfiguration.HasheousSubmitFixes = model.SignatureSource.HasheousSubmitFixes;
|
||||||
foreach (SystemSettingsModel.MetadataSourceItem metadataSourceItem in model.MetadataSources)
|
|
||||||
{
|
|
||||||
// configure the default metadata source
|
|
||||||
if (metadataSourceItem.Default == true)
|
|
||||||
{
|
|
||||||
Config.MetadataConfiguration.DefaultMetadataSource = metadataSourceItem.Source;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Config.MetadataConfiguration.DefaultMetadataSource = HasheousClient.Models.MetadataSources.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure the metadata source
|
|
||||||
switch (metadataSourceItem.Source)
|
|
||||||
{
|
|
||||||
case HasheousClient.Models.MetadataSources.None:
|
|
||||||
break;
|
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
Config.IGDB.UseHasheousProxy = metadataSourceItem.UseHasheousProxy;
|
|
||||||
Config.IGDB.ClientId = metadataSourceItem.ClientId;
|
|
||||||
Config.IGDB.Secret = metadataSourceItem.Secret;
|
|
||||||
break;
|
|
||||||
case HasheousClient.Models.MetadataSources.TheGamesDb:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Config.UpdateConfig();
|
Config.UpdateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +439,8 @@ ORDER BY Platform.`Name`; ";
|
|||||||
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
ProcessQueue.QueueItemType.LibraryScan,
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
ProcessQueue.QueueItemType.LibraryScanWorker,
|
ProcessQueue.QueueItemType.LibraryScanWorker,
|
||||||
ProcessQueue.QueueItemType.TitleIngestor
|
ProcessQueue.QueueItemType.TitleIngestor,
|
||||||
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -547,7 +462,32 @@ ORDER BY Platform.`Name`; ";
|
|||||||
this.DefaultAllowedEndHours = 23;
|
this.DefaultAllowedEndHours = 23;
|
||||||
this.DefaultAllowedEndMinutes = 59;
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.Rematcher:
|
||||||
|
this._UserManageable = true;
|
||||||
|
this.DefaultInterval = 1440;
|
||||||
|
this.MinimumAllowedInterval = 360;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScanWorker
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -795,7 +735,6 @@ ORDER BY Platform.`Name`; ";
|
|||||||
public int MinimumLogRetentionPeriod { get; set; }
|
public int MinimumLogRetentionPeriod { get; set; }
|
||||||
public bool EmulatorDebugMode { get; set; }
|
public bool EmulatorDebugMode { get; set; }
|
||||||
public SignatureSourceItem SignatureSource { get; set; }
|
public SignatureSourceItem SignatureSource { get; set; }
|
||||||
public List<MetadataSourceItem> MetadataSources { get; set; }
|
|
||||||
|
|
||||||
public class SignatureSourceItem
|
public class SignatureSourceItem
|
||||||
{
|
{
|
||||||
@@ -804,100 +743,5 @@ ORDER BY Platform.`Name`; ";
|
|||||||
public string HasheousAPIKey { get; set; }
|
public string HasheousAPIKey { get; set; }
|
||||||
public bool HasheousSubmitFixes { get; set; }
|
public bool HasheousSubmitFixes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MetadataSourceItem
|
|
||||||
{
|
|
||||||
public MetadataSourceItem()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public MetadataSourceItem(HasheousClient.Models.MetadataSources source, bool useHasheousProxy, string clientId, string secret, HasheousClient.Models.MetadataSources defaultSource)
|
|
||||||
{
|
|
||||||
Source = source;
|
|
||||||
UseHasheousProxy = useHasheousProxy;
|
|
||||||
ClientId = clientId;
|
|
||||||
Secret = secret;
|
|
||||||
if (Source == defaultSource)
|
|
||||||
{
|
|
||||||
Default = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Default = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HasheousClient.Models.MetadataSources Source { get; set; }
|
|
||||||
public bool UseHasheousProxy { get; set; }
|
|
||||||
public string ClientId { get; set; }
|
|
||||||
public string Secret { get; set; }
|
|
||||||
public bool Default { get; set; }
|
|
||||||
public bool? Configured
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (Source)
|
|
||||||
{
|
|
||||||
case HasheousClient.Models.MetadataSources.None:
|
|
||||||
return true;
|
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case HasheousClient.Models.MetadataSources.TheGamesDb:
|
|
||||||
if ((!String.IsNullOrEmpty(ClientId) && !String.IsNullOrEmpty(Secret)) || UseHasheousProxy == true)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public bool? UsesProxy
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (Source)
|
|
||||||
{
|
|
||||||
case HasheousClient.Models.MetadataSources.None:
|
|
||||||
return false;
|
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
return true;
|
|
||||||
case HasheousClient.Models.MetadataSources.TheGamesDb:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public bool? UsesClientIdAndSecret
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (Source)
|
|
||||||
{
|
|
||||||
case HasheousClient.Models.MetadataSources.None:
|
|
||||||
return false;
|
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
return true;
|
|
||||||
case HasheousClient.Models.MetadataSources.TheGamesDb:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||||||
using Authentication;
|
using Authentication;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
@@ -18,8 +19,6 @@ using Microsoft.CodeAnalysis.Scripting;
|
|||||||
using static gaseous_server.Classes.Metadata.AgeRatings;
|
using static gaseous_server.Classes.Metadata.AgeRatings;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using Humanizer;
|
using Humanizer;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
using gaseous_server.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers.v1_1
|
namespace gaseous_server.Controllers.v1_1
|
||||||
{
|
{
|
||||||
@@ -43,7 +42,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> Game_v1_1(GameSearchModel model, int pageNumber = 0, int pageSize = 0, bool returnSummary = true, bool returnGames = true)
|
public async Task<IActionResult> Game_v1_1(GameSearchModel model, int pageNumber = 0, int pageSize = 0)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
@@ -88,7 +87,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
model.GameAgeRating.IncludeUnrated = false;
|
model.GameAgeRating.IncludeUnrated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(GetGames(model, user.Id, pageNumber, pageSize, returnSummary, returnGames));
|
return Ok(GetGames(model, user.Id, pageNumber, pageSize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -98,9 +97,9 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
|
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{MetadataMapId}/Related")]
|
[Route("{GameId}/Related")]
|
||||||
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> GameRelated(long MetadataMapId)
|
public async Task<IActionResult> GameRelated(long GameId)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
@@ -113,19 +112,18 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
}
|
}
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT view_Games.Id, view_Games.AgeGroupId, Relation_Game_SimilarGames.SimilarGamesId FROM view_Games JOIN Relation_Game_SimilarGames ON view_Games.Id = Relation_Game_SimilarGames.GameId AND view_Games.GameIdType = Relation_Game_SimilarGames.GameSourceId AND Relation_Game_SimilarGames.SimilarGamesId IN (SELECT Id FROM view_Games) WHERE view_Games.Id = @id AND (view_Games.AgeGroupId <= @agegroupid" + IncludeUnrated + ")";
|
string sql = "SELECT view_Games.Id, view_Games.AgeGroupId, Relation_Game_SimilarGames.SimilarGamesId FROM view_Games JOIN Relation_Game_SimilarGames ON view_Games.Id = Relation_Game_SimilarGames.GameId AND Relation_Game_SimilarGames.SimilarGamesId IN (SELECT Id FROM view_Games) WHERE view_Games.Id = @id AND (view_Games.AgeGroupId <= @agegroupid" + IncludeUnrated + ")";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", MetadataMapId);
|
dbDict.Add("id", GameId);
|
||||||
dbDict.Add("agegroupid", (int)user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction);
|
dbDict.Add("agegroupid", (int)user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction);
|
||||||
|
|
||||||
List<Models.Game> RetVal = new List<Models.Game>();
|
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
||||||
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
{
|
{
|
||||||
MetadataMap.MetadataMapItem metadataMap = Classes.MetadataManagement.GetMetadataMap(MetadataMapId).PreferredMetadataMapItem;
|
RetVal.Add(Classes.Metadata.Games.GetGame((long)dr["SimilarGamesId"], false, false, false));
|
||||||
RetVal.Add(Classes.Metadata.Games.GetGame(metadataMap.SourceType, (long)dr["SimilarGamesId"]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameReturnPackage gameReturn = new GameReturnPackage(RetVal.Count, RetVal);
|
GameReturnPackage gameReturn = new GameReturnPackage(RetVal.Count, RetVal);
|
||||||
@@ -190,7 +188,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameReturnPackage GetGames(GameSearchModel model, string userid, int pageNumber = 0, int pageSize = 0, bool returnSummary = true, bool returnGames = true)
|
public static GameReturnPackage GetGames(GameSearchModel model, string userid, int pageNumber = 0, int pageSize = 0)
|
||||||
{
|
{
|
||||||
string whereClause = "";
|
string whereClause = "";
|
||||||
string havingClause = "";
|
string havingClause = "";
|
||||||
@@ -485,8 +483,6 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
|
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
Game.Id,
|
Game.Id,
|
||||||
Game.MetadataMapId,
|
|
||||||
Game.GameIdType,
|
|
||||||
Game.`Name`,
|
Game.`Name`,
|
||||||
Game.NameThe,
|
Game.NameThe,
|
||||||
Game.Slug,
|
Game.Slug,
|
||||||
@@ -511,11 +507,15 @@ SELECT DISTINCT
|
|||||||
FROM
|
FROM
|
||||||
(SELECT DISTINCT
|
(SELECT DISTINCT
|
||||||
Game.*,
|
Game.*,
|
||||||
|
CASE
|
||||||
|
WHEN Game.`Name` LIKE 'The %' THEN CONCAT(TRIM(SUBSTR(Game.`Name` FROM 4)), ', The')
|
||||||
|
ELSE Game.`Name`
|
||||||
|
END AS NameThe,
|
||||||
view_Games_Roms.PlatformId,
|
view_Games_Roms.PlatformId,
|
||||||
AgeGroup.AgeGroupId,
|
AgeGroup.AgeGroupId,
|
||||||
COUNT(view_Games_Roms.Id) AS RomCount
|
COUNT(view_Games_Roms.Id) AS RomCount
|
||||||
FROM
|
FROM
|
||||||
view_GamesWithRoms AS Game
|
Game
|
||||||
LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId
|
LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId
|
||||||
LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId" + platformWhereClause + @"
|
LEFT JOIN view_Games_Roms ON Game.Id = view_Games_Roms.GameId" + platformWhereClause + @"
|
||||||
LEFT JOIN AlternativeName ON Game.Id = AlternativeName.Game " + nameWhereClause + @"
|
LEFT JOIN AlternativeName ON Game.Id = AlternativeName.Game " + nameWhereClause + @"
|
||||||
@@ -540,111 +540,97 @@ FROM
|
|||||||
JOIN GameState ON RomMediaGroup.Id = GameState.RomId
|
JOIN GameState ON RomMediaGroup.Id = GameState.RomId
|
||||||
AND GameState.IsMediaGroup = 1
|
AND GameState.IsMediaGroup = 1
|
||||||
AND GameState.UserId = @userid
|
AND GameState.UserId = @userid
|
||||||
GROUP BY RomMediaGroup.GameId) RomGroupSavedStates ON Game.MetadataMapId = RomGroupSavedStates.GameId
|
GROUP BY RomMediaGroup.GameId) RomGroupSavedStates ON Game.Id = RomGroupSavedStates.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId AND Relation_Game_Genres.GameSourceId = Game.GameIdType
|
Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId AND Relation_Game_GameModes.GameSourceId = Game.GameIdType
|
Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId AND Relation_Game_PlayerPerspectives.GameSourceId = Game.GameIdType
|
Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId AND Relation_Game_Themes.GameSourceId = Game.GameIdType
|
Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
Favourites ON Game.MetadataMapId = Favourites.GameId AND Favourites.UserId = @userid " + whereClause + " " + havingClause + " " + orderByClause;
|
Favourites ON Game.Id = Favourites.GameId AND Favourites.UserId = @userid " + whereClause + " " + havingClause + " " + orderByClause;
|
||||||
|
List<Games.MinimalGameItem> RetVal = new List<Games.MinimalGameItem>();
|
||||||
// if (returnGames == true)
|
|
||||||
// {
|
|
||||||
// sql += " LIMIT @pageOffset, @pageSize";
|
|
||||||
// whereParams.Add("pageOffset", pageSize * (pageNumber - 1));
|
|
||||||
// whereParams.Add("pageSize", pageSize);
|
|
||||||
// }
|
|
||||||
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, whereParams, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 60));
|
DataTable dbResponse = db.ExecuteCMD(sql, whereParams, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 60));
|
||||||
|
|
||||||
// get count
|
// get count
|
||||||
int? RecordCount = null;
|
int RecordCount = dbResponse.Rows.Count;
|
||||||
if (returnSummary == true)
|
|
||||||
{
|
|
||||||
RecordCount = dbResponse.Rows.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compile data for return
|
// compile data for return
|
||||||
List<Games.MinimalGameItem>? RetVal = null;
|
int pageOffset = pageSize * (pageNumber - 1);
|
||||||
if (returnGames == true)
|
for (int i = pageOffset; i < dbResponse.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
RetVal = new List<Games.MinimalGameItem>();
|
if (pageNumber != 0 && pageSize != 0)
|
||||||
foreach (int i in Enumerable.Range(0, dbResponse.Rows.Count))
|
|
||||||
{
|
{
|
||||||
Models.Game retGame = Storage.BuildCacheObject<Models.Game>(new Models.Game(), dbResponse.Rows[i]);
|
if (i >= (pageOffset + pageSize))
|
||||||
retGame.MetadataMapId = (long)dbResponse.Rows[i]["MetadataMapId"];
|
|
||||||
retGame.MetadataSource = (HasheousClient.Models.MetadataSources)dbResponse.Rows[i]["GameIdType"];
|
|
||||||
|
|
||||||
Games.MinimalGameItem retMinGame = new Games.MinimalGameItem(retGame);
|
|
||||||
retMinGame.Index = i;
|
|
||||||
if (dbResponse.Rows[i]["RomSaveCount"] != DBNull.Value || dbResponse.Rows[i]["MediaGroupSaveCount"] != DBNull.Value)
|
|
||||||
{
|
{
|
||||||
retMinGame.HasSavedGame = true;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
retMinGame.HasSavedGame = false;
|
|
||||||
}
|
|
||||||
if ((int)dbResponse.Rows[i]["Favourite"] == 0)
|
|
||||||
{
|
|
||||||
retMinGame.IsFavourite = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
retMinGame.IsFavourite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
RetVal.Add(retMinGame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Game retGame = Storage.BuildCacheObject<Game>(new Game(), dbResponse.Rows[i]);
|
||||||
|
Games.MinimalGameItem retMinGame = new Games.MinimalGameItem(retGame);
|
||||||
|
retMinGame.Index = i;
|
||||||
|
if (dbResponse.Rows[i]["RomSaveCount"] != DBNull.Value || dbResponse.Rows[i]["MediaGroupSaveCount"] != DBNull.Value)
|
||||||
|
{
|
||||||
|
retMinGame.HasSavedGame = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retMinGame.HasSavedGame = false;
|
||||||
|
}
|
||||||
|
if ((int)dbResponse.Rows[i]["Favourite"] == 0)
|
||||||
|
{
|
||||||
|
retMinGame.IsFavourite = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retMinGame.IsFavourite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RetVal.Add(retMinGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, int>? AlphaList = null;
|
// build alpha list
|
||||||
if (returnSummary == true)
|
Dictionary<string, int> AlphaList = new Dictionary<string, int>();
|
||||||
|
if (orderByField == "NameThe" || orderByField == "Name")
|
||||||
{
|
{
|
||||||
AlphaList = new Dictionary<string, int>();
|
int CurrentPage = 1;
|
||||||
|
int NextPageIndex = pageSize;
|
||||||
|
|
||||||
// build alpha list
|
string alphaSearchField;
|
||||||
if (orderByField == "NameThe" || orderByField == "Name")
|
if (orderByField == "NameThe")
|
||||||
{
|
{
|
||||||
int CurrentPage = 1;
|
alphaSearchField = "NameThe";
|
||||||
int NextPageIndex = pageSize;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alphaSearchField = "Name";
|
||||||
|
}
|
||||||
|
|
||||||
string alphaSearchField;
|
for (int i = 0; i < dbResponse.Rows.Count; i++)
|
||||||
if (orderByField == "NameThe")
|
{
|
||||||
|
if (NextPageIndex == i + 1)
|
||||||
{
|
{
|
||||||
alphaSearchField = "NameThe";
|
NextPageIndex += pageSize;
|
||||||
|
CurrentPage += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
string firstChar = dbResponse.Rows[i][alphaSearchField].ToString().Substring(0, 1).ToUpperInvariant();
|
||||||
|
if ("ABCDEFGHIJKLMNOPQRSTUVWXYZ".Contains(firstChar))
|
||||||
|
{
|
||||||
|
if (!AlphaList.ContainsKey(firstChar))
|
||||||
|
{
|
||||||
|
AlphaList.Add(firstChar, CurrentPage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alphaSearchField = "Name";
|
if (!AlphaList.ContainsKey("#"))
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < dbResponse.Rows.Count; i++)
|
|
||||||
{
|
|
||||||
if (NextPageIndex == i + 1)
|
|
||||||
{
|
{
|
||||||
NextPageIndex += pageSize;
|
AlphaList.Add("#", 1);
|
||||||
CurrentPage += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
string firstChar = dbResponse.Rows[i][alphaSearchField].ToString().Substring(0, 1).ToUpperInvariant();
|
|
||||||
if ("ABCDEFGHIJKLMNOPQRSTUVWXYZ".Contains(firstChar))
|
|
||||||
{
|
|
||||||
if (!AlphaList.ContainsKey(firstChar))
|
|
||||||
{
|
|
||||||
AlphaList.Add(firstChar, CurrentPage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!AlphaList.ContainsKey("#"))
|
|
||||||
{
|
|
||||||
AlphaList.Add("#", 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -667,12 +653,12 @@ FROM
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameReturnPackage(int Count, List<Models.Game> Games)
|
public GameReturnPackage(int Count, List<Game> Games)
|
||||||
{
|
{
|
||||||
this.Count = Count;
|
this.Count = Count;
|
||||||
|
|
||||||
List<Games.MinimalGameItem> minimalGames = new List<Games.MinimalGameItem>();
|
List<Games.MinimalGameItem> minimalGames = new List<Games.MinimalGameItem>();
|
||||||
foreach (Models.Game game in Games)
|
foreach (Game game in Games)
|
||||||
{
|
{
|
||||||
minimalGames.Add(new Classes.Metadata.Games.MinimalGameItem(game));
|
minimalGames.Add(new Classes.Metadata.Games.MinimalGameItem(game));
|
||||||
}
|
}
|
||||||
@@ -680,9 +666,9 @@ FROM
|
|||||||
this.Games = minimalGames;
|
this.Games = minimalGames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Count { get; set; }
|
public int Count { get; set; }
|
||||||
public List<Games.MinimalGameItem>? Games { get; set; } = new List<Games.MinimalGameItem>();
|
public List<Games.MinimalGameItem> Games { get; set; } = new List<Games.MinimalGameItem>();
|
||||||
public Dictionary<string, int>? AlphaList { get; set; }
|
public Dictionary<string, int> AlphaList { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
RomMediaGroup.GameRomMediaGroupItem mediaGroupItem = RomMediaGroup.GetMediaGroup(RomId);
|
RomMediaGroup.GameRomMediaGroupItem mediaGroupItem = RomMediaGroup.GetMediaGroup(RomId);
|
||||||
Models.Game game = Games.GetGame(Communications.MetadataSource, mediaGroupItem.GameId);
|
IGDB.Models.Game game = Games.GetGame(mediaGroupItem.GameId, false, false, false);
|
||||||
Classes.Common.hashObject hashObject = new Classes.Common.hashObject(Path.Combine(Config.LibraryConfiguration.LibraryMediaGroupDirectory, mediaGroupItem.Id.ToString() + ".zip"));
|
Classes.Common.hashObject hashObject = new Classes.Common.hashObject(Path.Combine(Config.LibraryConfiguration.LibraryMediaGroupDirectory, mediaGroupItem.Id.ToString() + ".zip"));
|
||||||
romName = game.Name;
|
romName = game.Name;
|
||||||
romMd5 = hashObject.md5hash;
|
romMd5 = hashObject.md5hash;
|
||||||
|
|||||||
@@ -5,22 +5,50 @@ using Swashbuckle.AspNetCore.SwaggerGen;
|
|||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
{
|
{
|
||||||
public class Game : HasheousClient.Models.Metadata.IGDB.Game
|
public class GaseousGame : IGDB.Models.Game
|
||||||
{
|
{
|
||||||
[NoDatabase]
|
public GaseousGame()
|
||||||
public bool IsFavourite { get; set; } = false;
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public GaseousGame(IGDB.Models.Game game)
|
||||||
|
{
|
||||||
|
var targetType = this.GetType();
|
||||||
|
var sourceType = game.GetType();
|
||||||
|
foreach (var prop in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty))
|
||||||
|
{
|
||||||
|
// check whether source object has the the property
|
||||||
|
var sp = sourceType.GetProperty(prop.Name);
|
||||||
|
if (sp != null)
|
||||||
|
{
|
||||||
|
// if yes, copy the value to the matching property
|
||||||
|
var value = sp.GetValue(game, null);
|
||||||
|
prop.SetValue(this, value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NoDatabase]
|
|
||||||
public bool HasSavedGame { get; set; } = false;
|
public bool HasSavedGame { get; set; } = false;
|
||||||
|
|
||||||
[NoDatabase]
|
public IGDB.Models.Cover? CoverItem
|
||||||
public long MetadataMapId { get; set; }
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.Cover != null)
|
||||||
|
{
|
||||||
|
if (this.Cover.Id != null)
|
||||||
|
{
|
||||||
|
// IGDB.Models.Cover cover = Covers.GetCover(Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false);
|
||||||
|
IGDB.Models.Cover cover = new IGDB.Models.Cover()
|
||||||
|
{
|
||||||
|
Id = this.Cover.Id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[NoDatabase]
|
return null;
|
||||||
public HasheousClient.Models.MetadataSources MetadataSource { get; set; }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class NoDatabaseAttribute : Attribute
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using HasheousClient.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Models
|
|
||||||
{
|
|
||||||
public class MetadataMap
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public long PlatformId { get; set; }
|
|
||||||
public string SignatureGameName { get; set; }
|
|
||||||
public List<MetadataMapItem> MetadataMapItems { get; set; }
|
|
||||||
public MetadataMapItem? PreferredMetadataMapItem
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (MetadataMapItems == null || MetadataMapItems.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return MetadataMapItems.FirstOrDefault(mmi => mmi.Preferred);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MetadataMapItem
|
|
||||||
{
|
|
||||||
public HasheousClient.Models.MetadataSources SourceType { get; set; }
|
|
||||||
public long SourceId { get; set; }
|
|
||||||
public bool Preferred { get; set; }
|
|
||||||
public string SourceSlug
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string slug = "";
|
|
||||||
switch (SourceType)
|
|
||||||
{
|
|
||||||
case MetadataSources.IGDB:
|
|
||||||
Game game = Games.GetGame(SourceType, (long)SourceId);
|
|
||||||
if (game != null)
|
|
||||||
{
|
|
||||||
slug = game.Slug;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
slug = SourceId.ToString();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return slug;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string link
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
string link = "";
|
|
||||||
switch (SourceType)
|
|
||||||
{
|
|
||||||
case MetadataSources.IGDB:
|
|
||||||
link = $"https://www.igdb.com/games/{SourceSlug}";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MetadataSources.TheGamesDb:
|
|
||||||
link = $"https://thegamesdb.net/game.php?id={SourceId}";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
link = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ using System.Web;
|
|||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Controllers;
|
using gaseous_server.Controllers;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using IGDB.Models;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
@@ -46,7 +46,7 @@ namespace gaseous_server.Models
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WritePlatformMap(mapItem, true, true, true);
|
WritePlatformMap(mapItem, true, true);
|
||||||
Logging.Log(Logging.LogType.Information, "Platform Map", "Overwriting " + mapItem.IGDBName + " with default values.");
|
Logging.Log(Logging.LogType.Information, "Platform Map", "Overwriting " + mapItem.IGDBName + " with default values.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + mapItem.IGDBName + " from predefined data.");
|
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + mapItem.IGDBName + " from predefined data.");
|
||||||
// doesn't exist - add it
|
// doesn't exist - add it
|
||||||
WritePlatformMap(mapItem, false, true, true);
|
WritePlatformMap(mapItem, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,9 +92,9 @@ namespace gaseous_server.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Platform CreateDummyPlatform(PlatformMapItem mapItem)
|
private static IGDB.Models.Platform CreateDummyPlatform(PlatformMapItem mapItem)
|
||||||
{
|
{
|
||||||
Platform platform = new Platform
|
IGDB.Models.Platform platform = new IGDB.Models.Platform
|
||||||
{
|
{
|
||||||
Id = mapItem.IGDBId,
|
Id = mapItem.IGDBId,
|
||||||
Name = mapItem.IGDBName,
|
Name = mapItem.IGDBName,
|
||||||
@@ -102,14 +102,9 @@ namespace gaseous_server.Models
|
|||||||
AlternativeName = mapItem.AlternateNames.FirstOrDefault()
|
AlternativeName = mapItem.AlternateNames.FirstOrDefault()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Storage.GetCacheStatus(HasheousClient.Models.MetadataSources.None, "Platform", mapItem.IGDBId) == Storage.CacheStatus.NotPresent)
|
if (Storage.GetCacheStatus("Platform", mapItem.IGDBId) == Storage.CacheStatus.NotPresent)
|
||||||
{
|
{
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.None, platform);
|
Storage.NewCacheValue(platform);
|
||||||
}
|
|
||||||
|
|
||||||
if (Storage.GetCacheStatus(HasheousClient.Models.MetadataSources.IGDB, "Platform", mapItem.IGDBId) == Storage.CacheStatus.NotPresent)
|
|
||||||
{
|
|
||||||
Storage.NewCacheValue(HasheousClient.Models.MetadataSources.IGDB, platform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return platform;
|
return platform;
|
||||||
@@ -169,7 +164,7 @@ namespace gaseous_server.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WritePlatformMap(PlatformMapItem item, bool Update, bool AllowAvailableEmulatorOverwrite, bool overwriteBios = false)
|
public static void WritePlatformMap(PlatformMapItem item, bool Update, bool AllowAvailableEmulatorOverwrite)
|
||||||
{
|
{
|
||||||
CreateDummyPlatform(item);
|
CreateDummyPlatform(item);
|
||||||
|
|
||||||
@@ -252,21 +247,14 @@ namespace gaseous_server.Models
|
|||||||
foreach (PlatformMapItem.EmulatorBiosItem biosItem in item.Bios)
|
foreach (PlatformMapItem.EmulatorBiosItem biosItem in item.Bios)
|
||||||
{
|
{
|
||||||
bool isEnabled = false;
|
bool isEnabled = false;
|
||||||
if (overwriteBios == true)
|
if (item.EnabledBIOSHashes == null)
|
||||||
|
{
|
||||||
|
item.EnabledBIOSHashes = new List<string>();
|
||||||
|
}
|
||||||
|
if (item.EnabledBIOSHashes.Contains(biosItem.hash))
|
||||||
{
|
{
|
||||||
isEnabled = true;
|
isEnabled = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (item.EnabledBIOSHashes == null)
|
|
||||||
{
|
|
||||||
item.EnabledBIOSHashes = new List<string>();
|
|
||||||
}
|
|
||||||
if (item.EnabledBIOSHashes.Contains(biosItem.hash))
|
|
||||||
{
|
|
||||||
isEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = "INSERT INTO PlatformMap_Bios (Id, Filename, Description, Hash, Enabled) VALUES (@Id, @Filename, @Description, @Hash, @Enabled);";
|
sql = "INSERT INTO PlatformMap_Bios (Id, Filename, Description, Hash, Enabled) VALUES (@Id, @Filename, @Description, @Hash, @Enabled);";
|
||||||
dbDict.Clear();
|
dbDict.Clear();
|
||||||
@@ -315,15 +303,15 @@ namespace gaseous_server.Models
|
|||||||
string sql = "";
|
string sql = "";
|
||||||
|
|
||||||
// get platform data
|
// get platform data
|
||||||
Platform? platform = null;
|
// IGDB.Models.Platform? platform = Platforms.GetPlatform(IGDBId, false);
|
||||||
if (Storage.GetCacheStatus(HasheousClient.Models.MetadataSources.None, "Platform", IGDBId) == Storage.CacheStatus.NotPresent)
|
IGDB.Models.Platform? platform = null;
|
||||||
|
if (Storage.GetCacheStatus("Platform", IGDBId) == Storage.CacheStatus.NotPresent)
|
||||||
{
|
{
|
||||||
//platform = Platforms.GetPlatform(IGDBId, false);
|
//platform = Platforms.GetPlatform(IGDBId, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// platform = (Platform)Storage.GetCacheValue<Platform>(HasheousClient.Models.MetadataSources.None, new Platform(), "id", IGDBId);
|
platform = (IGDB.Models.Platform)Storage.GetCacheValue<IGDB.Models.Platform>(new Platform(), "id", IGDBId);
|
||||||
platform = Platforms.GetPlatform(IGDBId, HasheousClient.Models.MetadataSources.None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (platform != null)
|
if (platform != null)
|
||||||
@@ -452,8 +440,8 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
|
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
|
||||||
}
|
}
|
||||||
Signature.Flags.PlatformId = PlatformMapping.IGDBId;
|
Signature.Flags.IGDBPlatformId = PlatformMapping.IGDBId;
|
||||||
Signature.Flags.PlatformName = PlatformMapping.IGDBName;
|
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName;
|
||||||
|
|
||||||
PlatformFound = true;
|
PlatformFound = true;
|
||||||
|
|
||||||
@@ -476,8 +464,8 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
|
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
|
||||||
}
|
}
|
||||||
Signature.Flags.PlatformId = PlatformMapping.IGDBId;
|
Signature.Flags.IGDBPlatformId = PlatformMapping.IGDBId;
|
||||||
Signature.Flags.PlatformName = PlatformMapping.IGDBName;
|
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName;
|
||||||
|
|
||||||
PlatformFound = true;
|
PlatformFound = true;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using gaseous_server.Classes;
|
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using gaseous_signature_parser.models.RomSignatureObject;
|
using gaseous_signature_parser.models.RomSignatureObject;
|
||||||
using HasheousClient.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
{
|
{
|
||||||
public class Signatures_Games : HasheousClient.Models.SignatureModel
|
public class Signatures_Games : HasheousClient.Models.SignatureModel
|
||||||
{
|
{
|
||||||
public Signatures_Games()
|
public Signatures_Games()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int Score
|
public int Score
|
||||||
@@ -37,119 +34,13 @@ namespace gaseous_server.Models
|
|||||||
public GameItem Game = new GameItem();
|
public GameItem Game = new GameItem();
|
||||||
public RomItem Rom = new RomItem();
|
public RomItem Rom = new RomItem();
|
||||||
|
|
||||||
public SignatureFlags Flags
|
public SignatureFlags Flags = new SignatureFlags();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SignatureFlags _flags = new SignatureFlags();
|
|
||||||
|
|
||||||
foreach (SourceValues.SourceValueItem source in MetadataSources.Platforms)
|
|
||||||
{
|
|
||||||
if (source.Source == Config.MetadataConfiguration.DefaultMetadataSource)
|
|
||||||
{
|
|
||||||
_flags.PlatformId = source.Id;
|
|
||||||
_flags.PlatformName = source.Name;
|
|
||||||
_flags.PlatformMetadataSource = source.Source;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_flags.PlatformId == 0)
|
|
||||||
{
|
|
||||||
// fall back to the IGDB source if present
|
|
||||||
foreach (SourceValues.SourceValueItem source in MetadataSources.Platforms)
|
|
||||||
{
|
|
||||||
if (source.Source == HasheousClient.Models.MetadataSources.IGDB)
|
|
||||||
{
|
|
||||||
_flags.PlatformId = source.Id;
|
|
||||||
_flags.PlatformName = source.Name;
|
|
||||||
_flags.PlatformMetadataSource = source.Source;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (SourceValues.SourceValueItem source in MetadataSources.Games)
|
|
||||||
{
|
|
||||||
if (source.Source == Config.MetadataConfiguration.DefaultMetadataSource)
|
|
||||||
{
|
|
||||||
_flags.GameId = source.Id;
|
|
||||||
_flags.GameName = source.Name;
|
|
||||||
_flags.GameMetadataSource = source.Source;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_flags.GameId == null || _flags.GameId == 0)
|
|
||||||
{
|
|
||||||
_flags.GameId = 0;
|
|
||||||
_flags.GameName = "Unknown Game";
|
|
||||||
_flags.GameMetadataSource = HasheousClient.Models.MetadataSources.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _flags;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceValues MetadataSources = new SourceValues();
|
|
||||||
|
|
||||||
public class SourceValues
|
|
||||||
{
|
|
||||||
public List<SourceValueItem> Platforms = new List<SourceValueItem>();
|
|
||||||
public List<SourceValueItem> Games = new List<SourceValueItem>();
|
|
||||||
|
|
||||||
public class SourceValueItem
|
|
||||||
{
|
|
||||||
public long Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
public HasheousClient.Models.MetadataSources Source { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddPlatform(long Id, string Name, HasheousClient.Models.MetadataSources Source)
|
|
||||||
{
|
|
||||||
// check that the platform doesn't already exist
|
|
||||||
foreach (SourceValueItem item in Platforms)
|
|
||||||
{
|
|
||||||
if (item.Id == Id)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceValueItem newItem = new SourceValueItem();
|
|
||||||
newItem.Id = Id;
|
|
||||||
newItem.Name = Name;
|
|
||||||
newItem.Source = Source;
|
|
||||||
Platforms.Add(newItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddGame(long Id, string Name, HasheousClient.Models.MetadataSources Source)
|
|
||||||
{
|
|
||||||
// check that the game doesn't already exist
|
|
||||||
foreach (SourceValueItem item in Games)
|
|
||||||
{
|
|
||||||
if (item.Id == Id)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceValueItem newItem = new SourceValueItem();
|
|
||||||
newItem.Id = Id;
|
|
||||||
newItem.Name = Name;
|
|
||||||
newItem.Source = Source;
|
|
||||||
Games.Add(newItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SignatureFlags
|
public class SignatureFlags
|
||||||
{
|
{
|
||||||
public long PlatformId { get; set; }
|
public long IGDBPlatformId { get; set; }
|
||||||
public string PlatformName { get; set; }
|
public string IGDBPlatformName { get; set; }
|
||||||
public long GameId { get; set; }
|
public long IGDBGameId { get; set; }
|
||||||
public string GameName { get; set; }
|
|
||||||
public HasheousClient.Models.MetadataSources PlatformMetadataSource { get; set; }
|
|
||||||
public HasheousClient.Models.MetadataSources GameMetadataSource { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameItem : HasheousClient.Models.SignatureModel.GameItem
|
public class GameItem : HasheousClient.Models.SignatureModel.GameItem
|
||||||
@@ -159,8 +50,6 @@ namespace gaseous_server.Models
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string UserManual { get; set; }
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int Score
|
public int Score
|
||||||
{
|
{
|
||||||
@@ -322,8 +211,7 @@ namespace gaseous_server.Models
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
switch (inType.ToLower())
|
switch (inType.ToLower())
|
||||||
{
|
{
|
||||||
case "disk":
|
case "disk":
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
{
|
{
|
||||||
public class UserProfile
|
public class UserProfile
|
||||||
@@ -9,7 +11,7 @@ namespace gaseous_server.Models
|
|||||||
public class NowPlayingItem
|
public class NowPlayingItem
|
||||||
{
|
{
|
||||||
public Game Game { get; set; }
|
public Game Game { get; set; }
|
||||||
public HasheousClient.Models.Metadata.IGDB.Platform Platform { get; set; }
|
public Platform Platform { get; set; }
|
||||||
public long Duration { get; set; }
|
public long Duration { get; set; }
|
||||||
}
|
}
|
||||||
public ProfileImageItem? Avatar { get; set; }
|
public ProfileImageItem? Avatar { get; set; }
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ using NuGet.Packaging;
|
|||||||
|
|
||||||
namespace gaseous_server
|
namespace gaseous_server
|
||||||
{
|
{
|
||||||
public static class ProcessQueue
|
public static class ProcessQueue
|
||||||
{
|
{
|
||||||
public static List<QueueItem> QueueItems = new List<QueueItem>();
|
public static List<QueueItem> QueueItems = new List<QueueItem>();
|
||||||
|
|
||||||
public class QueueItem
|
public class QueueItem
|
||||||
@@ -338,6 +338,18 @@ namespace gaseous_server
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QueueItemType.Rematcher:
|
||||||
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Rematch");
|
||||||
|
Classes.ImportGame importRematch = new ImportGame
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
importRematch.Rematcher(_ForceExecute);
|
||||||
|
|
||||||
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case QueueItemType.CollectionCompiler:
|
case QueueItemType.CollectionCompiler:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Collection Compiler");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Collection Compiler");
|
||||||
Dictionary<string, object> collectionOptions = (Dictionary<string, object>)Options;
|
Dictionary<string, object> collectionOptions = (Dictionary<string, object>)Options;
|
||||||
@@ -356,8 +368,7 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.DailyMaintainer:
|
case QueueItemType.DailyMaintainer:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Daily Maintenance");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Daily Maintenance");
|
||||||
Classes.Maintenance maintenance = new Maintenance
|
Classes.Maintenance maintenance = new Maintenance{
|
||||||
{
|
|
||||||
CallingQueueItem = this
|
CallingQueueItem = this
|
||||||
};
|
};
|
||||||
maintenance.RunDailyMaintenance();
|
maintenance.RunDailyMaintenance();
|
||||||
@@ -368,8 +379,7 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.WeeklyMaintainer:
|
case QueueItemType.WeeklyMaintainer:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Weekly Maintenance");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Weekly Maintenance");
|
||||||
Classes.Maintenance weeklyMaintenance = new Maintenance
|
Classes.Maintenance weeklyMaintenance = new Maintenance{
|
||||||
{
|
|
||||||
CallingQueueItem = this
|
CallingQueueItem = this
|
||||||
};
|
};
|
||||||
weeklyMaintenance.RunWeeklyMaintenance();
|
weeklyMaintenance.RunWeeklyMaintenance();
|
||||||
@@ -562,6 +572,11 @@ namespace gaseous_server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
LibraryScanWorker,
|
LibraryScanWorker,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks for roms in the library that have an unknown platform or game match
|
||||||
|
/// </summary>
|
||||||
|
Rematcher,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds collections - set the options attribute to the id of the collection to build
|
/// Builds collections - set the options attribute to the id of the collection to build
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using Authentication;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
|
||||||
|
|
||||||
Logging.WriteToDiskOnly = true;
|
Logging.WriteToDiskOnly = true;
|
||||||
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server " + Assembly.GetExecutingAssembly().GetName().Version);
|
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server " + Assembly.GetExecutingAssembly().GetName().Version);
|
||||||
@@ -53,7 +52,7 @@ Config.UpdateConfig();
|
|||||||
GameLibrary.UpdateDefaultLibraryPath();
|
GameLibrary.UpdateDefaultLibraryPath();
|
||||||
|
|
||||||
// set api metadata source from config
|
// set api metadata source from config
|
||||||
Communications.MetadataSource = Config.MetadataConfiguration.DefaultMetadataSource;
|
Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource;
|
||||||
|
|
||||||
// set up hasheous client
|
// set up hasheous client
|
||||||
HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost;
|
HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost;
|
||||||
@@ -330,10 +329,11 @@ app.Use(async (context, next) =>
|
|||||||
// setup library directories
|
// setup library directories
|
||||||
Config.LibraryConfiguration.InitLibrary();
|
Config.LibraryConfiguration.InitLibrary();
|
||||||
|
|
||||||
// create unknown platform
|
// insert unknown platform and game if not present
|
||||||
Platforms.GetPlatform(0, HasheousClient.Models.MetadataSources.None);
|
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false);
|
||||||
Platforms.GetPlatform(0, HasheousClient.Models.MetadataSources.IGDB);
|
gaseous_server.Classes.Metadata.Games.AssignAllGamesToPlatformIdZero();
|
||||||
Platforms.GetPlatform(0, HasheousClient.Models.MetadataSources.TheGamesDb);
|
gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
|
||||||
|
gaseous_server.Classes.Metadata.Platforms.AssignAllPlatformsToGameIdZero();
|
||||||
|
|
||||||
// extract platform map if not present
|
// extract platform map if not present
|
||||||
PlatformMapping.ExtractPlatformMap();
|
PlatformMapping.ExtractPlatformMap();
|
||||||
@@ -357,6 +357,9 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.LibraryScan)
|
ProcessQueue.QueueItemType.LibraryScan)
|
||||||
);
|
);
|
||||||
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
|
ProcessQueue.QueueItemType.Rematcher)
|
||||||
|
);
|
||||||
|
|
||||||
// maintenance tasks
|
// maintenance tasks
|
||||||
ProcessQueue.QueueItem dailyMaintenance = new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItem dailyMaintenance = new ProcessQueue.QueueItem(
|
||||||
|
|||||||
@@ -97,384 +97,3 @@ SELECT *, DATE_ADD(
|
|||||||
SessionTime, INTERVAL SessionLength MINUTE
|
SessionTime, INTERVAL SessionLength MINUTE
|
||||||
) AS SessionEnd
|
) AS SessionEnd
|
||||||
FROM UserTimeTracking;
|
FROM UserTimeTracking;
|
||||||
|
|
||||||
CREATE INDEX idx_game_name ON Game (`Name`);
|
|
||||||
|
|
||||||
CREATE INDEX idx_game_totalratingcount ON Game (TotalRatingCount);
|
|
||||||
|
|
||||||
CREATE INDEX idx_alternativename_game ON AlternativeName (Game);
|
|
||||||
|
|
||||||
CREATE INDEX idx_gamestate_romid ON GameState (RomId);
|
|
||||||
|
|
||||||
CREATE INDEX idx_gamestate_ismediagroup_userid ON GameState (IsMediaGroup, UserId);
|
|
||||||
|
|
||||||
CREATE INDEX idx_rommediagroup_gameid ON RomMediaGroup (GameId);
|
|
||||||
|
|
||||||
CREATE INDEX idx_favourites_userid_gameid ON Favourites (UserId, GameId);
|
|
||||||
|
|
||||||
CREATE TABLE `MetadataMap` (
|
|
||||||
`Id` bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
`PlatformId` bigint(20) NOT NULL,
|
|
||||||
`SignatureGameName` varchar(255) NOT NULL,
|
|
||||||
`UserManualLink` varchar(255) DEFAULT NULL,
|
|
||||||
PRIMARY KEY (`id`),
|
|
||||||
INDEX `idx_gamename` (
|
|
||||||
`SignatureGameName`,
|
|
||||||
`PlatformId`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE `MetadataMapBridge` (
|
|
||||||
`ParentMapId` bigint(20) NOT NULL,
|
|
||||||
`MetadataSourceType` int(11) NOT NULL DEFAULT 0,
|
|
||||||
`MetadataSourceId` bigint(20) NOT NULL,
|
|
||||||
`Preferred` BOOLEAN NOT NULL DEFAULT 0,
|
|
||||||
`ProcessedAtImport` BOOLEAN NOT NULL DEFAULT 0,
|
|
||||||
PRIMARY KEY (
|
|
||||||
`ParentMapId`,
|
|
||||||
`MetadataSourceType`,
|
|
||||||
`MetadataSourceId`
|
|
||||||
),
|
|
||||||
CONSTRAINT `MetadataMapBridge_MetadataMap` FOREIGN KEY (`ParentMapId`) REFERENCES `MetadataMap` (`Id`) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW `view_MetadataMap` AS
|
|
||||||
SELECT `MetadataMap`.*, `MetadataMapBridge`.`MetadataSourceType`, `MetadataMapBridge`.`MetadataSourceId`
|
|
||||||
FROM
|
|
||||||
`MetadataMap`
|
|
||||||
LEFT JOIN `MetadataMapBridge` ON (
|
|
||||||
`MetadataMap`.`Id` = `MetadataMapBridge`.`ParentMapId`
|
|
||||||
AND `MetadataMapBridge`.`Preferred` = 1
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms`
|
|
||||||
ADD COLUMN `MetadataMapId` BIGINT NOT NULL DEFAULT 0;
|
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms`
|
|
||||||
ADD CONSTRAINT metadataMapId FOREIGN KEY (`MetadataMapId`) REFERENCES `MetadataMap` (`Id`) ON DELETE CASCADE;
|
|
||||||
|
|
||||||
ALTER TABLE `AgeGroup`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `AgeRating`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `AgeRatingContentDescription`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `AlternativeName`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Artwork`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Collection`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Company`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `CompanyLogo`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Cover`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `ExternalGame`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Franchise`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Game`
|
|
||||||
CHANGE `Id` `Id` bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP INDEX IF EXISTS `Id_UNIQUE`,
|
|
||||||
DROP INDEX IF EXISTS `PRIMARY`,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `GameMode`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `GameVideo`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Genre`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `InvolvedCompany`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `MultiplayerMode`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Platform`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP INDEX IF EXISTS `Id_UNIQUE`,
|
|
||||||
DROP INDEX IF EXISTS `PRIMARY`,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `PlatformLogo`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `PlatformVersion`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `PlayerPerspective`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `ReleaseDate`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Screenshot`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `Theme`
|
|
||||||
ADD COLUMN `SourceId` INT NOT NULL DEFAULT 1 AFTER `Id`,
|
|
||||||
DROP PRIMARY KEY,
|
|
||||||
ADD PRIMARY KEY (`Id`, `SourceId`);
|
|
||||||
|
|
||||||
ALTER TABLE `ReleaseDate`
|
|
||||||
CHANGE `m` `Month` int(11) DEFAULT NULL,
|
|
||||||
CHANGE `y` `Year` int(11) DEFAULT NULL;
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW `view_Games_Roms` AS
|
|
||||||
SELECT
|
|
||||||
`Games_Roms`.`Id` AS `Id`,
|
|
||||||
`Games_Roms`.`PlatformId` AS `PlatformId`,
|
|
||||||
`view_MetadataMap`.`Id` AS `MetadataMapId`,
|
|
||||||
`view_MetadataMap`.`MetadataSourceType` AS `GameIdType`,
|
|
||||||
`view_MetadataMap`.`MetadataSourceId` AS `GameId`,
|
|
||||||
`view_MetadataMap`.`UserManualLink` AS `UserManualLink`,
|
|
||||||
`Games_Roms`.`Name` AS `Name`,
|
|
||||||
`Games_Roms`.`Size` AS `Size`,
|
|
||||||
`Games_Roms`.`CRC` AS `CRC`,
|
|
||||||
`Games_Roms`.`MD5` AS `MD5`,
|
|
||||||
`Games_Roms`.`SHA1` AS `SHA1`,
|
|
||||||
`Games_Roms`.`DevelopmentStatus` AS `DevelopmentStatus`,
|
|
||||||
`Games_Roms`.`Flags` AS `Flags`,
|
|
||||||
`Games_Roms`.`Attributes` AS `Attributes`,
|
|
||||||
`Games_Roms`.`RomType` AS `RomType`,
|
|
||||||
`Games_Roms`.`RomTypeMedia` AS `RomTypeMedia`,
|
|
||||||
`Games_Roms`.`MediaLabel` AS `MediaLabel`,
|
|
||||||
`Games_Roms`.`RelativePath` AS `RelativePath`,
|
|
||||||
`Games_Roms`.`MetadataSource` AS `MetadataSource`,
|
|
||||||
`Games_Roms`.`MetadataGameName` AS `MetadataGameName`,
|
|
||||||
`Games_Roms`.`MetadataVersion` AS `MetadataVersion`,
|
|
||||||
`Games_Roms`.`LibraryId` AS `LibraryId`,
|
|
||||||
`Games_Roms`.`LastMatchAttemptDate` AS `LastMatchAttemptDate`,
|
|
||||||
`Games_Roms`.`RomDataVersion` AS `RomDataVersion`,
|
|
||||||
CONCAT(
|
|
||||||
`GameLibraries`.`Path`,
|
|
||||||
'/',
|
|
||||||
`Games_Roms`.`RelativePath`
|
|
||||||
) AS `Path`,
|
|
||||||
`GameLibraries`.`Name` AS `LibraryName`
|
|
||||||
FROM (
|
|
||||||
`Games_Roms`
|
|
||||||
JOIN `GameLibraries` ON (
|
|
||||||
`Games_Roms`.`LibraryId` = `GameLibraries`.`Id`
|
|
||||||
)
|
|
||||||
LEFT JOIN `view_MetadataMap` ON (
|
|
||||||
`Games_Roms`.`MetadataMapId` = `view_MetadataMap`.`Id`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW `view_GamesWithRoms` AS
|
|
||||||
SELECT DISTINCT
|
|
||||||
`Games_Roms`.`GameId` AS `ROMGameId`,
|
|
||||||
`view_MetadataMap`.`Id` AS `MetadataMapId`,
|
|
||||||
`view_MetadataMap`.`MetadataSourceType` AS `GameIdType`,
|
|
||||||
CASE
|
|
||||||
WHEN `Game`.`Id` IS NULL THEN 0
|
|
||||||
ELSE `Game`.`Id`
|
|
||||||
END AS `Id`,
|
|
||||||
`Game`.`AgeRatings` AS `AgeRatings`,
|
|
||||||
`Game`.`AggregatedRating` AS `AggregatedRating`,
|
|
||||||
`Game`.`AggregatedRatingCount` AS `AggregatedRatingCount`,
|
|
||||||
`Game`.`AlternativeNames` AS `AlternativeNames`,
|
|
||||||
`Game`.`Artworks` AS `Artworks`,
|
|
||||||
`Game`.`Bundles` AS `Bundles`,
|
|
||||||
`Game`.`Category` AS `Category`,
|
|
||||||
`Game`.`Checksum` AS `Checksum`,
|
|
||||||
`Game`.`Collection` AS `Collection`,
|
|
||||||
`Game`.`Cover` AS `Cover`,
|
|
||||||
`Game`.`CreatedAt` AS `CreatedAt`,
|
|
||||||
`Game`.`Dlcs` AS `Dlcs`,
|
|
||||||
`Game`.`Expansions` AS `Expansions`,
|
|
||||||
`Game`.`ExternalGames` AS `ExternalGames`,
|
|
||||||
`Game`.`FirstReleaseDate` AS `FirstReleaseDate`,
|
|
||||||
`Game`.`Follows` AS `Follows`,
|
|
||||||
`Game`.`Franchise` AS `Franchise`,
|
|
||||||
`Game`.`Franchises` AS `Franchises`,
|
|
||||||
`Game`.`GameEngines` AS `GameEngines`,
|
|
||||||
`Game`.`GameModes` AS `GameModes`,
|
|
||||||
`Game`.`Genres` AS `Genres`,
|
|
||||||
`Game`.`Hypes` AS `Hypes`,
|
|
||||||
`Game`.`InvolvedCompanies` AS `InvolvedCompanies`,
|
|
||||||
`Game`.`Keywords` AS `Keywords`,
|
|
||||||
`Game`.`MultiplayerModes` AS `MultiplayerModes`,
|
|
||||||
CASE
|
|
||||||
WHEN `Game`.`Name` IS NULL THEN `view_MetadataMap`.`SignatureGameName`
|
|
||||||
ELSE `Game`.`Name`
|
|
||||||
END AS `Name`,
|
|
||||||
CASE
|
|
||||||
WHEN `Game`.`Name` IS NULL THEN CASE
|
|
||||||
WHEN `view_MetadataMap`.`SignatureGameName` LIKE 'The %' THEN CONCAT(
|
|
||||||
TRIM(
|
|
||||||
SUBSTR(
|
|
||||||
`view_MetadataMap`.`SignatureGameName`,
|
|
||||||
4
|
|
||||||
)
|
|
||||||
),
|
|
||||||
', The'
|
|
||||||
)
|
|
||||||
ELSE `view_MetadataMap`.`SignatureGameName`
|
|
||||||
END
|
|
||||||
WHEN `Game`.`Name` LIKE 'The %' THEN CONCAT(
|
|
||||||
TRIM(SUBSTR(`Game`.`Name`, 4)),
|
|
||||||
', The'
|
|
||||||
)
|
|
||||||
ELSE `Game`.`Name`
|
|
||||||
END AS `NameThe`,
|
|
||||||
`Game`.`ParentGame` AS `ParentGame`,
|
|
||||||
`Game`.`Platforms` AS `Platforms`,
|
|
||||||
`Game`.`PlayerPerspectives` AS `PlayerPerspectives`,
|
|
||||||
`Game`.`Rating` AS `Rating`,
|
|
||||||
`Game`.`RatingCount` AS `RatingCount`,
|
|
||||||
`Game`.`ReleaseDates` AS `ReleaseDates`,
|
|
||||||
`Game`.`Screenshots` AS `Screenshots`,
|
|
||||||
`Game`.`SimilarGames` AS `SimilarGames`,
|
|
||||||
`Game`.`Slug` AS `Slug`,
|
|
||||||
`Game`.`StandaloneExpansions` AS `StandaloneExpansions`,
|
|
||||||
`Game`.`Status` AS `Status`,
|
|
||||||
`Game`.`StoryLine` AS `StoryLine`,
|
|
||||||
`Game`.`Summary` AS `Summary`,
|
|
||||||
`Game`.`Tags` AS `Tags`,
|
|
||||||
`Game`.`Themes` AS `Themes`,
|
|
||||||
`Game`.`TotalRating` AS `TotalRating`,
|
|
||||||
`Game`.`TotalRatingCount` AS `TotalRatingCount`,
|
|
||||||
`Game`.`UpdatedAt` AS `UpdatedAt`,
|
|
||||||
`Game`.`Url` AS `Url`,
|
|
||||||
`Game`.`VersionParent` AS `VersionParent`,
|
|
||||||
`Game`.`VersionTitle` AS `VersionTitle`,
|
|
||||||
`Game`.`Videos` AS `Videos`,
|
|
||||||
`Game`.`Websites` AS `Websites`,
|
|
||||||
`Game`.`dateAdded` AS `dateAdded`,
|
|
||||||
`Game`.`lastUpdated` AS `lastUpdated`
|
|
||||||
FROM (
|
|
||||||
`Games_Roms`
|
|
||||||
JOIN `view_MetadataMap` ON (
|
|
||||||
`view_MetadataMap`.`Id` = `Games_Roms`.`MetadataMapId`
|
|
||||||
)
|
|
||||||
LEFT JOIN `Game` ON (
|
|
||||||
`Game`.`SourceId` = `view_MetadataMap`.`MetadataSourceType`
|
|
||||||
AND `Game`.`Id` = `view_MetadataMap`.`MetadataSourceId`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW `view_Games` AS
|
|
||||||
SELECT
|
|
||||||
`a`.`ROMGameId` AS `ROMGameId`,
|
|
||||||
`a`.`Id` AS `Id`,
|
|
||||||
`a`.`GameIdType` AS `GameIdType`,
|
|
||||||
`a`.`AgeRatings` AS `AgeRatings`,
|
|
||||||
`a`.`AggregatedRating` AS `AggregatedRating`,
|
|
||||||
`a`.`AggregatedRatingCount` AS `AggregatedRatingCount`,
|
|
||||||
`a`.`AlternativeNames` AS `AlternativeNames`,
|
|
||||||
`a`.`Artworks` AS `Artworks`,
|
|
||||||
`a`.`Bundles` AS `Bundles`,
|
|
||||||
`a`.`Category` AS `Category`,
|
|
||||||
`a`.`Checksum` AS `Checksum`,
|
|
||||||
`a`.`Collection` AS `Collection`,
|
|
||||||
`a`.`Cover` AS `Cover`,
|
|
||||||
`a`.`CreatedAt` AS `CreatedAt`,
|
|
||||||
`a`.`Dlcs` AS `Dlcs`,
|
|
||||||
`a`.`Expansions` AS `Expansions`,
|
|
||||||
`a`.`ExternalGames` AS `ExternalGames`,
|
|
||||||
`a`.`FirstReleaseDate` AS `FirstReleaseDate`,
|
|
||||||
`a`.`Follows` AS `Follows`,
|
|
||||||
`a`.`Franchise` AS `Franchise`,
|
|
||||||
`a`.`Franchises` AS `Franchises`,
|
|
||||||
`a`.`GameEngines` AS `GameEngines`,
|
|
||||||
`a`.`GameModes` AS `GameModes`,
|
|
||||||
`a`.`Genres` AS `Genres`,
|
|
||||||
`a`.`Hypes` AS `Hypes`,
|
|
||||||
`a`.`InvolvedCompanies` AS `InvolvedCompanies`,
|
|
||||||
`a`.`Keywords` AS `Keywords`,
|
|
||||||
`a`.`MultiplayerModes` AS `MultiplayerModes`,
|
|
||||||
`a`.`Name` AS `Name`,
|
|
||||||
`a`.`ParentGame` AS `ParentGame`,
|
|
||||||
`a`.`Platforms` AS `Platforms`,
|
|
||||||
`a`.`PlayerPerspectives` AS `PlayerPerspectives`,
|
|
||||||
`a`.`Rating` AS `Rating`,
|
|
||||||
`a`.`RatingCount` AS `RatingCount`,
|
|
||||||
`a`.`ReleaseDates` AS `ReleaseDates`,
|
|
||||||
`a`.`Screenshots` AS `Screenshots`,
|
|
||||||
`a`.`SimilarGames` AS `SimilarGames`,
|
|
||||||
`a`.`Slug` AS `Slug`,
|
|
||||||
`a`.`StandaloneExpansions` AS `StandaloneExpansions`,
|
|
||||||
`a`.`Status` AS `Status`,
|
|
||||||
`a`.`StoryLine` AS `StoryLine`,
|
|
||||||
`a`.`Summary` AS `Summary`,
|
|
||||||
`a`.`Tags` AS `Tags`,
|
|
||||||
`a`.`Themes` AS `Themes`,
|
|
||||||
`a`.`TotalRating` AS `TotalRating`,
|
|
||||||
`a`.`TotalRatingCount` AS `TotalRatingCount`,
|
|
||||||
`a`.`UpdatedAt` AS `UpdatedAt`,
|
|
||||||
`a`.`Url` AS `Url`,
|
|
||||||
`a`.`VersionParent` AS `VersionParent`,
|
|
||||||
`a`.`VersionTitle` AS `VersionTitle`,
|
|
||||||
`a`.`Videos` AS `Videos`,
|
|
||||||
`a`.`Websites` AS `Websites`,
|
|
||||||
`a`.`dateAdded` AS `dateAdded`,
|
|
||||||
`a`.`lastUpdated` AS `lastUpdated`,
|
|
||||||
`a`.`NameThe` AS `NameThe`,
|
|
||||||
`b`.`AgeGroupId` AS `AgeGroupId`
|
|
||||||
FROM (
|
|
||||||
`view_GamesWithRoms` `a`
|
|
||||||
LEFT JOIN `AgeGroup` `b` ON (`b`.`GameId` = `a`.`Id`)
|
|
||||||
)
|
|
||||||
ORDER BY `a`.`NameThe`;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M403.2 803.2c-0.8 0-8.8 64-9.6 65.6-1.6 13.6-4 21.6-11.2 28-2.4 2.4-4.8 3.2-7.2 4.8-5.6 4-10.4 6.4-16.8 10.4-4.8 2.4-10.4 12-4.8 14.4h316.8c5.6-2.4 0-11.2-4.8-13.6-6.4-4-11.2-7.2-16.8-12-2.4-1.6-4.8-4-7.2-6.4-6.4-6.4-9.6-12-11.2-25.6 0-1.6-9.6-71.2-9.6-65.6" fill="#D2D5D6" /><path d="M992 704.8V124c0-14.4-11.2-26.4-25.6-26.4H57.6c-14.4 0-25.6 12-25.6 26.4v581.6" fill="#938993" /><path d="M84 149.6h856v503.2h-856z" fill="#E2D3E2" /><path d="M376 137.6l576 528v-528z" fill="#FAFBFA" /><path d="M32 704v72.8c0 14.4 11.2 26.4 25.6 26.4h908c14.4 0 25.6-12 25.6-26.4V704" fill="#D2D5D6" /><path d="M511.2 754.4m-24 0a24 24 0 1 0 48 0 24 24 0 1 0-48 0Z" fill="#414343" /><path d="M623.2 827.2c-0.8-24-1.6-24-1.6-24H404s-0.8 0-1.6 24h220.8z" fill="#0D1014" /><path d="M449.6 568.8l-1.6 4z" fill="#99D9E6" /><path d="M353.6 934.4c-0.8 0-2.4 0-3.2-0.8-4-1.6-7.2-5.6-7.2-10.4 0-8 6.4-16 11.2-18.4l3.2-1.6c4.8-2.4 8.8-4.8 12-8 1.6-0.8 2.4-1.6 4-2.4 0.8-0.8 1.6-0.8 2.4-1.6 4.8-4 6.4-10.4 8-22.4 8-67.2 8-67.2 16-67.2 4.8 0 8 3.2 8 8v2.4c-0.8 5.6-7.2 54.4-8 58.4-1.6 14.4-4.8 24.8-13.6 32.8-1.6 1.6-4 3.2-5.6 4-0.8 0.8-1.6 0.8-2.4 1.6-4.8 4-9.6 6.4-14.4 8.8l-3.2 1.6H656c-5.6-3.2-10.4-7.2-15.2-10.4-1.6-1.6-3.2-3.2-5.6-4.8l-2.4-1.6c-8.8-8-12-16.8-13.6-30.4-0.8-4-6.4-48.8-8-58.4 0-0.8-0.8-1.6-0.8-3.2 0-4 3.2-8 7.2-8.8 8.8-0.8 8.8-0.8 16.8 67.2 1.6 12.8 4 16.8 8 20.8l2.4 2.4c1.6 1.6 3.2 2.4 4 4 5.6 4 9.6 7.2 16 11.2 4.8 2.4 12 10.4 11.2 17.6 0 4.8-3.2 8-7.2 10.4-0.8 0.8-2.4 0.8-3.2 0.8l-312-1.6zM992 712.8c-4.8 0-8-3.2-8-8V124c0-10.4-8-18.4-17.6-18.4H57.6c-9.6 0-17.6 8-17.6 18.4v581.6c0 4.8-3.2 8-8 8s-8-3.2-8-8V124c0-19.2 15.2-34.4 33.6-34.4h908c18.4 0 33.6 15.2 33.6 34.4v581.6c0.8 4-2.4 7.2-7.2 7.2z" fill="#6A576D" /><path d="M940 660.8h-856c-4.8 0-8-3.2-8-8V149.6c0-4.8 3.2-8 8-8h856c4.8 0 8 3.2 8 8v503.2c0 4.8-4 8-8 8z m-848-16h840V157.6h-840v487.2zM966.4 811.2H57.6c-18.4 0-33.6-15.2-33.6-34.4V704c0-4.8 3.2-8 8-8h960c4.8 0 8 3.2 8 8v72.8c0 19.2-15.2 34.4-33.6 34.4zM40 712v64.8c0 10.4 8 18.4 17.6 18.4h908c9.6 0 17.6-8 17.6-18.4V712H40z" fill="#6A576D" /></svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -18,9 +18,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
||||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||||
<PackageReference Include="gaseous-signature-parser" Version="2.3.3" />
|
<PackageReference Include="gaseous-signature-parser" Version="2.2.1" />
|
||||||
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
||||||
<PackageReference Include="hasheous-client" Version="1.2.4" />
|
<PackageReference Include="hasheous-client" Version="1.0.2" />
|
||||||
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.8.0" />
|
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.8.0" />
|
||||||
<PackageReference Include="sharpcompress" Version="0.37.2" />
|
<PackageReference Include="sharpcompress" Version="0.37.2" />
|
||||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
|
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -92,7 +92,6 @@
|
|||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Support\Country.txt" />
|
<EmbeddedResource Include="Support\Country.txt" />
|
||||||
<EmbeddedResource Include="Support\Language.txt" />
|
<EmbeddedResource Include="Support\Language.txt" />
|
||||||
<EmbeddedResource Include="Support\DefaultPlatformLogo.svg" />
|
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1000.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1000.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1001.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1001.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1002.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1002.sql" />
|
||||||
|
|||||||
@@ -43,6 +43,8 @@
|
|||||||
EJS_threads = false;
|
EJS_threads = false;
|
||||||
|
|
||||||
EJS_Buttons = {
|
EJS_Buttons = {
|
||||||
|
saveSavFiles: false,
|
||||||
|
loadSavFiles: false,
|
||||||
exitEmulation: false
|
exitEmulation: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- Generated by Pixelmator Pro 3.6.14 -->
|
|
||||||
<svg width="800" height="800" viewBox="0 0 800 800" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path id="Path" fill="none" stroke="#000000" stroke-width="33.333332" stroke-linejoin="round" d="M 400 230.302979 C 363.330017 183.630981 306.802002 136.958984 166.706345 133.533997 C 157.504333 133.309326 150 140.78363 150 149.988342 C 150 218.270996 150 476.779999 150 553.233337 C 150 562.436646 157.505005 569.666687 166.704666 569.966675 C 306.801666 574.546692 363.330017 636.660034 400 683.333313 M 400 230.302979 C 436.669983 183.630981 493.196686 136.958984 633.293335 133.533997 C 642.496704 133.309326 650 140.615662 650 149.820313 C 650 226.148987 650 476.880005 650 553.210022 C 650 562.41333 642.496704 569.666687 633.296631 569.966675 C 493.199982 574.546692 436.669983 636.660034 400 683.333313 M 400 230.302979 L 400 683.333313"/>
|
|
||||||
<path id="path1" fill="none" stroke="#000000" stroke-width="33.333332" stroke-linejoin="round" d="M 641.176697 200 L 716.666687 200 C 725.869995 200 733.333313 207.461975 733.333313 216.666687 L 733.333313 651.299988 C 733.333313 664.786621 717.443359 673.746704 705.116638 668.27002 C 678.613342 656.493286 634.383301 642.106689 576.469971 642.106689 C 478.429993 642.106689 400 700 400 700 C 400 700 321.568665 642.106689 223.529343 642.106689 C 165.615005 642.106689 121.385338 656.493286 94.882339 668.27002 C 82.556 673.746704 66.666664 664.786621 66.666664 651.299988 L 66.666664 216.666687 C 66.666664 207.461975 74.12867 200 83.333336 200 L 158.823669 200"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<script type="text/javascript" src="/scripts/jquery-3.6.0.min.js"></script>
|
<script src="/api/v1.1/System/VersionFile"></script>
|
||||||
<script type="text/javascript" src="/scripts/jquery.lazy.min.js"></script>
|
|
||||||
<script type="text/javascript" src="/scripts/jquery.lazy.plugins.min.js"></script>
|
|
||||||
<script type="text/javascript" src="/scripts/moment-with-locales.min.js"></script>
|
|
||||||
<script type="text/javascript" src="/scripts/select2.min.js"></script>
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
@@ -25,6 +21,11 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
let scriptLinks = [
|
let scriptLinks = [
|
||||||
|
"/scripts/jquery-3.6.0.min.js",
|
||||||
|
"/scripts/jquery.lazy.min.js",
|
||||||
|
"/scripts/jquery.lazy.plugins.min.js",
|
||||||
|
"/scripts/moment-with-locales.min.js",
|
||||||
|
"/scripts/select2.min.js",
|
||||||
"/scripts/filterformating.js",
|
"/scripts/filterformating.js",
|
||||||
"/scripts/gamesformating.js",
|
"/scripts/gamesformating.js",
|
||||||
"/scripts/main.js",
|
"/scripts/main.js",
|
||||||
@@ -59,19 +60,31 @@
|
|||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Gaseous Games - Main Application Script
|
|
||||||
|
|
||||||
// start the application
|
// start the application
|
||||||
let AppVersion = "0.0.0";
|
|
||||||
let DBSchemaVersion = "1000";
|
|
||||||
let FirstRunStatus = "0";
|
|
||||||
let AgeRatingBoardStrings = {};
|
|
||||||
let AgeRatingStrings = {};
|
|
||||||
let AgeRatingGroups = {};
|
|
||||||
let emulatorDebugMode = "false";
|
|
||||||
|
|
||||||
let backgroundImageHandler = undefined;
|
let backgroundImageHandler = undefined;
|
||||||
|
|
||||||
|
async function loadScriptsAndStyles() {
|
||||||
|
// update script links
|
||||||
|
for (let i = 0; i < scriptLinks.length; i++) {
|
||||||
|
let newScript = document.createElement('script');
|
||||||
|
newScript.src = scriptLinks[i] + '?v=' + AppVersion;
|
||||||
|
newScript.type = "text/javascript";
|
||||||
|
newScript.async = false;
|
||||||
|
|
||||||
|
head.appendChild(newScript);
|
||||||
|
}
|
||||||
|
|
||||||
|
// update stylesheet links
|
||||||
|
for (let i = 0; i < styleSheets.length; i++) {
|
||||||
|
let newLink = document.createElement('link');
|
||||||
|
newLink.rel = "stylesheet";
|
||||||
|
newLink.href = styleSheets[i] + '?v=' + AppVersion;
|
||||||
|
newLink.type = "text/css";
|
||||||
|
|
||||||
|
head.appendChild(newLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function LoadPageContent(page, targetDiv) {
|
async function LoadPageContent(page, targetDiv) {
|
||||||
if (targetDiv == undefined || targetDiv == null || targetDiv == '') {
|
if (targetDiv == undefined || targetDiv == null || targetDiv == '') {
|
||||||
targetDiv = 'content';
|
targetDiv = 'content';
|
||||||
@@ -94,98 +107,49 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function startApp() {
|
async function startApp() {
|
||||||
// load /api/v1.1/System/Version
|
await loadScriptsAndStyles();
|
||||||
await fetch('/api/v1.1/System/Version')
|
|
||||||
.then(async response => {
|
|
||||||
if (response.ok) {
|
|
||||||
// get version information
|
|
||||||
let versionFile = await response.json();
|
|
||||||
AppVersion = versionFile.AppVersion;
|
|
||||||
DBSchemaVersion = versionFile.DBSchemaVersion;
|
|
||||||
FirstRunStatus = versionFile.FirstRunStatus;
|
|
||||||
AgeRatingBoardStrings = versionFile.AgeRatingBoardStrings;
|
|
||||||
AgeRatingStrings = versionFile.AgeRatingStrings;
|
|
||||||
AgeRatingGroups = versionFile.AgeRatingGroups;
|
|
||||||
emulatorDebugMode = versionFile.emulatorDebugMode;
|
|
||||||
|
|
||||||
// load scripts and style files
|
console.log("Starting Gaseous Games");
|
||||||
// update script links
|
console.log("App Version: " + AppVersion);
|
||||||
for (let i = 0; i < scriptLinks.length; i++) {
|
console.log("First Run Status: " + FirstRunStatus);
|
||||||
let newScript = document.createElement('script');
|
switch (FirstRunStatus) {
|
||||||
newScript.src = scriptLinks[i] + '?v=' + AppVersion;
|
case 0:
|
||||||
newScript.type = "text/javascript";
|
case "0":
|
||||||
newScript.async = false;
|
// first run - load first run wizard
|
||||||
|
await LoadPageContent('first', 'content');
|
||||||
|
break;
|
||||||
|
|
||||||
head.appendChild(newScript);
|
default:
|
||||||
}
|
// first run - load login page or redirect if user already logged in
|
||||||
|
|
||||||
// update stylesheet links
|
await fetch('/api/v1.1/Account/Profile/Basic')
|
||||||
for (let i = 0; i < styleSheets.length; i++) {
|
.then(async response => {
|
||||||
let newLink = document.createElement('link');
|
if (response.ok) {
|
||||||
newLink.rel = "stylesheet";
|
// user is signed in - start setting up the application
|
||||||
newLink.href = styleSheets[i] + '?v=' + AppVersion;
|
console.log("User is logged in");
|
||||||
newLink.type = "text/css";
|
userProfile = await response.json();
|
||||||
|
|
||||||
head.appendChild(newLink);
|
// load page banner
|
||||||
}
|
await LoadPageContent('banner', 'banner_target');
|
||||||
|
|
||||||
// wait for all scripts to load
|
// load page content
|
||||||
do {
|
let pageSelection = getQueryString('page', 'string');
|
||||||
if (typeof getQueryString === "function") {
|
|
||||||
break;
|
if (!pageSelection) {
|
||||||
|
pageSelection = GetPreference("DefaultHomePage", 'home');
|
||||||
|
}
|
||||||
|
await LoadPageContent(pageSelection, 'content');
|
||||||
|
} else {
|
||||||
|
// user is not signed in - load login page
|
||||||
|
await LoadPageContent('login');
|
||||||
}
|
}
|
||||||
console.log("Waiting for scripts to load...");
|
})
|
||||||
await new Promise(r => setTimeout(r, 100));
|
.catch(async (error) => {
|
||||||
} while (typeof getQueryString !== "function");
|
console.log(error);
|
||||||
|
await LoadPageContent('login');
|
||||||
// start the application
|
});
|
||||||
console.log("Starting Gaseous");
|
break;
|
||||||
console.log("App Version: " + AppVersion);
|
}
|
||||||
console.log("First Run Status: " + FirstRunStatus);
|
|
||||||
switch (FirstRunStatus) {
|
|
||||||
case 0:
|
|
||||||
case "0":
|
|
||||||
// first run - load first run wizard
|
|
||||||
await LoadPageContent('first', 'content');
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// first run - load login page or redirect if user already logged in
|
|
||||||
|
|
||||||
await fetch('/api/v1.1/Account/Profile/Basic')
|
|
||||||
.then(async response => {
|
|
||||||
if (response.ok) {
|
|
||||||
// user is signed in - start setting up the application
|
|
||||||
console.log("User is logged in");
|
|
||||||
userProfile = await response.json();
|
|
||||||
|
|
||||||
// load page banner
|
|
||||||
await LoadPageContent('banner', 'banner_target');
|
|
||||||
|
|
||||||
// load page content
|
|
||||||
let pageSelection = getQueryString('page', 'string');
|
|
||||||
|
|
||||||
if (!pageSelection) {
|
|
||||||
pageSelection = GetPreference("DefaultHomePage", "home");
|
|
||||||
}
|
|
||||||
console.log("Loading page: " + pageSelection);
|
|
||||||
await LoadPageContent(pageSelection, 'content');
|
|
||||||
} else {
|
|
||||||
// user is not signed in - load login page
|
|
||||||
await LoadPageContent('login');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async (error) => {
|
|
||||||
console.log(error);
|
|
||||||
await LoadPageContent('login');
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async (error) => {
|
|
||||||
console.log(error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.document.addEventListener('DOMContentLoaded', startApp);
|
window.document.addEventListener('DOMContentLoaded', startApp);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function SetupPage() {
|
|||||||
gameData = result;
|
gameData = result;
|
||||||
|
|
||||||
if (result.cover) {
|
if (result.cover) {
|
||||||
emuBackground = '/api/v1.1/Games/' + gameId + '/cover/' + result.cover + '/image/original/' + result.cover + '.jpg';
|
emuBackground = '/api/v1.1/Games/' + gameId + '/cover/' + result.cover.id + '/image/original/' + result.cover.imageId + '.jpg';
|
||||||
}
|
}
|
||||||
|
|
||||||
emuGameTitle = gameData.name;
|
emuGameTitle = gameData.name;
|
||||||
|
|||||||
@@ -104,26 +104,12 @@
|
|||||||
<div class="section-header">Similar Games</div>
|
<div class="section-header">Similar Games</div>
|
||||||
<div id="gamesummarysimilarcontent" class="section-body"></div>
|
<div id="gamesummarysimilarcontent" class="section-body"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="gamesmetadataprovider" class="section" style="display: none;">
|
|
||||||
<div id="gamesmetadataprovidercontent" class="section-body">
|
|
||||||
<table style="width: 100%;">
|
|
||||||
<tr>
|
|
||||||
<td style="width: 40px;">
|
|
||||||
<img src="/images/IGDB_logo.svg" class="metadata-attribution-icon"
|
|
||||||
id="metadata-attribution-icon" />
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span id="metadata-attribution-text">Game data provided by IGDB</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- page code -->
|
<!-- page code -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// setup the page
|
// setup the page
|
||||||
SetupPage();
|
SetupPage();
|
||||||
</script>
|
</script>
|
||||||
@@ -12,47 +12,28 @@ function SetupPage() {
|
|||||||
mappingScript.src = '/pages/settings/mapping.js';
|
mappingScript.src = '/pages/settings/mapping.js';
|
||||||
document.head.appendChild(mappingScript);
|
document.head.appendChild(mappingScript);
|
||||||
|
|
||||||
let nonce = (Math.random() + 1).toString(36).substring(7);
|
ajaxCall('/api/v1.1/Games/' + gameId, 'GET', function (result) {
|
||||||
|
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '?nonce=' + nonce, 'GET', function (result) {
|
|
||||||
// populate games page
|
// populate games page
|
||||||
gameData = result;
|
gameData = result;
|
||||||
console.log(gameData);
|
|
||||||
|
|
||||||
switch (gameData.metadataSource) {
|
|
||||||
case "IGDB":
|
|
||||||
let attributionSection = document.getElementById('gamesmetadataprovider');
|
|
||||||
attributionSection.style.display = 'block';
|
|
||||||
|
|
||||||
let attributionIcon = document.getElementById('metadata-attribution-icon');
|
|
||||||
attributionIcon.setAttribute('src', '/images/IGDB_Logo.svg');
|
|
||||||
|
|
||||||
let attributionText = document.getElementById('metadata-attribution-text');
|
|
||||||
attributionText.innerHTML = 'This game\'s metadata is provided by IGDB. <a href="https://www.igdb.com/games/' + gameData.slug + '" class="romlink" target="_blank" rel="noopener noreferrer">Source Page</a>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get name
|
// get name
|
||||||
var gameTitleLabel = document.getElementById('gametitle_label');
|
var gameTitleLabel = document.getElementById('gametitle_label');
|
||||||
gameTitleLabel.innerHTML = result.name;
|
gameTitleLabel.innerHTML = result.name;
|
||||||
|
|
||||||
// get critic rating
|
// get critic rating
|
||||||
if (gameData.total_rating) {
|
if (gameData.totalRating) {
|
||||||
var criticscoreval = document.getElementById('gametitle_criticrating_value');
|
var criticscoreval = document.getElementById('gametitle_criticrating_value');
|
||||||
criticscoreval.innerHTML = Math.floor(gameData.total_rating) + '%';
|
criticscoreval.innerHTML = Math.floor(gameData.totalRating) + '%';
|
||||||
|
|
||||||
if (gameData.total_rating_count) {
|
if (gameData.totalRatingCount) {
|
||||||
var criticscorelabel = document.getElementById('gametitle_criticrating_label');
|
var criticscorelabel = document.getElementById('gametitle_criticrating_label');
|
||||||
criticscorelabel.innerHTML = '<span style="font-size: 10px;"> User rating<br />based on ' + gameData.total_rating_count + ' votes</span>'
|
criticscorelabel.innerHTML = '<img src="/images/IGDB_logo.svg" style="filter: invert(100%); height: 13px; margin-bottom: -5px;" /><span style="font-size: 10px;"> User Rating<br />' + "based on " + gameData.totalRatingCount + " votes</span>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get alt name
|
// get alt name
|
||||||
var gameTitleAltLabel = document.getElementById('gametitle_alts');
|
var gameTitleAltLabel = document.getElementById('gametitle_alts');
|
||||||
if (result.alternative_names) {
|
if (result.alternativeNames) {
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '/alternativename', 'GET', function (result) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/alternativename', 'GET', function (result) {
|
||||||
var altNames = '';
|
var altNames = '';
|
||||||
for (var i = 0; i < result.length; i++) {
|
for (var i = 0; i < result.length; i++) {
|
||||||
@@ -69,9 +50,8 @@ function SetupPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get summary
|
// get summary
|
||||||
let gameSummaryBox = document.getElementById('gamesummarytext');
|
var gameSummaryLabel = document.getElementById('gamesummarytext_label');
|
||||||
if (result.summary || result.storyline) {
|
if (result.summary || result.storyline) {
|
||||||
let gameSummaryLabel = document.getElementById('gamesummarytext_label');
|
|
||||||
if (result.summary) {
|
if (result.summary) {
|
||||||
gameSummaryLabel.innerHTML = result.summary.replaceAll("\n", "<br />");
|
gameSummaryLabel.innerHTML = result.summary.replaceAll("\n", "<br />");
|
||||||
} else {
|
} else {
|
||||||
@@ -87,7 +67,7 @@ function SetupPage() {
|
|||||||
// your element doesn't overflow (not truncated)
|
// your element doesn't overflow (not truncated)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gameSummaryBox.setAttribute('style', 'display: none;');
|
gameSummaryLabel.setAttribute('style', 'display: none;');
|
||||||
}
|
}
|
||||||
|
|
||||||
// load cover
|
// load cover
|
||||||
@@ -123,7 +103,7 @@ function SetupPage() {
|
|||||||
var gamePublisherContent = document.getElementById('gamesummary_publishers_content');
|
var gamePublisherContent = document.getElementById('gamesummary_publishers_content');
|
||||||
var gameDeveloperLoaded = false;
|
var gameDeveloperLoaded = false;
|
||||||
var gamePublisherLoaded = false;
|
var gamePublisherLoaded = false;
|
||||||
if (result.involved_companies) {
|
if (result.involvedCompanies) {
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '/companies', 'GET', function (result) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/companies', 'GET', function (result) {
|
||||||
var lstDevelopers = [];
|
var lstDevelopers = [];
|
||||||
var lstPublishers = [];
|
var lstPublishers = [];
|
||||||
@@ -219,9 +199,9 @@ function SetupPage() {
|
|||||||
// load release date
|
// load release date
|
||||||
var gameSummaryRelease = document.getElementById('gamesummary_firstrelease');
|
var gameSummaryRelease = document.getElementById('gamesummary_firstrelease');
|
||||||
var gameSummaryReleaseContent = document.getElementById('gamesummary_firstrelease_content');
|
var gameSummaryReleaseContent = document.getElementById('gamesummary_firstrelease_content');
|
||||||
if (result.first_release_date) {
|
if (result.firstReleaseDate) {
|
||||||
var firstRelease = document.createElement('span');
|
var firstRelease = document.createElement('span');
|
||||||
firstRelease.innerHTML = moment(result.first_release_date).format('LL') + ' (' + moment(result.first_release_date).fromNow() + ')';
|
firstRelease.innerHTML = moment(result.firstReleaseDate).format('LL') + ' (' + moment(result.firstReleaseDate).fromNow() + ')';
|
||||||
gameSummaryReleaseContent.appendChild(firstRelease);
|
gameSummaryReleaseContent.appendChild(firstRelease);
|
||||||
} else {
|
} else {
|
||||||
gameSummaryRelease.setAttribute('style', 'display: none;');
|
gameSummaryRelease.setAttribute('style', 'display: none;');
|
||||||
@@ -230,7 +210,7 @@ function SetupPage() {
|
|||||||
// load ratings
|
// load ratings
|
||||||
let gameSummaryRatings = document.getElementById('gamesummary_ratings');
|
let gameSummaryRatings = document.getElementById('gamesummary_ratings');
|
||||||
let gameSummaryRatingsContent = document.getElementById('gamesummary_ratings_content');
|
let gameSummaryRatingsContent = document.getElementById('gamesummary_ratings_content');
|
||||||
if (result.age_ratings) {
|
if (result.ageRatings) {
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '/agerating', 'GET', function (result) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/agerating', 'GET', function (result) {
|
||||||
let classTable = document.createElement('table');
|
let classTable = document.createElement('table');
|
||||||
|
|
||||||
@@ -325,7 +305,7 @@ function SetupPage() {
|
|||||||
var gameScreenshots_Gallery = document.getElementById('gamescreenshots_gallery_panel');
|
var gameScreenshots_Gallery = document.getElementById('gamescreenshots_gallery_panel');
|
||||||
var imageIndex = 0;
|
var imageIndex = 0;
|
||||||
if (result.videos) {
|
if (result.videos) {
|
||||||
imageIndex = result.videos.length;
|
imageIndex = result.videos.ids.length;
|
||||||
}
|
}
|
||||||
if (result.screenshots) {
|
if (result.screenshots) {
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '/screenshots', 'GET', function (screenshotsItem) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/screenshots', 'GET', function (screenshotsItem) {
|
||||||
@@ -355,10 +335,10 @@ function SetupPage() {
|
|||||||
var vScreenshotItem = document.createElement('li');
|
var vScreenshotItem = document.createElement('li');
|
||||||
vScreenshotItem.id = 'gamescreenshots_gallery_' + i;
|
vScreenshotItem.id = 'gamescreenshots_gallery_' + i;
|
||||||
vScreenshotItem.setAttribute('name', 'gamescreenshots_gallery_item');
|
vScreenshotItem.setAttribute('name', 'gamescreenshots_gallery_item');
|
||||||
vScreenshotItem.setAttribute('style', 'background-image: url("https://i.ytimg.com/vi/' + result[i].video_id + '/hqdefault.jpg"); background-position: center; background-repeat: no-repeat; background-size: contain;)');
|
vScreenshotItem.setAttribute('style', 'background-image: url("https://i.ytimg.com/vi/' + result[i].videoId + '/hqdefault.jpg"); background-position: center; background-repeat: no-repeat; background-size: contain;)');
|
||||||
vScreenshotItem.setAttribute('imageid', i);
|
vScreenshotItem.setAttribute('imageid', i);
|
||||||
vScreenshotItem.setAttribute('imagetype', 1);
|
vScreenshotItem.setAttribute('imagetype', 1);
|
||||||
vScreenshotItem.setAttribute('imageref', result[i].video_id);
|
vScreenshotItem.setAttribute('imageref', result[i].videoId);
|
||||||
vScreenshotItem.className = 'gamescreenshots_gallery_item';
|
vScreenshotItem.className = 'gamescreenshots_gallery_item';
|
||||||
vScreenshotItem.setAttribute('onclick', 'selectScreenshot(' + i + ');');
|
vScreenshotItem.setAttribute('onclick', 'selectScreenshot(' + i + ');');
|
||||||
|
|
||||||
@@ -408,7 +388,7 @@ function SetupPage() {
|
|||||||
|
|
||||||
var gameSummarySimilarContent = document.getElementById('gamesummarysimilarcontent');
|
var gameSummarySimilarContent = document.getElementById('gamesummarysimilarcontent');
|
||||||
for (var i = 0; i < result.games.length; i++) {
|
for (var i = 0; i < result.games.length; i++) {
|
||||||
var similarObject = renderGameIcon(result.games[i], true, true, true, GetRatingsBoards(), false, true, false);
|
var similarObject = renderGameIcon(result.games[i], true, true, true, GetRatingsBoards(), false, true);
|
||||||
gameSummarySimilarContent.appendChild(similarObject);
|
gameSummarySimilarContent.appendChild(similarObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,11 +406,11 @@ function SetupPage() {
|
|||||||
|
|
||||||
function LoadGamePlatforms() {
|
function LoadGamePlatforms() {
|
||||||
// get platforms
|
// get platforms
|
||||||
ajaxCall('/api/v1.1/Games/' + gameId + '/platforms', 'GET', async function (result) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/platforms', 'GET', function (result) {
|
||||||
let platformContainer = document.getElementById('gamesummaryplatformscontent');
|
let platformContainer = document.getElementById('gamesummaryplatformscontent');
|
||||||
platformContainer.innerHTML = '';
|
platformContainer.innerHTML = '';
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
let logoUrl = '/api/v1.1/Platforms/' + result[i].id + '/platformlogo/original/';
|
let logoUrl = '/api/v1/Platforms/' + result[i].id + '/platformlogo/original/logo.png';
|
||||||
|
|
||||||
// create platform container
|
// create platform container
|
||||||
let platformItem = document.createElement('div');
|
let platformItem = document.createElement('div');
|
||||||
@@ -449,7 +429,6 @@ function LoadGamePlatforms() {
|
|||||||
// 1. if FavouriteRomId is not null, load the rom, otherwise
|
// 1. if FavouriteRomId is not null, load the rom, otherwise
|
||||||
// 2. if LastPlayedRomId is null, load the rom, otherwise
|
// 2. if LastPlayedRomId is null, load the rom, otherwise
|
||||||
// 3. load the rom management dialog
|
// 3. load the rom management dialog
|
||||||
console.log(result[i]);
|
|
||||||
if (result[i].emulatorConfiguration.emulatorType.length > 0 && result[i].emulatorConfiguration.core.length > 0 && result[i].favouriteRomId) {
|
if (result[i].emulatorConfiguration.emulatorType.length > 0 && result[i].emulatorConfiguration.core.length > 0 && result[i].favouriteRomId) {
|
||||||
showSaveState = true;
|
showSaveState = true;
|
||||||
romId = result[i].favouriteRomId;
|
romId = result[i].favouriteRomId;
|
||||||
@@ -458,8 +437,7 @@ function LoadGamePlatforms() {
|
|||||||
platformItem.setAttribute('isFavourite', true);
|
platformItem.setAttribute('isFavourite', true);
|
||||||
platformItem.classList.add('platform_item_green');
|
platformItem.classList.add('platform_item_green');
|
||||||
|
|
||||||
let launchLink = await BuildLaunchLink(platformData.emulatorConfiguration.emulatorType, platformData.emulatorConfiguration.core, platformData.id, Number(gameId), platformData.favouriteRomId, platformData.favouriteRomIsMediagroup, platformData.favouriteRomName);
|
let launchLink = BuildLaunchLink(platformData.emulatorConfiguration.emulatorType, platformData.emulatorConfiguration.core, platformData.id, Number(gameId), platformData.favouriteRomId, platformData.favouriteRomIsMediagroup, platformData.favouriteRomName);
|
||||||
console.log(launchLink);
|
|
||||||
|
|
||||||
platformItem.addEventListener('click', () => {
|
platformItem.addEventListener('click', () => {
|
||||||
window.location.href = launchLink;
|
window.location.href = launchLink;
|
||||||
@@ -472,8 +450,7 @@ function LoadGamePlatforms() {
|
|||||||
platformItem.setAttribute('isLastUsed', true);
|
platformItem.setAttribute('isLastUsed', true);
|
||||||
platformItem.classList.add('platform_item_green');
|
platformItem.classList.add('platform_item_green');
|
||||||
|
|
||||||
let launchLink = await BuildLaunchLink(platformData.emulatorConfiguration.emulatorType, platformData.emulatorConfiguration.core, platformData.id, Number(gameId), platformData.lastPlayedRomId, platformData.lastPlayedRomIsMediagroup, platformData.lastPlayedRomName);
|
let launchLink = BuildLaunchLink(platformData.emulatorConfiguration.emulatorType, platformData.emulatorConfiguration.core, platformData.id, Number(gameId), platformData.lastPlayedRomId, platformData.lastPlayedRomIsMediagroup, platformData.lastPlayedRomName);
|
||||||
console.log(launchLink);
|
|
||||||
|
|
||||||
platformItem.addEventListener('click', () => {
|
platformItem.addEventListener('click', () => {
|
||||||
window.location.href = launchLink;
|
window.location.href = launchLink;
|
||||||
@@ -508,16 +485,6 @@ function LoadGamePlatforms() {
|
|||||||
let platformEditButtonContainer = document.createElement('div');
|
let platformEditButtonContainer = document.createElement('div');
|
||||||
platformEditButtonContainer.className = 'platform_edit_button_container';
|
platformEditButtonContainer.className = 'platform_edit_button_container';
|
||||||
|
|
||||||
// create user manual button
|
|
||||||
let userManualButton = document.createElement('div');
|
|
||||||
userManualButton.className = 'platform_edit_button';
|
|
||||||
userManualButton.innerHTML = '<img src="/images/manual.svg" class="banner_button_image" />';
|
|
||||||
userManualButton.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
let guideUrl = window.open(result[i].userManualLink, '_blank');
|
|
||||||
guideUrl.opener = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// create platform state manager button
|
// create platform state manager button
|
||||||
let platformStateManagerButton = document.createElement('div');
|
let platformStateManagerButton = document.createElement('div');
|
||||||
if (showSaveState === true) {
|
if (showSaveState === true) {
|
||||||
@@ -547,15 +514,10 @@ function LoadGamePlatforms() {
|
|||||||
platformNameContainer.appendChild(platformName);
|
platformNameContainer.appendChild(platformName);
|
||||||
platformItem.appendChild(platformNameContainer);
|
platformItem.appendChild(platformNameContainer);
|
||||||
platformItem.appendChild(platformEditButtonContainer);
|
platformItem.appendChild(platformEditButtonContainer);
|
||||||
|
platformItem.appendChild(platformEditButton);
|
||||||
if (showSaveState === true) {
|
if (showSaveState === true) {
|
||||||
platformEditButtonContainer.appendChild(platformStateManagerButton);
|
platformItem.appendChild(platformStateManagerButton);
|
||||||
}
|
}
|
||||||
if (result[i].userManualLink) {
|
|
||||||
platformEditButtonContainer.appendChild(userManualButton);
|
|
||||||
}
|
|
||||||
platformEditButtonContainer.appendChild(platformEditButton);
|
|
||||||
|
|
||||||
platformContainer.appendChild(platformItem);
|
platformContainer.appendChild(platformItem);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -613,225 +575,96 @@ class RomManagement {
|
|||||||
this.#SetupFixPlatformDropDown();
|
this.#SetupFixPlatformDropDown();
|
||||||
|
|
||||||
// add buttons
|
// add buttons
|
||||||
if (userProfile.roles.includes("Admin")) {
|
let platformEditButton = new ModalButton('Edit Platform', 0, this, async function (callingObject) {
|
||||||
let platformMappingButton = new ModalButton('Metadata Mapping', 0, this, async function (callingObject) {
|
let mappingModal = await new Modal('messagebox');
|
||||||
let metadataModal = await new Modal('messagebox');
|
await mappingModal.BuildModal();
|
||||||
await metadataModal.BuildModal();
|
|
||||||
|
|
||||||
// override the dialog size
|
// override the dialog size
|
||||||
metadataModal.modalElement.style = 'width: 600px; height: 400px; min-width: unset; min-height: 400px; max-width: unset; max-height: 400px;';
|
mappingModal.modalElement.style = 'width: 600px; height: 80%; min-width: unset; min-height: 400px; max-width: unset; max-height: 80%;';
|
||||||
|
|
||||||
// set the title
|
// get the platform map
|
||||||
metadataModal.modalElement.querySelector('#modal-header-text').innerHTML = callingObject.Platform.name + ' Metadata Mapping';
|
let platformMap = await fetch('/api/v1.1/PlatformMaps/' + callingObject.Platform.id, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(response => response.json());
|
||||||
|
let defaultPlatformMap = platformMap;
|
||||||
|
|
||||||
// set the content
|
// get the user emulation configuration
|
||||||
let metadataContent = metadataModal.modalElement.querySelector('#modal-body');
|
let userEmuConfig = await fetch('/api/v1.1/Games/' + gameId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}).then(response => response.json());
|
||||||
|
if (userEmuConfig) {
|
||||||
|
if (userEmuConfig.emulatorType || userEmuConfig.core) {
|
||||||
|
platformMap.webEmulator.type = userEmuConfig.emulatorType;
|
||||||
|
platformMap.webEmulator.core = userEmuConfig.core;
|
||||||
|
}
|
||||||
|
if (userEmuConfig.enableBIOSFiles) {
|
||||||
|
platformMap.enabledBIOSHashes = userEmuConfig.enableBIOSFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fetch the metadata map
|
// set the title
|
||||||
let metadataMap = await fetch('/api/v1.1/Games/' + callingObject.Platform.metadataMapId + '/metadata', {
|
mappingModal.modalElement.querySelector('#modal-header-text').innerHTML = callingObject.Platform.name + ' Emulation Settings';
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}).then(response => response.json());
|
|
||||||
console.log(metadataMap);
|
|
||||||
|
|
||||||
metadataMap.metadataMapItems.forEach(element => {
|
// set the content
|
||||||
let itemSection = document.createElement('div');
|
let mappingContent = mappingModal.modalElement.querySelector('#modal-body');
|
||||||
itemSection.className = 'section';
|
mappingContent.innerHTML = '';
|
||||||
|
let emuConfig = await new WebEmulatorConfiguration(platformMap)
|
||||||
|
emuConfig.open();
|
||||||
|
mappingContent.appendChild(emuConfig.panel);
|
||||||
|
|
||||||
// header
|
// setup the buttons
|
||||||
let itemSectionHeader = document.createElement('div');
|
let resetButton = new ModalButton('Reset to Default', 0, callingObject, async function (callingObject) {
|
||||||
itemSectionHeader.className = 'section-header';
|
await fetch('/api/v1.1/Games/' + gameId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
||||||
|
method: 'DELETE'
|
||||||
let itemSectionHeaderRadio = document.createElement('input');
|
|
||||||
itemSectionHeaderRadio.id = 'platformMappingSource_' + element.sourceType;
|
|
||||||
itemSectionHeaderRadio.type = 'radio';
|
|
||||||
itemSectionHeaderRadio.name = 'platformMappingSource';
|
|
||||||
itemSectionHeaderRadio.value = element.sourceType;
|
|
||||||
itemSectionHeaderRadio.style.margin = '0px';
|
|
||||||
itemSectionHeaderRadio.style.height = 'unset';
|
|
||||||
itemSectionHeaderRadio.addEventListener('change', () => {
|
|
||||||
metadataMap.metadataMapItems.forEach(element => {
|
|
||||||
element.preferred = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
element.preferred = true;
|
|
||||||
console.log('Selected: ' + element.sourceType);
|
|
||||||
console.log(metadataMap);
|
|
||||||
});
|
|
||||||
if (element.preferred == true) {
|
|
||||||
itemSectionHeaderRadio.checked = true;
|
|
||||||
}
|
|
||||||
itemSectionHeader.appendChild(itemSectionHeaderRadio);
|
|
||||||
|
|
||||||
let itemSectionHeaderLabel = document.createElement('label');
|
|
||||||
itemSectionHeaderLabel.htmlFor = 'platformMappingSource_' + element.sourceType;
|
|
||||||
itemSectionHeaderLabel.style.marginLeft = '10px';
|
|
||||||
itemSectionHeaderLabel.innerHTML = element.sourceType;
|
|
||||||
itemSectionHeader.appendChild(itemSectionHeaderLabel);
|
|
||||||
|
|
||||||
itemSection.appendChild(itemSectionHeader);
|
|
||||||
|
|
||||||
// content
|
|
||||||
let itemSectionContent = document.createElement('div');
|
|
||||||
itemSectionContent.className = 'section-body';
|
|
||||||
switch (element.sourceType) {
|
|
||||||
case 'None':
|
|
||||||
let noneContent = document.createElement('div');
|
|
||||||
noneContent.className = 'section-body-content';
|
|
||||||
|
|
||||||
let noneContentLabel = document.createElement('label');
|
|
||||||
noneContentLabel.innerHTML = 'No Metadata Source';
|
|
||||||
noneContent.appendChild(noneContentLabel);
|
|
||||||
|
|
||||||
itemSectionContent.appendChild(noneContent);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
let contentLabel2 = document.createElement('div');
|
|
||||||
contentLabel2.innerHTML = 'ID: ' + element.sourceId;
|
|
||||||
itemSectionContent.appendChild(contentLabel2);
|
|
||||||
|
|
||||||
let contentLabel3 = document.createElement('div');
|
|
||||||
contentLabel3.innerHTML = 'Slug: ' + element.sourceSlug;
|
|
||||||
itemSectionContent.appendChild(contentLabel3);
|
|
||||||
|
|
||||||
if (element.link) {
|
|
||||||
if (element.link.length > 0) {
|
|
||||||
let contentLabel4 = document.createElement('div');
|
|
||||||
contentLabel4.innerHTML = 'Link: <a href="' + element.link + '" target="_blank" rel="noopener noreferrer" class="romlink">' + element.link + '</a>';
|
|
||||||
itemSectionContent.appendChild(contentLabel4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
itemSection.appendChild(itemSectionContent);
|
|
||||||
|
|
||||||
metadataContent.appendChild(itemSection);
|
|
||||||
});
|
});
|
||||||
|
callingObject.Platform.emulatorConfiguration.emulatorType = defaultPlatformMap.webEmulator.type;
|
||||||
|
callingObject.Platform.emulatorConfiguration.core = defaultPlatformMap.webEmulator.core;
|
||||||
// setup the buttons
|
callingObject.Platform.emulatorConfiguration.enabledBIOSHashes = defaultPlatformMap.enabledBIOSHashes;
|
||||||
let okButton = new ModalButton('OK', 1, callingObject, async function (callingObject) {
|
callingObject.#loadRoms();
|
||||||
let model = metadataMap.metadataMapItems;
|
callingObject.OkCallback();
|
||||||
|
mappingModal.close();
|
||||||
await fetch('/api/v1.1/Games/' + callingObject.Platform.metadataMapId + '/metadata', {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(model)
|
|
||||||
}).then(response => response.json()).then(result => {
|
|
||||||
location.reload(true);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
metadataModal.addButton(okButton);
|
|
||||||
|
|
||||||
let cancelButton = new ModalButton('Cancel', 0, metadataModal, async function (callingObject) {
|
|
||||||
metadataModal.close();
|
|
||||||
});
|
|
||||||
metadataModal.addButton(cancelButton);
|
|
||||||
|
|
||||||
// show the dialog
|
|
||||||
await metadataModal.open();
|
|
||||||
});
|
});
|
||||||
this.romsModal.addButton(platformMappingButton);
|
mappingModal.addButton(resetButton);
|
||||||
}
|
|
||||||
|
|
||||||
if (this.Platform.id != 0) {
|
let okButton = new ModalButton('OK', 1, callingObject, async function (callingObject) {
|
||||||
let platformEditButton = new ModalButton('Configure Emulator', 0, this, async function (callingObject) {
|
let model = {
|
||||||
let mappingModal = await new Modal('messagebox');
|
EmulatorType: emuConfig.PlatformMap.webEmulator.type,
|
||||||
await mappingModal.BuildModal();
|
Core: emuConfig.PlatformMap.webEmulator.core,
|
||||||
|
EnableBIOSFiles: emuConfig.PlatformMap.enabledBIOSHashes
|
||||||
// override the dialog size
|
|
||||||
mappingModal.modalElement.style = 'width: 600px; height: 80%; min-width: unset; min-height: 400px; max-width: unset; max-height: 80%;';
|
|
||||||
|
|
||||||
// get the platform map
|
|
||||||
let platformMap = await fetch('/api/v1.1/PlatformMaps/' + callingObject.Platform.id, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}).then(response => response.json());
|
|
||||||
let defaultPlatformMap = platformMap;
|
|
||||||
|
|
||||||
// get the user emulation configuration
|
|
||||||
let userEmuConfig = await fetch('/api/v1.1/Games/' + callingObject.Platform.metadataMapId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}).then(response => response.json());
|
|
||||||
if (userEmuConfig) {
|
|
||||||
if (userEmuConfig.emulatorType || userEmuConfig.core) {
|
|
||||||
platformMap.webEmulator.type = userEmuConfig.emulatorType;
|
|
||||||
platformMap.webEmulator.core = userEmuConfig.core;
|
|
||||||
}
|
|
||||||
if (userEmuConfig.enableBIOSFiles) {
|
|
||||||
platformMap.enabledBIOSHashes = userEmuConfig.enableBIOSFiles;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the title
|
await fetch('/api/v1.1/Games/' + gameId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
||||||
mappingModal.modalElement.querySelector('#modal-header-text').innerHTML = callingObject.Platform.name + ' Emulation Settings';
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
// set the content
|
'Content-Type': 'application/json'
|
||||||
let mappingContent = mappingModal.modalElement.querySelector('#modal-body');
|
},
|
||||||
mappingContent.innerHTML = '';
|
body: JSON.stringify(model)
|
||||||
let emuConfig = await new WebEmulatorConfiguration(platformMap)
|
|
||||||
emuConfig.open();
|
|
||||||
mappingContent.appendChild(emuConfig.panel);
|
|
||||||
|
|
||||||
// setup the buttons
|
|
||||||
let resetButton = new ModalButton('Reset to Default', 0, callingObject, async function (callingObject) {
|
|
||||||
await fetch('/api/v1.1/Games/' + callingObject.Platform.metadataMapId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
|
||||||
method: 'DELETE'
|
|
||||||
});
|
|
||||||
callingObject.Platform.emulatorConfiguration.emulatorType = defaultPlatformMap.webEmulator.type;
|
|
||||||
callingObject.Platform.emulatorConfiguration.core = defaultPlatformMap.webEmulator.core;
|
|
||||||
callingObject.Platform.emulatorConfiguration.enabledBIOSHashes = defaultPlatformMap.enabledBIOSHashes;
|
|
||||||
callingObject.#loadRoms();
|
|
||||||
callingObject.OkCallback();
|
|
||||||
mappingModal.close();
|
|
||||||
});
|
});
|
||||||
mappingModal.addButton(resetButton);
|
callingObject.Platform.emulatorConfiguration.emulatorType = emuConfig.PlatformMap.webEmulator.type;
|
||||||
|
callingObject.Platform.emulatorConfiguration.core = emuConfig.PlatformMap.webEmulator.core;
|
||||||
|
callingObject.Platform.emulatorConfiguration.enabledBIOSHashes = emuConfig.PlatformMap.enabledBIOSHashes;
|
||||||
|
|
||||||
let okButton = new ModalButton('OK', 1, callingObject, async function (callingObject) {
|
callingObject.#loadRoms();
|
||||||
let model = {
|
callingObject.OkCallback();
|
||||||
EmulatorType: emuConfig.PlatformMap.webEmulator.type,
|
mappingModal.close();
|
||||||
Core: emuConfig.PlatformMap.webEmulator.core,
|
|
||||||
EnableBIOSFiles: emuConfig.PlatformMap.enabledBIOSHashes
|
|
||||||
}
|
|
||||||
|
|
||||||
await fetch('/api/v1.1/Games/' + callingObject.Platform.metadataMapId + '/emulatorconfiguration/' + callingObject.Platform.id, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(model)
|
|
||||||
});
|
|
||||||
callingObject.Platform.emulatorConfiguration.emulatorType = emuConfig.PlatformMap.webEmulator.type;
|
|
||||||
callingObject.Platform.emulatorConfiguration.core = emuConfig.PlatformMap.webEmulator.core;
|
|
||||||
callingObject.Platform.emulatorConfiguration.enabledBIOSHashes = emuConfig.PlatformMap.enabledBIOSHashes;
|
|
||||||
|
|
||||||
callingObject.#loadRoms();
|
|
||||||
callingObject.OkCallback();
|
|
||||||
mappingModal.close();
|
|
||||||
});
|
|
||||||
mappingModal.addButton(okButton);
|
|
||||||
|
|
||||||
let cancelButton = new ModalButton('Cancel', 0, mappingModal, async function (callingObject) {
|
|
||||||
mappingModal.close();
|
|
||||||
});
|
|
||||||
mappingModal.addButton(cancelButton);
|
|
||||||
|
|
||||||
// show the dialog
|
|
||||||
await mappingModal.open();
|
|
||||||
});
|
});
|
||||||
this.romsModal.addButton(platformEditButton);
|
mappingModal.addButton(okButton);
|
||||||
}
|
|
||||||
|
let cancelButton = new ModalButton('Cancel', 0, mappingModal, async function (callingObject) {
|
||||||
|
mappingModal.close();
|
||||||
|
});
|
||||||
|
mappingModal.addButton(cancelButton);
|
||||||
|
|
||||||
|
// show the dialog
|
||||||
|
await mappingModal.open();
|
||||||
|
});
|
||||||
|
this.romsModal.addButton(platformEditButton);
|
||||||
|
|
||||||
let closeButton = new ModalButton('Close', 0, this, function (callingObject) {
|
let closeButton = new ModalButton('Close', 0, this, function (callingObject) {
|
||||||
callingObject.romsModal.close();
|
callingObject.romsModal.close();
|
||||||
@@ -847,13 +680,12 @@ class RomManagement {
|
|||||||
async #loadMediaGroups() {
|
async #loadMediaGroups() {
|
||||||
this.MediaGroupCount = 0;
|
this.MediaGroupCount = 0;
|
||||||
|
|
||||||
fetch('/api/v1.1/Games/' + this.Platform.metadataMapId + '/romgroup?platformid=' + this.Platform.id, {
|
fetch('/api/v1.1/Games/' + gameId + '/romgroup?platformid=' + this.Platform.id, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
}).then(response => response.json()).then(result => {
|
}).then(response => response.json()).then(result => {
|
||||||
console.log(result);
|
|
||||||
// display media groups
|
// display media groups
|
||||||
if (result.length == 0) {
|
if (result.length == 0) {
|
||||||
this.MediaGroups.style.display = 'none';
|
this.MediaGroups.style.display = 'none';
|
||||||
@@ -876,7 +708,7 @@ class RomManagement {
|
|||||||
let saveStatesButton = '';
|
let saveStatesButton = '';
|
||||||
if (this.Platform.emulatorConfiguration) {
|
if (this.Platform.emulatorConfiguration) {
|
||||||
if ((this.Platform.emulatorConfiguration.emulatorType.length > 0) && (this.Platform.emulatorConfiguration.core.length > 0)) {
|
if ((this.Platform.emulatorConfiguration.emulatorType.length > 0) && (this.Platform.emulatorConfiguration.core.length > 0)) {
|
||||||
let romPath = encodeURIComponent('/api/v1.1/Games/' + this.Platform.metadataMapId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip');
|
let romPath = encodeURIComponent('/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip');
|
||||||
|
|
||||||
if (mediaGroup.hasSaveStates == true) {
|
if (mediaGroup.hasSaveStates == true) {
|
||||||
let modalVariables = {
|
let modalVariables = {
|
||||||
@@ -891,13 +723,13 @@ class RomManagement {
|
|||||||
};
|
};
|
||||||
saveStatesButton = document.createElement('div');
|
saveStatesButton = document.createElement('div');
|
||||||
saveStatesButton.addEventListener('click', () => {
|
saveStatesButton.addEventListener('click', () => {
|
||||||
let stateManager = new EmulatorStateManager(mediaGroup.id, true, this.Platform.emulatorConfiguration.emulatorType, this.Platform.emulatorConfiguration.core, mediaGroup.platformId, this.Platform.metadataMapId, romPath);
|
let stateManager = new EmulatorStateManager(mediaGroup.id, true, this.Platform.emulatorConfiguration.emulatorType, this.Platform.emulatorConfiguration.core, mediaGroup.platformId, gameId, romPath);
|
||||||
stateManager.open();
|
stateManager.open();
|
||||||
});
|
});
|
||||||
saveStatesButton.innerHTML = '<img src="/images/SaveStates.png" class="savedstateicon" />';
|
saveStatesButton.innerHTML = '<img src="/images/SaveStates.png" class="savedstateicon" />';
|
||||||
}
|
}
|
||||||
|
|
||||||
launchButton = '<a href="/index.html?page=emulator&engine=' + this.Platform.emulatorConfiguration.emulatorType + '&core=' + this.Platform.emulatorConfiguration.core + '&platformid=' + mediaGroup.platformId + '&gameid=' + this.Platform.metadataMapId + '&romid=' + mediaGroup.id + '&mediagroup=1&rompath=' + romPath + '" class="romstart">Launch</a>';
|
launchButton = '<a href="/index.html?page=emulator&engine=' + this.Platform.emulatorConfiguration.emulatorType + '&core=' + this.Platform.emulatorConfiguration.core + '&platformid=' + mediaGroup.platformId + '&gameid=' + gameId + '&romid=' + mediaGroup.id + '&mediagroup=1&rompath=' + romPath + '" class="romstart">Launch</a>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,7 +745,7 @@ class RomManagement {
|
|||||||
favouriteRom.src = '/images/favourite-empty.svg';
|
favouriteRom.src = '/images/favourite-empty.svg';
|
||||||
}
|
}
|
||||||
favouriteRom.addEventListener('click', async () => {
|
favouriteRom.addEventListener('click', async () => {
|
||||||
await fetch('/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + mediaGroup.id + '/' + mediaGroup.platformId + '/favourite?IsMediaGroup=true&favourite=true', {
|
await fetch('/api/v1.1/Games/' + gameId + '/roms/' + mediaGroup.id + '/' + mediaGroup.platformId + '/favourite?IsMediaGroup=true&favourite=true', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -958,7 +790,7 @@ class RomManagement {
|
|||||||
break;
|
break;
|
||||||
case "Completed":
|
case "Completed":
|
||||||
statusText = 'Available';
|
statusText = 'Available';
|
||||||
downloadLink = '<a href="/api/v1.1/Games/' + this.Platform.metadataMapId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip" class="romlink"><img src="/images/download.svg" class="banner_button_image" alt="Download" title="Download" /></a>';
|
downloadLink = '<a href="/api/v1.1/Games/' + gameId + '/romgroup/' + mediaGroup.id + '/' + gameData.name + '.zip" class="romlink"><img src="/images/download.svg" class="banner_button_image" alt="Download" title="Download" /></a>';
|
||||||
packageSize = formatBytes(mediaGroup.size);
|
packageSize = formatBytes(mediaGroup.size);
|
||||||
launchButtonContent = launchButton;
|
launchButtonContent = launchButton;
|
||||||
break;
|
break;
|
||||||
@@ -988,7 +820,7 @@ class RomManagement {
|
|||||||
|
|
||||||
let deleteButton = new ModalButton("Delete", 2, deleteWindow, function (callingObject) {
|
let deleteButton = new ModalButton("Delete", 2, deleteWindow, function (callingObject) {
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/Games/' + this.Platform.metadataMapId + '/romgroup/' + mediaGroup.id,
|
'/api/v1.1/Games/' + gameData.id + '/romgroup/' + mediaGroup.id,
|
||||||
'DELETE',
|
'DELETE',
|
||||||
function (result) {
|
function (result) {
|
||||||
thisObject.#loadRoms();
|
thisObject.#loadRoms();
|
||||||
@@ -1092,7 +924,7 @@ class RomManagement {
|
|||||||
let gameRomsSection = this.Roms;
|
let gameRomsSection = this.Roms;
|
||||||
let gameRoms = this.RomsContent;
|
let gameRoms = this.RomsContent;
|
||||||
let pageSize = 200;
|
let pageSize = 200;
|
||||||
await fetch('/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms?pageNumber=' + pageNumber + '&pageSize=' + pageSize + '&platformId=' + selectedPlatform + nameSearchQuery, {
|
await fetch('/api/v1.1/Games/' + gameId + '/roms?pageNumber=' + pageNumber + '&pageSize=' + pageSize + '&platformId=' + selectedPlatform + nameSearchQuery, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -1100,7 +932,6 @@ class RomManagement {
|
|||||||
}).then(async response => {
|
}).then(async response => {
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let result = await response.json();
|
let result = await response.json();
|
||||||
console.log(result);
|
|
||||||
let romCount = this.romsModal.modalElement.querySelector('#games_roms_count');
|
let romCount = this.romsModal.modalElement.querySelector('#games_roms_count');
|
||||||
this.RomCount = result.count;
|
this.RomCount = result.count;
|
||||||
if (result.count != 1) {
|
if (result.count != 1) {
|
||||||
@@ -1157,7 +988,7 @@ class RomManagement {
|
|||||||
if (this.Platform.emulatorConfiguration) {
|
if (this.Platform.emulatorConfiguration) {
|
||||||
if (this.Platform.emulatorConfiguration.emulatorType) {
|
if (this.Platform.emulatorConfiguration.emulatorType) {
|
||||||
if (this.Platform.emulatorConfiguration.emulatorType.length > 0) {
|
if (this.Platform.emulatorConfiguration.emulatorType.length > 0) {
|
||||||
let romPath = encodeURIComponent('/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + gameRomItems[i].id + '/' + gameRomItems[i].name);
|
let romPath = encodeURIComponent('/api/v1.1/Games/' + gameId + '/roms/' + gameRomItems[i].id + '/' + gameRomItems[i].name);
|
||||||
if (gameRomItems[i].hasSaveStates == true) {
|
if (gameRomItems[i].hasSaveStates == true) {
|
||||||
let modalVariables = {
|
let modalVariables = {
|
||||||
"romId": gameRomItems[i].id,
|
"romId": gameRomItems[i].id,
|
||||||
@@ -1165,27 +996,28 @@ class RomManagement {
|
|||||||
"engine": this.Platform.emulatorConfiguration.emulatorType,
|
"engine": this.Platform.emulatorConfiguration.emulatorType,
|
||||||
"core": this.Platform.emulatorConfiguration.core,
|
"core": this.Platform.emulatorConfiguration.core,
|
||||||
"platformid": gameRomItems[i].platformId,
|
"platformid": gameRomItems[i].platformId,
|
||||||
"gameid": this.Platform.metadataMapId,
|
"gameid": gameId,
|
||||||
"mediagroup": 0,
|
"mediagroup": 0,
|
||||||
"rompath": romPath
|
"rompath": romPath
|
||||||
};
|
};
|
||||||
saveStatesButton = document.createElement('div');
|
saveStatesButton = document.createElement('div');
|
||||||
saveStatesButton.addEventListener('click', () => {
|
saveStatesButton.addEventListener('click', () => {
|
||||||
let stateManager = new EmulatorStateManager(gameRomItems[i].id, false, this.Platform.emulatorConfiguration.emulatorType, this.Platform.emulatorConfiguration.core, gameRomItems[i].platformId, this.Platform.metadataMapId, gameRomItems[i].name);
|
let stateManager = new EmulatorStateManager(gameRomItems[i].id, false, this.Platform.emulatorConfiguration.emulatorType, this.Platform.emulatorConfiguration.core, gameRomItems[i].platformId, gameId, gameRomItems[i].name);
|
||||||
stateManager.open();
|
stateManager.open();
|
||||||
});
|
});
|
||||||
saveStatesButton.innerHTML = '<img src="/images/SaveStates.png" class="savedstateicon" />';
|
saveStatesButton.innerHTML = '<img src="/images/SaveStates.png" class="savedstateicon" />';
|
||||||
}
|
}
|
||||||
launchButton = '<a href="/index.html?page=emulator&engine=' + this.Platform.emulatorConfiguration.emulatorType + '&core=' + this.Platform.emulatorConfiguration.core + '&platformid=' + gameRomItems[i].platformId + '&gameid=' + this.Platform.metadataMapId + '&romid=' + gameRomItems[i].id + '&mediagroup=0&rompath=' + romPath + '" class="romstart">Launch</a>';
|
launchButton = '<a href="/index.html?page=emulator&engine=' + this.Platform.emulatorConfiguration.emulatorType + '&core=' + this.Platform.emulatorConfiguration.core + '&platformid=' + gameRomItems[i].platformId + '&gameid=' + gameId + '&romid=' + gameRomItems[i].id + '&mediagroup=0&rompath=' + romPath + '" class="romstart">Launch</a>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let romInfoButton = document.createElement('div');
|
let romInfoButton = document.createElement('div');
|
||||||
romInfoButton.className = 'properties_button';
|
romInfoButton.className = 'properties_button';
|
||||||
|
//romInfoButton.setAttribute('onclick', 'showDialog(\'rominfo\', ' + gameRomItems[i].id + ');');
|
||||||
romInfoButton.setAttribute('data-romid', gameRomItems[i].id);
|
romInfoButton.setAttribute('data-romid', gameRomItems[i].id);
|
||||||
romInfoButton.addEventListener('click', () => {
|
romInfoButton.addEventListener('click', function () {
|
||||||
const romInfoDialog = new rominfodialog(this.Platform.metadataMapId, gameRomItems[i].id);
|
const romInfoDialog = new rominfodialog(gameId, this.getAttribute('data-romid'));
|
||||||
romInfoDialog.open();
|
romInfoDialog.open();
|
||||||
});
|
});
|
||||||
romInfoButton.innerHTML = 'i';
|
romInfoButton.innerHTML = 'i';
|
||||||
@@ -1212,7 +1044,7 @@ class RomManagement {
|
|||||||
favouriteRom.src = '/images/favourite-empty.svg';
|
favouriteRom.src = '/images/favourite-empty.svg';
|
||||||
}
|
}
|
||||||
favouriteRom.addEventListener('click', async () => {
|
favouriteRom.addEventListener('click', async () => {
|
||||||
await fetch('/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + gameRomItems[i].id + '/' + gameRomItems[i].platformId + '/favourite?IsMediaGroup=false&favourite=true', {
|
await fetch('/api/v1.1/Games/' + gameId + '/roms/' + gameRomItems[i].id + '/' + gameRomItems[i].platformId + '/favourite?IsMediaGroup=false&favourite=true', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -1239,7 +1071,7 @@ class RomManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let romLink = document.createElement('a');
|
let romLink = document.createElement('a');
|
||||||
romLink.href = '/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + gameRomItems[i].id + '/' + encodeURIComponent(gameRomItems[i].name);
|
romLink.href = '/api/v1.1/Games/' + gameId + '/roms/' + gameRomItems[i].id + '/' + encodeURIComponent(gameRomItems[i].name);
|
||||||
romLink.className = 'romlink';
|
romLink.className = 'romlink';
|
||||||
romLink.innerHTML = gameRomItems[i].name;
|
romLink.innerHTML = gameRomItems[i].name;
|
||||||
|
|
||||||
@@ -1268,51 +1100,51 @@ class RomManagement {
|
|||||||
this.#DisplayROMCheckboxes(true);
|
this.#DisplayROMCheckboxes(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (result.count > pageSize) {
|
if (result.count > pageSize) {
|
||||||
// // draw pagination
|
// draw pagination
|
||||||
// let numOfPages = Math.ceil(result.count / pageSize);
|
let numOfPages = Math.ceil(result.count / pageSize);
|
||||||
|
|
||||||
// let romPaginator = document.createElement('div');
|
let romPaginator = document.createElement('div');
|
||||||
// romPaginator.id = 'romPaginator';
|
romPaginator.id = 'romPaginator';
|
||||||
// romPaginator.className = 'rom_pager';
|
romPaginator.className = 'rom_pager';
|
||||||
|
|
||||||
// // draw previous page button
|
// draw previous page button
|
||||||
// let prevPage = document.createElement('span');
|
let prevPage = document.createElement('span');
|
||||||
// prevPage.className = 'rom_pager_number_disabled';
|
prevPage.className = 'rom_pager_number_disabled';
|
||||||
// prevPage.innerHTML = '<';
|
prevPage.innerHTML = '<';
|
||||||
// if (pageNumber != 1) {
|
if (pageNumber != 1) {
|
||||||
// prevPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (pageNumber - 1) + ', ' + selectedPlatform + ');');
|
prevPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (pageNumber - 1) + ', ' + selectedPlatform + ');');
|
||||||
// prevPage.className = 'rom_pager_number';
|
prevPage.className = 'rom_pager_number';
|
||||||
// }
|
}
|
||||||
// romPaginator.appendChild(prevPage);
|
romPaginator.appendChild(prevPage);
|
||||||
|
|
||||||
// // draw page numbers
|
// draw page numbers
|
||||||
// for (let i = 0; i < numOfPages; i++) {
|
for (let i = 0; i < numOfPages; i++) {
|
||||||
// let romPaginatorPage = document.createElement('span');
|
let romPaginatorPage = document.createElement('span');
|
||||||
// romPaginatorPage.className = 'rom_pager_number_disabled';
|
romPaginatorPage.className = 'rom_pager_number_disabled';
|
||||||
// romPaginatorPage.innerHTML = (i + 1);
|
romPaginatorPage.innerHTML = (i + 1);
|
||||||
// if ((i + 1) != pageNumber) {
|
if ((i + 1) != pageNumber) {
|
||||||
// romPaginatorPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (i + 1) + ', ' + selectedPlatform + ');');
|
romPaginatorPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (i + 1) + ', ' + selectedPlatform + ');');
|
||||||
// romPaginatorPage.className = 'rom_pager_number';
|
romPaginatorPage.className = 'rom_pager_number';
|
||||||
// }
|
}
|
||||||
|
|
||||||
// romPaginator.appendChild(romPaginatorPage);
|
romPaginator.appendChild(romPaginatorPage);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // draw next page button
|
// draw next page button
|
||||||
// let nextPage = document.createElement('span');
|
let nextPage = document.createElement('span');
|
||||||
// nextPage.className = 'rom_pager_number_disabled';
|
nextPage.className = 'rom_pager_number_disabled';
|
||||||
// nextPage.innerHTML = '>';
|
nextPage.innerHTML = '>';
|
||||||
// if (pageNumber != numOfPages) {
|
if (pageNumber != numOfPages) {
|
||||||
// nextPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (pageNumber + 1) + ', ' + selectedPlatform + ');');
|
nextPage.setAttribute('onclick', 'loadRoms(' + undefined + ', ' + (pageNumber + 1) + ', ' + selectedPlatform + ');');
|
||||||
// nextPage.className = 'rom_pager_number';
|
nextPage.className = 'rom_pager_number';
|
||||||
// }
|
}
|
||||||
// romPaginator.appendChild(nextPage);
|
romPaginator.appendChild(nextPage);
|
||||||
|
|
||||||
// gameRoms.appendChild(romPaginator);
|
gameRoms.appendChild(romPaginator);
|
||||||
|
|
||||||
// gameRomsSection.appendChild(gameRoms);
|
gameRomsSection.appendChild(gameRoms);
|
||||||
// }
|
}
|
||||||
} else {
|
} else {
|
||||||
gameRomsSection.setAttribute('style', 'display: none;');
|
gameRomsSection.setAttribute('style', 'display: none;');
|
||||||
}
|
}
|
||||||
@@ -1446,7 +1278,7 @@ class RomManagement {
|
|||||||
if (rom_checks[i].checked == true) {
|
if (rom_checks[i].checked == true) {
|
||||||
let romId = rom_checks[i].getAttribute('data-romid');
|
let romId = rom_checks[i].getAttribute('data-romid');
|
||||||
remapCallCounter += 1;
|
remapCallCounter += 1;
|
||||||
let deletePath = '/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + romId;
|
let deletePath = '/api/v1.1/Games/' + gameId + '/roms/' + romId;
|
||||||
let parentObject = this;
|
let parentObject = this;
|
||||||
ajaxCall(deletePath, 'DELETE', function (result) {
|
ajaxCall(deletePath, 'DELETE', function (result) {
|
||||||
parentObject.#remapTitlesCallback();
|
parentObject.#remapTitlesCallback();
|
||||||
@@ -1475,7 +1307,7 @@ class RomManagement {
|
|||||||
if (rom_checks[i].checked == true) {
|
if (rom_checks[i].checked == true) {
|
||||||
let romId = rom_checks[i].getAttribute('data-romid');
|
let romId = rom_checks[i].getAttribute('data-romid');
|
||||||
remapCallCounter += 1;
|
remapCallCounter += 1;
|
||||||
ajaxCall('/api/v1.1/Games/' + this.Platform.metadataMapId + '/roms/' + romId + '?NewPlatformId=' + fixplatform[0].id + '&NewGameId=' + fixgame[0].id, 'PATCH', function (result) {
|
ajaxCall('/api/v1.1/Games/' + gameId + '/roms/' + romId + '?NewPlatformId=' + fixplatform[0].id + '&NewGameId=' + fixgame[0].id, 'PATCH', function (result) {
|
||||||
thisObject.#remapTitlesCallback();
|
thisObject.#remapTitlesCallback();
|
||||||
}, function (result) {
|
}, function (result) {
|
||||||
thisObject.#remapTitlesCallback();
|
thisObject.#remapTitlesCallback();
|
||||||
@@ -1529,7 +1361,7 @@ class RomManagement {
|
|||||||
let currentObject = this;
|
let currentObject = this;
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/Games/' + this.Platform.metadataMapId + '/romgroup?PlatformId=' + platformId,
|
'/api/v1.1/Games/' + gameId + '/romgroup?PlatformId=' + platformId,
|
||||||
'POST',
|
'POST',
|
||||||
function (result) {
|
function (result) {
|
||||||
currentObject.#DisplayROMCheckboxes(false);
|
currentObject.#DisplayROMCheckboxes(false);
|
||||||
@@ -1616,7 +1448,7 @@ class RomManagement {
|
|||||||
id: data[i].id,
|
id: data[i].id,
|
||||||
text: data[i].name,
|
text: data[i].name,
|
||||||
cover: data[i].cover,
|
cover: data[i].cover,
|
||||||
releaseDate: data[i].first_release_date
|
releaseDate: data[i].firstReleaseDate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1634,8 +1466,8 @@ function loadArtwork(game, cover) {
|
|||||||
|
|
||||||
// default background should be the artworks
|
// default background should be the artworks
|
||||||
if (game.artworks) {
|
if (game.artworks) {
|
||||||
for (let i = 0; i < game.artworks.length; i++) {
|
for (let i = 0; i < game.artworks.ids.length; i++) {
|
||||||
URLList.push("/api/v1.1/Games/" + gameId + "/artwork/" + game.artworks[i] + "/image/original/" + game.artworks[i] + ".jpg");
|
URLList.push("/api/v1.1/Games/" + gameId + "/artwork/" + game.artworks.ids[i] + "/image/original/" + game.artworks.ids[i] + ".jpg");
|
||||||
}
|
}
|
||||||
} else if (game.cover) {
|
} else if (game.cover) {
|
||||||
// backup background is the cover artwork
|
// backup background is the cover artwork
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<div id="gamepage">
|
<div id="gamepage">
|
||||||
<div style="padding-top: 20px;">
|
<div style="padding-top: 20px;">
|
||||||
<div id="gamehome"
|
<div id="gamehome" style="display: inline-block; max-width: 820px; margin-right: 20px; vertical-align: top;">
|
||||||
style="display: inline-block; max-width: 820px; margin-right: 20px; vertical-align: top; width: 100%;">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="gameprofile" style="display: inline-block; width: 250px;">
|
<div id="gameprofile" style="display: inline-block; width: 250px;">
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class HomePageGameRow {
|
|||||||
let gameItem = document.createElement("li");
|
let gameItem = document.createElement("li");
|
||||||
gameItem.classList.add("homegame-item");
|
gameItem.classList.add("homegame-item");
|
||||||
|
|
||||||
let gameIcon = renderGameIcon(game, true, showRatings, showClassification, classificationDisplayOrder, true, false, true);
|
let gameIcon = renderGameIcon(game, true, showRatings, showClassification, classificationDisplayOrder, true, false);
|
||||||
gameItem.appendChild(gameIcon);
|
gameItem.appendChild(gameIcon);
|
||||||
scroller.appendChild(gameItem);
|
scroller.appendChild(gameItem);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,8 @@
|
|||||||
<div id="gamesummarymediagroupscontent" class="section-body"></div>
|
<div id="gamesummarymediagroupscontent" class="section-body"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="gamesummaryroms" class="section">
|
<div id="gamesummaryroms" class="section">
|
||||||
<div class="section-header">
|
<span id="rom_edit" class="romlink">Edit</span>
|
||||||
<span id="rom_edit" class="romlink">Edit</span>
|
<div class="section-header">ROMs/Images</div>
|
||||||
<span>ROMs/Images</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<div id="rom_edit_panel" style="display: none;">
|
<div id="rom_edit_panel" style="display: none;">
|
||||||
<div id="rom_edit_panel_center">
|
<div id="rom_edit_panel_center">
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
<p>This list is pre-populated with some of the more common platforms. New platforms will appear in this list as
|
<p>This list is pre-populated with some of the more common platforms. New platforms will appear in this list as
|
||||||
titles are added.</p>
|
titles are added.</p>
|
||||||
|
|
||||||
<p id="settings_mapping_import" style="display: none;"><button id="exportjson" value="Export to JSON">Export to
|
<p id="settings_mapping_import" style="display: none;"><button value="Export to JSON"
|
||||||
JSON</button><button id="importjson" value="Import JSON">Import
|
onclick="DownloadJSON();">Export to JSON</button><button id="importjson" value="Import JSON">Import
|
||||||
JSON</button><button id="resetmapping" value="Reset to Default">Reset to
|
JSON</button><button value="Reset to Default" onclick="loadPlatformMapping(true);">Reset to
|
||||||
Default</button></p>
|
Default</button></p>
|
||||||
|
|
||||||
<input id='uploadjson' type='file' name='files' hidden />
|
<input id='uploadjson' type='file' name='files' hidden />
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ function loadPlatformMapping(Overwrite) {
|
|||||||
createTableRow(
|
createTableRow(
|
||||||
true,
|
true,
|
||||||
[
|
[
|
||||||
'',
|
|
||||||
'Platform',
|
'Platform',
|
||||||
'Supported File Extensions',
|
'Supported File Extensions',
|
||||||
'Unique File Extensions',
|
'Unique File Extensions',
|
||||||
@@ -28,17 +27,6 @@ function loadPlatformMapping(Overwrite) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
let logoBox = document.createElement('div');
|
|
||||||
logoBox.classList.add('platform_image_container');
|
|
||||||
|
|
||||||
let logo = document.createElement('img');
|
|
||||||
logo.src = '/api/v1.1/Platforms/' + result[i].igdbId + '/platformlogo/original/';
|
|
||||||
logo.alt = result[i].igdbName;
|
|
||||||
logo.title = result[i].igdbName;
|
|
||||||
logo.classList.add('platform_image');
|
|
||||||
|
|
||||||
logoBox.appendChild(logo);
|
|
||||||
|
|
||||||
let hasWebEmulator = '';
|
let hasWebEmulator = '';
|
||||||
if (result[i].webEmulator.type.length > 0) {
|
if (result[i].webEmulator.type.length > 0) {
|
||||||
hasWebEmulator = 'Yes';
|
hasWebEmulator = 'Yes';
|
||||||
@@ -61,7 +49,6 @@ function loadPlatformMapping(Overwrite) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let newRow = [
|
let newRow = [
|
||||||
logoBox,
|
|
||||||
result[i].igdbName,
|
result[i].igdbName,
|
||||||
result[i].extensions.supportedFileExtensions.join(', '),
|
result[i].extensions.supportedFileExtensions.join(', '),
|
||||||
result[i].extensions.uniqueFileExtensions.join(', '),
|
result[i].extensions.uniqueFileExtensions.join(', '),
|
||||||
@@ -83,7 +70,6 @@ function SetupButtons() {
|
|||||||
if (userProfile.roles.includes("Admin")) {
|
if (userProfile.roles.includes("Admin")) {
|
||||||
document.getElementById('settings_mapping_import').style.display = '';
|
document.getElementById('settings_mapping_import').style.display = '';
|
||||||
|
|
||||||
// Setup the JSON import button
|
|
||||||
document.getElementById('uploadjson').addEventListener('change', function () {
|
document.getElementById('uploadjson').addEventListener('change', function () {
|
||||||
$(this).simpleUpload("/api/v1.1/PlatformMaps", {
|
$(this).simpleUpload("/api/v1.1/PlatformMaps", {
|
||||||
start: function (file) {
|
start: function (file) {
|
||||||
@@ -98,24 +84,6 @@ function SetupButtons() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('importjson').addEventListener('click', openDialog);
|
document.getElementById('importjson').addEventListener('click', openDialog);
|
||||||
|
|
||||||
// Setup the JSON export button
|
|
||||||
document.getElementById('exportjson').addEventListener('click', DownloadJSON);
|
|
||||||
|
|
||||||
// Setup the reset to defaults button
|
|
||||||
document.getElementById('resetmapping').addEventListener('click', function () {
|
|
||||||
let warningDialog = new MessageBox("Platform Mapping Reset", "This will reset the platform mappings to the default values. Are you sure you want to continue?");
|
|
||||||
warningDialog.addButton(new ModalButton("OK", 2, warningDialog, async (callingObject) => {
|
|
||||||
loadPlatformMapping(true);
|
|
||||||
callingObject.msgDialog.close();
|
|
||||||
let completedDialog = new MessageBox("Platform Mapping Reset", "All platform mappings have been reset to default values.");
|
|
||||||
completedDialog.open();
|
|
||||||
}));
|
|
||||||
warningDialog.addButton(new ModalButton("Cancel", 0, warningDialog, async (callingObject) => {
|
|
||||||
callingObject.msgDialog.close();
|
|
||||||
}));
|
|
||||||
warningDialog.open();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="section-header">Signature Sources</div>
|
<div class="section-header">Metadata Sources</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<table style="width: 100%;">
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width: 30%;">
|
<td style="width: 25%;">
|
||||||
Signature Source
|
Signature Source
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_local"
|
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_local"
|
||||||
value="LocalOnly">
|
value="LocalOnly"
|
||||||
|
onclick="document.getElementById('settings_hasheoushost_row').style.display = 'none';">
|
||||||
<label for="settings_signaturesource_local">Local Only</label>
|
<label for="settings_signaturesource_local">Local Only</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -20,27 +21,13 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_hasheous"
|
<input type="radio" name="settings_signaturesource" id="settings_signaturesource_hasheous"
|
||||||
value="Hasheous">
|
value="Hasheous"
|
||||||
|
onclick="document.getElementById('settings_hasheoushost_row').style.display = '';">
|
||||||
<label for="settings_signaturesource_hasheous">Hasheous</label>
|
<label for="settings_signaturesource_hasheous">Hasheous</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
<tr id="settings_hasheoushost_row" style="display: none;">
|
||||||
</div>
|
<td>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<div class="section-header">Default Metadata Source</div>
|
|
||||||
<div class="section-body" id="settings_metadata">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<div class="section-header">Hasheous Configuration</div>
|
|
||||||
<div class="section-body">
|
|
||||||
<table style="width: 100%;">
|
|
||||||
<tr id="settings_hasheoushost_row">
|
|
||||||
<td style="width: 30%;">
|
|
||||||
Hasheous Host
|
Hasheous Host
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -49,15 +36,14 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="settings_hasheoussubmit">Submit updates to Hasheous when fixing ROM
|
<label for="settings_hasheoussubmit">Submit updates to Hasheous when fixing ROM matches</label>
|
||||||
matches</label>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="checkbox" id="settings_hasheoussubmit" onchange="toggleHasheousAPIKey(this);">
|
<input type="checkbox" id="settings_hasheoussubmit" onchange="toggleHasheousAPIKey(this);">
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr id="settings_hasheousapikey_row">
|
<tr id="settings_hasheousapikey_row" style="display: none;">
|
||||||
<td style="width: 30%;">
|
<td>
|
||||||
Hasheous API key
|
Hasheous API key
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -66,9 +52,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="section">
|
|
||||||
<div class="section-header">Logging</div>
|
<div class="section-header">Logging</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<table>
|
<table>
|
||||||
@@ -102,8 +85,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="section">
|
|
||||||
<div class="section-header">Emulator</div>
|
<div class="section-header">Emulator</div>
|
||||||
<div class="section-body">
|
<div class="section-body">
|
||||||
<table>
|
<table>
|
||||||
@@ -114,10 +95,9 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div style="text-align: right;">
|
||||||
|
<button id="settings_tasktimers_new" onclick="setSystemSettings();">Save</button>
|
||||||
<div style="text-align: right;">
|
</div>
|
||||||
<button id="settings_tasktimers_new" onclick="setSystemSettings();">Save</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
function getSystemSettings() {
|
function getSystemSettings() {
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/System/Settings/System',
|
'/api/v1/System/Settings/System',
|
||||||
'GET',
|
'GET',
|
||||||
function (result) {
|
function (result) {
|
||||||
console.log(result);
|
console.log(result);
|
||||||
@@ -21,184 +21,11 @@ function getSystemSettings() {
|
|||||||
|
|
||||||
case "Hasheous":
|
case "Hasheous":
|
||||||
document.getElementById('settings_signaturesource_hasheous').checked = true;
|
document.getElementById('settings_signaturesource_hasheous').checked = true;
|
||||||
|
document.getElementById('settings_hasheoushost_row').style.display = '';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadataSettingsContainer = document.getElementById('settings_metadata');
|
|
||||||
metadataSettingsContainer.innerHTML = '';
|
|
||||||
result.metadataSources.forEach(element => {
|
|
||||||
// section
|
|
||||||
let sourceSection = document.createElement('div');
|
|
||||||
sourceSection.classList.add('section');
|
|
||||||
sourceSection.setAttribute('id', 'settings_metadatasource_' + element.source);
|
|
||||||
|
|
||||||
// section header
|
|
||||||
let sourceHeader = document.createElement('div');
|
|
||||||
sourceHeader.classList.add('section-header');
|
|
||||||
|
|
||||||
let sourceRadio = document.createElement('input');
|
|
||||||
sourceRadio.setAttribute('type', 'radio');
|
|
||||||
sourceRadio.setAttribute('name', 'settings_metadatasource');
|
|
||||||
sourceRadio.setAttribute('value', element.source);
|
|
||||||
sourceRadio.setAttribute('id', 'settings_metadatasource_' + element.source + '_radio');
|
|
||||||
sourceRadio.style.margin = '0px';
|
|
||||||
sourceRadio.style.height = 'unset';
|
|
||||||
if (element.default) {
|
|
||||||
sourceRadio.checked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let sourceLabel = document.createElement('label');
|
|
||||||
sourceLabel.setAttribute('for', 'settings_metadatasource_' + element.source + '_radio');
|
|
||||||
|
|
||||||
let sourceName = document.createElement('span');
|
|
||||||
switch (element.source) {
|
|
||||||
case "IGDB":
|
|
||||||
sourceName.innerText = 'Internet Game Database (IGDB)';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
sourceName.innerText = element.source;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sourceName.style.marginLeft = '10px';
|
|
||||||
sourceLabel.appendChild(sourceName);
|
|
||||||
|
|
||||||
let sourceConfigured = document.createElement('span');
|
|
||||||
sourceConfigured.style.float = 'right';
|
|
||||||
sourceConfigured.classList.add(element.configured ? 'greentext' : 'redtext');
|
|
||||||
sourceConfigured.innerText = element.configured ? 'Configured' : 'Not Configured';
|
|
||||||
|
|
||||||
sourceHeader.appendChild(sourceRadio);
|
|
||||||
sourceHeader.appendChild(sourceLabel);
|
|
||||||
sourceHeader.appendChild(sourceConfigured);
|
|
||||||
sourceSection.appendChild(sourceHeader);
|
|
||||||
|
|
||||||
// section body
|
|
||||||
let sourceContent = document.createElement('div');
|
|
||||||
sourceContent.classList.add('section-body');
|
|
||||||
if (element.usesProxy === false && element.usesClientIdAndSecret === false) {
|
|
||||||
sourceContent.innerText = 'No options to configure';
|
|
||||||
} else {
|
|
||||||
// render controls
|
|
||||||
let controlsTable = document.createElement('table');
|
|
||||||
controlsTable.style.width = '100%';
|
|
||||||
|
|
||||||
// hasheous proxy row
|
|
||||||
if (element.usesProxy === true) {
|
|
||||||
let proxyRow = document.createElement('tr');
|
|
||||||
|
|
||||||
let proxyLabel = document.createElement('td');
|
|
||||||
if (element.usesClientIdAndSecret === true) {
|
|
||||||
let proxyRadio = document.createElement('input');
|
|
||||||
proxyRadio.id = 'settings_metadatasource_proxy_' + element.source;
|
|
||||||
proxyRadio.setAttribute('type', 'radio');
|
|
||||||
proxyRadio.setAttribute('name', 'settings_metadatasource_proxy_' + element.source);
|
|
||||||
proxyRadio.style.marginRight = '10px';
|
|
||||||
if (element.useHasheousProxy === true) {
|
|
||||||
proxyRadio.checked = true;
|
|
||||||
}
|
|
||||||
proxyLabel.appendChild(proxyRadio);
|
|
||||||
|
|
||||||
let proxyLabelLabel = document.createElement('label');
|
|
||||||
proxyLabelLabel.setAttribute('for', 'settings_metadatasource_proxy_' + element.source);
|
|
||||||
|
|
||||||
let proxyLabelSpan = document.createElement('span');
|
|
||||||
proxyLabelSpan.innerText = 'Use Hasheous Proxy';
|
|
||||||
proxyLabelLabel.appendChild(proxyLabelSpan);
|
|
||||||
proxyLabel.appendChild(proxyLabelLabel);
|
|
||||||
|
|
||||||
proxyRow.appendChild(proxyLabel);
|
|
||||||
} else {
|
|
||||||
proxyLabel.innerHTML = 'Uses Hasheous Proxy';
|
|
||||||
proxyRow.appendChild(proxyLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
controlsTable.appendChild(proxyRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
// client id and secret row
|
|
||||||
if (element.usesClientIdAndSecret === true) {
|
|
||||||
if (element.usesProxy === true) {
|
|
||||||
let clientRadioRow = document.createElement('tr');
|
|
||||||
|
|
||||||
let clientRadioLabel = document.createElement('td');
|
|
||||||
let clientRadio = document.createElement('input');
|
|
||||||
clientRadio.id = 'settings_metadatasource_client_' + element.source;
|
|
||||||
clientRadio.setAttribute('type', 'radio');
|
|
||||||
clientRadio.setAttribute('name', 'settings_metadatasource_proxy_' + element.source);
|
|
||||||
clientRadio.style.marginRight = '10px';
|
|
||||||
if (element.useHasheousProxy === false) {
|
|
||||||
clientRadio.checked = true;
|
|
||||||
}
|
|
||||||
clientRadioLabel.appendChild(clientRadio);
|
|
||||||
|
|
||||||
let clientRadioLabelLabel = document.createElement('label');
|
|
||||||
clientRadioLabelLabel.setAttribute('for', 'settings_metadatasource_client_' + element.source);
|
|
||||||
|
|
||||||
let clientRadioLabelSpan = document.createElement('span');
|
|
||||||
clientRadioLabelSpan.innerText = 'Direct connection';
|
|
||||||
clientRadioLabelLabel.appendChild(clientRadioLabelSpan);
|
|
||||||
clientRadioLabel.appendChild(clientRadioLabelLabel);
|
|
||||||
|
|
||||||
clientRadioRow.appendChild(clientRadioLabel);
|
|
||||||
|
|
||||||
controlsTable.appendChild(clientRadioRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
let clientIdTable = document.createElement('table');
|
|
||||||
clientIdTable.style.width = '100%';
|
|
||||||
if (element.usesProxy === true) {
|
|
||||||
clientIdTable.style.marginLeft = '30px';
|
|
||||||
}
|
|
||||||
|
|
||||||
let clientIdRow = document.createElement('tr');
|
|
||||||
|
|
||||||
let clientIdLabel = document.createElement('td');
|
|
||||||
clientIdLabel.style.width = '15%';
|
|
||||||
clientIdLabel.innerText = 'Client ID';
|
|
||||||
clientIdRow.appendChild(clientIdLabel);
|
|
||||||
|
|
||||||
let clientIdInput = document.createElement('td');
|
|
||||||
let clientIdInputField = document.createElement('input');
|
|
||||||
clientIdInputField.style.width = '90%';
|
|
||||||
clientIdInputField.setAttribute('type', 'text');
|
|
||||||
clientIdInputField.setAttribute('id', 'settings_metadatasource_' + element.source + '_clientid');
|
|
||||||
clientIdInputField.value = element.clientId;
|
|
||||||
clientIdInput.appendChild(clientIdInputField);
|
|
||||||
clientIdRow.appendChild(clientIdInput);
|
|
||||||
|
|
||||||
clientIdTable.appendChild(clientIdRow);
|
|
||||||
|
|
||||||
let clientSecretRow = document.createElement('tr');
|
|
||||||
|
|
||||||
let clientSecretLabel = document.createElement('td');
|
|
||||||
clientSecretLabel.style.width = '15%';
|
|
||||||
clientSecretLabel.innerText = 'Client Secret';
|
|
||||||
clientSecretRow.appendChild(clientSecretLabel);
|
|
||||||
|
|
||||||
let clientSecretInput = document.createElement('td');
|
|
||||||
let clientSecretInputField = document.createElement('input');
|
|
||||||
clientSecretInputField.style.width = '90%';
|
|
||||||
clientSecretInputField.setAttribute('type', 'text');
|
|
||||||
clientSecretInputField.setAttribute('id', 'settings_metadatasource_' + element.source + '_clientsecret');
|
|
||||||
clientSecretInputField.value = element.secret;
|
|
||||||
clientSecretInput.appendChild(clientSecretInputField);
|
|
||||||
clientSecretRow.appendChild(clientSecretInput);
|
|
||||||
|
|
||||||
clientIdTable.appendChild(clientSecretRow);
|
|
||||||
|
|
||||||
controlsTable.appendChild(clientIdTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sourceContent.appendChild(controlsTable);
|
|
||||||
}
|
|
||||||
sourceSection.appendChild(sourceContent);
|
|
||||||
|
|
||||||
metadataSettingsContainer.appendChild(sourceSection);
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('settings_signaturesource_hasheoushost').value = result.signatureSource.hasheousHost;
|
document.getElementById('settings_signaturesource_hasheoushost').value = result.signatureSource.hasheousHost;
|
||||||
|
|
||||||
let hasheousSubmitCheck = document.getElementById('settings_hasheoussubmit');
|
let hasheousSubmitCheck = document.getElementById('settings_hasheoussubmit');
|
||||||
@@ -225,44 +52,10 @@ function setSystemSettings() {
|
|||||||
retentionValue = 7;
|
retentionValue = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadataSources = [];
|
|
||||||
let metadataSourceRadios = $("input[type='radio'][name='settings_metadatasource']");
|
|
||||||
metadataSourceRadios.each(function (index, element) {
|
|
||||||
let source = $(element).val();
|
|
||||||
let useHasheousProxy = false;
|
|
||||||
let clientId = '';
|
|
||||||
let secret = '';
|
|
||||||
if (source == "IGDB") {
|
|
||||||
let igdbClientId = document.getElementById('settings_metadatasource_' + source + '_clientid').value;
|
|
||||||
let igdbClientSecret = document.getElementById('settings_metadatasource_' + source + '_clientsecret').value;
|
|
||||||
if (igdbClientId && igdbClientSecret) {
|
|
||||||
clientId = igdbClientId;
|
|
||||||
secret = igdbClientSecret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let useHasheousProxyRadio = $("input[type='radio'][id='settings_metadatasource_proxy_" + source + "']:checked");
|
|
||||||
if (useHasheousProxyRadio.length > 0) {
|
|
||||||
useHasheousProxy = true;
|
|
||||||
} else {
|
|
||||||
useHasheousProxy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let metadataSource = {
|
|
||||||
"Source": source,
|
|
||||||
"UseHasheousProxy": useHasheousProxy,
|
|
||||||
"ClientId": clientId,
|
|
||||||
"Secret": secret,
|
|
||||||
"Default": $(element).is(':checked')
|
|
||||||
};
|
|
||||||
metadataSources.push(metadataSource);
|
|
||||||
});
|
|
||||||
|
|
||||||
let model = {
|
let model = {
|
||||||
"alwaysLogToDisk": alwaysLogToDisk,
|
"alwaysLogToDisk": alwaysLogToDisk,
|
||||||
"minimumLogRetentionPeriod": Number(retentionValue),
|
"minimumLogRetentionPeriod": Number(retentionValue),
|
||||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
||||||
"metadataSources": metadataSources,
|
|
||||||
"signatureSource": {
|
"signatureSource": {
|
||||||
"Source": $("input[type='radio'][name='settings_signaturesource']:checked").val(),
|
"Source": $("input[type='radio'][name='settings_signaturesource']:checked").val(),
|
||||||
"HasheousHost": document.getElementById('settings_signaturesource_hasheoushost').value,
|
"HasheousHost": document.getElementById('settings_signaturesource_hasheoushost').value,
|
||||||
@@ -273,7 +66,7 @@ function setSystemSettings() {
|
|||||||
console.log(model);
|
console.log(model);
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/System/Settings/System',
|
'/api/v1/System/Settings/System',
|
||||||
'POST',
|
'POST',
|
||||||
function (result) {
|
function (result) {
|
||||||
getSystemSettings();
|
getSystemSettings();
|
||||||
|
|||||||
@@ -368,8 +368,6 @@ class ProfileCard {
|
|||||||
this.ProfileBody.classList.add('profile-card-body');
|
this.ProfileBody.classList.add('profile-card-body');
|
||||||
this.ProfileNowPlaying = document.createElement('div');
|
this.ProfileNowPlaying = document.createElement('div');
|
||||||
this.ProfileNowPlaying.classList.add('profile-card-now-playing-body');
|
this.ProfileNowPlaying.classList.add('profile-card-now-playing-body');
|
||||||
this.ProfileNowPlayingBg = document.createElement('div');
|
|
||||||
this.ProfileNowPlayingBg.classList.add('profile-card-now-playing-body-bg');
|
|
||||||
this.ProfileNowPlayingLabel = document.createElement('div');
|
this.ProfileNowPlayingLabel = document.createElement('div');
|
||||||
this.ProfileNowPlayingLabel.classList.add('profile-card-now-playing-label');
|
this.ProfileNowPlayingLabel.classList.add('profile-card-now-playing-label');
|
||||||
this.ProfileNowPlayingCover = document.createElement('div');
|
this.ProfileNowPlayingCover = document.createElement('div');
|
||||||
@@ -390,7 +388,6 @@ class ProfileCard {
|
|||||||
this.ProfileBody.appendChild(this.Quip);
|
this.ProfileBody.appendChild(this.Quip);
|
||||||
|
|
||||||
// now playing
|
// now playing
|
||||||
this.ProfileNowPlayingBg.appendChild(this.ProfileNowPlaying);
|
|
||||||
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingLabel);
|
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingLabel);
|
||||||
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingCover);
|
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingCover);
|
||||||
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingTitle);
|
this.ProfileNowPlaying.appendChild(this.ProfileNowPlayingTitle);
|
||||||
@@ -400,7 +397,7 @@ class ProfileCard {
|
|||||||
// assemble card
|
// assemble card
|
||||||
this.Card.appendChild(this.BackgroundImage);
|
this.Card.appendChild(this.BackgroundImage);
|
||||||
this.Card.appendChild(this.ProfileBody);
|
this.Card.appendChild(this.ProfileBody);
|
||||||
this.Card.appendChild(this.ProfileNowPlayingBg);
|
this.Card.appendChild(this.ProfileNowPlaying);
|
||||||
this.Card.appendChild(this.Avatar);
|
this.Card.appendChild(this.Avatar);
|
||||||
|
|
||||||
this.ProfileData = null;
|
this.ProfileData = null;
|
||||||
@@ -456,14 +453,11 @@ class ProfileCard {
|
|||||||
|
|
||||||
if (profile.nowPlaying) {
|
if (profile.nowPlaying) {
|
||||||
callingObject.ProfileNowPlayingLabel.innerHTML = "Now Playing";
|
callingObject.ProfileNowPlayingLabel.innerHTML = "Now Playing";
|
||||||
let cardImage = '';
|
|
||||||
if (profile.nowPlaying.game.cover) {
|
if (profile.nowPlaying.game.cover) {
|
||||||
cardImage = "/api/v1.1/Games/" + profile.nowPlaying.game.metadataMapId + "/cover/" + profile.nowPlaying.game.cover + "/image/cover_big/" + profile.nowPlaying.game.cover + ".jpg";
|
callingObject.ProfileNowPlayingCover.style = "background-image: url('/api/v1.1/Games/" + profile.nowPlaying.game.id + "/cover/" + profile.nowPlaying.game.cover.id + "/image/cover_big/" + profile.nowPlaying.game.cover.id + ".jpg');";
|
||||||
} else {
|
} else {
|
||||||
cardImage = "/images/unknowngame.png";
|
callingObject.ProfileNowPlayingCover.style = "background-image: url('/images/unknowngame.png');";
|
||||||
}
|
}
|
||||||
callingObject.ProfileNowPlayingCover.style = "background-image: url(\"" + cardImage + "\");";
|
|
||||||
callingObject.ProfileNowPlayingBg.style = "background-image: url(\"" + cardImage + "\");";
|
|
||||||
callingObject.ProfileNowPlayingTitle.innerHTML = profile.nowPlaying.game.name;
|
callingObject.ProfileNowPlayingTitle.innerHTML = profile.nowPlaying.game.name;
|
||||||
callingObject.ProfileNowPlayingPlatform.innerHTML = profile.nowPlaying.platform.name;
|
callingObject.ProfileNowPlayingPlatform.innerHTML = profile.nowPlaying.platform.name;
|
||||||
if (profile.nowPlaying.duration === 1) {
|
if (profile.nowPlaying.duration === 1) {
|
||||||
@@ -471,9 +465,9 @@ class ProfileCard {
|
|||||||
} else {
|
} else {
|
||||||
callingObject.ProfileNowPlayingDuration.innerHTML = profile.nowPlaying.duration + " minutes";
|
callingObject.ProfileNowPlayingDuration.innerHTML = profile.nowPlaying.duration + " minutes";
|
||||||
}
|
}
|
||||||
callingObject.ProfileNowPlayingBg.style.display = "";
|
callingObject.ProfileNowPlaying.style.display = "";
|
||||||
} else {
|
} else {
|
||||||
callingObject.ProfileNowPlayingBg.style.display = "none";
|
callingObject.ProfileNowPlaying.style.display = "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
callingObject.ProfileData = profile;
|
callingObject.ProfileData = profile;
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ function formatGamesPanel(targetElement, result, pageNumber, pageSize, forceScro
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < result.games.length; i++) {
|
for (let i = 0; i < result.games.length; i++) {
|
||||||
let game = renderGameIcon(result.games[i], showTitle, showRatings, showClassification, classificationDisplayOrder, false, listView, true);
|
let game = renderGameIcon(result.games[i], showTitle, showRatings, showClassification, classificationDisplayOrder, false, listView);
|
||||||
switch (pageMode) {
|
switch (pageMode) {
|
||||||
case "paged":
|
case "paged":
|
||||||
targetElement.appendChild(game);
|
targetElement.appendChild(game);
|
||||||
@@ -396,19 +396,15 @@ function IsInView() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderGameIcon(gameObject, showTitle, showRatings, showClassification, classificationDisplayOrder, useSmallCover, listView, showFavourite) {
|
function renderGameIcon(gameObject, showTitle, showRatings, showClassification, classificationDisplayOrder, useSmallCover, listView) {
|
||||||
if (listView == undefined) {
|
if (listView == undefined) {
|
||||||
listView = false;
|
listView = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showFavourite == undefined) {
|
|
||||||
showFavourite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let classes = getViewModeClasses(listView);
|
let classes = getViewModeClasses(listView);
|
||||||
|
|
||||||
let gameBox = document.createElement('div');
|
let gameBox = document.createElement('div');
|
||||||
gameBox.metadataMapId = "game_tile_" + gameObject.metadataMapId;
|
gameBox.id = "game_tile_" + gameObject.id;
|
||||||
if (useSmallCover == true) {
|
if (useSmallCover == true) {
|
||||||
gameBox.classList.add(...classes['game_tile game_tile_small']);
|
gameBox.classList.add(...classes['game_tile game_tile_small']);
|
||||||
} else {
|
} else {
|
||||||
@@ -419,14 +415,14 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification,
|
|||||||
let gameImageBox = document.createElement('div');
|
let gameImageBox = document.createElement('div');
|
||||||
gameImageBox.classList.add(...classes['game_tile_box']);
|
gameImageBox.classList.add(...classes['game_tile_box']);
|
||||||
if (listView == true) {
|
if (listView == true) {
|
||||||
gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.metadataMapId + '";');
|
gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";');
|
||||||
} else {
|
} else {
|
||||||
gameImageBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.metadataMapId + '";');
|
gameImageBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";');
|
||||||
}
|
}
|
||||||
|
|
||||||
let gameImage = document.createElement('img');
|
let gameImage = document.createElement('img');
|
||||||
gameImage.id = 'game_tile_cover_' + gameObject.metadataMapId;
|
gameImage.id = 'game_tile_cover_' + gameObject.id;
|
||||||
gameImage.setAttribute('data-id', gameObject.metadataMapId);
|
gameImage.setAttribute('data-id', gameObject.id);
|
||||||
if (useSmallCover == true) {
|
if (useSmallCover == true) {
|
||||||
gameImage.classList.add(...classes['game_tile_image game_tile_image_small lazy']);
|
gameImage.classList.add(...classes['game_tile_image game_tile_image_small lazy']);
|
||||||
} else {
|
} else {
|
||||||
@@ -434,7 +430,7 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification,
|
|||||||
}
|
}
|
||||||
// gameImage.src = '/images/unknowngame.png';
|
// gameImage.src = '/images/unknowngame.png';
|
||||||
if (gameObject.cover) {
|
if (gameObject.cover) {
|
||||||
gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.metadataMapId + '/cover/' + gameObject.cover + '/image/cover_big/' + gameObject.cover + '.jpg');
|
gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/' + gameObject.cover.id + '/image/cover_big/' + gameObject.cover.id + '.jpg');
|
||||||
} else {
|
} else {
|
||||||
gameImage.classList.add(...classes['game_tile_image unknown']);
|
gameImage.classList.add(...classes['game_tile_image unknown']);
|
||||||
gameImage.setAttribute('data-src', '/images/unknowngame.png');
|
gameImage.setAttribute('data-src', '/images/unknowngame.png');
|
||||||
@@ -468,6 +464,49 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification,
|
|||||||
gameImageBox.appendChild(gameSaveIcon);
|
gameImageBox.appendChild(gameSaveIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add favourite game icon
|
||||||
|
let gameFavIconBox = document.createElement('div');
|
||||||
|
gameFavIconBox.classList.add(...classes['game_tile_box_favouritegame']);
|
||||||
|
|
||||||
|
let gameFavIcon = document.createElement('img');
|
||||||
|
gameFavIcon.classList.add(...classes['favouriteicon']);
|
||||||
|
if (gameObject.isFavourite == true) {
|
||||||
|
gameFavIcon.src = '/images/favourite-filled.svg';
|
||||||
|
gameFavIconBox.classList.add('favourite-filled');
|
||||||
|
} else {
|
||||||
|
gameFavIcon.src = '/images/favourite-empty.svg';
|
||||||
|
gameFavIconBox.classList.add('favourite-empty');
|
||||||
|
}
|
||||||
|
gameFavIconBox.appendChild(gameFavIcon);
|
||||||
|
|
||||||
|
gameFavIconBox.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (gameFavIconBox.classList.contains('favourite-filled')) {
|
||||||
|
gameFavIcon.src = '/images/favourite-empty.svg';
|
||||||
|
gameFavIconBox.classList.remove('favourite-filled');
|
||||||
|
gameFavIconBox.classList.add('favourite-empty');
|
||||||
|
gameObject.isFavourite = false;
|
||||||
|
} else {
|
||||||
|
gameFavIcon.src = '/images/favourite-filled.svg';
|
||||||
|
gameFavIconBox.classList.remove('favourite-empty');
|
||||||
|
gameFavIconBox.classList.add('favourite-filled');
|
||||||
|
gameObject.isFavourite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('/api/v1.1/Games/' + gameObject.id + '/favourite?favourite=' + gameObject.isFavourite, {
|
||||||
|
method: 'POST'
|
||||||
|
}).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
// console.log('Favourite status updated');
|
||||||
|
} else {
|
||||||
|
// console.log('Failed to update favourite status');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
gameImageBox.appendChild(gameFavIconBox);
|
||||||
|
|
||||||
// add ratings banner
|
// add ratings banner
|
||||||
if (gameObject.totalRating || displayClassification == true) {
|
if (gameObject.totalRating || displayClassification == true) {
|
||||||
let gameImageRatingBanner = document.createElement('div');
|
let gameImageRatingBanner = document.createElement('div');
|
||||||
@@ -499,51 +538,6 @@ function renderGameIcon(gameObject, showTitle, showRatings, showClassification,
|
|||||||
}
|
}
|
||||||
gameBox.appendChild(gameImageBox);
|
gameBox.appendChild(gameImageBox);
|
||||||
|
|
||||||
// add favourite game icon
|
|
||||||
if (showFavourite == true) {
|
|
||||||
let gameFavIconBox = document.createElement('div');
|
|
||||||
gameFavIconBox.classList.add(...classes['game_tile_box_favouritegame']);
|
|
||||||
|
|
||||||
let gameFavIcon = document.createElement('img');
|
|
||||||
gameFavIcon.classList.add(...classes['favouriteicon']);
|
|
||||||
if (gameObject.isFavourite == true) {
|
|
||||||
gameFavIcon.src = '/images/favourite-filled.svg';
|
|
||||||
gameFavIconBox.classList.add('favourite-filled');
|
|
||||||
} else {
|
|
||||||
gameFavIcon.src = '/images/favourite-empty.svg';
|
|
||||||
gameFavIconBox.classList.add('favourite-empty');
|
|
||||||
}
|
|
||||||
gameFavIconBox.appendChild(gameFavIcon);
|
|
||||||
|
|
||||||
gameFavIconBox.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
if (gameFavIconBox.classList.contains('favourite-filled')) {
|
|
||||||
gameFavIcon.src = '/images/favourite-empty.svg';
|
|
||||||
gameFavIconBox.classList.remove('favourite-filled');
|
|
||||||
gameFavIconBox.classList.add('favourite-empty');
|
|
||||||
gameObject.isFavourite = false;
|
|
||||||
} else {
|
|
||||||
gameFavIcon.src = '/images/favourite-filled.svg';
|
|
||||||
gameFavIconBox.classList.remove('favourite-empty');
|
|
||||||
gameFavIconBox.classList.add('favourite-filled');
|
|
||||||
gameObject.isFavourite = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch('/api/v1.1/Games/' + gameObject.metadataMapId + '/favourite?favourite=' + gameObject.isFavourite, {
|
|
||||||
method: 'POST'
|
|
||||||
}).then(response => {
|
|
||||||
if (response.ok) {
|
|
||||||
// console.log('Favourite status updated');
|
|
||||||
} else {
|
|
||||||
// console.log('Failed to update favourite status');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
gameImageBox.appendChild(gameFavIconBox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showTitle == true) {
|
if (showTitle == true) {
|
||||||
let gameBoxTitle = document.createElement('div');
|
let gameBoxTitle = document.createElement('div');
|
||||||
gameBoxTitle.classList.add(...classes['game_tile_label']);
|
gameBoxTitle.classList.add(...classes['game_tile_label']);
|
||||||
|
|||||||
@@ -699,129 +699,25 @@ class BackgroundImageRotator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function BuildLaunchLink(engine, core, platformId, gameId, romId, isMediaGroup, filename) {
|
function BuildLaunchLink(engine, core, platformId, gameId, romId, isMediaGroup, filename) {
|
||||||
let launchLink = '/index.html?page=emulator&engine=<ENGINE>&core=<CORE>&platformid=<PLATFORMID>&gameid=<GAMEID>&romid=<ROMID>&mediagroup=<ISMEDIAGROUP>&rompath=<FILENAME>';
|
let launchLink = '/index.html?page=emulator&engine=<ENGINE>&core=<CORE>&platformid=<PLATFORMID>&gameid=<GAMEID>&romid=<ROMID>&mediagroup=<ISMEDIAGROUP>&rompath=<FILENAME>';
|
||||||
|
|
||||||
let isValid = true;
|
// http://localhost:5198/index.html?page=emulator&engine=EmulatorJS&core=amiga&platformid=16&gameid=5519&romid=19&mediagroup=1&rompath=%2Fapi%2Fv1.1%2FGames%2F5519%2Fromgroup%2F19%2FCannon%20Fodder.zip
|
||||||
|
|
||||||
console.log('Validating launch link: ' + engine + ' ' + core + ' ' + platformId + ' ' + gameId + ' ' + romId + ' ' + isMediaGroup + ' ' + filename);
|
// http://localhost:5198/index.html?page=emulator&engine=EmulatorJS&core=amiga&platformid=16&gameid=5519&romid=102&mediagroup=0&rompath=%2Fapi%2Fv1.1%2FGames%2F5519%2Froms%2F102%2FCannon%20Fodder%20(1993)(Virgin)(Disk%201%20of%203)%5Bcr%20CSL%5D.adf
|
||||||
|
|
||||||
let returnLink = '/index.html';
|
launchLink = launchLink.replace('<ENGINE>', engine);
|
||||||
|
launchLink = launchLink.replace('<CORE>', core);
|
||||||
// check if engine is valid
|
launchLink = launchLink.replace('<PLATFORMID>', platformId);
|
||||||
let validEngines = ['EmulatorJS'];
|
launchLink = launchLink.replace('<GAMEID>', gameId);
|
||||||
if (!validEngines.includes(engine)) {
|
launchLink = launchLink.replace('<ROMID>', romId);
|
||||||
isValid = false;
|
if (isMediaGroup == true) {
|
||||||
console.log('Engine is invalid!');
|
launchLink = launchLink.replace('<ISMEDIAGROUP>', 1);
|
||||||
|
launchLink = launchLink.replace('<FILENAME>', '/api/v1.1/Games/' + encodeURI(gameId) + '/romgroup/' + encodeURI(romId) + '/' + encodeURI(filename) + '.zip');
|
||||||
|
} else {
|
||||||
|
launchLink = launchLink.replace('<ISMEDIAGROUP>', 0);
|
||||||
|
launchLink = launchLink.replace('<FILENAME>', '/api/v1.1/Games/' + encodeURI(gameId) + '/roms/' + encodeURI(romId) + '/' + encodeURI(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch valid cores from json file /emulators/EmulatorJS/data/cores.json
|
return launchLink;
|
||||||
let validCores = [];
|
|
||||||
await fetch('/api/v1.1/PlatformMaps', {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
validCores = data;
|
|
||||||
|
|
||||||
for (let i = 0; i < validCores.length; i++) {
|
|
||||||
isValid = false;
|
|
||||||
if (validCores[i].webEmulator) {
|
|
||||||
if (validCores[i].webEmulator.availableWebEmulators) {
|
|
||||||
for (let y = 0; y < validCores[i].webEmulator.availableWebEmulators.length; y++) {
|
|
||||||
if (validCores[i].webEmulator.availableWebEmulators[y].emulatorType == engine) {
|
|
||||||
for (let x = 0; x < validCores[i].webEmulator.availableWebEmulators[y].availableWebEmulatorCores.length; x++) {
|
|
||||||
if (validCores[i].webEmulator.availableWebEmulators[y].availableWebEmulatorCores[x].core == core ||
|
|
||||||
validCores[i].webEmulator.availableWebEmulators[y].availableWebEmulatorCores[x].alternateCoreName == core
|
|
||||||
) {
|
|
||||||
isValid = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid == true) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isValid == false) {
|
|
||||||
console.log('Core is invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if platformId is an int64
|
|
||||||
if (!Number(platformId)) {
|
|
||||||
isValid = false;
|
|
||||||
console.log('PlatformId is invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if gameId is a an int64
|
|
||||||
if (!Number(gameId)) {
|
|
||||||
isValid = false;
|
|
||||||
console.log('GameId is invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if romId is a an int64
|
|
||||||
if (!Number(romId)) {
|
|
||||||
isValid = false;
|
|
||||||
console.log('RomId is invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if isMediaGroup is a boolean in a number format - if not, verify it is a boolean
|
|
||||||
if (isMediaGroup == 0 || isMediaGroup == 1) {
|
|
||||||
// value is a number, and is valid
|
|
||||||
} else {
|
|
||||||
if (isMediaGroup == true || isMediaGroup == false) {
|
|
||||||
// value is a boolean, and is valid
|
|
||||||
} else {
|
|
||||||
isValid = false;
|
|
||||||
console.log('IsMediaGroup is invalid!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if filename is a string
|
|
||||||
if (typeof (filename) != 'string') {
|
|
||||||
isValid = false;
|
|
||||||
console.log('Filename is invalid!');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValid == false) {
|
|
||||||
console.log('Link is invalid!');
|
|
||||||
returnLink = '/index.html';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate the launch link
|
|
||||||
launchLink = launchLink.replace('<ENGINE>', engine);
|
|
||||||
launchLink = launchLink.replace('<CORE>', core);
|
|
||||||
launchLink = launchLink.replace('<PLATFORMID>', platformId);
|
|
||||||
launchLink = launchLink.replace('<GAMEID>', gameId);
|
|
||||||
launchLink = launchLink.replace('<ROMID>', romId);
|
|
||||||
if (isMediaGroup == true) {
|
|
||||||
launchLink = launchLink.replace('<ISMEDIAGROUP>', 1);
|
|
||||||
launchLink = launchLink.replace('<FILENAME>', '/api/v1.1/Games/' + encodeURI(gameId) + '/romgroup/' + encodeURI(romId) + '/' + encodeURI(filename) + '.zip');
|
|
||||||
} else {
|
|
||||||
launchLink = launchLink.replace('<ISMEDIAGROUP>', 0);
|
|
||||||
launchLink = launchLink.replace('<FILENAME>', '/api/v1.1/Games/' + encodeURI(gameId) + '/roms/' + encodeURI(romId) + '/' + encodeURI(filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Validated link: ' + launchLink);
|
|
||||||
|
|
||||||
returnLink = launchLink;
|
|
||||||
|
|
||||||
return;
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error:', error);
|
|
||||||
isValid = false;
|
|
||||||
console.log('Link is invalid!');
|
|
||||||
returnLink = '/index.html';
|
|
||||||
});
|
|
||||||
|
|
||||||
return returnLink;
|
|
||||||
}
|
}
|
||||||
@@ -503,20 +503,20 @@ class EmulatorStateManager {
|
|||||||
let stateControlsLaunch = document.createElement('span');
|
let stateControlsLaunch = document.createElement('span');
|
||||||
stateControlsLaunch.id = 'stateControlsLaunch_' + result[i].id;
|
stateControlsLaunch.id = 'stateControlsLaunch_' + result[i].id;
|
||||||
stateControlsLaunch.className = 'romstart';
|
stateControlsLaunch.className = 'romstart';
|
||||||
let emulatorTarget;
|
let emulatorTarget;// = '/index.html?page=emulator&engine=@engine&core=@core&platformid=@platformid&gameid=@gameid&romid=@romid&mediagroup=@mediagroup&rompath=@rompath&stateid=' + result[i].id;
|
||||||
let mediagroupint = 0;
|
let mediagroupint = 0;
|
||||||
if (thisObject.IsMediaGroup == true) {
|
if (thisObject.IsMediaGroup == true) {
|
||||||
mediagroupint = 1;
|
mediagroupint = 1;
|
||||||
}
|
}
|
||||||
switch (getQueryString('page', 'string')) {
|
switch (getQueryString('page', 'string')) {
|
||||||
case 'emulator':
|
case 'emulator':
|
||||||
emulatorTarget = await BuildLaunchLink(getQueryString('engine', 'string'), getQueryString('core', 'string'), getQueryString('platformid', 'string'), getQueryString('gameid', 'string'), getQueryString('romid', 'string'), mediagroupint, thisObject.rompath, result[i].id) + '&stateid=' + result[i].id;
|
emulatorTarget = BuildLaunchLink(getQueryString('engine', 'string'), getQueryString('core', 'string'), getQueryString('platformid', 'string'), getQueryString('gameid', 'string'), getQueryString('romid', 'string'), mediagroupint, thisObject.rompath, result[i].id) + '&stateid=' + result[i].id;
|
||||||
stateControlsLaunch.addEventListener('click', () => {
|
stateControlsLaunch.addEventListener('click', () => {
|
||||||
window.location.replace(emulatorTarget);
|
window.location.replace(emulatorTarget);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'game':
|
case 'game':
|
||||||
emulatorTarget = await BuildLaunchLink(thisObject.engine, thisObject.core, thisObject.platformid, thisObject.gameid, thisObject.RomId, mediagroupint, thisObject.rompath, result[i].id) + '&stateid=' + result[i].id;
|
emulatorTarget = BuildLaunchLink(thisObject.engine, thisObject.core, thisObject.platformid, thisObject.gameid, thisObject.RomId, mediagroupint, thisObject.rompath, result[i].id) + '&stateid=' + result[i].id;
|
||||||
stateControlsLaunch.addEventListener('click', () => {
|
stateControlsLaunch.addEventListener('click', () => {
|
||||||
window.location.href = emulatorTarget;
|
window.location.href = emulatorTarget;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -181,40 +181,15 @@ class PreferencesWindow {
|
|||||||
"Adult"
|
"Adult"
|
||||||
];
|
];
|
||||||
for (let j = 0; j < ratingGroupsOrder.length; j++) {
|
for (let j = 0; j < ratingGroupsOrder.length; j++) {
|
||||||
let ratingGroup = ratingGroupsOrder[j];
|
let ageGroupValue = AgeRatingGroups[ratingGroupsOrder[j]];
|
||||||
let ageGroupValue = AgeRatingGroups[ratingGroup];
|
let iconIdList = ageGroupValue[key];
|
||||||
let ageGroupValueLower = {};
|
|
||||||
for (const [key, value] of Object.entries(ageGroupValue)) {
|
|
||||||
ageGroupValueLower[key.toLowerCase()] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
let iconIdList = ageGroupValueLower[key.toLowerCase()];
|
|
||||||
console.log(key.toLowerCase());
|
|
||||||
if (key == 'clasS_IND' || key == 'CLASS_IND') {
|
|
||||||
console.log("here");
|
|
||||||
}
|
|
||||||
// loop the age rating icons
|
// loop the age rating icons
|
||||||
if (iconIdList) {
|
for (let i = 0; i < iconIdList.length; i++) {
|
||||||
for (const [i, value] of Object.entries(iconIdList)) {
|
let icon = document.createElement('img');
|
||||||
console.log(" " + iconIdList[i]);
|
icon.src = "/images/Ratings/" + key + "/" + AgeRatingStrings[iconIdList[i]] + ".svg";
|
||||||
let icon = document.createElement('img');
|
icon.title = AgeRatingStrings[iconIdList[i]];
|
||||||
|
icon.classList.add("rating_image_mini");
|
||||||
// get age rating strings
|
classificationIcons.appendChild(icon);
|
||||||
let iconId = iconIdList[i];
|
|
||||||
let ageRatingString;
|
|
||||||
for (const [x, y] of Object.entries(AgeRatingStrings)) {
|
|
||||||
if (AgeRatingStrings[x] == iconId) {
|
|
||||||
ageRatingString = AgeRatingStrings[x];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
icon.src = "/images/Ratings/" + key + "/" + ageRatingString + ".svg";
|
|
||||||
icon.title = ageRatingString;
|
|
||||||
icon.alt = ageRatingString;
|
|
||||||
icon.classList.add("rating_image_mini");
|
|
||||||
classificationIcons.appendChild(icon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
classificationItemBox.appendChild(classificationIcons);
|
classificationItemBox.appendChild(classificationIcons);
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ class UploadRom {
|
|||||||
if (xhr.status === 200) {
|
if (xhr.status === 200) {
|
||||||
// process the results
|
// process the results
|
||||||
let response = JSON.parse(xhr.responseText);
|
let response = JSON.parse(xhr.responseText);
|
||||||
console.log(response);
|
|
||||||
switch (response.type) {
|
switch (response.type) {
|
||||||
case 'rom':
|
case 'rom':
|
||||||
switch (response.status) {
|
switch (response.status) {
|
||||||
@@ -122,21 +121,16 @@ class UploadRom {
|
|||||||
uploadedItem.platformName = 'Unknown Platform';
|
uploadedItem.platformName = 'Unknown Platform';
|
||||||
uploadedItem.gameId = 0;
|
uploadedItem.gameId = 0;
|
||||||
uploadedItem.gameName = 'Unknown Game';
|
uploadedItem.gameName = 'Unknown Game';
|
||||||
uploadedItem.gameData = response.game;
|
|
||||||
uploadedItem.romId = response.romid;
|
uploadedItem.romId = response.romid;
|
||||||
|
|
||||||
if (response.game) {
|
if (response.game) {
|
||||||
// game data was returned
|
uploadedItem.gameId = response.game.id;
|
||||||
uploadedItem.gameId = response.rom.metadataMapId;
|
|
||||||
uploadedItem.gameName = response.game.name;
|
uploadedItem.gameName = response.game.name;
|
||||||
if (response.game.cover != null) {
|
if (response.game.cover != null) {
|
||||||
if (response.game.cover != null) {
|
if (response.game.cover.id != null) {
|
||||||
uploadedItem.coverId = response.game.cover;
|
uploadedItem.coverId = response.game.cover.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// game has been deemed to be unknown
|
|
||||||
uploadedItem.gameId = response.rom.metadataMapId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.platform) {
|
if (response.platform) {
|
||||||
@@ -203,12 +197,12 @@ class UploadItem {
|
|||||||
// file name label
|
// file name label
|
||||||
this.filenameLabel = document.createElement('div');
|
this.filenameLabel = document.createElement('div');
|
||||||
this.filenameLabel.classList.add('uploadItem-Label');
|
this.filenameLabel.classList.add('uploadItem-Label');
|
||||||
this.filenameLabel.textContent = this.Filename;
|
this.filenameLabel.innerHTML = this.Filename;
|
||||||
|
|
||||||
// status label
|
// status label
|
||||||
this.statusLabel = document.createElement('div');
|
this.statusLabel = document.createElement('div');
|
||||||
this.statusLabel.classList.add('uploadItem-Status');
|
this.statusLabel.classList.add('uploadItem-Status');
|
||||||
this.statusLabel.textContent = UploadItem.StatusValues[this.Status];
|
this.statusLabel.innerHTML = UploadItem.StatusValues[this.Status];
|
||||||
|
|
||||||
// game name label
|
// game name label
|
||||||
this.gameNameLabel = document.createElement('div');
|
this.gameNameLabel = document.createElement('div');
|
||||||
@@ -279,7 +273,6 @@ class UploadItem {
|
|||||||
platformName = null;
|
platformName = null;
|
||||||
gameId = null;
|
gameId = null;
|
||||||
gameName = null;
|
gameName = null;
|
||||||
gameData = null;
|
|
||||||
coverId = null;
|
coverId = null;
|
||||||
romId = null;
|
romId = null;
|
||||||
|
|
||||||
@@ -326,7 +319,7 @@ class UploadItem {
|
|||||||
case 'rom':
|
case 'rom':
|
||||||
this.infoButton.style.display = 'block';
|
this.infoButton.style.display = 'block';
|
||||||
|
|
||||||
if (this.gameId === null || this.gameId === 0 || this.gameData === null) {
|
if (this.gameId === null || this.gameId === 0) {
|
||||||
this.coverArt.src = '/images/unknowngame.png';
|
this.coverArt.src = '/images/unknowngame.png';
|
||||||
} else {
|
} else {
|
||||||
this.coverArt.src = '/api/v1.1/Games/' + this.gameId + '/cover/' + this.coverId + '/image/cover_big/cover.jpg';
|
this.coverArt.src = '/api/v1.1/Games/' + this.gameId + '/cover/' + this.coverId + '/image/cover_big/cover.jpg';
|
||||||
|
|||||||
@@ -1109,7 +1109,6 @@ input[name='filter_panel_range_max'] {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
top: 30%;
|
top: 30%;
|
||||||
padding-top: 7px;
|
|
||||||
right: 10px;
|
right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,28 +1138,6 @@ input[name='filter_panel_range_max'] {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
top: 30%;
|
top: 30%;
|
||||||
right: 50px;
|
right: 50px;
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 5px;
|
|
||||||
padding-left: 4px;
|
|
||||||
padding-right: 3px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
border-color: transparent;
|
|
||||||
border-width: 1px;
|
|
||||||
border-style: solid;
|
|
||||||
border-radius: var(--standard-radius);
|
|
||||||
z-index: +1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game_tile_box_row:hover>.game_tile_box_favouritegame_row {
|
|
||||||
border-color: var(--input-border);
|
|
||||||
background-color: var(--fancybutton-background);
|
|
||||||
}
|
|
||||||
|
|
||||||
.game_tile_box_row:hover>.game_tile_box_favouritegame_row:hover {
|
|
||||||
border-color: var(--input-border-hover);
|
|
||||||
background-color: var(--fancybutton-background-hover);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image {
|
.game_tile_image {
|
||||||
@@ -1901,9 +1878,8 @@ div[name="properties_profile_toc_item"]:hover {
|
|||||||
|
|
||||||
button:not(.select2-selection__choice__remove):not(.select2-selection__clear):not(.ejs_menu_button):not(.bigbutton) {
|
button:not(.select2-selection__choice__remove):not(.select2-selection__clear):not(.ejs_menu_button):not(.bigbutton) {
|
||||||
background-color: var(--button-background);
|
background-color: var(--button-background);
|
||||||
background: var(--button-background-gradient);
|
|
||||||
color: var(--button-font-colour);
|
color: var(--button-font-colour);
|
||||||
border-width: 0px;
|
border-width: 1px;
|
||||||
border-color: var(--button-border);
|
border-color: var(--button-border);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-radius: var(--standard-radius);
|
border-radius: var(--standard-radius);
|
||||||
@@ -1919,7 +1895,6 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
|
|
||||||
button:not(.select2-selection__choice__remove):not(.select2-selection__clear):not(.ejs_menu_button):hover {
|
button:not(.select2-selection__choice__remove):not(.select2-selection__clear):not(.ejs_menu_button):hover {
|
||||||
background-color: var(--button-background-hover);
|
background-color: var(--button-background-hover);
|
||||||
background: var(--button-background-hover);
|
|
||||||
border-color: var(--button-border-hover);
|
border-color: var(--button-border-hover);
|
||||||
color: var(--button-font-colour-hover);
|
color: var(--button-font-colour-hover);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -1949,42 +1924,36 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
|
|
||||||
.redbutton {
|
.redbutton {
|
||||||
background-color: var(--button-red-background) !important;
|
background-color: var(--button-red-background) !important;
|
||||||
background: var(--button-red-background-gradient) !important;
|
|
||||||
border-color: var(--button-red-border) !important;
|
border-color: var(--button-red-border) !important;
|
||||||
color: var(--button-red-font-colour) !important;
|
color: var(--button-red-font-colour) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.redbutton:hover {
|
.redbutton:hover {
|
||||||
background-color: var(--button-red-background-hover) !important;
|
background-color: var(--button-red-background-hover) !important;
|
||||||
background: var(--button-red-background-hover) !important;
|
|
||||||
border-color: var(--button-red-border-hover) !important;
|
border-color: var(--button-red-border-hover) !important;
|
||||||
color: var(--button-red-font-colour-hover) !important;
|
color: var(--button-red-font-colour-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.redbutton:disabled {
|
.redbutton:disabled {
|
||||||
background-color: var(--button-red-background-disabled) !important;
|
background-color: var(--button-red-background-disabled) !important;
|
||||||
background: var(--button-red-background-disabled) !important;
|
|
||||||
border-color: var(--button-red-border-disabled) !important;
|
border-color: var(--button-red-border-disabled) !important;
|
||||||
color: var(--button-red-font-colour-disabled) !important;
|
color: var(--button-red-font-colour-disabled) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bluebutton {
|
.bluebutton {
|
||||||
background-color: var(--button-blue-background) !important;
|
background-color: var(--button-blue-background) !important;
|
||||||
background: var(--button-blue-background-gradient) !important;
|
|
||||||
border-color: var(--button-blue-border) !important;
|
border-color: var(--button-blue-border) !important;
|
||||||
color: var(--button-blue-font-colour) !important;
|
color: var(--button-blue-font-colour) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bluebutton:hover {
|
.bluebutton:hover {
|
||||||
background-color: var(--button-blue-background-hover) !important;
|
background-color: var(--button-blue-background-hover) !important;
|
||||||
background: var(--button-blue-background-hover) !important;
|
|
||||||
border-color: var(--button-blue-border-hover) !important;
|
border-color: var(--button-blue-border-hover) !important;
|
||||||
color: var(--button-blue-font-colour-hover) !important;
|
color: var(--button-blue-font-colour-hover) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bluebutton:disabled {
|
.bluebutton:disabled {
|
||||||
background-color: var(--button-blue-background-disabled) !important;
|
background-color: var(--button-blue-background-disabled) !important;
|
||||||
background: var(--button-blue-background-disabled) !important;
|
|
||||||
border-color: var(--button-blue-border-disabled) !important;
|
border-color: var(--button-blue-border-disabled) !important;
|
||||||
color: var(--button-blue-font-colour-disabled) !important;
|
color: var(--button-blue-font-colour-disabled) !important;
|
||||||
}
|
}
|
||||||
@@ -2169,9 +2138,9 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #rom_edit {
|
#rom_edit {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
} */
|
}
|
||||||
|
|
||||||
#rom_edit_panel {
|
#rom_edit_panel {
|
||||||
background-color: rgba(56, 56, 56, 0.3);
|
background-color: rgba(56, 56, 56, 0.3);
|
||||||
@@ -2602,7 +2571,6 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
position: relative;
|
|
||||||
background-color: var(--section-header-background);
|
background-color: var(--section-header-background);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@@ -2738,24 +2706,14 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
color: var(--profile-card-quip-text-color);
|
color: var(--profile-card-quip-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-card-now-playing-body-bg {
|
|
||||||
position: relative;
|
|
||||||
min-height: 70px;
|
|
||||||
background-position: center;
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-card-now-playing-body {
|
.profile-card-now-playing-body {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 70px;
|
min-height: 70px;
|
||||||
/* background-color: var(--profile-card-body-background); */
|
background-color: var(--profile-card-body-background);
|
||||||
background-color: var(--profile-card-now-playing-background-color);
|
padding-top: 0px;
|
||||||
padding-top: 10px;
|
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
backdrop-filter: blur(2px);
|
|
||||||
-webkit-backdrop-filter: blur(2px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile-card-now-playing-label {
|
.profile-card-now-playing-label {
|
||||||
@@ -2766,7 +2724,7 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
.profile-card-now-playing-cover {
|
.profile-card-now-playing-cover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
top: 35px;
|
top: 25px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
@@ -2923,13 +2881,13 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: 10px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_item {
|
.platform_item {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
/* flex-basis: 45%; */
|
flex-basis: 45%;
|
||||||
border-radius: var(--standard-radius);
|
border-radius: var(--standard-radius);
|
||||||
/* background-color: var(--section-header-background); */
|
/* background-color: var(--section-header-background); */
|
||||||
background: linear-gradient(90deg, rgba(200, 200, 200, 0.7469362745098039) 0%, rgba(133, 133, 133, 1) 50%);
|
background: linear-gradient(90deg, rgba(200, 200, 200, 0.7469362745098039) 0%, rgba(133, 133, 133, 1) 50%);
|
||||||
@@ -2938,13 +2896,9 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
padding-left: 0;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_item:hover {
|
.platform_item:hover {
|
||||||
@@ -2958,30 +2912,15 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
.platform_item_background:hover {}
|
.platform_item_background:hover {}
|
||||||
|
|
||||||
.platform_image_container {
|
.platform_image_container {
|
||||||
|
margin-left: 10px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
width: 70px;
|
max-width: 50px;
|
||||||
height: 70px;
|
max-height: 50px;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
/* text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
line-height: 75px; */
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
background-color: white;
|
|
||||||
border-right-style: solid;
|
|
||||||
border-right-width: 1px;
|
|
||||||
border-right-color: #000000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_image {
|
.platform_image {
|
||||||
max-width: 90px;
|
width: 40px;
|
||||||
max-height: 60px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_name_container {
|
.platform_name_container {
|
||||||
@@ -2990,27 +2929,19 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
|
|
||||||
.platform_name {
|
.platform_name {
|
||||||
display: block;
|
display: block;
|
||||||
/* max-width: 75px; */
|
|
||||||
width: 25%;
|
|
||||||
height: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_edit_button_container {
|
.platform_edit_button_container {
|
||||||
/* width: 90px; */
|
width: 90px;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
text-align: right;
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.platform_edit_button {
|
.platform_edit_button {
|
||||||
/* position: absolute;
|
position: absolute;
|
||||||
right: 14px;
|
right: 14px;
|
||||||
top: 14px;*/
|
top: 14px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
display: inline-block;
|
|
||||||
margin-left: 10px;
|
|
||||||
|
|
||||||
background-color: var(--fancybutton-background);
|
background-color: var(--fancybutton-background);
|
||||||
border-radius: var(--standard-radius);
|
border-radius: var(--standard-radius);
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@@ -3054,11 +2985,3 @@ button:not(.select2-selection__choice__remove):not(.select2-selection__clear):no
|
|||||||
width: 160px;
|
width: 160px;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.metadata-attribution-icon {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
margin-right: 13px;
|
|
||||||
margin-left: 10px;
|
|
||||||
filter: invert(1);
|
|
||||||
}
|
|
||||||
@@ -42,8 +42,7 @@
|
|||||||
--input-font-colour: var(--page-font-colour);
|
--input-font-colour: var(--page-font-colour);
|
||||||
|
|
||||||
/* button */
|
/* button */
|
||||||
--button-background: rgb(110, 109, 109);
|
--button-background: rgb(85, 85, 85);
|
||||||
--button-background-gradient: linear-gradient(140deg, rgba(110, 109, 109, 1) 0%, rgba(85, 85, 85, 1) 100%);
|
|
||||||
--button-background-hover: rgb(136, 136, 136);
|
--button-background-hover: rgb(136, 136, 136);
|
||||||
--button-background-disabled: var(--button-background-hover);
|
--button-background-disabled: var(--button-background-hover);
|
||||||
--button-border: rgb(85, 85, 85);
|
--button-border: rgb(85, 85, 85);
|
||||||
@@ -52,21 +51,19 @@
|
|||||||
--button-font-colour: rgb(255, 255, 255);
|
--button-font-colour: rgb(255, 255, 255);
|
||||||
--button-font-colour-hover: var(--button-font-colour);
|
--button-font-colour-hover: var(--button-font-colour);
|
||||||
--button-font-colour-disabled: var(--button-border-hover);
|
--button-font-colour-disabled: var(--button-border-hover);
|
||||||
--button-red-background: rgb(139, 0, 0);
|
--button-red-background: darkred;
|
||||||
--button-red-background-gradient: linear-gradient(140deg, rgba(255, 0, 0, 1) 0%, rgba(139, 0, 0, 1) 100%);
|
--button-red-background-hover: red;
|
||||||
--button-red-background-hover: rgb(255, 0, 0);
|
|
||||||
--button-red-background-disabled: rgb(85, 85, 85);
|
--button-red-background-disabled: rgb(85, 85, 85);
|
||||||
--button-red-border: rgb(139, 0, 0);
|
--button-red-border: darkred;
|
||||||
--button-red-border-hover: rgb(255, 0, 0);
|
--button-red-border-hover: red;
|
||||||
--button-red-border-disabled: rgb(85, 85, 85);
|
--button-red-border-disabled: rgb(85, 85, 85);
|
||||||
--button-red-font-colour: rgb(255, 255, 255);
|
--button-red-font-colour: rgb(255, 255, 255);
|
||||||
--button-red-font-colour-hover: var(--button-red-font-colour);
|
--button-red-font-colour-hover: var(--button-red-font-colour);
|
||||||
--button-red-font-colour-disabled: var(--button-red-font-colour);
|
--button-red-font-colour-disabled: var(--button-red-font-colour);
|
||||||
--button-blue-background: rgb(0, 0, 170);
|
--button-blue-background: rgb(0, 0, 170);
|
||||||
--button-blue-background-gradient: linear-gradient(140deg, rgba(0, 0, 255, 1) 0%, rgba(0, 0, 150, 1) 100%);
|
|
||||||
--button-blue-background-hover: rgb(0, 0, 255);
|
--button-blue-background-hover: rgb(0, 0, 255);
|
||||||
--button-blue-background-disabled: rgb(85, 85, 85);
|
--button-blue-background-disabled: rgb(85, 85, 85);
|
||||||
--button-blue-border: rgb(0, 0, 255);
|
--button-blue-border: rgb(0, 0, 170);
|
||||||
--button-blue-border-hover: rgb(0, 0, 255);
|
--button-blue-border-hover: rgb(0, 0, 255);
|
||||||
--button-blue-border-disabled: rgb(85, 85, 85);
|
--button-blue-border-disabled: rgb(85, 85, 85);
|
||||||
--button-blue-font-colour: rgb(255, 255, 255);
|
--button-blue-font-colour: rgb(255, 255, 255);
|
||||||
@@ -127,7 +124,6 @@
|
|||||||
--profile-card-body-background: rgb(133, 156, 163);
|
--profile-card-body-background: rgb(133, 156, 163);
|
||||||
--profile-card-display-name-text-color: rgb(255, 255, 255);
|
--profile-card-display-name-text-color: rgb(255, 255, 255);
|
||||||
--profile-card-quip-text-color: var(--profile-card-display-name-text-color);
|
--profile-card-quip-text-color: var(--profile-card-display-name-text-color);
|
||||||
--profile-card-now-playing-background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
|
|
||||||
/* login */
|
/* login */
|
||||||
/* ------------------------------------------- */
|
/* ------------------------------------------- */
|
||||||
|
|||||||
Reference in New Issue
Block a user