Compare commits
54 Commits
main
...
v1.7.8-pre
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9922e61b44 | ||
![]() |
98a09c32f8 | ||
![]() |
81b58e9b9f | ||
![]() |
928a1538ea | ||
![]() |
f4a8892cbb | ||
![]() |
c4435628e0 | ||
![]() |
933c624885 | ||
![]() |
06e344c74a | ||
![]() |
9150ce7377 | ||
![]() |
08a40e3dd9 | ||
![]() |
d7fca42057 | ||
![]() |
1672520a29 | ||
![]() |
3366d926f4 | ||
![]() |
6d7f6f63c6 | ||
![]() |
590a7829b1 | ||
![]() |
ae75fc1490 | ||
![]() |
0c645d04aa | ||
![]() |
13b3764fcf | ||
![]() |
57d4fe7cf9 | ||
![]() |
8519d4c745 | ||
![]() |
822a40b61b | ||
![]() |
b463bb6064 | ||
![]() |
3e8696e6e8 | ||
![]() |
d1f157ac08 | ||
![]() |
30be179367 | ||
![]() |
787bb47bd3 | ||
![]() |
ccf9afd561 | ||
![]() |
c7b6233ad6 | ||
![]() |
afb72c3d74 | ||
![]() |
299e24793f | ||
![]() |
de9b9bf706 | ||
![]() |
28bc50a82e | ||
![]() |
f9f65f3ffb | ||
![]() |
87f3a1aa89 | ||
![]() |
b3e7696292 | ||
![]() |
29c685c791 | ||
![]() |
f0020e5b1f | ||
![]() |
3897ed65ef | ||
![]() |
cebab38dd6 | ||
![]() |
69da6ee346 | ||
![]() |
59173d8ae5 | ||
![]() |
178f70cb98 | ||
![]() |
60dbaf85a4 | ||
![]() |
8a80274030 | ||
![]() |
123239cf58 | ||
![]() |
04419383aa | ||
![]() |
0bef298abf | ||
![]() |
a4d581b369 | ||
![]() |
16cb0c89dc | ||
![]() |
95b52c47dd | ||
![]() |
b1056299b8 | ||
![]() |
14c5761959 | ||
![]() |
d7b3711be6 | ||
![]() |
f2a58d23f0 |
4
.devcontainer/.env
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
DATABASE_HOST=mariadb
|
||||||
|
DATABASE_USER=root
|
||||||
|
DATABASE_PASSWORD=gaseous
|
||||||
|
DATABASE_DB=gaseous
|
@@ -1,6 +1,10 @@
|
|||||||
FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm
|
FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y p7zip-full
|
# update apt-get
|
||||||
RUN mkdir -p /workspace/gaseous-server/wwwroot/emulators/EmulatorJS
|
RUN apt-get update
|
||||||
RUN wget https://cdn.emulatorjs.org/releases/4.0.12.7z
|
|
||||||
RUN 7z x -y -o/workspace/gaseous-server/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
# download and unzip EmulatorJS from CDN
|
||||||
|
RUN apt-get install -y p7zip-full
|
||||||
|
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
|
@@ -36,9 +36,7 @@
|
|||||||
"AndersEAndersen.html-class-suggestions",
|
"AndersEAndersen.html-class-suggestions",
|
||||||
"george-alisson.html-preview-vscode",
|
"george-alisson.html-preview-vscode",
|
||||||
"ms-dotnettools.vscodeintellicode-csharp",
|
"ms-dotnettools.vscodeintellicode-csharp",
|
||||||
"Zignd.html-css-class-completion",
|
"Zignd.html-css-class-completion"
|
||||||
"PWABuilder.pwa-studio",
|
|
||||||
"ms-azuretools.vscode-docker"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,13 +11,11 @@ services:
|
|||||||
- dbhost=${DATABASE_HOST}
|
- dbhost=${DATABASE_HOST}
|
||||||
- dbuser=${DATABASE_USER}
|
- dbuser=${DATABASE_USER}
|
||||||
- dbpass=${DATABASE_PASSWORD}
|
- dbpass=${DATABASE_PASSWORD}
|
||||||
- igdbclientid=${IGDB_CLIENT_ID}
|
- igdbclientid=<clientid>
|
||||||
- igdbclientsecret=${IGDB_CLIENT_SECRET}
|
- igdbclientsecret=<clientsecret>
|
||||||
mariadb:
|
mariadb:
|
||||||
hostname: mariadb
|
hostname: mariadb
|
||||||
image: mariadb:latest
|
image: mariadb:latest
|
||||||
ports:
|
|
||||||
- 3306:3306
|
|
||||||
environment:
|
environment:
|
||||||
- MARIADB_ROOT_PASSWORD=${DATABASE_PASSWORD}
|
- MARIADB_ROOT_PASSWORD=${DATABASE_PASSWORD}
|
||||||
- MARIADB_DATABASE=${DATABASE_DB}
|
- MARIADB_DATABASE=${DATABASE_DB}
|
||||||
|
@@ -1,51 +0,0 @@
|
|||||||
name: release-tag
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'main'
|
|
||||||
jobs:
|
|
||||||
release-image:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER_ORG: sendnrw
|
|
||||||
DOCKER_LATEST: latest
|
|
||||||
RUNNER_TOOL_CACHE: /toolcache
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v2
|
|
||||||
|
|
||||||
- name: Set up Docker BuildX
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
with: # replace it with your local IP
|
|
||||||
config-inline: |
|
|
||||||
[registry."git.send.nrw"]
|
|
||||||
http = true
|
|
||||||
insecure = true
|
|
||||||
|
|
||||||
- name: Login to DockerHub
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
with:
|
|
||||||
registry: git.send.nrw # replace it with your local IP
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Get Meta
|
|
||||||
id: meta
|
|
||||||
run: |
|
|
||||||
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
|
|
||||||
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v4
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./build/Dockerfile
|
|
||||||
platforms: |
|
|
||||||
linux/amd64
|
|
||||||
push: true
|
|
||||||
tags: | # replace it with your local IP and tags
|
|
||||||
git.send.nrw/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
|
|
||||||
git.send.nrw/${{ env.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }}
|
|
@@ -59,5 +59,7 @@ jobs:
|
|||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
|
gaseousgames/gaseousserver:latest-embeddeddb
|
||||||
gaseousgames/gaseousserver:${{ github.ref_name}}-embeddeddb
|
gaseousgames/gaseousserver:${{ github.ref_name}}-embeddeddb
|
||||||
|
ghcr.io/gaseous-project/gaseousserver:latest-embeddeddb
|
||||||
ghcr.io/gaseous-project/gaseousserver:${{ github.ref_name}}-embeddeddb
|
ghcr.io/gaseous-project/gaseousserver:${{ github.ref_name}}-embeddeddb
|
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
|
|
13
.github/workflows/BuildOnTestBranch.yml
vendored
@@ -27,10 +27,19 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
- name: Build and push
|
- name: Build and push standard image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
|
file: ./build/Dockerfile
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: gaseousgames/test:latest
|
tags: gaseousgames/test:latest
|
||||||
|
- 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/test:latest-embeddeddb
|
3
.gitignore
vendored
@@ -404,7 +404,4 @@ ASALocalRun/
|
|||||||
# Local History for Visual Studio
|
# Local History for Visual Studio
|
||||||
.localhistory/
|
.localhistory/
|
||||||
gaseous-server/.DS_Store
|
gaseous-server/.DS_Store
|
||||||
gaseous-server/wwwroot/.DS_Store
|
|
||||||
gaseous-server/wwwroot/emulators/EmulatorJS
|
gaseous-server/wwwroot/emulators/EmulatorJS
|
||||||
.devcontainer/.env
|
|
||||||
.mono/
|
|
||||||
|
@@ -21,8 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "screenshots", "screenshots"
|
|||||||
screenshots\Game.png = screenshots\Game.png
|
screenshots\Game.png = screenshots\Game.png
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-cli", "gaseous-cli\gaseous-cli.csproj", "{419CC4E4-8932-4E4A-B027-5521AA0CBA85}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -33,10 +31,6 @@ Global
|
|||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{419CC4E4-8932-4E4A-B027-5521AA0CBA85}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
39
README.MD
@@ -1,30 +1,34 @@
|
|||||||
[](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/codeql.yml) [](https://github.com/gaseous-project/gaseous-server/actions/workflows/BuildDockerOnTag-Release.yml)
|
||||||
# <img src="./logo.png" height="28" style="float: right;" /> Gaseous Server
|
# 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.
|
||||||
|
|
||||||
Version 1.7.0 and later contain user authentication, and can be exposed to the internet. However, it is recommended to not expose the server to the internet if you're not actively using it remotely, or if you have alternative means to access it remotely like a VPN.
|
## Warning
|
||||||
|
|
||||||
|
Versions 1.6.1 and earlier are not suitable for being exposed to the internet, as:
|
||||||
|
1. there is no authentication support, meaning anyone could trash your library
|
||||||
|
2. the server has not been hardened for exposure to the internet - so there maybe unknown vulnerabilities
|
||||||
|
|
||||||
|
If you expose one of these earlier versions of the server to the internet, **you do so at your own risk**.
|
||||||
|
|
||||||
|
Version 1.7.0 and later contain user authentication, and can be exposed to the internet. However, it is recommended to no expose the server to the internet if you're not actively using it remotely, or if you have alternative means to access it remotely like a VPN.
|
||||||
|
|
||||||
While we do our best to stay on top of server security, if you expose the server to the internet **you do so at your own risk**.
|
While we do our best to stay on top of server security, if you expose the server to the internet **you do so at your own risk**.
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
* MariaDB 11.1.2+ (preferred) or MySQL Server 8+
|
* MariaDB 11.1.2 (preferred) or MySQL Server 8+
|
||||||
* These are the database versions Gaseous has been tested and developed against. Your mileage may vary with earlier versions.
|
* These are the database versions Gaseous has been tested and developed against. Your mileage may vary with earlier versions.
|
||||||
* MariaDB is the preferred database server, while MySQL will continue to be supported for existing users (they should be interchangable).
|
* MariaDB is the preferred database server, while MySQL will continue to be supported for existing users (they should be interchangable).
|
||||||
* Note that due to the earlier database schema using MySQL specific features, moving to MariaDB from MySQL will require rebuilding your database from scratch. The "Library Scan" background task can be used to re-import all titles.
|
* Note that due to the earlier database schema using MySQL specific features, moving to MariaDB from MySQL will require rebuilding your database from scratch. The "Library Scan" background task can be used to re-import all titles.
|
||||||
* Internet Game Database API Key. See: https://api-docs.igdb.com/#account-creation
|
* Internet Game Database API Key. See: https://api-docs.igdb.com/#account-creation
|
||||||
|
|
||||||
# Installation
|
If using the provided docker-compose.yml, MariaDB will be installed for you.
|
||||||
See https://github.com/gaseous-project/gaseous-server/wiki/Installation for installation instructions.
|
|
||||||
|
|
||||||
# Adding Content
|
|
||||||
1. Import signatures: see https://github.com/gaseous-project/gaseous-server/wiki/Signatures
|
|
||||||
2. Add ROMs: see https://github.com/gaseous-project/gaseous-server/wiki/Adding-ROMs
|
|
||||||
|
|
||||||
## Friends of Gaseous
|
## Friends of Gaseous
|
||||||
* [EmulatorJS](https://github.com/EmulatorJS/EmulatorJS): A fantastic (and fast) Javascript based implementation of RetroArch, supporting a wide variety of platforms. Discord: https://discord.gg/6akryGkETU
|
* [EmulatorJS](https://github.com/EmulatorJS/EmulatorJS): A fantastic (and fast) Javascript based implementation of RetroArch, supporting a wide variety of platforms. Discord: https://discord.gg/6akryGkETU
|
||||||
@@ -39,4 +43,11 @@ The following projects are used by Gaseous
|
|||||||
* [EmulatorJS](https://github.com/EmulatorJS/EmulatorJS)
|
* [EmulatorJS](https://github.com/EmulatorJS/EmulatorJS)
|
||||||
|
|
||||||
## Discord Server
|
## Discord Server
|
||||||
Join our Discord server: https://discord.gg/Nhu7wpT3k4
|
[](https://discord.gg/Nhu7wpT3k4)
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
See https://github.com/gaseous-project/gaseous-server/wiki/Installation for installation instructions.
|
||||||
|
|
||||||
|
# Adding Content
|
||||||
|
1. Import signatures: see https://github.com/gaseous-project/gaseous-server/wiki/Signatures
|
||||||
|
2. Add ROMs: see https://github.com/gaseous-project/gaseous-server/wiki/Adding-ROMs
|
||||||
|
@@ -9,27 +9,19 @@ RUN echo "Build: $BUILDPLATFORM"
|
|||||||
|
|
||||||
# Copy everything
|
# Copy everything
|
||||||
COPY .. ./
|
COPY .. ./
|
||||||
|
|
||||||
# Build Gaseous Web Server
|
|
||||||
# Restore as distinct layers
|
# Restore as distinct layers
|
||||||
RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
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.0.12.7z
|
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
||||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.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
|
||||||
@@ -40,34 +32,8 @@ ENV INDOCKER=1
|
|||||||
WORKDIR /App
|
WORKDIR /App
|
||||||
COPY --from=build-env /App/out .
|
COPY --from=build-env /App/out .
|
||||||
|
|
||||||
# variables
|
# Configure healthcheck
|
||||||
ARG PUID=1000
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 CMD curl --fail http://localhost:80/healthCheck || exit 1
|
||||||
ARG PGID=1000
|
|
||||||
ARG dbhost=localhost
|
|
||||||
ARG dbuser=root
|
|
||||||
ARG dbpass=gaseous
|
|
||||||
|
|
||||||
ENV PUID=${PUID}
|
# start gaseous-server
|
||||||
ENV PGID=${PGID}
|
ENTRYPOINT ["dotnet", "gaseous-server.dll"]
|
||||||
ENV dbhost=${dbhost}
|
|
||||||
ENV dbuser=${dbuser}
|
|
||||||
ENV dbpass=${dbpass}
|
|
||||||
|
|
||||||
# install supervisord
|
|
||||||
RUN apt-get update && apt-get install -y supervisor
|
|
||||||
COPY ../build/standard/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
|
||||||
RUN mkdir -p /var/run/supervisord
|
|
||||||
RUN mkdir -p /var/log/supervisord
|
|
||||||
|
|
||||||
# clean up apt-get
|
|
||||||
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
|
||||||
|
|
||||||
# copy entrypoint
|
|
||||||
COPY ../build/standard/entrypoint.sh /usr/sbin/entrypoint.sh
|
|
||||||
RUN chmod +x /usr/sbin/entrypoint.sh
|
|
||||||
|
|
||||||
# volumes
|
|
||||||
VOLUME /home/gaseous/.gaseous-server
|
|
||||||
|
|
||||||
# start services
|
|
||||||
ENTRYPOINT [ "/usr/sbin/entrypoint.sh" ]
|
|
||||||
|
@@ -9,27 +9,24 @@ RUN echo "Build: $BUILDPLATFORM"
|
|||||||
|
|
||||||
# Copy everything
|
# Copy everything
|
||||||
COPY .. ./
|
COPY .. ./
|
||||||
|
|
||||||
# Build Gaseous Web Server
|
|
||||||
# Restore as distinct layers
|
# Restore as distinct layers
|
||||||
RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
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.0.12.7z
|
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
||||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.7z
|
||||||
|
|
||||||
|
RUN wget --recursive --no-parent https://cdn.emulatorjs.org/latest/
|
||||||
|
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
||||||
|
RUN cp -fr cdn.emulatorjs.org/latest/* out/wwwroot/emulators/EmulatorJS
|
||||||
|
RUN rm -Rf cdn.emulatorjs.org
|
||||||
|
|
||||||
# Build runtime image
|
# Build runtime image
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||||
@@ -56,12 +53,12 @@ ENV MARIADB_ROOT_PASSWORD=${dbpass}
|
|||||||
RUN DEBIAN_FRONTEND=noninteractive && \
|
RUN DEBIAN_FRONTEND=noninteractive && \
|
||||||
apt-get update && apt-get install -y mariadb-server
|
apt-get update && apt-get install -y mariadb-server
|
||||||
RUN mkdir -p /run/mysqld
|
RUN mkdir -p /run/mysqld
|
||||||
COPY ../build/embeddeddb/mariadb.sh /usr/sbin/start-mariadb.sh
|
COPY ../build/mariadb.sh /usr/sbin/start-mariadb.sh
|
||||||
RUN chmod +x /usr/sbin/start-mariadb.sh
|
RUN chmod +x /usr/sbin/start-mariadb.sh
|
||||||
|
|
||||||
# install supervisord
|
# install supervisord
|
||||||
RUN apt-get install -y supervisor
|
RUN apt-get install -y supervisor
|
||||||
COPY ../build/embeddeddb/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
COPY ../build/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
RUN mkdir -p /var/run/supervisord
|
RUN mkdir -p /var/run/supervisord
|
||||||
RUN mkdir -p /var/log/supervisord
|
RUN mkdir -p /var/log/supervisord
|
||||||
|
|
||||||
@@ -69,7 +66,7 @@ RUN mkdir -p /var/log/supervisord
|
|||||||
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
||||||
|
|
||||||
# copy entrypoint
|
# copy entrypoint
|
||||||
COPY ../build/embeddeddb/entrypoint.sh /usr/sbin/entrypoint.sh
|
COPY ../build/entrypoint.sh /usr/sbin/entrypoint.sh
|
||||||
RUN chmod +x /usr/sbin/entrypoint.sh
|
RUN chmod +x /usr/sbin/entrypoint.sh
|
||||||
|
|
||||||
# volumes
|
# volumes
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# create the user
|
|
||||||
echo "Creating user gaseous with UID ${PUID} and GID ${PGID}"
|
|
||||||
groupadd -g ${PGID} gaseous
|
|
||||||
useradd -u ${PUID} -g ${PGID} -m gaseous -d /home/gaseous -G sudo
|
|
||||||
usermod -p "*" gaseous
|
|
||||||
mkdir -p /home/gaseous/.aspnet
|
|
||||||
chown -R ${PUID} /App /home/gaseous/.aspnet
|
|
||||||
chgrp -R ${PGID} /App /home/gaseous/.aspnet
|
|
||||||
mkdir -p /home/gaseous/.gaseous-server
|
|
||||||
chown -R ${PUID} /App /home/gaseous/.gaseous-server
|
|
||||||
chgrp -R ${PGID} /App /home/gaseous/.gaseous-server
|
|
||||||
|
|
||||||
# Set MariaDB permissions
|
|
||||||
mkdir -p /var/lib/mysql /var/log/mariadb /run/mysqld
|
|
||||||
chown -R ${PUID} /var/lib/mysql /var/log/mariadb /run/mysqld
|
|
||||||
chgrp -R ${PGID} /var/lib/mysql /var/log/mariadb /run/mysqld
|
|
||||||
|
|
||||||
# Start supervisord and services
|
|
||||||
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
|
13
build/entrypoint.sh
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# create the user
|
||||||
|
echo "Creating user gaseous with UID ${PUID} and GID ${PGID}"
|
||||||
|
groupadd -g ${PGID} gaseous
|
||||||
|
useradd -u ${PUID} -g ${PGID} -m gaseous -d /home/gaseous -G sudo
|
||||||
|
usermod -p "*" gaseous
|
||||||
|
mkdir -p /home/gaseous/.gaseous-server /var/lib/mysql /var/log/mariadb /run/mysqld
|
||||||
|
chown -R ${PUID} /App /home/gaseous/.gaseous-server /var/lib/mysql /var/log/mariadb /run/mysqld
|
||||||
|
chgrp -R ${PGID} /App /home/gaseous/.gaseous-server /var/lib/mysql /var/log/mariadb /run/mysqld
|
||||||
|
|
||||||
|
# Start supervisord and services
|
||||||
|
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
@@ -1,25 +1,20 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# install the database
|
# install the database
|
||||||
echo "Installing MariaDB"
|
|
||||||
/usr/bin/mariadb-install-db --datadir=/var/lib/mysql --user=gaseous
|
/usr/bin/mariadb-install-db --datadir=/var/lib/mysql --user=gaseous
|
||||||
|
|
||||||
# start the database server without network or grant tables
|
# start the database server without network or grant tables
|
||||||
echo "Starting MariaDB"
|
|
||||||
/usr/sbin/mariadbd --datadir=/var/lib/mysql --skip-grant-tables --skip-networking &
|
/usr/sbin/mariadbd --datadir=/var/lib/mysql --skip-grant-tables --skip-networking &
|
||||||
|
|
||||||
# wait for the server to start
|
# wait for the server to start
|
||||||
sleep 5
|
sleep 5
|
||||||
|
|
||||||
# change the root password
|
# change the root password
|
||||||
echo "Setting MariaDB root password"
|
|
||||||
mariadb -u root -e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; ALTER USER 'gaseous'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; FLUSH PRIVILEGES; SHUTDOWN;"
|
mariadb -u root -e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; ALTER USER 'gaseous'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; FLUSH PRIVILEGES; SHUTDOWN;"
|
||||||
|
|
||||||
# stop the server
|
# stop the server
|
||||||
sleep 5
|
sleep 5
|
||||||
echo "Stopping MariaDB"
|
|
||||||
killall mariadbd
|
killall mariadbd
|
||||||
|
|
||||||
# start the server normally
|
# start the server normally
|
||||||
echo "Starting MariaDB"
|
/usr/sbin/mariadbd --datadir=/var/lib/mysql
|
||||||
/usr/sbin/mariadbd --datadir=/var/lib/mysql --user=gaseous
|
|
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# create the user
|
|
||||||
echo "Creating user gaseous with UID ${PUID} and GID ${PGID}"
|
|
||||||
groupadd -g ${PGID} gaseous
|
|
||||||
useradd -u ${PUID} -g ${PGID} -m gaseous -d /home/gaseous -G sudo
|
|
||||||
usermod -p "*" gaseous
|
|
||||||
mkdir -p /home/gaseous/.aspnet
|
|
||||||
chown -R ${PUID} /App /home/gaseous/.aspnet
|
|
||||||
chgrp -R ${PGID} /App /home/gaseous/.aspnet
|
|
||||||
mkdir -p /home/gaseous/.gaseous-server
|
|
||||||
chown -R ${PUID} /App /home/gaseous/.gaseous-server
|
|
||||||
chgrp -R ${PGID} /App /home/gaseous/.gaseous-server
|
|
||||||
|
|
||||||
# Start supervisord and services
|
|
||||||
/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
|
@@ -1,28 +0,0 @@
|
|||||||
[supervisord]
|
|
||||||
user=root
|
|
||||||
nodaemon=true
|
|
||||||
logfile=/var/log/supervisord/supervisord.log
|
|
||||||
logfile_maxbytes=50
|
|
||||||
logfile_backups=5
|
|
||||||
pidfile=/var/run/supervisord/supervisord.pid
|
|
||||||
loglevel = info
|
|
||||||
|
|
||||||
[unix_http_server]
|
|
||||||
file=/var/run/supervisord/supervisor.sock
|
|
||||||
chmod=0700
|
|
||||||
|
|
||||||
[rpcinterface:supervisor]
|
|
||||||
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
|
||||||
|
|
||||||
[supervisorctl]
|
|
||||||
serverurl=unix:///var/run/supervisord/supervisor.sock
|
|
||||||
|
|
||||||
[program:gaseous-server]
|
|
||||||
user=gaseous
|
|
||||||
command=dotnet /App/gaseous-server.dll
|
|
||||||
environment=HOME="/home/gaseous",USER="gaseous"
|
|
||||||
autostart=true
|
|
||||||
autorestart=true
|
|
||||||
redirect_stderr=true
|
|
||||||
stdout_logfile=/dev/fd/1
|
|
||||||
stdout_logfile_maxbytes=0
|
|
@@ -4,7 +4,6 @@ services:
|
|||||||
container_name: gaseous-server
|
container_name: gaseous-server
|
||||||
build:
|
build:
|
||||||
context: ./
|
context: ./
|
||||||
dockerfile: ./build/Dockerfile
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- gaseous
|
- gaseous
|
||||||
@@ -13,7 +12,7 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- 5198:80
|
- 5198:80
|
||||||
volumes:
|
volumes:
|
||||||
- gs:/home/gaseous/.gaseous-server
|
- gs:/root/.gaseous-server
|
||||||
environment:
|
environment:
|
||||||
- TZ=Australia/Sydney
|
- TZ=Australia/Sydney
|
||||||
- dbhost=gsdb
|
- dbhost=gsdb
|
||||||
|
39
docker-compose.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
gaseous-server:
|
||||||
|
container_name: gaseous-server
|
||||||
|
image: gaseousgames/gaseousserver:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- gaseous
|
||||||
|
depends_on:
|
||||||
|
- gsdb
|
||||||
|
ports:
|
||||||
|
- 5198:80
|
||||||
|
volumes:
|
||||||
|
- gs:/root/.gaseous-server
|
||||||
|
environment:
|
||||||
|
- TZ=Australia/Sydney
|
||||||
|
- dbhost=gsdb
|
||||||
|
- dbuser=root
|
||||||
|
- dbpass=gaseous
|
||||||
|
- igdbclientid=<clientid>
|
||||||
|
- igdbclientsecret=<clientsecret>
|
||||||
|
gsdb:
|
||||||
|
container_name: gsdb
|
||||||
|
image: mariadb
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- gaseous
|
||||||
|
volumes:
|
||||||
|
- gsdb:/var/lib/mysql
|
||||||
|
environment:
|
||||||
|
- MARIADB_ROOT_PASSWORD=gaseous
|
||||||
|
- MARIADB_USER=gaseous
|
||||||
|
- MARIADB_PASSWORD=gaseous
|
||||||
|
networks:
|
||||||
|
gaseous:
|
||||||
|
driver: bridge
|
||||||
|
volumes:
|
||||||
|
gs:
|
||||||
|
gsdb:
|
@@ -1,354 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Authentication;
|
|
||||||
using gaseous_server.Classes;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
/* ------------------------------------------------- */
|
|
||||||
/* This tool is a CLI tool that is used to manage */
|
|
||||||
/* the Gaseous Server. */
|
|
||||||
/* Functions such as user management, and backups */
|
|
||||||
/* are available. */
|
|
||||||
/* ------------------------------------------------- */
|
|
||||||
|
|
||||||
// load app settings
|
|
||||||
Config.InitSettings();
|
|
||||||
|
|
||||||
// set up database connection
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
|
|
||||||
// set up identity
|
|
||||||
IServiceCollection services = new ServiceCollection();
|
|
||||||
services.AddLogging();
|
|
||||||
|
|
||||||
services.AddIdentity<ApplicationUser, ApplicationRole>(options =>
|
|
||||||
{
|
|
||||||
options.Password.RequireDigit = true;
|
|
||||||
options.Password.RequireLowercase = true;
|
|
||||||
options.Password.RequireNonAlphanumeric = false;
|
|
||||||
options.Password.RequireUppercase = true;
|
|
||||||
options.Password.RequiredLength = 10;
|
|
||||||
options.User.AllowedUserNameCharacters = null;
|
|
||||||
options.User.RequireUniqueEmail = true;
|
|
||||||
options.SignIn.RequireConfirmedPhoneNumber = false;
|
|
||||||
options.SignIn.RequireConfirmedEmail = false;
|
|
||||||
options.SignIn.RequireConfirmedAccount = false;
|
|
||||||
})
|
|
||||||
.AddUserStore<UserStore>()
|
|
||||||
.AddRoleStore<RoleStore>()
|
|
||||||
;
|
|
||||||
services.AddScoped<UserStore>();
|
|
||||||
services.AddScoped<RoleStore>();
|
|
||||||
|
|
||||||
services.AddTransient<IUserStore<ApplicationUser>, UserStore>();
|
|
||||||
services.AddTransient<IRoleStore<ApplicationRole>, RoleStore>();
|
|
||||||
var userManager = services.BuildServiceProvider().GetService<UserManager<ApplicationUser>>();
|
|
||||||
|
|
||||||
// load the command line arguments
|
|
||||||
string[] cmdArgs = Environment.GetCommandLineArgs();
|
|
||||||
|
|
||||||
// check if the user has entered any arguments
|
|
||||||
if (cmdArgs.Length == 1)
|
|
||||||
{
|
|
||||||
// no arguments were entered
|
|
||||||
Console.WriteLine("Gaseous CLI - A tool for managing the Gaseous Server");
|
|
||||||
Console.WriteLine("Usage: gaseous-cli [command] [options]");
|
|
||||||
Console.WriteLine("Commands:");
|
|
||||||
Console.WriteLine(" user [command] [options] - Manage users");
|
|
||||||
Console.WriteLine(" role [command] [options] - Manage roles");
|
|
||||||
// Console.WriteLine(" backup [command] [options] - Manage backups");
|
|
||||||
// Console.WriteLine(" restore [command] [options] - Restore backups");
|
|
||||||
Console.WriteLine(" help - Display this help message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the help command
|
|
||||||
if (cmdArgs[1] == "help")
|
|
||||||
{
|
|
||||||
// display the help message
|
|
||||||
Console.WriteLine("Gaseous CLI - A tool for managing the Gaseous Server");
|
|
||||||
Console.WriteLine("Usage: gaseous-cli [command] [options]");
|
|
||||||
Console.WriteLine("Commands:");
|
|
||||||
Console.WriteLine(" user [command] [options] - Manage users");
|
|
||||||
Console.WriteLine(" role [command] [options] - Manage roles");
|
|
||||||
// Console.WriteLine(" backup [command] [options] - Manage backups");
|
|
||||||
// Console.WriteLine(" restore [command] [options] - Restore backups");
|
|
||||||
Console.WriteLine(" help - Display this help message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the user command
|
|
||||||
if (cmdArgs[1] == "user")
|
|
||||||
{
|
|
||||||
// check if the user has entered any arguments
|
|
||||||
if (cmdArgs.Length == 2)
|
|
||||||
{
|
|
||||||
// no arguments were entered
|
|
||||||
Console.WriteLine("User Management");
|
|
||||||
Console.WriteLine("Usage: gaseous-cli user [command] [options]");
|
|
||||||
Console.WriteLine("Commands:");
|
|
||||||
Console.WriteLine(" add [username] [password] - Add a new user");
|
|
||||||
Console.WriteLine(" delete [username] - Delete a user");
|
|
||||||
Console.WriteLine(" resetpassword [username] [password] - Reset a user's password");
|
|
||||||
Console.WriteLine(" list - List all users");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the add command
|
|
||||||
if (cmdArgs[2] == "add")
|
|
||||||
{
|
|
||||||
// check if the user has entered the username and password
|
|
||||||
if (cmdArgs.Length < 5)
|
|
||||||
{
|
|
||||||
// the username and password were not entered
|
|
||||||
Console.WriteLine("Error: Please enter a username and password");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a new user
|
|
||||||
UserTable<ApplicationUser> userTable = new UserTable<ApplicationUser>(db);
|
|
||||||
if (userTable.GetUserByEmail(cmdArgs[3]) != null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: User already exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the user object
|
|
||||||
ApplicationUser user = new ApplicationUser
|
|
||||||
{
|
|
||||||
Id = Guid.NewGuid().ToString(),
|
|
||||||
Email = cmdArgs[3],
|
|
||||||
NormalizedEmail = cmdArgs[3].ToUpper(),
|
|
||||||
EmailConfirmed = true,
|
|
||||||
UserName = cmdArgs[3],
|
|
||||||
NormalizedUserName = cmdArgs[3].ToUpper()
|
|
||||||
};
|
|
||||||
|
|
||||||
// create the password
|
|
||||||
PasswordHasher<ApplicationUser> passwordHasher = new PasswordHasher<ApplicationUser>();
|
|
||||||
user.PasswordHash = passwordHasher.HashPassword(user, cmdArgs[4]);
|
|
||||||
|
|
||||||
await userManager.CreateAsync(user);
|
|
||||||
await userManager.AddToRoleAsync(user, "Player");
|
|
||||||
|
|
||||||
Console.WriteLine("User created successfully with default role: Player");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the delete command
|
|
||||||
if (cmdArgs[2] == "delete")
|
|
||||||
{
|
|
||||||
// check if the user has entered the username
|
|
||||||
if (cmdArgs.Length < 4)
|
|
||||||
{
|
|
||||||
// the username was not entered
|
|
||||||
Console.WriteLine("Error: Please enter a username");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete the user
|
|
||||||
UserTable<ApplicationUser> userTable = new UserTable<ApplicationUser>(db);
|
|
||||||
ApplicationUser user = userTable.GetUserByEmail(cmdArgs[3]);
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: User not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await userManager.DeleteAsync(user);
|
|
||||||
|
|
||||||
Console.WriteLine("User deleted successfully");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the resetpassword command
|
|
||||||
if (cmdArgs[2] == "resetpassword")
|
|
||||||
{
|
|
||||||
// check if the user has entered the username and password
|
|
||||||
if (cmdArgs.Length < 5)
|
|
||||||
{
|
|
||||||
// the username and password were not entered
|
|
||||||
Console.WriteLine("Error: Please enter a username and password");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset the user's password
|
|
||||||
UserTable<ApplicationUser> userTable = new UserTable<ApplicationUser>(db);
|
|
||||||
ApplicationUser user = userTable.GetUserByEmail(cmdArgs[3]);
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: User not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the password
|
|
||||||
PasswordHasher<ApplicationUser> passwordHasher = new PasswordHasher<ApplicationUser>();
|
|
||||||
user.PasswordHash = passwordHasher.HashPassword(user, cmdArgs[4]);
|
|
||||||
|
|
||||||
await userManager.UpdateAsync(user);
|
|
||||||
|
|
||||||
Console.WriteLine("Password reset successfully");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the list command
|
|
||||||
if (cmdArgs[2] == "list")
|
|
||||||
{
|
|
||||||
// list all users
|
|
||||||
UserTable<ApplicationUser> userTable = new UserTable<ApplicationUser>(db);
|
|
||||||
var userList = userTable.GetUsers();
|
|
||||||
foreach (var user in userList)
|
|
||||||
{
|
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
|
||||||
Console.WriteLine(user.Email + " - " + string.Join(", ", roles));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the role command
|
|
||||||
if (cmdArgs[1] == "role")
|
|
||||||
{
|
|
||||||
// check if the user has entered any arguments
|
|
||||||
if (cmdArgs.Length == 2)
|
|
||||||
{
|
|
||||||
// no arguments were entered
|
|
||||||
Console.WriteLine("Role Management");
|
|
||||||
Console.WriteLine("Usage: gaseous-cli role [command] [options]");
|
|
||||||
Console.WriteLine("Commands:");
|
|
||||||
Console.WriteLine(" set [username] [role] - Set the role of a user");
|
|
||||||
Console.WriteLine(" list - List all roles");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the role command
|
|
||||||
if (cmdArgs[2] == "set")
|
|
||||||
{
|
|
||||||
// check if the user has entered the username and role
|
|
||||||
if (cmdArgs.Length < 5)
|
|
||||||
{
|
|
||||||
// the username and role were not entered
|
|
||||||
Console.WriteLine("Error: Please enter a username and role");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the role of the user
|
|
||||||
UserTable<ApplicationUser> userTable = new UserTable<ApplicationUser>(db);
|
|
||||||
ApplicationUser user = userTable.GetUserByEmail(cmdArgs[3]);
|
|
||||||
if (user == null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: User not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all existing roles from user
|
|
||||||
var roles = await userManager.GetRolesAsync(user);
|
|
||||||
await userManager.RemoveFromRolesAsync(user, roles.ToArray());
|
|
||||||
|
|
||||||
// add the new role to the user
|
|
||||||
await userManager.AddToRoleAsync(user, cmdArgs[4]);
|
|
||||||
|
|
||||||
Console.WriteLine("Role set successfully");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the user has entered the list command
|
|
||||||
if (cmdArgs[2] == "list")
|
|
||||||
{
|
|
||||||
// list all roles
|
|
||||||
string[] roles = { "Player", "Gamer", "Admin" };
|
|
||||||
foreach (var role in roles)
|
|
||||||
{
|
|
||||||
Console.WriteLine(role);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// // check if the user has entered the backup command
|
|
||||||
// if (cmdArgs[1] == "backup")
|
|
||||||
// {
|
|
||||||
// // check if the user has entered any arguments
|
|
||||||
// if (cmdArgs.Length == 2)
|
|
||||||
// {
|
|
||||||
// // no arguments were entered
|
|
||||||
// Console.WriteLine("Backup Management");
|
|
||||||
// Console.WriteLine("Usage: gaseous-cli backup [command] [options]");
|
|
||||||
// Console.WriteLine("Commands:");
|
|
||||||
// Console.WriteLine(" create - Create a backup");
|
|
||||||
// Console.WriteLine(" list - List all backups");
|
|
||||||
// Console.WriteLine(" remove [backup_id] - Remove a backup");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // check if the user has entered the create command
|
|
||||||
// if (cmdArgs[2] == "create")
|
|
||||||
// {
|
|
||||||
// // create a backup
|
|
||||||
// Backup.CreateBackup();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // check if the user has entered the list command
|
|
||||||
// if (cmdArgs[2] == "list")
|
|
||||||
// {
|
|
||||||
// // list all backups
|
|
||||||
// Backup.ListBackups();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // check if the user has entered the remove command
|
|
||||||
// if (cmdArgs[2] == "remove")
|
|
||||||
// {
|
|
||||||
// // check if the user has entered the backup id
|
|
||||||
// if (cmdArgs.Length < 4)
|
|
||||||
// {
|
|
||||||
// // the backup id was not entered
|
|
||||||
// Console.WriteLine("Error: Please enter a backup id");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // remove the backup
|
|
||||||
// Backup.RemoveBackup(cmdArgs[3]);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // check if the user has entered the restore command
|
|
||||||
// if (cmdArgs[1] == "restore")
|
|
||||||
// {
|
|
||||||
// // check if the user has entered any arguments
|
|
||||||
// if (cmdArgs.Length == 2)
|
|
||||||
// {
|
|
||||||
// // no arguments were entered
|
|
||||||
// Console.WriteLine("Restore Management");
|
|
||||||
// Console.WriteLine("Usage: gaseous-cli restore [command] [options]");
|
|
||||||
// Console.WriteLine("Commands:");
|
|
||||||
// Console.WriteLine(" restore [backup_id] - Restore a backup");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // check if the user has entered the restore command
|
|
||||||
// if (cmdArgs[2] == "restore")
|
|
||||||
// {
|
|
||||||
// // check if the user has entered the backup id
|
|
||||||
// if (cmdArgs.Length < 4)
|
|
||||||
// {
|
|
||||||
// // the backup id was not entered
|
|
||||||
// Console.WriteLine("Error: Please enter a backup id");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // restore the backup
|
|
||||||
// Restore.RestoreBackup(cmdArgs[3]);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// the user entered an invalid command
|
|
||||||
Console.WriteLine("Error: Invalid command");
|
|
@@ -1,28 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<RootNamespace>gaseous_cli</RootNamespace>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<DocumentationFile>bin\Debug\net8.0\gaseous-cli.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<DocumentationFile>bin\Release\net8.0\gaseous-cli.xml</DocumentationFile>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\gaseous-server\gaseous-server.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
BIN
gaseous-server/.DS_Store
vendored
Normal file
@@ -12,6 +12,6 @@ namespace Authentication
|
|||||||
{
|
{
|
||||||
public SecurityProfileViewModel SecurityProfile { get; set; }
|
public SecurityProfileViewModel SecurityProfile { get; set; }
|
||||||
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
||||||
public Guid ProfileId { get; set; }
|
public Guid Avatar { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,7 +75,7 @@ namespace Authentication
|
|||||||
public TUser GetUserById(string userId)
|
public TUser GetUserById(string userId)
|
||||||
{
|
{
|
||||||
TUser user = null;
|
TUser user = null;
|
||||||
string commandText = "Select * from Users LEFT JOIN (SELECT Id As ProfileId, UserId FROM UserProfiles) UserProfiles ON Users.Id = UserProfiles.UserId where Id = @id";
|
string commandText = "Select * from Users LEFT JOIN (SELECT UserId, Id AS AvatarId FROM UserAvatars) UserAvatars ON Users.Id = UserAvatars.UserId where Id = @id";
|
||||||
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@id", userId } };
|
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@id", userId } };
|
||||||
|
|
||||||
var rows = _database.ExecuteCMDDict(commandText, parameters);
|
var rows = _database.ExecuteCMDDict(commandText, parameters);
|
||||||
@@ -100,7 +100,7 @@ namespace Authentication
|
|||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
user.UserPreferences = GetPreferences(user);
|
user.UserPreferences = GetPreferences(user);
|
||||||
user.ProfileId = string.IsNullOrEmpty((string?)row["ProfileId"]) ? Guid.Empty : Guid.Parse((string?)row["ProfileId"]);
|
user.Avatar = string.IsNullOrEmpty((string?)row["AvatarId"]) ? Guid.Empty : Guid.Parse((string?)row["AvatarId"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
@@ -114,7 +114,7 @@ namespace Authentication
|
|||||||
public List<TUser> GetUserByName(string normalizedUserName)
|
public List<TUser> GetUserByName(string normalizedUserName)
|
||||||
{
|
{
|
||||||
List<TUser> users = new List<TUser>();
|
List<TUser> users = new List<TUser>();
|
||||||
string commandText = "Select * from Users LEFT JOIN (SELECT Id As ProfileId, UserId FROM UserProfiles) UserProfiles ON Users.Id = UserProfiles.UserId where NormalizedEmail = @name";
|
string commandText = "Select * from Users LEFT JOIN (SELECT UserId, Id AS AvatarId FROM UserAvatars) UserAvatars ON Users.Id = UserAvatars.UserId where NormalizedEmail = @name";
|
||||||
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@name", normalizedUserName } };
|
Dictionary<string, object> parameters = new Dictionary<string, object>() { { "@name", normalizedUserName } };
|
||||||
|
|
||||||
var rows = _database.ExecuteCMDDict(commandText, parameters);
|
var rows = _database.ExecuteCMDDict(commandText, parameters);
|
||||||
@@ -138,7 +138,7 @@ namespace Authentication
|
|||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
user.UserPreferences = GetPreferences(user);
|
user.UserPreferences = GetPreferences(user);
|
||||||
user.ProfileId = string.IsNullOrEmpty((string?)row["ProfileId"]) ? Guid.Empty : Guid.Parse((string?)row["ProfileId"]);
|
user.Avatar = string.IsNullOrEmpty((string?)row["AvatarId"]) ? Guid.Empty : Guid.Parse((string?)row["AvatarId"]);
|
||||||
users.Add(user);
|
users.Add(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ namespace Authentication
|
|||||||
public List<TUser> GetUsers()
|
public List<TUser> GetUsers()
|
||||||
{
|
{
|
||||||
List<TUser> users = new List<TUser>();
|
List<TUser> users = new List<TUser>();
|
||||||
string commandText = "Select * from Users LEFT JOIN (SELECT Id As ProfileId, UserId FROM UserProfiles) UserProfiles ON Users.Id = UserProfiles.UserId order by NormalizedUserName";
|
string commandText = "Select * from Users LEFT JOIN (SELECT UserId, Id AS AvatarId FROM UserAvatars) UserAvatars ON Users.Id = UserAvatars.UserId order by NormalizedUserName";
|
||||||
|
|
||||||
var rows = _database.ExecuteCMDDict(commandText);
|
var rows = _database.ExecuteCMDDict(commandText);
|
||||||
foreach(Dictionary<string, object> row in rows)
|
foreach(Dictionary<string, object> row in rows)
|
||||||
@@ -171,7 +171,7 @@ namespace Authentication
|
|||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
user.UserPreferences = GetPreferences(user);
|
user.UserPreferences = GetPreferences(user);
|
||||||
user.ProfileId = string.IsNullOrEmpty((string?)row["ProfileId"]) ? Guid.Empty : Guid.Parse((string?)row["ProfileId"]);
|
user.Avatar = string.IsNullOrEmpty((string?)row["AvatarId"]) ? Guid.Empty : Guid.Parse((string?)row["AvatarId"]);
|
||||||
users.Add(user);
|
users.Add(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +258,10 @@ namespace Authentication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public int Insert(TUser user)
|
public int Insert(TUser user)
|
||||||
{
|
{
|
||||||
string commandText = @"Insert into Users (UserName, Id, PasswordHash, SecurityStamp, ConcurrencyStamp, Email, EmailConfirmed, PhoneNumber, PhoneNumberConfirmed, NormalizedEmail, NormalizedUserName, AccessFailedCount, LockoutEnabled, LockoutEnd, TwoFactorEnabled) values (@name, @id, @pwdHash, @SecStamp, @concurrencystamp, @email ,@emailconfirmed ,@phonenumber, @phonenumberconfirmed, @normalizedemail, @normalizedusername, @accesscount, @lockoutenabled, @lockoutenddate, @twofactorenabled); Insert into UserProfiles (Id, UserId, DisplayName, Quip, UnstructuredData) values (@profileId, @id, @email, '', '{}');";
|
string commandText = @"Insert into Users (UserName, Id, PasswordHash, SecurityStamp, ConcurrencyStamp, Email, EmailConfirmed, PhoneNumber, PhoneNumberConfirmed, NormalizedEmail, NormalizedUserName, AccessFailedCount, LockoutEnabled, LockoutEnd, TwoFactorEnabled) values (@name, @id, @pwdHash, @SecStamp, @concurrencystamp, @email ,@emailconfirmed ,@phonenumber, @phonenumberconfirmed, @normalizedemail, @normalizedusername, @accesscount, @lockoutenabled, @lockoutenddate, @twofactorenabled);";
|
||||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||||
parameters.Add("@name", user.UserName);
|
parameters.Add("@name", user.UserName);
|
||||||
parameters.Add("@id", user.Id);
|
parameters.Add("@id", user.Id);
|
||||||
parameters.Add("@profileId", Guid.NewGuid());
|
|
||||||
parameters.Add("@pwdHash", user.PasswordHash);
|
parameters.Add("@pwdHash", user.PasswordHash);
|
||||||
parameters.Add("@SecStamp", user.SecurityStamp);
|
parameters.Add("@SecStamp", user.SecurityStamp);
|
||||||
parameters.Add("@concurrencystamp", user.ConcurrencyStamp);
|
parameters.Add("@concurrencystamp", user.ConcurrencyStamp);
|
||||||
@@ -293,7 +292,7 @@ namespace Authentication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private int Delete(string userId)
|
private int Delete(string userId)
|
||||||
{
|
{
|
||||||
string commandText = "Delete from Users where Id = @userId; Delete from User_Settings where Id = @userId; Delete from UserProfiles where UserId = @userId; Delete from GameState where UserId = @userId;";
|
string commandText = "Delete from Users where Id = @userId; Delete from User_Settings where Id = @userId; Delete from GameState where UserId = @userId;";
|
||||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||||
parameters.Add("@userId", userId);
|
parameters.Add("@userId", userId);
|
||||||
|
|
||||||
|
@@ -8,9 +8,8 @@ namespace Authentication
|
|||||||
public List<String> Roles { get; set; }
|
public List<String> Roles { get; set; }
|
||||||
public SecurityProfileViewModel SecurityProfile { get; set; }
|
public SecurityProfileViewModel SecurityProfile { get; set; }
|
||||||
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
||||||
public Guid ProfileId { get; set; }
|
public Guid Avatar { get; set; }
|
||||||
public string HighestRole
|
public string HighestRole {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string _highestRole = "";
|
string _highestRole = "";
|
||||||
|
@@ -8,14 +8,11 @@ namespace Authentication
|
|||||||
public DateTimeOffset? LockoutEnd { get; set; }
|
public DateTimeOffset? LockoutEnd { get; set; }
|
||||||
public List<string> Roles { get; set; }
|
public List<string> Roles { get; set; }
|
||||||
public SecurityProfileViewModel SecurityProfile { get; set; }
|
public SecurityProfileViewModel SecurityProfile { get; set; }
|
||||||
public Guid ProfileId { get; set; }
|
public Guid Avatar { get; set; }
|
||||||
public string HighestRole
|
public string HighestRole {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string _highestRole = "";
|
string _highestRole = "";
|
||||||
if (Roles != null)
|
|
||||||
{
|
|
||||||
foreach (string role in Roles)
|
foreach (string role in Roles)
|
||||||
{
|
{
|
||||||
switch (role)
|
switch (role)
|
||||||
@@ -43,11 +40,6 @@ namespace Authentication
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_highestRole = "Player";
|
|
||||||
}
|
|
||||||
|
|
||||||
return _highestRole;
|
return _highestRole;
|
||||||
}
|
}
|
||||||
|
@@ -11,33 +11,6 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
if (Directory.Exists(Config.LibraryConfiguration.LibraryBIOSDirectory))
|
|
||||||
{
|
|
||||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
|
||||||
{
|
|
||||||
if (platformMapping.Bios != null)
|
|
||||||
{
|
|
||||||
foreach (Models.PlatformMapping.PlatformMapItem.EmulatorBiosItem emulatorBiosItem in platformMapping.Bios)
|
|
||||||
{
|
|
||||||
string oldBiosPath = Path.Combine(Config.LibraryConfiguration.LibraryBIOSDirectory, platformMapping.IGDBSlug.ToString(), emulatorBiosItem.filename);
|
|
||||||
string newBiosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, emulatorBiosItem.hash + ".bios");
|
|
||||||
|
|
||||||
if (File.Exists(oldBiosPath))
|
|
||||||
{
|
|
||||||
File.Copy(oldBiosPath, newBiosPath, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove old BIOS folder structure
|
|
||||||
Directory.Delete(Config.LibraryConfiguration.LibraryBIOSDirectory, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Models.PlatformMapping.PlatformMapItem? BiosHashSignatureLookup(string MD5)
|
public static Models.PlatformMapping.PlatformMapItem? BiosHashSignatureLookup(string MD5)
|
||||||
{
|
{
|
||||||
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||||
@@ -123,11 +96,10 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, hash + ".bios");
|
return Path.Combine(Config.LibraryConfiguration.LibraryBIOSDirectory, platformslug, base.filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public bool Available
|
public bool Available {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
bool fileExists = File.Exists(biosPath);
|
bool fileExists = File.Exists(biosPath);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
|
@@ -154,8 +154,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Console.WriteLine("Using configuration:");
|
Console.WriteLine("Using configuration:");
|
||||||
// Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(_config, Formatting.Indented));
|
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(_config, Formatting.Indented));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateConfig()
|
public static void UpdateConfig()
|
||||||
@@ -197,12 +197,17 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
string SettingName = (string)dataRow["Setting"];
|
string SettingName = (string)dataRow["Setting"];
|
||||||
|
|
||||||
|
if (SettingName.StartsWith("LastRun_"))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Break");
|
||||||
|
}
|
||||||
|
|
||||||
if (AppSettings.ContainsKey(SettingName))
|
if (AppSettings.ContainsKey(SettingName))
|
||||||
{
|
{
|
||||||
AppSettings.Remove(SettingName);
|
AppSettings.Remove(SettingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging.Log(Logging.LogType.Information, "Load Settings", "Loading setting " + SettingName + " from database");
|
Logging.Log(Logging.LogType.Information, "Load Settings", "Loading setting " + SettingName + " from database");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -356,8 +361,10 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
||||||
Type type = typeof(T);
|
Type type = typeof(T);
|
||||||
if (type.ToString() == "System.DateTime")
|
|
||||||
|
switch (type.ToString())
|
||||||
{
|
{
|
||||||
|
case "System.DateTime":
|
||||||
dbDict = new Dictionary<string, object>
|
dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "SettingName", SettingName },
|
{ "SettingName", SettingName },
|
||||||
@@ -365,9 +372,19 @@ namespace gaseous_server.Classes
|
|||||||
{ "Value", null },
|
{ "Value", null },
|
||||||
{ "ValueDate", Value }
|
{ "ValueDate", Value }
|
||||||
};
|
};
|
||||||
}
|
break;
|
||||||
else
|
|
||||||
|
case "System.Collections.Generic.List`1[gaseous_server.Classes.Metadata.Games+SearchType]":
|
||||||
|
dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
|
{ "SettingName", SettingName },
|
||||||
|
{ "ValueType", 2 },
|
||||||
|
{ "Value", JsonConvert.SerializeObject(Value) },
|
||||||
|
{ "ValueDate", null }
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
dbDict = new Dictionary<string, object>
|
dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "SettingName", SettingName },
|
{ "SettingName", SettingName },
|
||||||
@@ -375,6 +392,7 @@ namespace gaseous_server.Classes
|
|||||||
{ "Value", Value },
|
{ "Value", Value },
|
||||||
{ "ValueDate", null }
|
{ "ValueDate", null }
|
||||||
};
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -531,7 +549,11 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Path.Combine(Config.ConfigurationPath, "Data");
|
return ReadSetting<string>("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data"));
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
SetSetting<string>("LibraryRootDirectory", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,14 +597,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibraryFirmwareDirectory
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Path.Combine(LibraryRootDirectory, "Firmware");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LibraryUploadDirectory
|
public string LibraryUploadDirectory
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -644,7 +658,7 @@ namespace gaseous_server.Classes
|
|||||||
return MetadataPath;
|
return MetadataPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibrarySignaturesDirectory
|
public string LibrarySignatureImportDirectory
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -652,26 +666,16 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string LibrarySignaturesProcessedDirectory
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Path.Combine(LibraryRootDirectory, "Signatures - Processed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitLibrary()
|
public void InitLibrary()
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
if (!Directory.Exists(LibraryRootDirectory)) { Directory.CreateDirectory(LibraryRootDirectory); }
|
||||||
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
|
if (!Directory.Exists(LibraryImportDirectory)) { Directory.CreateDirectory(LibraryImportDirectory); }
|
||||||
// if (!Directory.Exists(LibraryBIOSDirectory)) { Directory.CreateDirectory(LibraryBIOSDirectory); }
|
if (!Directory.Exists(LibraryBIOSDirectory)) { Directory.CreateDirectory(LibraryBIOSDirectory); }
|
||||||
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); }
|
||||||
if (!Directory.Exists(LibraryTempDirectory)) { Directory.CreateDirectory(LibraryTempDirectory); }
|
if (!Directory.Exists(LibraryTempDirectory)) { Directory.CreateDirectory(LibraryTempDirectory); }
|
||||||
if (!Directory.Exists(LibraryCollectionsDirectory)) { Directory.CreateDirectory(LibraryCollectionsDirectory); }
|
if (!Directory.Exists(LibraryCollectionsDirectory)) { Directory.CreateDirectory(LibraryCollectionsDirectory); }
|
||||||
if (!Directory.Exists(LibrarySignaturesDirectory)) { Directory.CreateDirectory(LibrarySignaturesDirectory); }
|
if (!Directory.Exists(LibrarySignatureImportDirectory)) { Directory.CreateDirectory(LibrarySignatureImportDirectory); }
|
||||||
if (!Directory.Exists(LibrarySignaturesProcessedDirectory)) { Directory.CreateDirectory(LibrarySignaturesProcessedDirectory); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,10 +711,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool _HasheousSubmitFixes { get; set; } = false;
|
|
||||||
|
|
||||||
private static string _HasheousAPIKey { get; set; } = "";
|
|
||||||
|
|
||||||
private static int _MaxLibraryScanWorkers
|
private static int _MaxLibraryScanWorkers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -745,10 +745,6 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
public HasheousClient.Models.MetadataModel.SignatureSources SignatureSource = _SignatureSource;
|
||||||
|
|
||||||
public bool HasheousSubmitFixes = _HasheousSubmitFixes;
|
|
||||||
|
|
||||||
public string HasheousAPIKey = _HasheousAPIKey;
|
|
||||||
|
|
||||||
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
public int MaxLibraryScanWorkers = _MaxLibraryScanWorkers;
|
||||||
|
|
||||||
public string HasheousHost = _HasheousHost;
|
public string HasheousHost = _HasheousHost;
|
||||||
|
@@ -73,8 +73,6 @@ namespace gaseous_server.Classes
|
|||||||
// load resources
|
// load resources
|
||||||
var assembly = Assembly.GetExecutingAssembly();
|
var assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = new DatabaseMemoryCacheOptions(false);
|
|
||||||
|
|
||||||
switch (_ConnectorType)
|
switch (_ConnectorType)
|
||||||
{
|
{
|
||||||
case databaseType.MySql:
|
case databaseType.MySql:
|
||||||
@@ -82,22 +80,22 @@ namespace gaseous_server.Classes
|
|||||||
string sql = "CREATE DATABASE IF NOT EXISTS `" + Config.DatabaseConfiguration.DatabaseName + "`;";
|
string sql = "CREATE DATABASE IF NOT EXISTS `" + Config.DatabaseConfiguration.DatabaseName + "`;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
Logging.Log(Logging.LogType.Information, "Database", "Creating database if it doesn't exist");
|
Logging.Log(Logging.LogType.Information, "Database", "Creating database if it doesn't exist");
|
||||||
ExecuteCMD(sql, dbDict, CacheOptions, 30, "server=" + Config.DatabaseConfiguration.HostName + ";port=" + Config.DatabaseConfiguration.Port + ";userid=" + Config.DatabaseConfiguration.UserName + ";password=" + Config.DatabaseConfiguration.Password);
|
ExecuteCMD(sql, dbDict, 30, "server=" + Config.DatabaseConfiguration.HostName + ";port=" + Config.DatabaseConfiguration.Port + ";userid=" + Config.DatabaseConfiguration.UserName + ";password=" + Config.DatabaseConfiguration.Password);
|
||||||
|
|
||||||
// check if schema version table is in place - if not, create the schema version table
|
// check if schema version table is in place - if not, create the schema version table
|
||||||
sql = "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '" + Config.DatabaseConfiguration.DatabaseName + "' AND TABLE_NAME = 'schema_version';";
|
sql = "SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '" + Config.DatabaseConfiguration.DatabaseName + "' AND TABLE_NAME = 'schema_version';";
|
||||||
DataTable SchemaVersionPresent = ExecuteCMD(sql, dbDict, CacheOptions);
|
DataTable SchemaVersionPresent = ExecuteCMD(sql, dbDict);
|
||||||
if (SchemaVersionPresent.Rows.Count == 0)
|
if (SchemaVersionPresent.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// no schema table present - create it
|
// no schema table present - create it
|
||||||
Logging.Log(Logging.LogType.Information, "Database", "Schema version table doesn't exist. Creating it.");
|
Logging.Log(Logging.LogType.Information, "Database", "Schema version table doesn't exist. Creating it.");
|
||||||
sql = "CREATE TABLE `schema_version` (`schema_version` INT NOT NULL, PRIMARY KEY (`schema_version`)); INSERT INTO `schema_version` (`schema_version`) VALUES (0);";
|
sql = "CREATE TABLE `schema_version` (`schema_version` INT NOT NULL, PRIMARY KEY (`schema_version`)); INSERT INTO `schema_version` (`schema_version`) VALUES (0);";
|
||||||
ExecuteCMD(sql, dbDict, CacheOptions);
|
ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = "SELECT schema_version FROM schema_version;";
|
sql = "SELECT schema_version FROM schema_version;";
|
||||||
dbDict = new Dictionary<string, object>();
|
dbDict = new Dictionary<string, object>();
|
||||||
DataTable SchemaVersion = ExecuteCMD(sql, dbDict, CacheOptions);
|
DataTable SchemaVersion = ExecuteCMD(sql, dbDict);
|
||||||
int OuterSchemaVer = (int)SchemaVersion.Rows[0][0];
|
int OuterSchemaVer = (int)SchemaVersion.Rows[0][0];
|
||||||
if (OuterSchemaVer == 0)
|
if (OuterSchemaVer == 0)
|
||||||
{
|
{
|
||||||
@@ -120,7 +118,7 @@ namespace gaseous_server.Classes
|
|||||||
// apply script
|
// apply script
|
||||||
sql = "SELECT schema_version FROM schema_version;";
|
sql = "SELECT schema_version FROM schema_version;";
|
||||||
dbDict = new Dictionary<string, object>();
|
dbDict = new Dictionary<string, object>();
|
||||||
SchemaVersion = ExecuteCMD(sql, dbDict, CacheOptions);
|
SchemaVersion = ExecuteCMD(sql, dbDict);
|
||||||
if (SchemaVersion.Rows.Count == 0)
|
if (SchemaVersion.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// something is broken here... where's the table?
|
// something is broken here... where's the table?
|
||||||
@@ -142,12 +140,12 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// apply schema!
|
// apply schema!
|
||||||
Logging.Log(Logging.LogType.Information, "Database", "Updating schema to version " + i);
|
Logging.Log(Logging.LogType.Information, "Database", "Updating schema to version " + i);
|
||||||
ExecuteCMD(dbScript, dbDict, CacheOptions, 180);
|
ExecuteCMD(dbScript, dbDict, 180);
|
||||||
|
|
||||||
sql = "UPDATE schema_version SET schema_version=@schemaver";
|
sql = "UPDATE schema_version SET schema_version=@schemaver";
|
||||||
dbDict = new Dictionary<string, object>();
|
dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("schemaver", i);
|
dbDict.Add("schemaver", i);
|
||||||
ExecuteCMD(sql, dbDict, CacheOptions);
|
ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
// run post-upgrade code
|
// run post-upgrade code
|
||||||
DatabaseMigration.PostUpgradeScript(i, _ConnectorType);
|
DatabaseMigration.PostUpgradeScript(i, _ConnectorType);
|
||||||
@@ -172,83 +170,39 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
public DataTable ExecuteCMD(string Command)
|
public DataTable ExecuteCMD(string Command)
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
|
||||||
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
return _ExecuteCMD(Command, dbDict, CacheOptions, 30, "");
|
return _ExecuteCMD(Command, dbDict, 30, "");
|
||||||
}
|
|
||||||
|
|
||||||
public DataTable ExecuteCMD(string Command, DatabaseMemoryCacheOptions? CacheOptions)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
return _ExecuteCMD(Command, dbDict, CacheOptions, 30, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters)
|
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters)
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
return _ExecuteCMD(Command, Parameters, 30, "");
|
||||||
|
|
||||||
return _ExecuteCMD(Command, Parameters, CacheOptions, 30, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions)
|
|
||||||
{
|
|
||||||
return _ExecuteCMD(Command, Parameters, CacheOptions, 30, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
return _ExecuteCMD(Command, Parameters, Timeout, ConnectionString);
|
||||||
|
|
||||||
return _ExecuteCMD(Command, Parameters, CacheOptions, Timeout, ConnectionString);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions, int Timeout = 30, string ConnectionString = "")
|
|
||||||
{
|
|
||||||
return _ExecuteCMD(Command, Parameters, CacheOptions, Timeout, ConnectionString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command)
|
public List<Dictionary<string, object>> ExecuteCMDDict(string Command)
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
|
||||||
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
return _ExecuteCMDDict(Command, dbDict, CacheOptions, 30, "");
|
return _ExecuteCMDDict(Command, dbDict, 30, "");
|
||||||
}
|
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, DatabaseMemoryCacheOptions? CacheOptions)
|
|
||||||
{
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
return _ExecuteCMDDict(Command, dbDict, CacheOptions, 30, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters)
|
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters)
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
return _ExecuteCMDDict(Command, Parameters, 30, "");
|
||||||
|
|
||||||
return _ExecuteCMDDict(Command, Parameters, CacheOptions, 30, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions)
|
|
||||||
{
|
|
||||||
return _ExecuteCMDDict(Command, Parameters, CacheOptions, 30, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
{
|
{
|
||||||
DatabaseMemoryCacheOptions? CacheOptions = null;
|
return _ExecuteCMDDict(Command, Parameters, Timeout, ConnectionString);
|
||||||
|
|
||||||
return _ExecuteCMDDict(Command, Parameters, CacheOptions, Timeout, ConnectionString);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Dictionary<string, object>> ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions, int Timeout = 30, string ConnectionString = "")
|
private List<Dictionary<string, object>> _ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
{
|
{
|
||||||
return _ExecuteCMDDict(Command, Parameters, CacheOptions, Timeout, ConnectionString);
|
DataTable dataTable = _ExecuteCMD(Command, Parameters, Timeout, ConnectionString);
|
||||||
}
|
|
||||||
|
|
||||||
private List<Dictionary<string, object>> _ExecuteCMDDict(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions, int Timeout = 30, string ConnectionString = "")
|
|
||||||
{
|
|
||||||
DataTable dataTable = _ExecuteCMD(Command, Parameters, CacheOptions, Timeout, ConnectionString);
|
|
||||||
|
|
||||||
// convert datatable to dictionary
|
// convert datatable to dictionary
|
||||||
List<Dictionary<string, object?>> rows = new List<Dictionary<string, object?>>();
|
List<Dictionary<string, object?>> rows = new List<Dictionary<string, object?>>();
|
||||||
@@ -274,45 +228,14 @@ namespace gaseous_server.Classes
|
|||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataTable _ExecuteCMD(string Command, Dictionary<string, object> Parameters, DatabaseMemoryCacheOptions? CacheOptions, int Timeout = 30, string ConnectionString = "")
|
private DataTable _ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
|
||||||
{
|
{
|
||||||
string CacheKey = Command + string.Join(";", Parameters.Select(x => string.Join("=", x.Key, x.Value)));
|
|
||||||
|
|
||||||
if (CacheOptions is object && CacheOptions.CacheEnabled)
|
|
||||||
{
|
|
||||||
object? CachedData = DatabaseMemoryCache.GetCacheObject(CacheKey);
|
|
||||||
if (CachedData is object)
|
|
||||||
{
|
|
||||||
return (DataTable)CachedData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// purge cache if command contains "INSERT", "UPDATE", "DELETE", or "ALTER"
|
|
||||||
if (
|
|
||||||
Command.Contains("INSERT", StringComparison.InvariantCultureIgnoreCase) ||
|
|
||||||
Command.Contains("UPDATE", StringComparison.InvariantCultureIgnoreCase) ||
|
|
||||||
Command.Contains("DELETE", StringComparison.InvariantCultureIgnoreCase) ||
|
|
||||||
Command.Contains("ALTER", StringComparison.InvariantCultureIgnoreCase)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// exclude logging events from purging the cache
|
|
||||||
if (!Command.StartsWith("INSERT INTO SERVERLOGS", StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
|
||||||
DatabaseMemoryCache.ClearCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ConnectionString == "") { ConnectionString = _ConnectionString; }
|
if (ConnectionString == "") { ConnectionString = _ConnectionString; }
|
||||||
switch (_ConnectorType)
|
switch (_ConnectorType)
|
||||||
{
|
{
|
||||||
case databaseType.MySql:
|
case databaseType.MySql:
|
||||||
MySQLServerConnector conn = new MySQLServerConnector(ConnectionString);
|
MySQLServerConnector conn = new MySQLServerConnector(ConnectionString);
|
||||||
DataTable RetTable = conn.ExecCMD(Command, Parameters, Timeout);
|
return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
|
||||||
if (CacheOptions is object && CacheOptions.CacheEnabled)
|
|
||||||
{
|
|
||||||
DatabaseMemoryCache.SetCacheObject(CacheKey, RetTable, CacheOptions.ExpirationSeconds);
|
|
||||||
}
|
|
||||||
return RetTable;
|
|
||||||
default:
|
default:
|
||||||
return new DataTable();
|
return new DataTable();
|
||||||
}
|
}
|
||||||
@@ -371,148 +294,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class DatabaseMemoryCache
|
|
||||||
{
|
|
||||||
private class MemoryCacheItem
|
|
||||||
{
|
|
||||||
public MemoryCacheItem(object CacheObject)
|
|
||||||
{
|
|
||||||
cacheObject = CacheObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MemoryCacheItem(object CacheObject, int ExpirationSeconds)
|
|
||||||
{
|
|
||||||
cacheObject = CacheObject;
|
|
||||||
expirationSeconds = ExpirationSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time the object was added to the cache in ticks
|
|
||||||
/// </summary>
|
|
||||||
public long addedTime { get; } = Environment.TickCount64;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The time the object will expire in ticks
|
|
||||||
/// </summary>
|
|
||||||
public long expirationTime
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return addedTime + _expirationTicks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The number of seconds the object will be cached
|
|
||||||
/// </summary>
|
|
||||||
public int expirationSeconds
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return (int)TimeSpan.FromTicks(_expirationTicks).Seconds;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_expirationTicks = (long)TimeSpan.FromSeconds(value).Ticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private long _expirationTicks = (long)TimeSpan.FromSeconds(2).Ticks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The object to be cached
|
|
||||||
/// </summary>
|
|
||||||
public object cacheObject { get; set; }
|
|
||||||
}
|
|
||||||
private static Dictionary<string, MemoryCacheItem> MemoryCache = new Dictionary<string, MemoryCacheItem>();
|
|
||||||
private static Timer CacheTimer = new Timer(CacheTimerCallback, null, 0, 1000);
|
|
||||||
|
|
||||||
private static void CacheTimerCallback(object? state)
|
|
||||||
{
|
|
||||||
ClearExpiredCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static object? GetCacheObject(string CacheKey)
|
|
||||||
{
|
|
||||||
if (MemoryCache.ContainsKey(CacheKey))
|
|
||||||
{
|
|
||||||
if (MemoryCache[CacheKey].expirationTime < Environment.TickCount)
|
|
||||||
{
|
|
||||||
MemoryCache.Remove(CacheKey);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return MemoryCache[CacheKey].cacheObject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void SetCacheObject(string CacheKey, object CacheObject, int ExpirationSeconds = 2)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (MemoryCache.ContainsKey(CacheKey))
|
|
||||||
{
|
|
||||||
MemoryCache.Remove(CacheKey);
|
|
||||||
}
|
|
||||||
MemoryCache.Add(CacheKey, new MemoryCacheItem(CacheObject, ExpirationSeconds));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Database", "Error while setting cache object", ex);
|
|
||||||
ClearCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void RemoveCacheObject(string CacheKey)
|
|
||||||
{
|
|
||||||
if (MemoryCache.ContainsKey(CacheKey))
|
|
||||||
{
|
|
||||||
MemoryCache.Remove(CacheKey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void ClearCache()
|
|
||||||
{
|
|
||||||
MemoryCache.Clear();
|
|
||||||
}
|
|
||||||
private static void ClearExpiredCache()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
long currTime = Environment.TickCount64;
|
|
||||||
|
|
||||||
Dictionary<string, MemoryCacheItem> ExpiredItems = MemoryCache;
|
|
||||||
foreach (string key in ExpiredItems.Keys)
|
|
||||||
{
|
|
||||||
if (MemoryCache[key].expirationTime < currTime)
|
|
||||||
{
|
|
||||||
Console.WriteLine("\x1b[95mPurging expired cache item " + key + ". Added: " + MemoryCache[key].addedTime + ". Expired: " + MemoryCache[key].expirationTime);
|
|
||||||
MemoryCache.Remove(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Database", "Error while clearing expired cache", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DatabaseMemoryCacheOptions
|
|
||||||
{
|
|
||||||
public DatabaseMemoryCacheOptions(bool CacheEnabled = false, int ExpirationSeconds = 1)
|
|
||||||
{
|
|
||||||
this.CacheEnabled = CacheEnabled;
|
|
||||||
this.ExpirationSeconds = ExpirationSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CacheEnabled { get; set; }
|
|
||||||
public int ExpirationSeconds { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetDatabaseSchemaVersion()
|
public int GetDatabaseSchemaVersion()
|
||||||
{
|
{
|
||||||
switch (_ConnectorType)
|
switch (_ConnectorType)
|
||||||
@@ -603,9 +384,7 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Debug, "Database", "Parameters: " + dictValues, null, true);
|
Logging.Log(Logging.LogType.Debug, "Database", "Parameters: " + dictValues, null, true);
|
||||||
}
|
}
|
||||||
RetTable.Load(cmd.ExecuteReader());
|
RetTable.Load(cmd.ExecuteReader());
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Critical, "Database", "Error while executing '" + SQL + "'", ex);
|
Logging.Log(Logging.LogType.Critical, "Database", "Error while executing '" + SQL + "'", ex);
|
||||||
Trace.WriteLine("Error executing " + SQL);
|
Trace.WriteLine("Error executing " + SQL);
|
||||||
Trace.WriteLine("Full exception: " + ex.ToString());
|
Trace.WriteLine("Full exception: " + ex.ToString());
|
||||||
@@ -648,9 +427,7 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Debug, "Database", "Parameters: " + dictValues, null, true);
|
Logging.Log(Logging.LogType.Debug, "Database", "Parameters: " + dictValues, null, true);
|
||||||
}
|
}
|
||||||
result = cmd.ExecuteNonQuery();
|
result = cmd.ExecuteNonQuery();
|
||||||
}
|
} catch (Exception ex) {
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Critical, "Database", "Error while executing '" + SQL + "'", ex);
|
Logging.Log(Logging.LogType.Critical, "Database", "Error while executing '" + SQL + "'", ex);
|
||||||
Trace.WriteLine("Error executing " + SQL);
|
Trace.WriteLine("Error executing " + SQL);
|
||||||
Trace.WriteLine("Full exception: " + ex.ToString());
|
Trace.WriteLine("Full exception: " + ex.ToString());
|
||||||
|
@@ -1,9 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using gaseous_server.Models;
|
|
||||||
using IGDB.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -150,102 +147,6 @@ namespace gaseous_server.Classes
|
|||||||
} while (reader.EndOfStream == false);
|
} while (reader.EndOfStream == false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1024:
|
|
||||||
// create profiles for all existing users
|
|
||||||
sql = "SELECT * FROM Users;";
|
|
||||||
data = db.ExecuteCMD(sql);
|
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
{
|
|
||||||
// get legacy avatar from UserAvatars table
|
|
||||||
sql = "SELECT Avatar FROM UserAvatars WHERE UserId = @userid;";
|
|
||||||
dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "userid", row["Id"] }
|
|
||||||
};
|
|
||||||
DataTable avatarData = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
sql = "INSERT INTO UserProfiles (Id, UserId, DisplayName, Quip, Avatar, AvatarExtension, UnstructuredData) VALUES (@id, @userid, @displayname, @quip, @avatar, @avatarextension, @data);";
|
|
||||||
dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "id", Guid.NewGuid() },
|
|
||||||
{ "userid", row["Id"] },
|
|
||||||
{ "displayname", row["Email"] },
|
|
||||||
{ "quip", "" },
|
|
||||||
{ "avatar", avatarData.Rows.Count > 0 ? avatarData.Rows[0]["Avatar"] : null },
|
|
||||||
{ "avatarextension", avatarData.Rows.Count > 0 ? ".jpg" : null },
|
|
||||||
{ "data", "{}" }
|
|
||||||
};
|
|
||||||
db.ExecuteNonQuery(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update all rom paths to use the new format
|
|
||||||
sql = "SELECT * FROM GameLibraries;";
|
|
||||||
data = db.ExecuteCMD(sql);
|
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
{
|
|
||||||
sql = "SELECT * FROM Games_Roms WHERE LibraryId = @libraryid;";
|
|
||||||
dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "libraryid", row["Id"] }
|
|
||||||
};
|
|
||||||
DataTable romData = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
string libraryRootPath = (string)row["Path"];
|
|
||||||
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
|
|
||||||
{
|
|
||||||
libraryRootPath += Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLastThreeElements = (bool)row["DefaultLibrary"];
|
|
||||||
|
|
||||||
foreach (DataRow romRow in romData.Rows)
|
|
||||||
{
|
|
||||||
string existingPath = (string)romRow["RelativePath"];
|
|
||||||
string newPath = "";
|
|
||||||
|
|
||||||
if (GetLastThreeElements == true)
|
|
||||||
{
|
|
||||||
// strip all but the last 3 elements from existingPath separated by directory separator
|
|
||||||
// this mode only works for the default library
|
|
||||||
string[] pathParts = existingPath.Split(Path.DirectorySeparatorChar);
|
|
||||||
if (pathParts.Length > 3)
|
|
||||||
{
|
|
||||||
newPath = Path.Combine(pathParts[pathParts.Length - 3], pathParts[pathParts.Length - 2], pathParts[pathParts.Length - 1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newPath = existingPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// strip the library root path from the existing path
|
|
||||||
if (existingPath.StartsWith(libraryRootPath))
|
|
||||||
{
|
|
||||||
newPath = existingPath.Substring(libraryRootPath.Length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newPath = existingPath;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Updating ROM path from " + existingPath + " to " + newPath);
|
|
||||||
|
|
||||||
sql = "UPDATE Games_Roms SET RelativePath = @newpath WHERE Id = @id;";
|
|
||||||
dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "newpath", newPath },
|
|
||||||
{ "id", romRow["Id"] }
|
|
||||||
};
|
|
||||||
db.ExecuteNonQuery(sql, dbDict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// migrating metadata is a safe background task
|
|
||||||
BackgroundUpgradeTargetSchemaVersions.Add(1024);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -260,10 +161,6 @@ namespace gaseous_server.Classes
|
|||||||
case 1002:
|
case 1002:
|
||||||
MySql_1002_MigrateMetadataVersion();
|
MySql_1002_MigrateMetadataVersion();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1024:
|
|
||||||
MySql_1024_MigrateMetadataVersion();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,39 +261,5 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void MySql_1024_MigrateMetadataVersion()
|
|
||||||
{
|
|
||||||
FileSignature fileSignature = new FileSignature();
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "SELECT * FROM view_Games_Roms WHERE RomDataVersion = 1;";
|
|
||||||
DataTable data = db.ExecuteCMD(sql);
|
|
||||||
long count = 1;
|
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Database Migration", "Updating ROM table for ROM (" + count + " / " + data.Rows.Count + "): " + (string)row["Name"]);
|
|
||||||
|
|
||||||
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)row["LibraryId"]);
|
|
||||||
Common.hashObject hash = new Common.hashObject()
|
|
||||||
{
|
|
||||||
md5hash = (string)row["MD5"],
|
|
||||||
sha1hash = (string)row["SHA1"]
|
|
||||||
};
|
|
||||||
Signatures_Games signature = fileSignature.GetFileSignature(
|
|
||||||
library,
|
|
||||||
hash,
|
|
||||||
new FileInfo((string)row["Path"]),
|
|
||||||
(string)row["Path"]
|
|
||||||
);
|
|
||||||
|
|
||||||
Platform platform = Platforms.GetPlatform((long)row["PlatformId"], false);
|
|
||||||
Game game = Games.GetGame((long)row["GameId"], false, false, false);
|
|
||||||
|
|
||||||
ImportGame.StoreROM(library, hash, game, platform, signature, (string)row["Path"], (long)row["Id"]);
|
|
||||||
|
|
||||||
count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,9 +1,6 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net;
|
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using HasheousClient.Models;
|
using HasheousClient.Models;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
using SevenZip;
|
using SevenZip;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
@@ -113,10 +110,8 @@ namespace gaseous_server.Classes
|
|||||||
// loop through contents until we find the first signature match
|
// loop through contents until we find the first signature match
|
||||||
List<ArchiveData> archiveFiles = new List<ArchiveData>();
|
List<ArchiveData> archiveFiles = new List<ArchiveData>();
|
||||||
bool signatureFound = false;
|
bool signatureFound = false;
|
||||||
bool signatureSelectorAlreadyApplied = false;
|
|
||||||
foreach (string file in Directory.GetFiles(ExtractPath, "*.*", SearchOption.AllDirectories))
|
foreach (string file in Directory.GetFiles(ExtractPath, "*.*", SearchOption.AllDirectories))
|
||||||
{
|
{
|
||||||
bool signatureSelector = false;
|
|
||||||
if (File.Exists(file))
|
if (File.Exists(file))
|
||||||
{
|
{
|
||||||
FileInfo zfi = new FileInfo(file);
|
FileInfo zfi = new FileInfo(file);
|
||||||
@@ -126,6 +121,16 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
if (zfi != null)
|
if (zfi != null)
|
||||||
{
|
{
|
||||||
|
ArchiveData archiveData = new ArchiveData
|
||||||
|
{
|
||||||
|
FileName = Path.GetFileName(file),
|
||||||
|
FilePath = zfi.Directory.FullName.Replace(ExtractPath, ""),
|
||||||
|
Size = zfi.Length,
|
||||||
|
MD5 = hash.md5hash,
|
||||||
|
SHA1 = hash.sha1hash
|
||||||
|
};
|
||||||
|
archiveFiles.Add(archiveData);
|
||||||
|
|
||||||
if (signatureFound == false)
|
if (signatureFound == false)
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi.Name, zfi.Extension, zfi.Length, file, true);
|
gaseous_server.Models.Signatures_Games zDiscoveredSignature = _GetFileSignature(zhash, zfi.Name, zfi.Extension, zfi.Length, file, true);
|
||||||
@@ -147,37 +152,15 @@ namespace gaseous_server.Classes
|
|||||||
discoveredSignature = zDiscoveredSignature;
|
discoveredSignature = zDiscoveredSignature;
|
||||||
|
|
||||||
signatureFound = true;
|
signatureFound = true;
|
||||||
|
}
|
||||||
if (signatureSelectorAlreadyApplied == false)
|
}
|
||||||
{
|
|
||||||
signatureSelector = true;
|
|
||||||
signatureSelectorAlreadyApplied = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchiveData archiveData = new ArchiveData
|
discoveredSignature.Rom.Attributes.Add(new KeyValuePair<string, object>(
|
||||||
{
|
|
||||||
FileName = Path.GetFileName(file),
|
|
||||||
FilePath = zfi.Directory.FullName.Replace(ExtractPath, ""),
|
|
||||||
Size = zfi.Length,
|
|
||||||
MD5 = zhash.md5hash,
|
|
||||||
SHA1 = zhash.sha1hash,
|
|
||||||
isSignatureSelector = signatureSelector
|
|
||||||
};
|
|
||||||
archiveFiles.Add(archiveData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discoveredSignature.Rom.Attributes == null)
|
|
||||||
{
|
|
||||||
discoveredSignature.Rom.Attributes = new Dictionary<string, object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
discoveredSignature.Rom.Attributes.Add(
|
|
||||||
"ZipContents", Newtonsoft.Json.JsonConvert.SerializeObject(archiveFiles)
|
"ZipContents", Newtonsoft.Json.JsonConvert.SerializeObject(archiveFiles)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -193,45 +176,37 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Checking signature for file: " + GameFileImportPath + "\nMD5 hash: " + hash.md5hash + "\nSHA1 hash: " + hash.sha1hash);
|
Logging.Log(Logging.LogType.Information, "Import Game", "Checking signature for file: " + GameFileImportPath + "\nMD5 hash: " + hash.md5hash + "\nSHA1 hash: " + hash.sha1hash);
|
||||||
|
|
||||||
|
|
||||||
gaseous_server.Models.Signatures_Games? discoveredSignature = null;
|
gaseous_server.Models.Signatures_Games discoveredSignature = new gaseous_server.Models.Signatures_Games();
|
||||||
|
|
||||||
// begin signature search
|
// do database search first
|
||||||
switch (Config.MetadataConfiguration.SignatureSource)
|
gaseous_server.Models.Signatures_Games? dbSignature = _GetFileSignatureFromDatabase(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||||
|
|
||||||
|
if (dbSignature != null)
|
||||||
{
|
{
|
||||||
case HasheousClient.Models.MetadataModel.SignatureSources.LocalOnly:
|
// local signature found
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Hasheous disabled - searching local database only");
|
Logging.Log(Logging.LogType.Information, "Import Game", "Signature found in local database for game: " + dbSignature.Game.Name);
|
||||||
|
discoveredSignature = dbSignature;
|
||||||
discoveredSignature = _GetFileSignatureFromDatabase(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HasheousClient.Models.MetadataModel.SignatureSources.Hasheous:
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Hasheous enabled - searching Hashesous and then local database if not found");
|
|
||||||
|
|
||||||
discoveredSignature = _GetFileSignatureFromHasheous(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
|
||||||
|
|
||||||
if (discoveredSignature == null)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature not found in Hasheous - checking local database");
|
|
||||||
|
|
||||||
discoveredSignature = _GetFileSignatureFromDatabase(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature retrieved from Hasheous for game: " + discoveredSignature.Game.Name);
|
// no local signature attempt to pull from Hasheous
|
||||||
}
|
dbSignature = _GetFileSignatureFromHasheous(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
if (dbSignature != null)
|
||||||
|
{
|
||||||
|
// signature retrieved from Hasheous
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", "Signature retrieved from Hasheous for game: " + dbSignature.Game.Name);
|
||||||
|
|
||||||
if (discoveredSignature == null)
|
discoveredSignature = dbSignature;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// construct a signature from file data
|
// construct a signature from file data
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature not found in local database or Hasheous (if enabled) - generating from file data");
|
dbSignature = _GetFileSignatureFromFileData(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", "Signature generated from provided file for game: " + dbSignature.Game.Name);
|
||||||
|
|
||||||
discoveredSignature = _GetFileSignatureFromFileData(hash, ImageName, ImageExtension, ImageSize, GameFileImportPath);
|
discoveredSignature = dbSignature;
|
||||||
|
}
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", "Signature generated from provided file for game: " + discoveredSignature.Game.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, ImageExtension, false);
|
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, ImageExtension, false);
|
||||||
@@ -290,11 +265,11 @@ namespace gaseous_server.Classes
|
|||||||
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
if (Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous)
|
||||||
{
|
{
|
||||||
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
HasheousClient.Hasheous hasheous = new HasheousClient.Hasheous();
|
||||||
Console.WriteLine(HasheousClient.WebApp.HttpHelper.BaseUri);
|
SignatureLookupItem? HasheousResult = null;
|
||||||
LookupItemModel? HasheousResult = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HasheousResult = hasheous.RetrieveFromHasheous(new HashLookupModel
|
HasheousResult = hasheous.RetrieveFromHasheousAsync(new HashLookupModel
|
||||||
{
|
{
|
||||||
MD5 = hash.md5hash,
|
MD5 = hash.md5hash,
|
||||||
SHA1 = hash.sha1hash
|
SHA1 = hash.sha1hash
|
||||||
@@ -305,46 +280,19 @@ namespace gaseous_server.Classes
|
|||||||
if (HasheousResult.Signature != null)
|
if (HasheousResult.Signature != null)
|
||||||
{
|
{
|
||||||
gaseous_server.Models.Signatures_Games signature = new Models.Signatures_Games();
|
gaseous_server.Models.Signatures_Games signature = new Models.Signatures_Games();
|
||||||
string gameJson = Newtonsoft.Json.JsonConvert.SerializeObject(HasheousResult.Signature.Game);
|
signature.Game = HasheousResult.Signature.Game;
|
||||||
string romJson = Newtonsoft.Json.JsonConvert.SerializeObject(HasheousResult.Signature.Rom);
|
signature.Rom = HasheousResult.Signature.Rom;
|
||||||
signature.Game = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Signatures_Games.GameItem>(gameJson);
|
|
||||||
signature.Rom = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Signatures_Games.RomItem>(romJson);
|
|
||||||
|
|
||||||
// get platform metadata
|
if (HasheousResult.MetadataResults != null)
|
||||||
if (HasheousResult.Platform != null)
|
|
||||||
{
|
{
|
||||||
if (HasheousResult.Platform.metadata.Count > 0)
|
if (HasheousResult.MetadataResults.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Platform.metadata)
|
foreach (SignatureLookupItem.MetadataResult metadataResult in HasheousResult.MetadataResults)
|
||||||
{
|
{
|
||||||
if (metadataResult.Id.Length > 0)
|
if (metadataResult.Source == MetadataModel.MetadataSources.IGDB)
|
||||||
{
|
{
|
||||||
switch (metadataResult.Source)
|
signature.Flags.IGDBPlatformId = (long)metadataResult.PlatformId;
|
||||||
{
|
signature.Flags.IGDBGameId = (long)metadataResult.GameId;
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id, false).Id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get game metadata
|
|
||||||
if (HasheousResult.Metadata != null)
|
|
||||||
{
|
|
||||||
if (HasheousResult.Metadata.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (HasheousClient.Models.MetadataItem metadataResult in HasheousResult.Metadata)
|
|
||||||
{
|
|
||||||
if (metadataResult.Id.Length > 0)
|
|
||||||
{
|
|
||||||
switch (metadataResult.Source)
|
|
||||||
{
|
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
|
||||||
signature.Flags.IGDBGameId = (long)Games.GetGame(metadataResult.Id, false, false, false).Id;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,29 +302,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AggregateException aggEx)
|
|
||||||
{
|
|
||||||
foreach (Exception ex in aggEx.InnerExceptions)
|
|
||||||
{
|
|
||||||
// get exception type
|
|
||||||
if (ex is HttpRequestException)
|
|
||||||
{
|
|
||||||
if (ex.Message.Contains("404 (Not Found)"))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Get Signature", "No signature found in Hasheous");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Get Signature", "Error retrieving signature from Hasheous", ex);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
||||||
@@ -454,7 +379,6 @@ namespace gaseous_server.Classes
|
|||||||
public long Size { get; set; }
|
public long Size { get; set; }
|
||||||
public string MD5 { get; set; }
|
public string MD5 { get; set; }
|
||||||
public string SHA1 { get; set; }
|
public string SHA1 { get; set; }
|
||||||
public bool isSignatureSelector { get; set; } = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -24,9 +24,9 @@ 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 GROUP BY Platform.`Name`;";
|
string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, Games_Roms.PlatformId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id , 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);
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
{
|
{
|
||||||
@@ -82,8 +82,8 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// age groups
|
// age groups
|
||||||
List<FilterItem> agegroupings = new List<FilterItem>();
|
List<FilterItem> agegroupings = new List<FilterItem>();
|
||||||
sql = "SELECT Game.AgeGroupId, 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_Platform + ") GROUP BY Game.Id HAVING RomCount > 0) Game GROUP BY Game.AgeGroupId ORDER BY Game.AgeGroupId DESC";
|
sql = "SELECT Game.AgeGroupId, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = Games_Roms.GameId WHERE (" + ageRestriction_Platform + ") GROUP BY Game.Id HAVING RomCount > 0) Game GROUP BY Game.AgeGroupId ORDER BY Game.AgeGroupId DESC";
|
||||||
dbResponse = db.ExecuteCMD(sql, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 300));
|
dbResponse = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
{
|
{
|
||||||
@@ -112,9 +112,9 @@ 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 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`;";
|
string sql = "SELECT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(Game.Id) AS GameCount FROM (SELECT DISTINCT Game.Id, AgeGroup.AgeGroupId, COUNT(Games_Roms.Id) AS RomCount FROM Game LEFT JOIN AgeGroup ON Game.Id = AgeGroup.GameId LEFT JOIN Games_Roms ON Game.Id = 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);
|
||||||
|
|
||||||
return dbResponse;
|
return dbResponse;
|
||||||
}
|
}
|
||||||
|
@@ -60,25 +60,13 @@ namespace gaseous_server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update default library path
|
|
||||||
public static void UpdateDefaultLibraryPath()
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "UPDATE GameLibraries SET Path=@path WHERE DefaultLibrary=1;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "path", Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "Library") }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<LibraryItem> GetLibraries
|
public static List<LibraryItem> GetLibraries
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
List<LibraryItem> libraryItems = new List<LibraryItem>();
|
List<LibraryItem> libraryItems = new List<LibraryItem>();
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT * FROM GameLibraries ORDER BY `Name`;";
|
string sql = "SELECT * FROM GameLibraries";
|
||||||
DataTable data = db.ExecuteCMD(sql);
|
DataTable data = db.ExecuteCMD(sql);
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
@@ -187,24 +175,6 @@ namespace gaseous_server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LibraryItem ScanLibrary(int LibraryId)
|
|
||||||
{
|
|
||||||
// add the library to scan to the queue
|
|
||||||
LibraryItem library = GetLibrary(LibraryId);
|
|
||||||
ImportGame.LibrariesToScan.Add(library);
|
|
||||||
|
|
||||||
// start the library scan if it's not already running
|
|
||||||
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
|
||||||
{
|
|
||||||
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScan && item.ItemState != ProcessQueue.QueueItemState.Running)
|
|
||||||
{
|
|
||||||
item.ForceExecute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return library;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LibraryItem
|
public class LibraryItem
|
||||||
{
|
{
|
||||||
public LibraryItem(int Id, string Name, string Path, long DefaultPlatformId, bool IsDefaultLibrary)
|
public LibraryItem(int Id, string Name, string Path, long DefaultPlatformId, bool IsDefaultLibrary)
|
||||||
|
@@ -47,11 +47,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
public void ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> RetVal = new Dictionary<string, object>();
|
|
||||||
RetVal.Add("path", Path.GetFileName(GameFileImportPath));
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
@@ -70,10 +67,8 @@ namespace gaseous_server.Classes
|
|||||||
if (IsBios == null)
|
if (IsBios == null)
|
||||||
{
|
{
|
||||||
// file is a rom
|
// file is a rom
|
||||||
RetVal.Add("type", "rom");
|
|
||||||
|
|
||||||
// check to make sure we don't already have this file imported
|
// 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";
|
sql = "SELECT COUNT(Id) AS count FROM Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
|
||||||
dbDict.Add("md5", hash.md5hash);
|
dbDict.Add("md5", hash.md5hash);
|
||||||
dbDict.Add("sha1", hash.sha1hash);
|
dbDict.Add("sha1", hash.sha1hash);
|
||||||
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -99,8 +94,6 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping import");
|
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping import");
|
||||||
}
|
}
|
||||||
|
|
||||||
RetVal.Add("status", "duplicate");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -129,53 +122,32 @@ namespace gaseous_server.Classes
|
|||||||
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
|
IGDB.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
|
||||||
|
|
||||||
// add to database
|
// add to database
|
||||||
long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath, 0, true);
|
StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath);
|
||||||
|
|
||||||
// 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
|
||||||
RetVal.Add("type", "bios");
|
if (IsBios.WebEmulator != null)
|
||||||
RetVal.Add("status", "notimported");
|
{
|
||||||
|
|
||||||
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
||||||
{
|
{
|
||||||
if (biosItem.Available == false)
|
if (biosItem.Available == false && biosItem.hash == hash.md5hash)
|
||||||
{
|
{
|
||||||
if (biosItem.hash == hash.md5hash)
|
string biosPath = biosItem.biosPath.Replace(biosItem.filename, "");
|
||||||
|
if (!Directory.Exists(biosPath))
|
||||||
{
|
{
|
||||||
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
|
Directory.CreateDirectory(biosPath);
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " is a BIOS file - moving to " + biosPath);
|
}
|
||||||
|
|
||||||
File.Move(GameFileImportPath, biosItem.biosPath, true);
|
File.Move(GameFileImportPath, biosItem.biosPath, true);
|
||||||
|
|
||||||
RetVal.Add("name", biosItem.filename);
|
break;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
public static IGDB.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
||||||
@@ -209,7 +181,13 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " Searching for title: " + SearchCandidate);
|
Logging.Log(Logging.LogType.Information, "Import Game", " Searching for title: " + SearchCandidate);
|
||||||
|
|
||||||
foreach (Metadata.Games.SearchType searchType in Enum.GetValues(typeof(Metadata.Games.SearchType)))
|
List<Metadata.Games.SearchType> allowedSearchTypes = Config.ReadSetting<List<Metadata.Games.SearchType>>("DefaultSearchMethods", new List<gaseous_server.Classes.Metadata.Games.SearchType>() {
|
||||||
|
Games.SearchType.where,
|
||||||
|
Games.SearchType.wherefuzzy,
|
||||||
|
Games.SearchType.search,
|
||||||
|
Games.SearchType.searchNoPlatform
|
||||||
|
});
|
||||||
|
foreach (Metadata.Games.SearchType searchType in allowedSearchTypes)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString());
|
Logging.Log(Logging.LogType.Information, "Import Game", " Search type: " + searchType.ToString());
|
||||||
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
||||||
@@ -267,7 +245,13 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
foreach (string SearchCandidate in SearchCandidates)
|
foreach (string SearchCandidate in SearchCandidates)
|
||||||
{
|
{
|
||||||
foreach (Metadata.Games.SearchType searchType in Enum.GetValues(typeof(Metadata.Games.SearchType)))
|
List<Metadata.Games.SearchType> allowedSearchTypes = Config.ReadSetting<List<Metadata.Games.SearchType>>("DefaultSearchMethods", new List<gaseous_server.Classes.Metadata.Games.SearchType>() {
|
||||||
|
Games.SearchType.where,
|
||||||
|
Games.SearchType.wherefuzzy,
|
||||||
|
Games.SearchType.search,
|
||||||
|
Games.SearchType.searchNoPlatform
|
||||||
|
});
|
||||||
|
foreach (Metadata.Games.SearchType searchType in allowedSearchTypes)
|
||||||
{
|
{
|
||||||
if ((PlatformId == 0 && searchType == SearchType.searchNoPlatform) || (PlatformId != 0 && searchType != SearchType.searchNoPlatform))
|
if ((PlatformId == 0 && searchType == SearchType.searchNoPlatform) || (PlatformId != 0 && searchType != SearchType.searchNoPlatform))
|
||||||
{
|
{
|
||||||
@@ -326,7 +310,7 @@ 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)
|
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)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
@@ -336,11 +320,11 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
if (UpdateId == 0)
|
if (UpdateId == 0)
|
||||||
{
|
{
|
||||||
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, 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);";
|
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, Path, MetadataSource, MetadataGameName, MetadataVersion, LibraryId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion WHERE Id=@id;";
|
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion WHERE Id=@id;";
|
||||||
dbDict.Add("id", UpdateId);
|
dbDict.Add("id", UpdateId);
|
||||||
}
|
}
|
||||||
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
dbDict.Add("platformid", Common.ReturnValueIfNull(determinedPlatform.Id, 0));
|
||||||
@@ -355,7 +339,6 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("metadatagamename", discoveredSignature.Game.Name);
|
dbDict.Add("metadatagamename", discoveredSignature.Game.Name);
|
||||||
dbDict.Add("metadataversion", 2);
|
dbDict.Add("metadataversion", 2);
|
||||||
dbDict.Add("libraryid", library.Id);
|
dbDict.Add("libraryid", library.Id);
|
||||||
dbDict.Add("romdataversion", 2);
|
|
||||||
|
|
||||||
if (discoveredSignature.Rom.Attributes != null)
|
if (discoveredSignature.Rom.Attributes != null)
|
||||||
{
|
{
|
||||||
@@ -375,13 +358,7 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("romtype", (int)discoveredSignature.Rom.RomType);
|
dbDict.Add("romtype", (int)discoveredSignature.Rom.RomType);
|
||||||
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(discoveredSignature.Rom.RomTypeMedia, ""));
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(discoveredSignature.Rom.RomTypeMedia, ""));
|
||||||
dbDict.Add("medialabel", Common.ReturnValueIfNull(discoveredSignature.Rom.MediaLabel, ""));
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(discoveredSignature.Rom.MediaLabel, ""));
|
||||||
|
dbDict.Add("path", GameFileImportPath);
|
||||||
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);
|
DataTable romInsert = db.ExecuteCMD(sql, dbDict);
|
||||||
long romId = 0;
|
long romId = 0;
|
||||||
@@ -397,7 +374,7 @@ namespace gaseous_server.Classes
|
|||||||
// move to destination
|
// move to destination
|
||||||
if (library.IsDefaultLibrary == true)
|
if (library.IsDefaultLibrary == true)
|
||||||
{
|
{
|
||||||
MoveGameFile(romId, SourceIsExternal);
|
MoveGameFile(romId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return romId;
|
return romId;
|
||||||
@@ -433,14 +410,10 @@ namespace gaseous_server.Classes
|
|||||||
return DestinationPathName;
|
return DestinationPathName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool MoveGameFile(long RomId, bool SourceIsExternal)
|
public static bool MoveGameFile(long RomId)
|
||||||
{
|
{
|
||||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
||||||
string romPath = rom.Path;
|
string romPath = rom.Path;
|
||||||
if (SourceIsExternal == true)
|
|
||||||
{
|
|
||||||
romPath = rom.RelativePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists(romPath))
|
if (File.Exists(romPath))
|
||||||
{
|
{
|
||||||
@@ -456,31 +429,22 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "Moving " + romPath + " to " + DestinationPath);
|
Logging.Log(Logging.LogType.Information, "Move Game ROM", "Moving " + romPath + " to " + DestinationPath);
|
||||||
if (File.Exists(DestinationPath))
|
if (File.Exists(DestinationPath))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - aborting");
|
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - overwriting");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
File.Move(romPath, DestinationPath, true);
|
||||||
File.Move(romPath, DestinationPath);
|
|
||||||
|
|
||||||
// update the db
|
// update the db
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "UPDATE Games_Roms SET RelativePath=@path WHERE Id=@id";
|
string sql = "UPDATE Games_Roms SET Path=@path WHERE Id=@id";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("id", RomId);
|
dbDict.Add("id", RomId);
|
||||||
|
dbDict.Add("path", DestinationPath);
|
||||||
string libraryRootPath = rom.Library.Path;
|
|
||||||
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
|
|
||||||
{
|
|
||||||
libraryRootPath += Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
dbDict.Add("path", DestinationPath.Replace(libraryRootPath, ""));
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Move Game ROM", "File " + romPath + " appears to be missing!");
|
Logging.Log(Logging.LogType.Warning, "Move Game ROM", "File " + romPath + " appears to be missing!");
|
||||||
@@ -496,7 +460,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
// move rom files to their new location
|
// move rom files to their new location
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT * FROM view_Games_Roms WHERE LibraryId = @libraryid";
|
string sql = "SELECT * FROM Games_Roms WHERE LibraryId = @libraryid";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("libraryid", library.Id);
|
dbDict.Add("libraryid", library.Id);
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -508,7 +472,7 @@ namespace gaseous_server.Classes
|
|||||||
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
||||||
Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]);
|
Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]);
|
||||||
long RomId = (long)romDT.Rows[i]["id"];
|
long RomId = (long)romDT.Rows[i]["id"];
|
||||||
MoveGameFile(RomId, false);
|
MoveGameFile(RomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
@@ -536,40 +500,22 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<GameLibrary.LibraryItem> LibrariesToScan = new List<GameLibrary.LibraryItem>();
|
public void LibraryScan(GameLibrary.LibraryItem? singleLibrary = null)
|
||||||
public void LibraryScan()
|
|
||||||
{
|
{
|
||||||
int maxWorkers = Config.MetadataConfiguration.MaxLibraryScanWorkers;
|
int maxWorkers = Config.MetadataConfiguration.MaxLibraryScanWorkers;
|
||||||
|
|
||||||
if (LibrariesToScan.Count == 0)
|
List<GameLibrary.LibraryItem> libraries = new List<GameLibrary.LibraryItem>();
|
||||||
|
if (singleLibrary == null)
|
||||||
{
|
{
|
||||||
LibrariesToScan.AddRange(GameLibrary.GetLibraries);
|
libraries.AddRange(GameLibrary.GetLibraries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
libraries.Add(singleLibrary);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup background tasks for each library
|
// setup background tasks for each library
|
||||||
do
|
foreach (GameLibrary.LibraryItem library in libraries)
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan queue size: " + LibrariesToScan.Count);
|
|
||||||
|
|
||||||
GameLibrary.LibraryItem library = LibrariesToScan[0];
|
|
||||||
LibrariesToScan.RemoveAt(0);
|
|
||||||
|
|
||||||
// check if library is already being scanned
|
|
||||||
bool libraryAlreadyScanning = false;
|
|
||||||
List<ProcessQueue.QueueItem> ProcessQueueItems = new List<ProcessQueue.QueueItem>();
|
|
||||||
ProcessQueueItems.AddRange(ProcessQueue.QueueItems);
|
|
||||||
foreach (ProcessQueue.QueueItem item in ProcessQueueItems)
|
|
||||||
{
|
|
||||||
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
|
|
||||||
{
|
|
||||||
if (((GameLibrary.LibraryItem)item.Options).Id == library.Id)
|
|
||||||
{
|
|
||||||
libraryAlreadyScanning = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libraryAlreadyScanning == false)
|
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting worker process for library " + library.Name);
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting worker process for library " + library.Name);
|
||||||
ProcessQueue.QueueItem queue = new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItem queue = new ProcessQueue.QueueItem(
|
||||||
@@ -581,10 +527,8 @@ namespace gaseous_server.Classes
|
|||||||
ProcessQueue.QueueItemType.Rematcher
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
true)
|
true);
|
||||||
{
|
queue.Options = library;
|
||||||
Options = library
|
|
||||||
};
|
|
||||||
queue.ForceExecute();
|
queue.ForceExecute();
|
||||||
|
|
||||||
ProcessQueue.QueueItems.Add(queue);
|
ProcessQueue.QueueItems.Add(queue);
|
||||||
@@ -595,9 +539,9 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
allowContinue = true;
|
allowContinue = true;
|
||||||
int currentWorkerCount = 0;
|
int currentWorkerCount = 0;
|
||||||
List<ProcessQueue.QueueItem> LibraryScan_QueueItems = new List<ProcessQueue.QueueItem>();
|
List<ProcessQueue.QueueItem> queueItems = new List<ProcessQueue.QueueItem>();
|
||||||
LibraryScan_QueueItems.AddRange(ProcessQueue.QueueItems);
|
queueItems.AddRange(ProcessQueue.QueueItems);
|
||||||
foreach (ProcessQueue.QueueItem item in LibraryScan_QueueItems)
|
foreach (ProcessQueue.QueueItem item in queueItems)
|
||||||
{
|
{
|
||||||
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
|
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
|
||||||
{
|
{
|
||||||
@@ -611,7 +555,6 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
} while (allowContinue == false);
|
} while (allowContinue == false);
|
||||||
}
|
}
|
||||||
} while (LibrariesToScan.Count > 0);
|
|
||||||
|
|
||||||
bool WorkersStillWorking;
|
bool WorkersStillWorking;
|
||||||
do
|
do
|
||||||
@@ -631,12 +574,6 @@ namespace gaseous_server.Classes
|
|||||||
} while (WorkersStillWorking == true);
|
} while (WorkersStillWorking == true);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan complete. All workers stopped");
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan complete. All workers stopped");
|
||||||
|
|
||||||
if (LibrariesToScan.Count > 0)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "There are still libraries to scan. Restarting scan process");
|
|
||||||
LibraryScan();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LibrarySpecificScan(GameLibrary.LibraryItem library)
|
public void LibrarySpecificScan(GameLibrary.LibraryItem library)
|
||||||
@@ -652,7 +589,7 @@ namespace gaseous_server.Classes
|
|||||||
dupDict.Add("libraryid", library.Id);
|
dupDict.Add("libraryid", library.Id);
|
||||||
db.ExecuteCMD(duplicateSql, dupDict);
|
db.ExecuteCMD(duplicateSql, dupDict);
|
||||||
|
|
||||||
string sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
string sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("libraryid", library.Id);
|
dbDict.Add("libraryid", library.Id);
|
||||||
DataTable dtRoms = db.ExecuteCMD(sql, dbDict);
|
DataTable dtRoms = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -677,7 +614,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
||||||
dtRoms = db.ExecuteCMD(sql, dbDict);
|
dtRoms = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
// search for files in the library that aren't in the database
|
// search for files in the library that aren't in the database
|
||||||
@@ -749,7 +686,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
ClearStatus();
|
ClearStatus();
|
||||||
|
|
||||||
sql = "SELECT * FROM view_Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
||||||
dtRoms = db.ExecuteCMD(sql, dbDict);
|
dtRoms = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
// check all roms to see if their local file still exists
|
// check all roms to see if their local file still exists
|
||||||
@@ -773,7 +710,7 @@ namespace gaseous_server.Classes
|
|||||||
if (romPath != ComputeROMPath(romId))
|
if (romPath != ComputeROMPath(romId))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "ROM at path " + romPath + " found, but needs to be moved");
|
Logging.Log(Logging.LogType.Information, "Library Scan", "ROM at path " + romPath + " found, but needs to be moved");
|
||||||
MoveGameFile(romId, false);
|
MoveGameFile(romId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -814,11 +751,11 @@ namespace gaseous_server.Classes
|
|||||||
string sql = "";
|
string sql = "";
|
||||||
if (ForceExecute == false)
|
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;";
|
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) AND LibraryId = @libraryid LIMIT 100;";
|
||||||
}
|
}
|
||||||
else
|
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;";
|
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 AND GameId <> 0) OR (((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) OR (PlatformId = 0 AND GameId = 0)) AND LibraryId = @libraryid;";
|
||||||
}
|
}
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
||||||
|
@@ -3,7 +3,6 @@ using System.Data;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
using Microsoft.VisualStudio.Web.CodeGenerators.Mvc.Templates.BlazorIdentity.Pages;
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class Logging
|
public class Logging
|
||||||
@@ -22,13 +21,8 @@ namespace gaseous_server.Classes
|
|||||||
ExceptionValue = Common.ReturnValueIfNull(ExceptionValue, "").ToString()
|
ExceptionValue = Common.ReturnValueIfNull(ExceptionValue, "").ToString()
|
||||||
};
|
};
|
||||||
|
|
||||||
_ = Task.Run(() => WriteLogAsync(logItem, LogToDiskOnly));
|
|
||||||
}
|
|
||||||
|
|
||||||
static async Task WriteLogAsync(LogItem logItem, bool LogToDiskOnly)
|
|
||||||
{
|
|
||||||
bool AllowWrite = false;
|
bool AllowWrite = false;
|
||||||
if (logItem.EventType == LogType.Debug)
|
if (EventType == LogType.Debug)
|
||||||
{
|
{
|
||||||
if (Config.LoggingConfiguration.DebugLogging == true)
|
if (Config.LoggingConfiguration.DebugLogging == true)
|
||||||
{
|
{
|
||||||
@@ -48,32 +42,26 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
TraceOutput += Environment.NewLine + logItem.ExceptionValue.ToString();
|
TraceOutput += Environment.NewLine + logItem.ExceptionValue.ToString();
|
||||||
}
|
}
|
||||||
string consoleColour = "";
|
switch(logItem.EventType) {
|
||||||
switch (logItem.EventType)
|
|
||||||
{
|
|
||||||
case LogType.Information:
|
case LogType.Information:
|
||||||
// Console.ForegroundColor = ConsoleColor.Blue;
|
Console.ForegroundColor = ConsoleColor.Blue;
|
||||||
consoleColour = "\u001b[1;34m]";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogType.Warning:
|
case LogType.Warning:
|
||||||
// Console.ForegroundColor = ConsoleColor.Yellow;
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
consoleColour = "\u001b[1;33m]";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogType.Critical:
|
case LogType.Critical:
|
||||||
// Console.ForegroundColor = ConsoleColor.Red;
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
consoleColour = "\u001b[1;31m]";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogType.Debug:
|
case LogType.Debug:
|
||||||
// Console.ForegroundColor = ConsoleColor.Magenta;
|
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||||
consoleColour = "\u001b[1;36m]";
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
Console.WriteLine(consoleColour + TraceOutput);
|
Console.WriteLine(TraceOutput);
|
||||||
// Console.ResetColor();
|
Console.ResetColor();
|
||||||
|
|
||||||
if (WriteToDiskOnly == true)
|
if (WriteToDiskOnly == true)
|
||||||
{
|
{
|
||||||
|
@@ -37,7 +37,7 @@ namespace gaseous_server.Classes
|
|||||||
Logging.Log(Logging.LogType.Information, "Maintenance", "Removing logs older than " + Config.LoggingConfiguration.LogRetention + " days");
|
Logging.Log(Logging.LogType.Information, "Maintenance", "Removing logs older than " + Config.LoggingConfiguration.LogRetention + " days");
|
||||||
long deletedCount = 1;
|
long deletedCount = 1;
|
||||||
long deletedEventCount = 0;
|
long deletedEventCount = 0;
|
||||||
long maxLoops = 10000;
|
long maxLoops = 1000;
|
||||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRetentionDate LIMIT 1000; SELECT ROW_COUNT() AS Count;";
|
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRetentionDate LIMIT 1000; SELECT ROW_COUNT() AS Count;";
|
||||||
dbDict.Add("EventRetentionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
dbDict.Add("EventRetentionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||||
while (deletedCount > 0)
|
while (deletedCount > 0)
|
||||||
@@ -46,8 +46,6 @@ namespace gaseous_server.Classes
|
|||||||
deletedCount = (long)deletedCountTable.Rows[0][0];
|
deletedCount = (long)deletedCountTable.Rows[0][0];
|
||||||
deletedEventCount += deletedCount;
|
deletedEventCount += deletedCount;
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Maintenance", "Deleted " + deletedCount + " log entries");
|
|
||||||
|
|
||||||
// check if we've hit the limit
|
// check if we've hit the limit
|
||||||
maxLoops -= 1;
|
maxLoops -= 1;
|
||||||
if (maxLoops <= 0)
|
if (maxLoops <= 0)
|
||||||
|
@@ -216,8 +216,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly static AgeGroupItem Adult_Item = new AgeGroupItem
|
readonly static AgeGroupItem Adult_Item = new AgeGroupItem{
|
||||||
{
|
|
||||||
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_R18, AgeRatingTitle.ACB_RC },
|
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_R18, AgeRatingTitle.ACB_RC },
|
||||||
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_Z },
|
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_Z },
|
||||||
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Eighteen },
|
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Eighteen },
|
||||||
@@ -227,8 +226,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_18}
|
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_18}
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly static AgeGroupItem Mature_Item = new AgeGroupItem
|
readonly static AgeGroupItem Mature_Item = new AgeGroupItem{
|
||||||
{
|
|
||||||
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_M, AgeRatingTitle.ACB_MA15 },
|
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_M, AgeRatingTitle.ACB_MA15 },
|
||||||
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_C, AgeRatingTitle.CERO_D },
|
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_C, AgeRatingTitle.CERO_D },
|
||||||
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Sixteen },
|
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Sixteen },
|
||||||
@@ -238,8 +236,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_16}
|
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_16}
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly static AgeGroupItem Teen_Item = new AgeGroupItem
|
readonly static AgeGroupItem Teen_Item = new AgeGroupItem{
|
||||||
{
|
|
||||||
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_PG },
|
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_PG },
|
||||||
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_B },
|
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_B },
|
||||||
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Twelve, AgeRatingTitle.CLASS_IND_Fourteen },
|
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_Twelve, AgeRatingTitle.CLASS_IND_Fourteen },
|
||||||
@@ -249,12 +246,11 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_12}
|
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_12}
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly static AgeGroupItem Child_Item = new AgeGroupItem
|
readonly static AgeGroupItem Child_Item = new AgeGroupItem{
|
||||||
{
|
|
||||||
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_G },
|
ACB = new List<AgeRatingTitle>{ AgeRatingTitle.ACB_G },
|
||||||
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_A },
|
CERO = new List<AgeRatingTitle>{ AgeRatingTitle.CERO_A },
|
||||||
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_L, AgeRatingTitle.CLASS_IND_Ten },
|
CLASS_IND = new List<AgeRatingTitle>{ AgeRatingTitle.CLASS_IND_L, AgeRatingTitle.CLASS_IND_Ten },
|
||||||
ESRB = new List<AgeRatingTitle> { AgeRatingTitle.EC, AgeRatingTitle.E, AgeRatingTitle.E10 },
|
ESRB = new List<AgeRatingTitle>{ AgeRatingTitle.E, AgeRatingTitle.E10 },
|
||||||
GRAC = new List<AgeRatingTitle>{ AgeRatingTitle.GRAC_All },
|
GRAC = new List<AgeRatingTitle>{ AgeRatingTitle.GRAC_All },
|
||||||
PEGI = new List<AgeRatingTitle>{ AgeRatingTitle.Three, AgeRatingTitle.Seven},
|
PEGI = new List<AgeRatingTitle>{ AgeRatingTitle.Three, AgeRatingTitle.Seven},
|
||||||
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_0, AgeRatingTitle.USK_6}
|
USK = new List<AgeRatingTitle>{ AgeRatingTitle.USK_0, AgeRatingTitle.USK_6}
|
||||||
|
@@ -74,14 +74,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
Storage.NewCacheValue(returnValue, true);
|
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;
|
forceImageDownload = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
@@ -195,7 +195,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
if (InRateLimitAvoidanceMode == true)
|
if (InRateLimitAvoidanceMode == true)
|
||||||
{
|
{
|
||||||
// sleep for a moment to help avoid hitting the rate limiter
|
// sleep for a moment to help avoid hitting the rate limiter
|
||||||
Logging.Log(Logging.LogType.Information, "API Connection: Endpoint:" + Endpoint, "IGDB rate limit hit. Pausing API communications for " + RateLimitAvoidanceWait + " milliseconds to avoid rate limiter.");
|
|
||||||
Thread.Sleep(RateLimitAvoidanceWait);
|
Thread.Sleep(RateLimitAvoidanceWait);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,7 +393,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
if (InRateLimitAvoidanceMode == true)
|
if (InRateLimitAvoidanceMode == true)
|
||||||
{
|
{
|
||||||
// sleep for a moment to help avoid hitting the rate limiter
|
// sleep for a moment to help avoid hitting the rate limiter
|
||||||
Logging.Log(Logging.LogType.Information, "API Connection: Fetch Image", "IGDB rate limit hit. Pausing API communications for " + RateLimitAvoidanceWait + " milliseconds to avoid rate limiter.");
|
|
||||||
Thread.Sleep(RateLimitAvoidanceWait);
|
Thread.Sleep(RateLimitAvoidanceWait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,14 +76,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
Storage.NewCacheValue(returnValue, true);
|
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;
|
forceImageDownload = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
@@ -76,14 +76,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
Storage.NewCacheValue(returnValue, true);
|
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;
|
forceImageDownload = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Models;
|
|
||||||
using IGDB;
|
using IGDB;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
|
|
||||||
@@ -505,161 +504,24 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<AvailablePlatformItem> GetAvailablePlatforms(string UserId, long GameId)
|
public static List<KeyValuePair<long, string>> GetAvailablePlatforms(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 Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE Games_Roms.GameId = @gameid ORDER BY Platform.`Name`;";
|
||||||
SELECT DISTINCT
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
view_Games_Roms.GameId,
|
dbDict.Add("gameid", GameId);
|
||||||
view_Games_Roms.PlatformId,
|
|
||||||
Platform.`Name`,
|
|
||||||
User_RecentPlayedRoms.UserId AS MostRecentUserId,
|
|
||||||
User_RecentPlayedRoms.RomId AS MostRecentRomId,
|
|
||||||
CASE User_RecentPlayedRoms.IsMediaGroup
|
|
||||||
WHEN 0 THEN GMR.`Name`
|
|
||||||
WHEN 1 THEN 'Media Group'
|
|
||||||
ELSE NULL
|
|
||||||
END AS `MostRecentRomName`,
|
|
||||||
User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup,
|
|
||||||
User_GameFavouriteRoms.UserId AS FavouriteUserId,
|
|
||||||
User_GameFavouriteRoms.RomId AS FavouriteRomId,
|
|
||||||
CASE User_GameFavouriteRoms.IsMediaGroup
|
|
||||||
WHEN 0 THEN GFV.`Name`
|
|
||||||
WHEN 1 THEN 'Media Group'
|
|
||||||
ELSE NULL
|
|
||||||
END AS `FavouriteRomName`,
|
|
||||||
User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup
|
|
||||||
FROM
|
|
||||||
view_Games_Roms
|
|
||||||
LEFT JOIN
|
|
||||||
Platform ON view_Games_Roms.PlatformId = Platform.Id
|
|
||||||
LEFT JOIN
|
|
||||||
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
|
||||||
AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId
|
|
||||||
AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId
|
|
||||||
LEFT JOIN
|
|
||||||
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
|
||||||
AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId
|
|
||||||
AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId
|
|
||||||
LEFT JOIN
|
|
||||||
view_Games_Roms AS GMR ON GMR.Id = User_RecentPlayedRoms.RomId
|
|
||||||
LEFT JOIN
|
|
||||||
view_Games_Roms AS GFV ON GFV.Id = User_GameFavouriteRoms.RomId
|
|
||||||
WHERE
|
|
||||||
view_Games_Roms.GameId = @gameid
|
|
||||||
ORDER BY Platform.`Name`;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "gameid", GameId },
|
|
||||||
{ "userid", UserId }
|
|
||||||
};
|
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
PlatformMapping platformMapping = new PlatformMapping();
|
List<KeyValuePair<long, string>> platforms = new List<KeyValuePair<long, string>>();
|
||||||
List<AvailablePlatformItem> platforms = new List<AvailablePlatformItem>();
|
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
IGDB.Models.Platform platform = Platforms.GetPlatform((long)row["PlatformId"]);
|
KeyValuePair<long, string> valuePair = new KeyValuePair<long, string>((long)row["PlatformId"], (string)row["Name"]);
|
||||||
PlatformMapping.UserEmulatorConfiguration? emulatorConfiguration = platformMapping.GetUserEmulator(UserId, GameId, (long)platform.Id);
|
|
||||||
|
|
||||||
if (emulatorConfiguration == null)
|
|
||||||
{
|
|
||||||
if (platform.Id != 0)
|
|
||||||
{
|
|
||||||
Models.PlatformMapping.PlatformMapItem platformMap = PlatformMapping.GetPlatformMap((long)platform.Id);
|
|
||||||
emulatorConfiguration = new PlatformMapping.UserEmulatorConfiguration
|
|
||||||
{
|
|
||||||
EmulatorType = platformMap.WebEmulator.Type,
|
|
||||||
Core = platformMap.WebEmulator.Core,
|
|
||||||
EnableBIOSFiles = platformMap.EnabledBIOSHashes
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long? LastPlayedRomId = null;
|
|
||||||
bool? LastPlayedIsMediagroup = false;
|
|
||||||
string? LastPlayedRomName = null;
|
|
||||||
if (row["MostRecentRomId"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
LastPlayedRomId = (long?)row["MostRecentRomId"];
|
|
||||||
LastPlayedIsMediagroup = (bool)row["MostRecentRomIsMediaGroup"];
|
|
||||||
if (row["MostRecentRomName"] != System.DBNull.Value)
|
|
||||||
{
|
|
||||||
LastPlayedRomName = string.IsNullOrEmpty((string?)row["MostRecentRomName"]) ? "" : (string)row["MostRecentRomName"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
long? FavouriteRomId = null;
|
|
||||||
bool? FavouriteRomIsMediagroup = false;
|
|
||||||
string? FavouriteRomName = null;
|
|
||||||
if (row["FavouriteRomId"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
FavouriteRomId = (long?)row["FavouriteRomId"];
|
|
||||||
FavouriteRomIsMediagroup = (bool)row["FavouriteRomIsMediaGroup"];
|
|
||||||
if (row["MostRecentRomName"] != System.DBNull.Value)
|
|
||||||
{
|
|
||||||
FavouriteRomName = string.IsNullOrEmpty((string?)row["MostRecentRomName"]) ? "" : (string)row["MostRecentRomName"];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AvailablePlatformItem valuePair = new AvailablePlatformItem
|
|
||||||
{
|
|
||||||
Id = platform.Id,
|
|
||||||
Name = platform.Name,
|
|
||||||
Category = platform.Category,
|
|
||||||
emulatorConfiguration = emulatorConfiguration,
|
|
||||||
LastPlayedRomId = LastPlayedRomId,
|
|
||||||
LastPlayedRomIsMediagroup = LastPlayedIsMediagroup,
|
|
||||||
LastPlayedRomName = LastPlayedRomName,
|
|
||||||
FavouriteRomId = FavouriteRomId,
|
|
||||||
FavouriteRomIsMediagroup = FavouriteRomIsMediagroup,
|
|
||||||
FavouriteRomName = FavouriteRomName
|
|
||||||
};
|
|
||||||
platforms.Add(valuePair);
|
platforms.Add(valuePair);
|
||||||
}
|
}
|
||||||
|
|
||||||
return platforms;
|
return platforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GameSetFavouriteRom(string UserId, long GameId, long PlatformId, long RomId, bool IsMediaGroup)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "DELETE FROM User_GameFavouriteRoms WHERE UserId = @userid AND GameId = @gameid AND PlatformId = @platformid; INSERT INTO User_GameFavouriteRoms (UserId, GameId, PlatformId, RomId, IsMediaGroup) VALUES (@userid, @gameid, @platformid, @romid, @ismediagroup);";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "userid", UserId },
|
|
||||||
{ "gameid", GameId },
|
|
||||||
{ "platformid", PlatformId },
|
|
||||||
{ "romid", RomId },
|
|
||||||
{ "ismediagroup", IsMediaGroup }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void GameClearFavouriteRom(string UserId, long GameId, long PlatformId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "DELETE FROM User_GameFavouriteRoms WHERE UserId = @userid AND GameId = @gameid AND PlatformId = @platformid;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "userid", UserId },
|
|
||||||
{ "gameid", GameId },
|
|
||||||
{ "platformid", PlatformId }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class AvailablePlatformItem : IGDB.Models.Platform
|
|
||||||
{
|
|
||||||
public PlatformMapping.UserEmulatorConfiguration emulatorConfiguration { get; set; }
|
|
||||||
public long? LastPlayedRomId { get; set; }
|
|
||||||
public bool? LastPlayedRomIsMediagroup { get; set; }
|
|
||||||
public string? LastPlayedRomName { get; set; }
|
|
||||||
public long? FavouriteRomId { get; set; }
|
|
||||||
public bool? FavouriteRomIsMediagroup { get; set; }
|
|
||||||
public string? FavouriteRomName { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum SearchType
|
public enum SearchType
|
||||||
{
|
{
|
||||||
where = 0,
|
where = 0,
|
||||||
@@ -680,7 +542,6 @@ ORDER BY Platform.`Name`;";
|
|||||||
this.Id = gameObject.Id;
|
this.Id = gameObject.Id;
|
||||||
this.Name = gameObject.Name;
|
this.Name = gameObject.Name;
|
||||||
this.Slug = gameObject.Slug;
|
this.Slug = gameObject.Slug;
|
||||||
this.Summary = gameObject.Summary;
|
|
||||||
this.TotalRating = gameObject.TotalRating;
|
this.TotalRating = gameObject.TotalRating;
|
||||||
this.TotalRatingCount = gameObject.TotalRatingCount;
|
this.TotalRatingCount = gameObject.TotalRatingCount;
|
||||||
this.Cover = gameObject.Cover;
|
this.Cover = gameObject.Cover;
|
||||||
@@ -706,7 +567,6 @@ ORDER BY Platform.`Name`;";
|
|||||||
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; }
|
||||||
public string Summary { get; set; }
|
|
||||||
public double? TotalRating { get; set; }
|
public double? TotalRating { get; set; }
|
||||||
public int? TotalRatingCount { get; set; }
|
public int? TotalRatingCount { get; set; }
|
||||||
public bool HasSavedGame { get; set; } = false;
|
public bool HasSavedGame { get; set; } = false;
|
||||||
|
@@ -76,14 +76,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
Storage.NewCacheValue(returnValue, true);
|
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;
|
forceImageDownload = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
@@ -26,7 +26,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlatformVersion GetPlatformVersion(string Slug, Platform ParentPlatform, bool GetImages = false)
|
public static PlatformVersion GetPlatformVersion(string Slug, Platform ParentPlatform, bool GetImages)
|
||||||
{
|
{
|
||||||
Task<PlatformVersion> RetVal = _GetPlatformVersion(SearchUsing.slug, Slug, ParentPlatform, GetImages);
|
Task<PlatformVersion> RetVal = _GetPlatformVersion(SearchUsing.slug, Slug, ParentPlatform, GetImages);
|
||||||
return RetVal.Result;
|
return RetVal.Result;
|
||||||
|
@@ -74,14 +74,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
returnValue = await GetObjectFromServer(WhereClause, ImagePath);
|
||||||
Storage.NewCacheValue(returnValue, true);
|
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;
|
forceImageDownload = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
@@ -175,7 +175,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
dbDict.Add("Endpoint", Endpoint);
|
dbDict.Add("Endpoint", Endpoint);
|
||||||
dbDict.Add(SearchField, SearchValue);
|
dbDict.Add(SearchField, SearchValue);
|
||||||
|
|
||||||
DataTable dt = db.ExecuteCMD(sql, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromHours(8).Ticks));
|
DataTable dt = db.ExecuteCMD(sql, dbDict);
|
||||||
if (dt.Rows.Count == 0)
|
if (dt.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// no data stored for this item
|
// no data stored for this item
|
||||||
|
@@ -81,42 +81,14 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<GameRomMediaGroupItem> GetMediaGroupsFromGameId(long GameId, string userid = "", long? PlatformId = null)
|
public static List<GameRomMediaGroupItem> GetMediaGroupsFromGameId(long GameId, string userid = "")
|
||||||
{
|
{
|
||||||
string PlatformWhereClause = "";
|
|
||||||
if (PlatformId != null)
|
|
||||||
{
|
|
||||||
PlatformWhereClause = " AND RomMediaGroup.PlatformId=@platformid";
|
|
||||||
}
|
|
||||||
|
|
||||||
string UserFields = "";
|
|
||||||
string UserJoin = "";
|
|
||||||
if (userid.Length > 0)
|
|
||||||
{
|
|
||||||
UserFields = ", User_RecentPlayedRoms.RomId AS MostRecentRomId, User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup, User_GameFavouriteRoms.RomId AS FavouriteRomId, User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup";
|
|
||||||
UserJoin = @"
|
|
||||||
LEFT JOIN
|
|
||||||
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
|
||||||
AND User_RecentPlayedRoms.GameId = RomMediaGroup.GameId
|
|
||||||
AND User_RecentPlayedRoms.PlatformId = RomMediaGroup.PlatformId
|
|
||||||
AND User_RecentPlayedRoms.RomId = RomMediaGroup.Id
|
|
||||||
AND User_RecentPlayedRoms.IsMediaGroup = 1
|
|
||||||
LEFT JOIN
|
|
||||||
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
|
||||||
AND User_GameFavouriteRoms.GameId = RomMediaGroup.GameId
|
|
||||||
AND User_GameFavouriteRoms.PlatformId = RomMediaGroup.PlatformId
|
|
||||||
AND User_GameFavouriteRoms.RomId = RomMediaGroup.Id
|
|
||||||
AND User_GameFavouriteRoms.IsMediaGroup = 1
|
|
||||||
";
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT DISTINCT RomMediaGroup.*, GameState.RomId AS GameStateRomId" + UserFields + " FROM gaseous.RomMediaGroup LEFT JOIN GameState ON RomMediaGroup.Id = GameState.RomId AND GameState.IsMediaGroup = 1 AND GameState.UserId = @userid " + UserJoin + " WHERE RomMediaGroup.GameId=@gameid" + PlatformWhereClause + ";";
|
string sql = "SELECT DISTINCT RomMediaGroup.*, GameState.RomId AS GameStateRomId FROM gaseous.RomMediaGroup LEFT JOIN GameState ON RomMediaGroup.Id = GameState.RomId AND GameState.IsMediaGroup = 1 AND GameState.UserId = @userid WHERE RomMediaGroup.GameId=@gameid;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "gameid", GameId },
|
{ "gameid", GameId },
|
||||||
{ "userid", userid },
|
{ "userid", userid }
|
||||||
{ "platformid", PlatformId }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DataTable dataTable = db.ExecuteCMD(sql, dbDict);
|
DataTable dataTable = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -193,7 +165,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; 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;";
|
||||||
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);
|
||||||
@@ -216,34 +188,14 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GameRomMediaGroupItem mediaGroupItem = new GameRomMediaGroupItem
|
GameRomMediaGroupItem mediaGroupItem = new GameRomMediaGroupItem();
|
||||||
{
|
mediaGroupItem.Id = (long)row["Id"];
|
||||||
Id = (long)row["Id"],
|
mediaGroupItem.Status = (GameRomMediaGroupItem.GroupBuildStatus)row["Status"];
|
||||||
Status = (GameRomMediaGroupItem.GroupBuildStatus)row["Status"],
|
mediaGroupItem.PlatformId = (long)row["PlatformId"];
|
||||||
PlatformId = (long)row["PlatformId"],
|
mediaGroupItem.GameId = (long)row["GameId"];
|
||||||
GameId = (long)row["GameId"],
|
mediaGroupItem.RomIds = new List<long>();
|
||||||
RomIds = new List<long>(),
|
mediaGroupItem.Roms = new List<Roms.GameRomItem>();
|
||||||
Roms = new List<Roms.GameRomItem>(),
|
mediaGroupItem.HasSaveStates = hasSaveStates;
|
||||||
HasSaveStates = hasSaveStates
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaGroupItem.RomUserLastUsed = false;
|
|
||||||
if (row.Table.Columns.Contains("MostRecentRomId"))
|
|
||||||
{
|
|
||||||
if (row["MostRecentRomId"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
mediaGroupItem.RomUserLastUsed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaGroupItem.RomUserFavourite = false;
|
|
||||||
if (row.Table.Columns.Contains("FavouriteRomId"))
|
|
||||||
{
|
|
||||||
if (row["FavouriteRomId"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
mediaGroupItem.RomUserFavourite = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get members
|
// get members
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
@@ -264,6 +216,18 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for a web emulator and update the romItem
|
||||||
|
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||||
|
{
|
||||||
|
if (platformMapping.IGDBId == mediaGroupItem.PlatformId)
|
||||||
|
{
|
||||||
|
if (platformMapping.WebEmulator != null)
|
||||||
|
{
|
||||||
|
mediaGroupItem.Emulator = platformMapping.WebEmulator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mediaGroupItem;
|
return mediaGroupItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,8 +515,7 @@ namespace gaseous_server.Classes
|
|||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public long GameId { get; set; }
|
public long GameId { get; set; }
|
||||||
public long PlatformId { get; set; }
|
public long PlatformId { get; set; }
|
||||||
public string Platform
|
public string Platform {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -565,14 +528,12 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||||
public List<long> RomIds { get; set; }
|
public List<long> RomIds { get; set; }
|
||||||
public List<Roms.GameRomItem> Roms { get; set; }
|
public List<Roms.GameRomItem> Roms { get; set; }
|
||||||
public bool HasSaveStates { get; set; } = false;
|
public bool HasSaveStates { get; set; } = false;
|
||||||
public bool RomUserLastUsed { get; set; }
|
|
||||||
public bool RomUserFavourite { get; set; }
|
|
||||||
private GroupBuildStatus _Status { get; set; }
|
private GroupBuildStatus _Status { get; set; }
|
||||||
public GroupBuildStatus Status
|
public GroupBuildStatus Status {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_Status == GroupBuildStatus.Completed)
|
if (_Status == GroupBuildStatus.Completed)
|
||||||
@@ -596,8 +557,7 @@ namespace gaseous_server.Classes
|
|||||||
_Status = value;
|
_Status = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public long? Size
|
public long? Size {
|
||||||
{
|
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Status == GroupBuildStatus.Completed)
|
if (Status == GroupBuildStatus.Completed)
|
||||||
|
@@ -4,9 +4,6 @@ using gaseous_signature_parser.models.RomSignatureObject;
|
|||||||
using static gaseous_server.Classes.RomMediaGroup;
|
using static gaseous_server.Classes.RomMediaGroup;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
using static HasheousClient.Models.FixMatchModel;
|
|
||||||
using NuGet.Protocol.Core.Types;
|
|
||||||
using static gaseous_server.Classes.FileSignature;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -39,54 +36,34 @@ namespace gaseous_server.Classes
|
|||||||
string NameSearchWhere = "";
|
string NameSearchWhere = "";
|
||||||
if (NameSearch.Length > 0)
|
if (NameSearch.Length > 0)
|
||||||
{
|
{
|
||||||
NameSearchWhere = " AND view_Games_Roms.`Name` LIKE @namesearch";
|
NameSearchWhere = " AND Games_Roms.`Name` LIKE @namesearch";
|
||||||
dbDict.Add("namesearch", '%' + NameSearch + '%');
|
dbDict.Add("namesearch", '%' + NameSearch + '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
string UserFields = "";
|
|
||||||
string UserJoin = "";
|
|
||||||
if (userid.Length > 0)
|
|
||||||
{
|
|
||||||
UserFields = ", User_RecentPlayedRoms.RomId AS MostRecentRomId, User_RecentPlayedRoms.IsMediaGroup AS MostRecentRomIsMediaGroup, User_GameFavouriteRoms.RomId AS FavouriteRomId, User_GameFavouriteRoms.IsMediaGroup AS FavouriteRomIsMediaGroup";
|
|
||||||
UserJoin = @"
|
|
||||||
LEFT JOIN
|
|
||||||
User_RecentPlayedRoms ON User_RecentPlayedRoms.UserId = @userid
|
|
||||||
AND User_RecentPlayedRoms.GameId = view_Games_Roms.GameId
|
|
||||||
AND User_RecentPlayedRoms.PlatformId = view_Games_Roms.PlatformId
|
|
||||||
AND User_RecentPlayedRoms.RomId = view_Games_Roms.Id
|
|
||||||
AND User_RecentPlayedRoms.IsMediaGroup = 0
|
|
||||||
LEFT JOIN
|
|
||||||
User_GameFavouriteRoms ON User_GameFavouriteRoms.UserId = @userid
|
|
||||||
AND User_GameFavouriteRoms.GameId = view_Games_Roms.GameId
|
|
||||||
AND User_GameFavouriteRoms.PlatformId = view_Games_Roms.PlatformId
|
|
||||||
AND User_GameFavouriteRoms.RomId = view_Games_Roms.Id
|
|
||||||
AND User_GameFavouriteRoms.IsMediaGroup = 0
|
|
||||||
";
|
|
||||||
}
|
|
||||||
|
|
||||||
// platform query
|
// platform query
|
||||||
sqlPlatform = "SELECT DISTINCT view_Games_Roms.PlatformId, Platform.`Name` FROM view_Games_Roms LEFT JOIN Platform ON view_Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
sqlPlatform = "SELECT DISTINCT Games_Roms.PlatformId, Platform.`Name` FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE GameId = @id ORDER BY Platform.`Name`;";
|
||||||
|
|
||||||
if (PlatformId == -1)
|
if (PlatformId == -1)
|
||||||
{
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = "SELECT DISTINCT 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;";
|
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
||||||
|
|
||||||
// count query
|
// count query
|
||||||
sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id" + NameSearchWhere + ";";
|
sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id" + NameSearchWhere + ";";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// data query
|
// data query
|
||||||
sql = "SELECT DISTINCT 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;";
|
sql = "SELECT DISTINCT Games_Roms.*, Platform.`Name` AS platformname, GameState.RomId AS SavedStateRomId FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id LEFT JOIN GameState ON (Games_Roms.Id = GameState.RomId AND GameState.UserId = @userid AND GameState.IsMediaGroup = 0) WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + " ORDER BY Platform.`Name`, Games_Roms.`Name` LIMIT 1000;";
|
||||||
|
|
||||||
// count query
|
// count query
|
||||||
sqlCount = "SELECT COUNT(view_Games_Roms.Id) AS RomCount FROM view_Games_Roms WHERE view_Games_Roms.GameId = @id AND view_Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";";
|
sqlCount = "SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.GameId = @id AND Games_Roms.PlatformId = @platformid" + NameSearchWhere + ";";
|
||||||
|
|
||||||
dbDict.Add("platformid", PlatformId);
|
dbDict.Add("platformid", PlatformId);
|
||||||
}
|
}
|
||||||
DataTable romDT = db.ExecuteCMD(sql, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks));
|
DataTable romDT = db.ExecuteCMD(sql, dbDict);
|
||||||
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromMinutes(1).Ticks))[0];
|
Dictionary<string, object> rowCount = db.ExecuteCMDDict(sqlCount, dbDict)[0];
|
||||||
|
DataTable platformDT = db.ExecuteCMD(sqlPlatform, dbDict);
|
||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -96,9 +73,10 @@ namespace gaseous_server.Classes
|
|||||||
int pageOffset = pageSize * (pageNumber - 1);
|
int pageOffset = pageSize * (pageNumber - 1);
|
||||||
for (int i = 0; i < romDT.Rows.Count; i++)
|
for (int i = 0; i < romDT.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
|
GameRomItem gameRomItem = BuildRom(romDT.Rows[i]);
|
||||||
|
|
||||||
if ((i >= pageOffset && i < pageOffset + pageSize) || pageSize == 0)
|
if ((i >= pageOffset && i < pageOffset + pageSize) || pageSize == 0)
|
||||||
{
|
{
|
||||||
GameRomItem gameRomItem = BuildRom(romDT.Rows[i]);
|
|
||||||
GameRoms.GameRomItems.Add(gameRomItem);
|
GameRoms.GameRomItems.Add(gameRomItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +92,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 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";
|
string sql = "SELECT Games_Roms.*, Platform.`Name` AS platformname FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE 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);
|
||||||
@@ -134,7 +112,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 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";
|
string sql = "SELECT Games_Roms.*, Platform.`Name` AS platformname FROM Games_Roms LEFT JOIN Platform ON Games_Roms.PlatformId = Platform.Id WHERE 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);
|
||||||
@@ -169,53 +147,6 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
GameRomItem rom = GetRom(RomId);
|
GameRomItem rom = GetRom(RomId);
|
||||||
|
|
||||||
// send update to Hasheous if enabled
|
|
||||||
if (PlatformId != 0 && GameId != 0)
|
|
||||||
{
|
|
||||||
if (Config.MetadataConfiguration.HasheousSubmitFixes == true)
|
|
||||||
{
|
|
||||||
if (
|
|
||||||
Config.MetadataConfiguration.SignatureSource == HasheousClient.Models.MetadataModel.SignatureSources.Hasheous &&
|
|
||||||
(
|
|
||||||
Config.MetadataConfiguration.HasheousAPIKey != null &&
|
|
||||||
Config.MetadataConfiguration.HasheousAPIKey != "")
|
|
||||||
)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// find signature used for identifing the rom
|
|
||||||
string md5String = rom.Md5;
|
|
||||||
string sha1String = rom.Sha1;
|
|
||||||
if (rom.Attributes.ContainsKey("ZipContents"))
|
|
||||||
{
|
|
||||||
bool selectorFound = false;
|
|
||||||
List<ArchiveData> archiveDataValues = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ArchiveData>>(rom.Attributes["ZipContents"].ToString());
|
|
||||||
foreach (ArchiveData archiveData in archiveDataValues)
|
|
||||||
{
|
|
||||||
if (archiveData.isSignatureSelector == true)
|
|
||||||
{
|
|
||||||
md5String = archiveData.MD5;
|
|
||||||
sha1String = archiveData.SHA1;
|
|
||||||
selectorFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HasheousClient.WebApp.HttpHelper.AddHeader("X-API-Key", Config.MetadataConfiguration.HasheousAPIKey);
|
|
||||||
HasheousClient.Hasheous hasheousClient = new HasheousClient.Hasheous();
|
|
||||||
List<MetadataMatch> metadataMatchList = new List<MetadataMatch>();
|
|
||||||
metadataMatchList.Add(new MetadataMatch(HasheousClient.Models.MetadataSources.IGDB, platform.Slug, game.Slug));
|
|
||||||
hasheousClient.FixMatch(new HasheousClient.Models.FixMatchModel(md5String, sha1String, metadataMatchList));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Critical, "Fix Match", "An error occurred while sending a fixed match to Hasheous.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rom;
|
return rom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,7 +161,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; 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;";
|
||||||
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);
|
||||||
@@ -248,63 +179,39 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, object> romAttributes = new Dictionary<string, object>();
|
|
||||||
if (romDR["attributes"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if ((string)romDR["attributes"] != "[ ]")
|
|
||||||
{
|
|
||||||
romAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>((string)romDR["attributes"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Roms", "Error parsing rom attributes: " + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GameRomItem romItem = new GameRomItem
|
GameRomItem romItem = new GameRomItem
|
||||||
{
|
{
|
||||||
Id = (long)romDR["id"],
|
Id = (long)romDR["id"],
|
||||||
PlatformId = (long)romDR["platformid"],
|
PlatformId = (long)romDR["platformid"],
|
||||||
Platform = (string)romDR["platformname"],
|
Platform = (string)romDR["platformname"],
|
||||||
GameId = (long)romDR["gameid"],
|
GameId = (long)romDR["gameid"],
|
||||||
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(),
|
||||||
Md5 = ((string)romDR["md5"]).ToLower(),
|
Md5 = ((string)romDR["md5"]).ToLower(),
|
||||||
Sha1 = ((string)romDR["sha1"]).ToLower(),
|
Sha1 = ((string)romDR["sha1"]).ToLower(),
|
||||||
DevelopmentStatus = (string)romDR["developmentstatus"],
|
DevelopmentStatus = (string)romDR["developmentstatus"],
|
||||||
Attributes = romAttributes,
|
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<KeyValuePair<string, object>>>((string)Common.ReturnValueIfNull(romDR["attributes"], "[ ]")),
|
||||||
RomType = (HasheousClient.Models.SignatureModel.RomItem.RomTypes)(int)romDR["romtype"],
|
RomType = (HasheousClient.Models.LookupResponseModel.RomItem.RomTypes)(int)romDR["romtype"],
|
||||||
RomTypeMedia = (string)romDR["romtypemedia"],
|
RomTypeMedia = (string)romDR["romtypemedia"],
|
||||||
MediaLabel = (string)romDR["medialabel"],
|
MediaLabel = (string)romDR["medialabel"],
|
||||||
Path = (string)romDR["path"],
|
Path = (string)romDR["path"],
|
||||||
RelativePath = (string)romDR["relativepath"],
|
|
||||||
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"],
|
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)romDR["metadatasource"],
|
||||||
SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""),
|
SignatureSourceGameTitle = (string)Common.ReturnValueIfNull(romDR["MetadataGameName"], ""),
|
||||||
HasSaveStates = hasSaveStates,
|
HasSaveStates = hasSaveStates,
|
||||||
Library = GameLibrary.GetLibrary((int)romDR["LibraryId"])
|
Library = GameLibrary.GetLibrary((int)romDR["LibraryId"])
|
||||||
};
|
};
|
||||||
|
|
||||||
romItem.RomUserLastUsed = false;
|
// check for a web emulator and update the romItem
|
||||||
if (romDR.Table.Columns.Contains("MostRecentRomId"))
|
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in Models.PlatformMapping.PlatformMap)
|
||||||
{
|
{
|
||||||
if (romDR["MostRecentRomId"] != DBNull.Value)
|
if (platformMapping.IGDBId == romItem.PlatformId)
|
||||||
{
|
{
|
||||||
romItem.RomUserLastUsed = true;
|
if (platformMapping.WebEmulator != null)
|
||||||
|
{
|
||||||
|
romItem.Emulator = platformMapping.WebEmulator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
romItem.RomUserFavourite = false;
|
|
||||||
if (romDR.Table.Columns.Contains("FavouriteRomId"))
|
|
||||||
{
|
|
||||||
if (romDR["FavouriteRomId"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
romItem.RomUserFavourite = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return romItem;
|
return romItem;
|
||||||
@@ -316,20 +223,16 @@ namespace gaseous_server.Classes
|
|||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameRomItem : HasheousClient.Models.SignatureModel.RomItem
|
public class GameRomItem : HasheousClient.Models.LookupResponseModel.RomItem
|
||||||
{
|
{
|
||||||
public long PlatformId { get; set; }
|
public long PlatformId { get; set; }
|
||||||
public string Platform { get; set; }
|
public string Platform { get; set; }
|
||||||
|
public Models.PlatformMapping.PlatformMapItem.WebEmulatorItem? Emulator { get; set; }
|
||||||
public long GameId { get; set; }
|
public long GameId { get; set; }
|
||||||
public string Game { get; set; }
|
|
||||||
public string? Path { get; set; }
|
public string? Path { get; set; }
|
||||||
public string? RelativePath { get; set; }
|
|
||||||
public string? SignatureSourceGameTitle { get; set; }
|
public string? SignatureSourceGameTitle { get; set; }
|
||||||
public bool HasSaveStates { get; set; } = false;
|
public bool HasSaveStates { get; set; } = false;
|
||||||
public GameLibrary.LibraryItem Library { get; set; }
|
public GameLibrary.LibraryItem Library { get; set; }
|
||||||
public bool RomUserLastUsed { get; set; }
|
|
||||||
public bool RomUserFavourite { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using gaseous_signature_parser.models.RomSignatureObject;
|
using gaseous_signature_parser.models.RomSignatureObject;
|
||||||
using static gaseous_server.Classes.Common;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -48,7 +47,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
Game = new gaseous_server.Models.Signatures_Games.GameItem
|
Game = new gaseous_server.Models.Signatures_Games.GameItem
|
||||||
{
|
{
|
||||||
Id = (long)(int)sigDbRow["Id"],
|
Id = (Int32)sigDbRow["Id"],
|
||||||
Name = (string)sigDbRow["Name"],
|
Name = (string)sigDbRow["Name"],
|
||||||
Description = (string)sigDbRow["Description"],
|
Description = (string)sigDbRow["Description"],
|
||||||
Year = (string)sigDbRow["Year"],
|
Year = (string)sigDbRow["Year"],
|
||||||
@@ -57,26 +56,35 @@ namespace gaseous_server.Classes
|
|||||||
System = (string)sigDbRow["Platform"],
|
System = (string)sigDbRow["Platform"],
|
||||||
SystemVariant = (string)sigDbRow["SystemVariant"],
|
SystemVariant = (string)sigDbRow["SystemVariant"],
|
||||||
Video = (string)sigDbRow["Video"],
|
Video = (string)sigDbRow["Video"],
|
||||||
Countries = new Dictionary<string, string>(GetLookup(LookupTypes.Country, (long)(int)sigDbRow["Id"])),
|
Country = "",
|
||||||
Languages = new Dictionary<string, string>(GetLookup(LookupTypes.Language, (long)(int)sigDbRow["Id"])),
|
Language = "",
|
||||||
Copyright = (string)sigDbRow["Copyright"]
|
Copyright = (string)sigDbRow["Copyright"]
|
||||||
},
|
},
|
||||||
Rom = new gaseous_server.Models.Signatures_Games.RomItem
|
Rom = new gaseous_server.Models.Signatures_Games.RomItem
|
||||||
{
|
{
|
||||||
Id = (long)(int)sigDbRow["romid"],
|
Id = (Int32)sigDbRow["romid"],
|
||||||
Name = (string)sigDbRow["romname"],
|
Name = (string)sigDbRow["romname"],
|
||||||
Size = (Int64)sigDbRow["Size"],
|
Size = (Int64)sigDbRow["Size"],
|
||||||
Crc = (string)sigDbRow["CRC"],
|
Crc = (string)sigDbRow["CRC"],
|
||||||
Md5 = ((string)sigDbRow["MD5"]).ToLower(),
|
Md5 = ((string)sigDbRow["MD5"]).ToLower(),
|
||||||
Sha1 = ((string)sigDbRow["SHA1"]).ToLower(),
|
Sha1 = ((string)sigDbRow["SHA1"]).ToLower(),
|
||||||
DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"],
|
DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"],
|
||||||
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")),
|
|
||||||
RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"],
|
RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"],
|
||||||
RomTypeMedia = (string)sigDbRow["RomTypeMedia"],
|
RomTypeMedia = (string)sigDbRow["RomTypeMedia"],
|
||||||
MediaLabel = (string)sigDbRow["MediaLabel"],
|
MediaLabel = (string)sigDbRow["MediaLabel"],
|
||||||
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)sigDbRow["MetadataSource"]
|
SignatureSource = (gaseous_server.Models.Signatures_Games.RomItem.SignatureSourceType)(Int32)sigDbRow["MetadataSource"]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
string attributeValues = (string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]");
|
||||||
|
Dictionary<string, object> attributesDict = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(attributeValues);
|
||||||
|
if (attributesDict != null)
|
||||||
|
{
|
||||||
|
gameItem.Rom.Attributes = [.. attributesDict];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameItem.Rom.Attributes = new List<KeyValuePair<string, object>>();
|
||||||
|
}
|
||||||
GamesList.Add(gameItem);
|
GamesList.Add(gameItem);
|
||||||
}
|
}
|
||||||
return GamesList;
|
return GamesList;
|
||||||
@@ -122,36 +130,5 @@ namespace gaseous_server.Classes
|
|||||||
};
|
};
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, string> GetLookup(LookupTypes LookupType, long GameId)
|
|
||||||
{
|
|
||||||
string tableName = "";
|
|
||||||
switch (LookupType)
|
|
||||||
{
|
|
||||||
case LookupTypes.Country:
|
|
||||||
tableName = "Countries";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LookupTypes.Language:
|
|
||||||
tableName = "Languages";
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "SELECT " + LookupType.ToString() + ".Code, " + LookupType.ToString() + ".Value FROM Signatures_Games_" + tableName + " JOIN " + LookupType.ToString() + " ON Signatures_Games_" + tableName + "." + LookupType.ToString() + "Id = " + LookupType.ToString() + ".Id WHERE Signatures_Games_" + tableName + ".GameId = @id;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "id", GameId }
|
|
||||||
};
|
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
Dictionary<string, string> returnDict = new Dictionary<string, string>();
|
|
||||||
foreach (DataRow row in data.Rows)
|
|
||||||
{
|
|
||||||
returnDict.Add((string)row["Code"], (string)row["Value"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnDict;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -5,45 +5,29 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
public class Statistics
|
public class Statistics
|
||||||
{
|
{
|
||||||
public StatisticsModel RecordSession(Guid SessionId, long GameId, long PlatformId, long RomId, bool IsMediaGroup, string UserId)
|
public StatisticsModel RecordSession(Guid SessionId, long GameId, 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;
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
Dictionary<string, object> dbDict;
|
||||||
{ "userid", UserId },
|
|
||||||
{ "gameid", GameId },
|
|
||||||
{ "platformid", PlatformId },
|
|
||||||
{ "romid", RomId },
|
|
||||||
{ "ismediagroup", IsMediaGroup }
|
|
||||||
};
|
|
||||||
|
|
||||||
// update last played rom id
|
|
||||||
sql = "INSERT INTO User_RecentPlayedRoms (UserId, GameId, PlatformId, RomId, IsMediaGroup) VALUES (@userid, @gameid, @platformid, @romid, @ismediagroup) ON DUPLICATE KEY UPDATE RomId = @romid, IsMediaGroup = @ismediagroup;";
|
|
||||||
db.ExecuteNonQuery(sql, dbDict);
|
|
||||||
|
|
||||||
// update sessions
|
|
||||||
|
|
||||||
if (SessionId == Guid.Empty)
|
if (SessionId == Guid.Empty)
|
||||||
{
|
{
|
||||||
// new session required
|
// new session required
|
||||||
SessionId = Guid.NewGuid();
|
SessionId = Guid.NewGuid();
|
||||||
|
|
||||||
sql = "INSERT INTO UserTimeTracking (GameId, UserId, SessionId, SessionTime, SessionLength, PlatformId, IsMediaGroup, RomId) VALUES (@gameid, @userid, @sessionid, @sessiontime, @sessionlength, @platformid, @ismediagroup, @romid);";
|
sql = "INSERT INTO UserTimeTracking (GameId, UserId, SessionId, SessionTime, SessionLength) VALUES (@gameid, @userid, @sessionid, @sessiontime, @sessionlength);";
|
||||||
dbDict = new Dictionary<string, object>{
|
dbDict = new Dictionary<string, object>{
|
||||||
{ "gameid", GameId },
|
{ "gameid", GameId },
|
||||||
{ "userid", UserId },
|
{ "userid", UserId },
|
||||||
{ "sessionid", SessionId },
|
{ "sessionid", SessionId },
|
||||||
{ "sessiontime", DateTime.UtcNow },
|
{ "sessiontime", DateTime.UtcNow },
|
||||||
{ "sessionlength", 1 },
|
{ "sessionlength", 1 }
|
||||||
{ "platformid", PlatformId },
|
|
||||||
{ "ismediagroup", IsMediaGroup },
|
|
||||||
{ "romid", RomId }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
db.ExecuteNonQuery(sql, dbDict);
|
db.ExecuteNonQuery(sql, dbDict);
|
||||||
|
|
||||||
return new StatisticsModel
|
return new StatisticsModel{
|
||||||
{
|
|
||||||
GameId = GameId,
|
GameId = GameId,
|
||||||
SessionId = SessionId,
|
SessionId = SessionId,
|
||||||
SessionStart = (DateTime)dbDict["sessiontime"],
|
SessionStart = (DateTime)dbDict["sessiontime"],
|
||||||
@@ -66,8 +50,7 @@ namespace gaseous_server.Classes
|
|||||||
sql = "SELECT * FROM UserTimeTracking WHERE GameId = @gameid AND UserId = @userid AND SessionId = @sessionid;";
|
sql = "SELECT * FROM UserTimeTracking WHERE GameId = @gameid AND UserId = @userid AND SessionId = @sessionid;";
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
return new StatisticsModel
|
return new StatisticsModel{
|
||||||
{
|
|
||||||
GameId = (long)data.Rows[0]["GameId"],
|
GameId = (long)data.Rows[0]["GameId"],
|
||||||
SessionId = Guid.Parse(data.Rows[0]["SessionId"].ToString()),
|
SessionId = Guid.Parse(data.Rows[0]["SessionId"].ToString()),
|
||||||
SessionStart = (DateTime)data.Rows[0]["SessionTime"],
|
SessionStart = (DateTime)data.Rows[0]["SessionTime"],
|
||||||
@@ -104,8 +87,7 @@ namespace gaseous_server.Classes
|
|||||||
sql = "SELECT * FROM UserTimeTracking WHERE GameId = @gameid AND UserId = @userid ORDER BY SessionTime DESC LIMIT 1;";
|
sql = "SELECT * FROM UserTimeTracking WHERE GameId = @gameid AND UserId = @userid ORDER BY SessionTime DESC LIMIT 1;";
|
||||||
data = db.ExecuteCMD(sql, dbDict);
|
data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
return new StatisticsModel
|
return new StatisticsModel{
|
||||||
{
|
|
||||||
GameId = GameId,
|
GameId = GameId,
|
||||||
SessionLength = TotalTime,
|
SessionLength = TotalTime,
|
||||||
SessionStart = (DateTime)data.Rows[0]["SessionTime"]
|
SessionStart = (DateTime)data.Rows[0]["SessionTime"]
|
||||||
|
@@ -1,209 +0,0 @@
|
|||||||
using System.Data;
|
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using IGDB.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
|
||||||
{
|
|
||||||
public class UserProfile
|
|
||||||
{
|
|
||||||
static readonly Dictionary<string, string> supportedImages = new Dictionary<string, string>{
|
|
||||||
{ ".png", "image/png" },
|
|
||||||
{ ".jpg", "image/jpeg" },
|
|
||||||
{ ".jpeg", "image/jpeg" },
|
|
||||||
{ ".gif", "image/gif" },
|
|
||||||
{ ".bmp", "image/bmp" },
|
|
||||||
{ ".svg", "image/svg+xml" }
|
|
||||||
};
|
|
||||||
|
|
||||||
public Models.UserProfile? GetUserProfile(string UserId)
|
|
||||||
{
|
|
||||||
// build the user profile object
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "SELECT Id, UserId, DisplayName, Quip, AvatarExtension, ProfileBackgroundExtension, UnstructuredData FROM UserProfiles WHERE Id = @userid;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "userid", UserId }
|
|
||||||
};
|
|
||||||
|
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (data.Rows.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Models.UserProfile.ProfileImageItem? Avatar = null;
|
|
||||||
if (data.Rows[0]["AvatarExtension"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
Avatar = new Models.UserProfile.ProfileImageItem
|
|
||||||
{
|
|
||||||
MimeType = supportedImages[data.Rows[0]["AvatarExtension"].ToString()],
|
|
||||||
Extension = data.Rows[0]["AvatarExtension"].ToString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Models.UserProfile.ProfileImageItem? ProfileBackground = null;
|
|
||||||
if (data.Rows[0]["ProfileBackgroundExtension"] != DBNull.Value)
|
|
||||||
{
|
|
||||||
ProfileBackground = new Models.UserProfile.ProfileImageItem
|
|
||||||
{
|
|
||||||
MimeType = supportedImages[data.Rows[0]["ProfileBackgroundExtension"].ToString()],
|
|
||||||
Extension = data.Rows[0]["ProfileBackgroundExtension"].ToString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// get now playing game - if available
|
|
||||||
Models.UserProfile.NowPlayingItem? NowPlaying = null;
|
|
||||||
sql = "SELECT * FROM `view_UserTimeTracking` WHERE UserId = @userid AND UTC_TIMESTAMP() BETWEEN SessionTime AND DATE_ADD(SessionEnd, INTERVAL 2 MINUTE) ORDER BY SessionEnd DESC LIMIT 1;";
|
|
||||||
dbDict = new Dictionary<string, object>{
|
|
||||||
{ "userid", data.Rows[0]["UserId"].ToString() }
|
|
||||||
};
|
|
||||||
DataTable nowPlayingData = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (nowPlayingData.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
NowPlaying = new Models.UserProfile.NowPlayingItem
|
|
||||||
{
|
|
||||||
Game = Games.GetGame((long)nowPlayingData.Rows[0]["GameId"], false, false, false),
|
|
||||||
Platform = Platforms.GetPlatform((long)nowPlayingData.Rows[0]["PlatformId"], false, false),
|
|
||||||
Duration = Convert.ToInt64(nowPlayingData.Rows[0]["SessionLength"])
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the user profile object
|
|
||||||
return new Models.UserProfile
|
|
||||||
{
|
|
||||||
UserId = Guid.Parse(data.Rows[0]["Id"].ToString()),
|
|
||||||
DisplayName = data.Rows[0]["DisplayName"].ToString(),
|
|
||||||
Quip = data.Rows[0]["Quip"].ToString(),
|
|
||||||
Avatar = Avatar,
|
|
||||||
ProfileBackground = ProfileBackground,
|
|
||||||
NowPlaying = NowPlaying,
|
|
||||||
Data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, object>>(data.Rows[0]["UnstructuredData"].ToString())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateUserProfile(string InternalUserId, Models.UserProfile profile)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "UPDATE UserProfiles SET DisplayName = @displayname, Quip = @quip, UnstructuredData = @data WHERE UserId = @internalId AND Id = @userid;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "displayname", profile.DisplayName },
|
|
||||||
{ "quip", profile.Quip },
|
|
||||||
{ "data", Newtonsoft.Json.JsonConvert.SerializeObject(profile.Data) },
|
|
||||||
{ "userid", profile.UserId },
|
|
||||||
{ "internalId", InternalUserId }
|
|
||||||
};
|
|
||||||
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum ImageType
|
|
||||||
{
|
|
||||||
Avatar,
|
|
||||||
Background
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateImage(ImageType imageType, string UserId, string InternalUserId, string Filename, byte[] bytes)
|
|
||||||
{
|
|
||||||
// check if it's a supported file type
|
|
||||||
if (!supportedImages.ContainsKey(Path.GetExtension(Filename).ToLower()))
|
|
||||||
{
|
|
||||||
throw new Exception("File type not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
string ByteFieldName;
|
|
||||||
string ExtensionFieldName;
|
|
||||||
switch (imageType)
|
|
||||||
{
|
|
||||||
case ImageType.Avatar:
|
|
||||||
ByteFieldName = "Avatar";
|
|
||||||
ExtensionFieldName = "AvatarExtension";
|
|
||||||
break;
|
|
||||||
case ImageType.Background:
|
|
||||||
ByteFieldName = "ProfileBackground";
|
|
||||||
ExtensionFieldName = "ProfileBackgroundExtension";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception("Invalid image type");
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = String.Format("UPDATE UserProfiles SET {0} = @content, {1} = @extension WHERE Id = @userid AND UserId = @internaluserid;", ByteFieldName, ExtensionFieldName);
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "content", bytes },
|
|
||||||
{ "extension", Path.GetExtension(Filename) },
|
|
||||||
{ "userid", UserId },
|
|
||||||
{ "internaluserid", InternalUserId }
|
|
||||||
};
|
|
||||||
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Models.ImageItem? GetImage(ImageType imageType, string UserId)
|
|
||||||
{
|
|
||||||
string ByteFieldName;
|
|
||||||
string ExtensionFieldName;
|
|
||||||
switch (imageType)
|
|
||||||
{
|
|
||||||
case ImageType.Avatar:
|
|
||||||
ByteFieldName = "Avatar";
|
|
||||||
ExtensionFieldName = "AvatarExtension";
|
|
||||||
break;
|
|
||||||
case ImageType.Background:
|
|
||||||
ByteFieldName = "ProfileBackground";
|
|
||||||
ExtensionFieldName = "ProfileBackgroundExtension";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception("Invalid image type");
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = String.Format("SELECT {0}, {1} FROM UserProfiles WHERE Id = @userid;", ByteFieldName, ExtensionFieldName);
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "userid", UserId }
|
|
||||||
};
|
|
||||||
|
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (data.Rows.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Models.ImageItem? image = new Models.ImageItem
|
|
||||||
{
|
|
||||||
content = data.Rows[0][ByteFieldName] as byte[],
|
|
||||||
mimeType = supportedImages[data.Rows[0][ExtensionFieldName] as string],
|
|
||||||
extension = data.Rows[0][ExtensionFieldName] as string
|
|
||||||
};
|
|
||||||
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteImage(ImageType imageType, string UserId)
|
|
||||||
{
|
|
||||||
string ByteFieldName;
|
|
||||||
string ExtensionFieldName;
|
|
||||||
switch (imageType)
|
|
||||||
{
|
|
||||||
case ImageType.Avatar:
|
|
||||||
ByteFieldName = "Avatar";
|
|
||||||
ExtensionFieldName = "AvatarExtension";
|
|
||||||
break;
|
|
||||||
case ImageType.Background:
|
|
||||||
ByteFieldName = "ProfileBackground";
|
|
||||||
ExtensionFieldName = "ProfileBackgroundExtension";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Exception("Invalid image type");
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = String.Format("UPDATE UserProfiles SET {0} = NULL, {1} = NULL WHERE UserId = @userid;", ByteFieldName, ExtensionFieldName);
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
|
||||||
{ "userid", UserId }
|
|
||||||
};
|
|
||||||
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,7 +15,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class AccountController : Controller
|
public class AccountController : Controller
|
||||||
@@ -99,7 +99,7 @@ namespace gaseous_server.Controllers
|
|||||||
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
||||||
profile.SecurityProfile = user.SecurityProfile;
|
profile.SecurityProfile = user.SecurityProfile;
|
||||||
profile.UserPreferences = user.UserPreferences;
|
profile.UserPreferences = user.UserPreferences;
|
||||||
profile.ProfileId = user.ProfileId;
|
profile.Avatar = user.Avatar;
|
||||||
profile.Roles.Sort();
|
profile.Roles.Sort();
|
||||||
|
|
||||||
return Ok(profile);
|
return Ok(profile);
|
||||||
@@ -188,7 +188,7 @@ namespace gaseous_server.Controllers
|
|||||||
user.LockoutEnabled = rawUser.LockoutEnabled;
|
user.LockoutEnabled = rawUser.LockoutEnabled;
|
||||||
user.LockoutEnd = rawUser.LockoutEnd;
|
user.LockoutEnd = rawUser.LockoutEnd;
|
||||||
user.SecurityProfile = rawUser.SecurityProfile;
|
user.SecurityProfile = rawUser.SecurityProfile;
|
||||||
user.ProfileId = rawUser.ProfileId;
|
user.Avatar = rawUser.Avatar;
|
||||||
|
|
||||||
// get roles
|
// get roles
|
||||||
ApplicationUser? aUser = await _userManager.FindByIdAsync(rawUser.Id);
|
ApplicationUser? aUser = await _userManager.FindByIdAsync(rawUser.Id);
|
||||||
@@ -220,10 +220,6 @@ namespace gaseous_server.Controllers
|
|||||||
Email = model.Email,
|
Email = model.Email,
|
||||||
NormalizedEmail = model.Email.ToUpper()
|
NormalizedEmail = model.Email.ToUpper()
|
||||||
};
|
};
|
||||||
if (await _userManager.FindByEmailAsync(model.Email) != null)
|
|
||||||
{
|
|
||||||
return NotFound("User already exists");
|
|
||||||
}
|
|
||||||
var result = await _userManager.CreateAsync(user, model.Password);
|
var result = await _userManager.CreateAsync(user, model.Password);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
@@ -245,23 +241,6 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("Users/Test")]
|
|
||||||
[Authorize(Roles = "Admin")]
|
|
||||||
public async Task<IActionResult> TestUserExists(string Email)
|
|
||||||
{
|
|
||||||
ApplicationUser? rawUser = await _userManager.FindByEmailAsync(Email);
|
|
||||||
|
|
||||||
if (rawUser != null)
|
|
||||||
{
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Users/{UserId}")]
|
[Route("Users/{UserId}")]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
@@ -277,7 +256,6 @@ namespace gaseous_server.Controllers
|
|||||||
user.LockoutEnabled = rawUser.LockoutEnabled;
|
user.LockoutEnabled = rawUser.LockoutEnabled;
|
||||||
user.LockoutEnd = rawUser.LockoutEnd;
|
user.LockoutEnd = rawUser.LockoutEnd;
|
||||||
user.SecurityProfile = rawUser.SecurityProfile;
|
user.SecurityProfile = rawUser.SecurityProfile;
|
||||||
user.ProfileId = rawUser.ProfileId;
|
|
||||||
|
|
||||||
// get roles
|
// get roles
|
||||||
IList<string> aUserRoles = await _userManager.GetRolesAsync(rawUser);
|
IList<string> aUserRoles = await _userManager.GetRolesAsync(rawUser);
|
||||||
|
@@ -10,7 +10,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize(Roles = "Admin,Gamer,Player")]
|
[Authorize(Roles = "Admin,Gamer,Player")]
|
||||||
public class BackgroundTasksController : Controller
|
public class BackgroundTasksController : Controller
|
||||||
|
@@ -7,30 +7,16 @@ using gaseous_server.Classes;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using Authentication;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using gaseous_server.Models;
|
|
||||||
using IGDB.Models;
|
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class BiosController : Controller
|
public class BiosController : Controller
|
||||||
{
|
{
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
|
||||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
|
||||||
|
|
||||||
public BiosController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_signInManager = signInManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -57,51 +43,24 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpHead]
|
[HttpHead]
|
||||||
[Route("zip/{PlatformId}")]
|
[Route("zip/{PlatformId}")]
|
||||||
[Route("zip/{PlatformId}/{GameId}")]
|
|
||||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GetBiosCompressedAsync(long PlatformId, long GameId = -1, bool filtered = false)
|
public ActionResult GetBiosCompressed(long PlatformId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Platform platform = Platforms.GetPlatform(PlatformId);
|
IGDB.Models.Platform platform = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
PlatformMapping.PlatformMapItem platformMap = PlatformMapping.GetPlatformMap(PlatformId);
|
|
||||||
|
|
||||||
List<string> biosHashes = new List<string>();
|
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryBIOSDirectory, platform.Slug);
|
||||||
|
|
||||||
if (GameId == -1 || filtered == false)
|
|
||||||
{
|
|
||||||
// get all bios files for selected platform
|
|
||||||
biosHashes.AddRange(platformMap.EnabledBIOSHashes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get user platform map
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
PlatformMapping platformMapping = new PlatformMapping();
|
|
||||||
PlatformMapping.PlatformMapItem userPlatformMap = platformMapping.GetUserPlatformMap(user.Id, PlatformId, GameId);
|
|
||||||
|
|
||||||
biosHashes.AddRange(userPlatformMap.EnabledBIOSHashes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// build zip file
|
|
||||||
string tempFile = Path.GetTempFileName();
|
string tempFile = Path.GetTempFileName();
|
||||||
|
|
||||||
using (FileStream zipFile = System.IO.File.Create(tempFile))
|
using (FileStream zipFile = System.IO.File.Create(tempFile))
|
||||||
using (var zipArchive = new ZipArchive(zipFile, ZipArchiveMode.Create))
|
using (var zipArchive = new ZipArchive(zipFile, ZipArchiveMode.Create))
|
||||||
{
|
{
|
||||||
foreach (string hash in biosHashes)
|
foreach (string file in Directory.GetFiles(biosPath))
|
||||||
{
|
{
|
||||||
// get the bios data for the hash
|
zipArchive.CreateEntryFromFile(file, Path.GetFileName(file));
|
||||||
foreach (PlatformMapping.PlatformMapItem.EmulatorBiosItem bios in platformMap.Bios)
|
|
||||||
{
|
|
||||||
if (bios.hash == hash)
|
|
||||||
{
|
|
||||||
// add the bios file to the zip
|
|
||||||
zipArchive.CreateEntryFromFile(Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, hash + ".bios"), bios.filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class CollectionsController : Controller
|
public class CollectionsController : Controller
|
||||||
|
@@ -15,7 +15,7 @@ using Asp.Versioning;
|
|||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
|
@@ -18,12 +18,11 @@ 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 static gaseous_server.Models.PlatformMapping;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@@ -105,7 +104,7 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
if (platform.Length > 0)
|
if (platform.Length > 0)
|
||||||
{
|
{
|
||||||
tempVal = "view_Games_Roms.PlatformId IN (";
|
tempVal = "Games_Roms.PlatformId IN (";
|
||||||
string[] platformClauseItems = platform.Split(",");
|
string[] platformClauseItems = platform.Split(",");
|
||||||
for (int i = 0; i < platformClauseItems.Length; i++)
|
for (int i = 0; i < platformClauseItems.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -281,7 +280,9 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
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.GameId AS ROMGameId, Game.*, case when Game.`Name` like 'The %' then CONCAT(trim(substr(Game.`Name` from 4)), ', The') else Game.`Name` end as NameThe FROM view_Games_Roms LEFT JOIN Game ON Game.Id = view_Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId LEFT JOIN (SELECT Relation_Game_AgeRatings.GameId, AgeRating.* FROM Relation_Game_AgeRatings JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id) view_AgeRatings ON Game.Id = view_AgeRatings.GameId " + whereClause + " " + havingClause + " " + orderByClause;
|
//string sql = "SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Game.* FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId " + whereClause + " " + havingClause + " " + orderByClause;
|
||||||
|
|
||||||
|
string sql = "SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Game.*, case when Game.`Name` like 'The %' then CONCAT(trim(substr(Game.`Name` from 4)), ', The') else Game.`Name` end as NameThe FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId LEFT JOIN (SELECT Relation_Game_AgeRatings.GameId, AgeRating.* FROM Relation_Game_AgeRatings JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id) view_AgeRatings ON Game.Id = view_AgeRatings.GameId " + whereClause + " " + havingClause + " " + orderByClause;
|
||||||
|
|
||||||
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
||||||
|
|
||||||
@@ -456,6 +457,74 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{GameId}/artwork/{ArtworkId}/image/{size}")]
|
||||||
|
[Route("{GameId}/artwork/{ArtworkId}/image/{size}/{ImageName}")]
|
||||||
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GameCoverImage(long GameId, long ArtworkId, Communications.IGDBAPI_ImageSize size, string ImageName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IGDB.Models.Artwork artworkObject = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
||||||
|
|
||||||
|
if (artworkObject != null)
|
||||||
|
{
|
||||||
|
//string coverFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Artwork", size.ToString(), artworkObject.ImageId + ".jpg");
|
||||||
|
|
||||||
|
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Artwork");
|
||||||
|
|
||||||
|
Communications comms = new Communications();
|
||||||
|
Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, artworkObject.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.original });
|
||||||
|
|
||||||
|
string coverFilePath = ImgFetch.Result;
|
||||||
|
|
||||||
|
|
||||||
|
if (System.IO.File.Exists(coverFilePath))
|
||||||
|
{
|
||||||
|
string filename = artworkObject.ImageId + ".jpg";
|
||||||
|
string filepath = coverFilePath;
|
||||||
|
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||||
|
string contentType = "image/jpg";
|
||||||
|
|
||||||
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
|
{
|
||||||
|
FileName = filename,
|
||||||
|
Inline = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||||
|
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
||||||
|
|
||||||
|
return File(filedata, contentType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -494,103 +563,33 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{GameId}/{ImageType}/{ImageId}/image/{size}")]
|
[Route("{GameId}/cover/image/{size}")]
|
||||||
[Route("{GameId}/{ImageType}/{ImageId}/image/{size}/{imagename}")]
|
[Route("{GameId}/cover/image/{size}/{imagename}")]
|
||||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GameImage(long GameId, MetadataImageType imageType, long ImageId, Communications.IGDBAPI_ImageSize size, string imagename = "")
|
public async Task<ActionResult> GameCoverImage(long GameId, Communications.IGDBAPI_ImageSize size, string imagename = "")
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
|
||||||
string? imageId = null;
|
|
||||||
string? imageTypePath = null;
|
|
||||||
|
|
||||||
switch (imageType)
|
|
||||||
{
|
|
||||||
case MetadataImageType.cover:
|
|
||||||
if (gameObject.Cover != null)
|
if (gameObject.Cover != null)
|
||||||
{
|
{
|
||||||
if (gameObject.Cover.Id != null)
|
if (gameObject.Cover.Id != null)
|
||||||
{
|
{
|
||||||
IGDB.Models.Cover cover = Classes.Metadata.Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), false);
|
IGDB.Models.Cover cover = Classes.Metadata.Covers.GetCover(gameObject.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), false);
|
||||||
imageId = cover.ImageId;
|
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Covers");
|
||||||
imageTypePath = "Covers";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MetadataImageType.screenshots:
|
|
||||||
if (gameObject.Screenshots != null)
|
|
||||||
{
|
|
||||||
if (gameObject.Screenshots.Ids.Contains(ImageId))
|
|
||||||
{
|
|
||||||
IGDB.Models.Screenshot imageObject = Screenshots.GetScreenshot(ImageId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
|
||||||
|
|
||||||
imageId = imageObject.ImageId;
|
|
||||||
imageTypePath = "Screenshots";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MetadataImageType.artwork:
|
|
||||||
if (gameObject.Artworks != null)
|
|
||||||
{
|
|
||||||
if (gameObject.Artworks.Ids.Contains(ImageId))
|
|
||||||
{
|
|
||||||
IGDB.Models.Artwork imageObject = Artworks.GetArtwork(ImageId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
|
||||||
|
|
||||||
imageId = imageObject.ImageId;
|
|
||||||
imageTypePath = "Artwork";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (imageId == null)
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), imageTypePath);
|
|
||||||
string imagePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), imageTypePath, size.ToString(), imageId + ".jpg");
|
|
||||||
|
|
||||||
if (!System.IO.File.Exists(imagePath))
|
|
||||||
{
|
|
||||||
Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
Task<string> ImgFetch = comms.GetSpecificImageFromServer(Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), imageTypePath), imageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, cover.ImageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
||||||
|
|
||||||
imagePath = ImgFetch.Result;
|
string coverFilePath = ImgFetch.Result;
|
||||||
}
|
|
||||||
|
|
||||||
if (!System.IO.File.Exists(imagePath))
|
if (System.IO.File.Exists(coverFilePath))
|
||||||
{
|
{
|
||||||
Communications comms = new Communications();
|
string filename = cover.ImageId + ".jpg";
|
||||||
Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, imageId, size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.cover_big, Communications.IGDBAPI_ImageSize.original });
|
string filepath = coverFilePath;
|
||||||
|
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||||
imagePath = ImgFetch.Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (System.IO.File.Exists(imagePath))
|
|
||||||
{
|
|
||||||
string filename = imageId + ".jpg";
|
|
||||||
string filepath = imagePath;
|
|
||||||
string contentType = "image/jpg";
|
string contentType = "image/jpg";
|
||||||
|
|
||||||
var cd = new System.Net.Mime.ContentDisposition
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
@@ -602,18 +601,10 @@ namespace gaseous_server.Controllers
|
|||||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||||
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
||||||
|
|
||||||
byte[] filedata = null;
|
|
||||||
using (FileStream fs = System.IO.File.OpenRead(filepath))
|
|
||||||
{
|
|
||||||
using (BinaryReader binaryReader = new BinaryReader(fs))
|
|
||||||
{
|
|
||||||
filedata = binaryReader.ReadBytes((int)fs.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return File(filedata, contentType);
|
return File(filedata, contentType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -622,13 +613,6 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MetadataImageType
|
|
||||||
{
|
|
||||||
cover,
|
|
||||||
screenshots,
|
|
||||||
artwork
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
@@ -876,146 +860,17 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{GameId}/emulatorconfiguration/{PlatformId}")]
|
|
||||||
[Authorize]
|
|
||||||
[ProducesResponseType(typeof(UserEmulatorConfiguration), StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult> GetGameEmulator(long GameId, long PlatformId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
|
||||||
|
|
||||||
if (gameObject != null)
|
|
||||||
{
|
|
||||||
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
|
||||||
|
|
||||||
if (platformObject != null)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
PlatformMapping platformMapping = new PlatformMapping();
|
|
||||||
UserEmulatorConfiguration platformMappingObject = platformMapping.GetUserEmulator(user.Id, GameId, PlatformId);
|
|
||||||
|
|
||||||
if (platformMappingObject != null)
|
|
||||||
{
|
|
||||||
return Ok(platformMappingObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpPost]
|
|
||||||
[Route("{GameId}/emulatorconfiguration/{PlatformId}")]
|
|
||||||
[Authorize]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult> SetGameEmulator(long GameId, long PlatformId, UserEmulatorConfiguration configuration)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
|
||||||
|
|
||||||
if (gameObject != null)
|
|
||||||
{
|
|
||||||
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
|
||||||
|
|
||||||
if (platformObject != null)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
PlatformMapping platformMapping = new PlatformMapping();
|
|
||||||
platformMapping.SetUserEmulator(user.Id, GameId, PlatformId, configuration);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpDelete]
|
|
||||||
[Route("{GameId}/emulatorconfiguration/{PlatformId}")]
|
|
||||||
[Authorize]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult> DeleteGameEmulator(long GameId, long PlatformId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
|
||||||
|
|
||||||
if (gameObject != null)
|
|
||||||
{
|
|
||||||
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
|
||||||
|
|
||||||
if (platformObject != null)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
PlatformMapping platformMapping = new PlatformMapping();
|
|
||||||
platformMapping.DeleteUserEmulator(user.Id, GameId, PlatformId);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{GameId}/platforms")]
|
[Route("{GameId}/platforms")]
|
||||||
[ProducesResponseType(typeof(List<Games.AvailablePlatformItem>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(List<KeyValuePair<long, string>>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GamePlatforms(long GameId)
|
public async Task<ActionResult> GamePlatforms(long GameId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
return Ok(Games.GetAvailablePlatforms(GameId));
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
return Ok(Games.GetAvailablePlatforms(user.Id, GameId));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -1173,67 +1028,6 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpPost]
|
|
||||||
[Route("{GameId}/roms/{RomId}/{PlatformId}/favourite")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public async Task<ActionResult> GameRomFavourite(long GameId, long RomId, long PlatformId, bool IsMediaGroup, bool favourite)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ApplicationUser? user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
|
||||||
|
|
||||||
if (IsMediaGroup == false)
|
|
||||||
{
|
|
||||||
Classes.Roms.GameRomItem rom = Classes.Roms.GetRom(RomId);
|
|
||||||
if (rom.GameId == GameId)
|
|
||||||
{
|
|
||||||
if (favourite == true)
|
|
||||||
{
|
|
||||||
Classes.Metadata.Games.GameSetFavouriteRom(user.Id, GameId, PlatformId, RomId, IsMediaGroup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Classes.Metadata.Games.GameClearFavouriteRom(user.Id, GameId, PlatformId);
|
|
||||||
}
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Classes.RomMediaGroup.GameRomMediaGroupItem rom = Classes.RomMediaGroup.GetMediaGroup(RomId, user.Id);
|
|
||||||
if (rom.GameId == GameId)
|
|
||||||
{
|
|
||||||
if (favourite == true)
|
|
||||||
{
|
|
||||||
Classes.Metadata.Games.GameSetFavouriteRom(user.Id, GameId, PlatformId, RomId, IsMediaGroup);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Classes.Metadata.Games.GameClearFavouriteRom(user.Id, GameId, PlatformId);
|
|
||||||
}
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -1346,10 +1140,11 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
[Authorize(Roles = "Admin,Gamer")]
|
||||||
[Route("{GameId}/romgroup")]
|
[Route("{GameId}/romgroup")]
|
||||||
[ProducesResponseType(typeof(List<RomMediaGroup.GameRomMediaGroupItem>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(List<RomMediaGroup.GameRomMediaGroupItem>), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GetGameRomGroupAsync(long GameId, long? PlatformId = null)
|
public async Task<ActionResult> GetGameRomGroupAsync(long GameId)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
@@ -1359,7 +1154,7 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ok(RomMediaGroup.GetMediaGroupsFromGameId(GameId, user.Id, PlatformId));
|
return Ok(RomMediaGroup.GetMediaGroupsFromGameId(GameId, user.Id));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -1619,56 +1414,56 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
// [MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
// [HttpGet]
|
[HttpGet]
|
||||||
// [Route("{GameId}/screenshots/{ScreenshotId}/image/{size}")]
|
[Route("{GameId}/screenshots/{ScreenshotId}/image/{size}")]
|
||||||
// [Route("{GameId}/screenshots/{ScreenshotId}/image/{size}/{ImageName}")]
|
[Route("{GameId}/screenshots/{ScreenshotId}/image/{size}/{ImageName}")]
|
||||||
// [ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
// [ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
// public async Task<ActionResult> GameScreenshotImage(long GameId, long ScreenshotId, Communications.IGDBAPI_ImageSize Size, string ImageName)
|
public async Task<ActionResult> GameScreenshotImage(long GameId, long ScreenshotId, Communications.IGDBAPI_ImageSize Size, string ImageName)
|
||||||
// {
|
{
|
||||||
// try
|
try
|
||||||
// {
|
{
|
||||||
// IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
|
||||||
// IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
||||||
|
|
||||||
// string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Screenshots");
|
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), "Screenshots");
|
||||||
|
|
||||||
// Communications comms = new Communications();
|
Communications comms = new Communications();
|
||||||
// Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, screenshotObject.ImageId, Size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.original });
|
Task<string> ImgFetch = comms.GetSpecificImageFromServer(basePath, screenshotObject.ImageId, Size, new List<Communications.IGDBAPI_ImageSize> { Communications.IGDBAPI_ImageSize.original });
|
||||||
|
|
||||||
// string coverFilePath = ImgFetch.Result;
|
string coverFilePath = ImgFetch.Result;
|
||||||
|
|
||||||
// if (System.IO.File.Exists(coverFilePath))
|
if (System.IO.File.Exists(coverFilePath))
|
||||||
// {
|
{
|
||||||
// string filename = screenshotObject.ImageId + ".jpg";
|
string filename = screenshotObject.ImageId + ".jpg";
|
||||||
// string filepath = coverFilePath;
|
string filepath = coverFilePath;
|
||||||
// byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||||
// string contentType = "image/jpg";
|
string contentType = "image/jpg";
|
||||||
|
|
||||||
// var cd = new System.Net.Mime.ContentDisposition
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
// {
|
{
|
||||||
// FileName = filename,
|
FileName = filename,
|
||||||
// Inline = true,
|
Inline = true,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// Response.Headers.Add("Content-Disposition", cd.ToString());
|
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||||
// Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
||||||
|
|
||||||
// return File(filedata, contentType);
|
return File(filedata, contentType);
|
||||||
// }
|
}
|
||||||
// else
|
else
|
||||||
// {
|
{
|
||||||
// return NotFound();
|
return NotFound();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// catch
|
catch
|
||||||
// {
|
{
|
||||||
// return NotFound();
|
return NotFound();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
|
@@ -11,7 +11,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
public class LibraryController : Controller
|
public class LibraryController : Controller
|
||||||
@@ -86,24 +86,5 @@ namespace gaseous_server.Controllers
|
|||||||
return NotFound(exLNF.ToString());
|
return NotFound(exLNF.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpPost("{LibraryId}/Scan")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public ActionResult ScanLibrary(int LibraryId)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GameLibrary.ScanLibrary(LibraryId);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (GameLibrary.LibraryNotFound exLNF)
|
|
||||||
{
|
|
||||||
return NotFound(exLNF.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -11,7 +11,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
public class LogsController : Controller
|
public class LogsController : Controller
|
||||||
|
@@ -19,7 +19,7 @@ using Asp.Versioning;
|
|||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
@@ -149,6 +149,35 @@ namespace gaseous_server.Controllers
|
|||||||
return Ok(new { count = files.Count, size });
|
return Ok(new { count = files.Count, size });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// [MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpPost]
|
||||||
|
// [Route("{PlatformId}")]
|
||||||
|
// [ProducesResponseType(typeof(PlatformMapping.PlatformMapItem), StatusCodes.Status200OK)]
|
||||||
|
// [ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
// [ProducesResponseType(StatusCodes.Status409Conflict)]
|
||||||
|
// public ActionResult NewPlatformMap(long PlatformId, PlatformMapping.PlatformMapItem Map)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(PlatformId);
|
||||||
|
|
||||||
|
// if (platformMapItem != null)
|
||||||
|
// {
|
||||||
|
// return Conflict();
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// PlatformMapping.WritePlatformMap(Map, false, false);
|
||||||
|
// return Ok(PlatformMapping.GetPlatformMap(PlatformId));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch
|
||||||
|
// {
|
||||||
|
// return NotFound();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpPatch]
|
[HttpPatch]
|
||||||
|
@@ -18,7 +18,7 @@ using Asp.Versioning;
|
|||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@@ -37,7 +37,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
string sql = "SELECT * FROM Platform WHERE Id IN (SELECT DISTINCT PlatformId FROM view_Games_Roms) ORDER BY `Name` ASC;";
|
string sql = "SELECT * FROM Platform WHERE Id IN (SELECT DISTINCT PlatformId FROM Games_Roms) ORDER BY `Name` ASC;";
|
||||||
|
|
||||||
List<Platform> RetVal = new List<Platform>();
|
List<Platform> RetVal = new List<Platform>();
|
||||||
|
|
||||||
@@ -114,64 +114,22 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("{PlatformId}/platformlogo/{size}/logo.png")]
|
[Route("{PlatformId}/platformlogo/image")]
|
||||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> GameImage(long PlatformId, Communications.IGDBAPI_ImageSize size)
|
public ActionResult PlatformLogoImage(long PlatformId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
IGDB.Models.Platform platformObject = Classes.Metadata.Platforms.GetPlatform(PlatformId);
|
||||||
IGDB.Models.PlatformLogo? logoObject = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logoObject = PlatformLogos.GetPlatformLogo(platformObject.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// getting the logo failed, so we'll try a platform variant if available
|
|
||||||
if (platformObject.Versions != null)
|
|
||||||
{
|
|
||||||
if (platformObject.Versions.Ids.Length > 0)
|
|
||||||
{
|
|
||||||
IGDB.Models.PlatformVersion platformVersion = Classes.Metadata.PlatformVersions.GetPlatformVersion(platformObject.Versions.Ids[0], platformObject);
|
|
||||||
logoObject = PlatformLogos.GetPlatformLogo(platformVersion.PlatformLogo.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string basePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject));
|
string logoFilePath = Path.Combine(Config.LibraryConfiguration.LibraryMetadataDirectory_Platform(platformObject), "Logo_Medium.png");
|
||||||
string imagePath = Path.Combine(basePath, size.ToString(), logoObject.ImageId + ".jpg");
|
if (System.IO.File.Exists(logoFilePath))
|
||||||
|
|
||||||
if (!System.IO.File.Exists(imagePath))
|
|
||||||
{
|
{
|
||||||
Communications comms = new Communications();
|
string filename = "Logo.png";
|
||||||
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 });
|
string filepath = logoFilePath;
|
||||||
|
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||||
imagePath = ImgFetch.Result;
|
string contentType = "image/png";
|
||||||
}
|
|
||||||
|
|
||||||
if (!System.IO.File.Exists(imagePath))
|
|
||||||
{
|
|
||||||
Communications comms = new Communications();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (System.IO.File.Exists(imagePath))
|
|
||||||
{
|
|
||||||
string filename = logoObject.ImageId + ".jpg";
|
|
||||||
string filepath = imagePath;
|
|
||||||
string contentType = "image/jpg";
|
|
||||||
|
|
||||||
var cd = new System.Net.Mime.ContentDisposition
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
{
|
{
|
||||||
@@ -180,22 +138,14 @@ namespace gaseous_server.Controllers
|
|||||||
};
|
};
|
||||||
|
|
||||||
Response.Headers.Add("Content-Disposition", cd.ToString());
|
Response.Headers.Add("Content-Disposition", cd.ToString());
|
||||||
Response.Headers.Add("Cache-Control", "public, max-age=604800");
|
|
||||||
|
|
||||||
byte[] filedata = null;
|
|
||||||
using (FileStream fs = System.IO.File.OpenRead(filepath))
|
|
||||||
{
|
|
||||||
using (BinaryReader binaryReader = new BinaryReader(fs))
|
|
||||||
{
|
|
||||||
filedata = binaryReader.ReadBytes((int)fs.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return File(filedata, contentType);
|
return File(filedata, contentType);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@@ -19,7 +19,7 @@ using Asp.Versioning;
|
|||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@@ -31,34 +31,41 @@ namespace gaseous_server.Controllers
|
|||||||
[Authorize(Roles = "Admin,Gamer")]
|
[Authorize(Roles = "Admin,Gamer")]
|
||||||
[ProducesResponseType(typeof(List<IFormFile>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(List<IFormFile>), StatusCodes.Status200OK)]
|
||||||
[RequestSizeLimit(long.MaxValue)]
|
[RequestSizeLimit(long.MaxValue)]
|
||||||
[Consumes("multipart/form-data")]
|
|
||||||
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue, ValueLengthLimit = int.MaxValue)]
|
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue, ValueLengthLimit = int.MaxValue)]
|
||||||
public async Task<IActionResult> UploadRom(IFormFile file, long? OverridePlatformId = null)
|
public async Task<IActionResult> UploadRom(List<IFormFile> files, long? OverridePlatformId = null)
|
||||||
{
|
{
|
||||||
Guid sessionid = Guid.NewGuid();
|
Guid sessionid = Guid.NewGuid();
|
||||||
|
|
||||||
string workPath = Path.Combine(Config.LibraryConfiguration.LibraryUploadDirectory, sessionid.ToString());
|
string workPath = Path.Combine(Config.LibraryConfiguration.LibraryUploadDirectory, sessionid.ToString());
|
||||||
|
|
||||||
if (file.Length > 0)
|
long size = files.Sum(f => f.Length);
|
||||||
|
|
||||||
|
List<Dictionary<string, object>> UploadedFiles = new List<Dictionary<string, object>>();
|
||||||
|
|
||||||
|
foreach (IFormFile formFile in files)
|
||||||
|
{
|
||||||
|
if (formFile.Length > 0)
|
||||||
{
|
{
|
||||||
Guid FileId = Guid.NewGuid();
|
Guid FileId = Guid.NewGuid();
|
||||||
|
|
||||||
string filePath = Path.Combine(workPath, Path.GetFileName(file.FileName));
|
string filePath = Path.Combine(workPath, Path.GetFileName(formFile.FileName));
|
||||||
|
|
||||||
if (!Directory.Exists(workPath))
|
if (!Directory.Exists(workPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(workPath);
|
Directory.CreateDirectory(workPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<string, object> UploadedFile = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
using (var stream = System.IO.File.Create(filePath))
|
using (var stream = System.IO.File.Create(filePath))
|
||||||
{
|
{
|
||||||
await file.CopyToAsync(stream);
|
await formFile.CopyToAsync(stream);
|
||||||
|
|
||||||
|
Dictionary<string, object> UploadedFile = new Dictionary<string, object>();
|
||||||
UploadedFile.Add("id", FileId.ToString());
|
UploadedFile.Add("id", FileId.ToString());
|
||||||
UploadedFile.Add("originalname", Path.GetFileName(file.FileName));
|
UploadedFile.Add("originalname", Path.GetFileName(formFile.FileName));
|
||||||
UploadedFile.Add("fullpath", filePath);
|
UploadedFile.Add("fullpath", filePath);
|
||||||
|
UploadedFiles.Add(UploadedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get override platform if specified
|
// get override platform if specified
|
||||||
@@ -68,22 +75,11 @@ namespace gaseous_server.Controllers
|
|||||||
OverridePlatform = Platforms.GetPlatform((long)OverridePlatformId);
|
OverridePlatform = Platforms.GetPlatform((long)OverridePlatformId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process uploaded file
|
// Process uploaded files
|
||||||
|
foreach (Dictionary<string, object> UploadedFile in UploadedFiles)
|
||||||
|
{
|
||||||
Classes.ImportGame uploadImport = new ImportGame();
|
Classes.ImportGame uploadImport = new ImportGame();
|
||||||
Dictionary<string, object> RetVal = uploadImport.ImportGameFile((string)UploadedFile["fullpath"], OverridePlatform);
|
uploadImport.ImportGameFile((string)UploadedFile["fullpath"], OverridePlatform);
|
||||||
switch (RetVal["type"])
|
|
||||||
{
|
|
||||||
case "rom":
|
|
||||||
if (RetVal["status"] == "imported")
|
|
||||||
{
|
|
||||||
IGDB.Models.Game? game = (IGDB.Models.Game)RetVal["game"];
|
|
||||||
if (game.Id == null)
|
|
||||||
{
|
|
||||||
RetVal["game"] = Games.GetGame(0, false, false, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Directory.Exists(workPath))
|
if (Directory.Exists(workPath))
|
||||||
@@ -91,10 +87,7 @@ namespace gaseous_server.Controllers
|
|||||||
Directory.Delete(workPath, true);
|
Directory.Delete(workPath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(RetVal);
|
return Ok(new { count = files.Count, size });
|
||||||
}
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -18,7 +18,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class SearchController : Controller
|
public class SearchController : Controller
|
||||||
@@ -73,6 +73,7 @@ namespace gaseous_server.Controllers
|
|||||||
private static async Task<List<GaseousGame>> _SearchForGame(long PlatformId, string SearchString)
|
private static async Task<List<GaseousGame>> _SearchForGame(long PlatformId, string SearchString)
|
||||||
{
|
{
|
||||||
string searchBody = "";
|
string searchBody = "";
|
||||||
|
// string searchFields = "fields cover,first_release_date,name,platforms,slug; ";
|
||||||
string searchFields = "fields *; ";
|
string searchFields = "fields *; ";
|
||||||
searchBody += "search \"" + SearchString + "\";";
|
searchBody += "search \"" + SearchString + "\";";
|
||||||
searchBody += "where platforms = (" + PlatformId + ");";
|
searchBody += "where platforms = (" + PlatformId + ");";
|
||||||
|
@@ -17,7 +17,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]/[action]")]
|
[Route("api/v{version:apiVersion}/[controller]/[action]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class SignaturesController : Controller
|
public class SignaturesController : Controller
|
||||||
|
@@ -19,7 +19,7 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class SystemController : Controller
|
public class SystemController : Controller
|
||||||
@@ -38,10 +38,7 @@ namespace gaseous_server.Controllers
|
|||||||
List<SystemInfo.PathItem> Disks = new List<SystemInfo.PathItem>();
|
List<SystemInfo.PathItem> Disks = new List<SystemInfo.PathItem>();
|
||||||
foreach (GameLibrary.LibraryItem libraryItem in GameLibrary.GetLibraries)
|
foreach (GameLibrary.LibraryItem libraryItem in GameLibrary.GetLibraries)
|
||||||
{
|
{
|
||||||
SystemInfo.PathItem pathItem = GetDisk(libraryItem.Path);
|
Disks.Add(GetDisk(libraryItem.Path));
|
||||||
pathItem.Name = libraryItem.Name;
|
|
||||||
|
|
||||||
Disks.Add(pathItem);
|
|
||||||
}
|
}
|
||||||
ReturnValue.Paths = Disks;
|
ReturnValue.Paths = Disks;
|
||||||
|
|
||||||
@@ -51,7 +48,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 = "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`;";
|
sql = "SELECT Platform.`name`, grc.Count, grs.Size FROM Platform INNER JOIN (SELECT Platform.`name` AS `Name`, SUM(grs.Size) AS Size FROM Platform JOIN Games_Roms AS grs ON (grs.PlatformId = Platform.Id) GROUP BY Platform.`name`) grs ON (grs.`Name` = Platform.`name`) INNER JOIN (SELECT Platform.`name` AS `Name`, COUNT(grc.Size) AS Count FROM Platform JOIN Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;";
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
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)
|
||||||
@@ -264,13 +261,12 @@ namespace gaseous_server.Controllers
|
|||||||
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
||||||
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention,
|
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention,
|
||||||
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString())),
|
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString())),
|
||||||
SignatureSource = new SystemSettingsModel.SignatureSourceItem()
|
SearchTypes = Config.ReadSetting<List<Classes.Metadata.Games.SearchType>>("DefaultSearchMethods", new List<gaseous_server.Classes.Metadata.Games.SearchType>() {
|
||||||
{
|
Games.SearchType.where,
|
||||||
Source = Config.MetadataConfiguration.SignatureSource,
|
Games.SearchType.wherefuzzy,
|
||||||
HasheousHost = Config.MetadataConfiguration.HasheousHost,
|
Games.SearchType.search,
|
||||||
HasheousSubmitFixes = (bool)Config.MetadataConfiguration.HasheousSubmitFixes,
|
Games.SearchType.searchNoPlatform
|
||||||
HasheousAPIKey = Config.MetadataConfiguration.HasheousAPIKey
|
})
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(systemSettingsModel);
|
return Ok(systemSettingsModel);
|
||||||
@@ -289,10 +285,7 @@ namespace gaseous_server.Controllers
|
|||||||
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
||||||
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
||||||
Config.SetSetting<string>("emulatorDebugMode", model.EmulatorDebugMode.ToString());
|
Config.SetSetting<string>("emulatorDebugMode", model.EmulatorDebugMode.ToString());
|
||||||
Config.MetadataConfiguration.SignatureSource = model.SignatureSource.Source;
|
Config.SetSetting<List<Classes.Metadata.Games.SearchType>>("DefaultSearchMethods", model.SearchTypes);
|
||||||
Config.MetadataConfiguration.HasheousHost = model.SignatureSource.HasheousHost;
|
|
||||||
Config.MetadataConfiguration.HasheousAPIKey = model.SignatureSource.HasheousAPIKey;
|
|
||||||
Config.MetadataConfiguration.HasheousSubmitFixes = model.SignatureSource.HasheousSubmitFixes;
|
|
||||||
Config.UpdateConfig();
|
Config.UpdateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +320,6 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
public class PathItem
|
public class PathItem
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
|
||||||
public string LibraryPath { get; set; }
|
public string LibraryPath { get; set; }
|
||||||
public long SpaceUsed { get; set; }
|
public long SpaceUsed { get; set; }
|
||||||
public long SpaceAvailable { get; set; }
|
public long SpaceAvailable { get; set; }
|
||||||
@@ -734,14 +726,6 @@ namespace gaseous_server.Controllers
|
|||||||
public bool AlwaysLogToDisk { get; set; }
|
public bool AlwaysLogToDisk { get; set; }
|
||||||
public int MinimumLogRetentionPeriod { get; set; }
|
public int MinimumLogRetentionPeriod { get; set; }
|
||||||
public bool EmulatorDebugMode { get; set; }
|
public bool EmulatorDebugMode { get; set; }
|
||||||
public SignatureSourceItem SignatureSource { get; set; }
|
public List<Classes.Metadata.Games.SearchType> SearchTypes { get; set; }
|
||||||
|
|
||||||
public class SignatureSourceItem
|
|
||||||
{
|
|
||||||
public HasheousClient.Models.MetadataModel.SignatureSources Source { get; set; }
|
|
||||||
public string HasheousHost { get; set; }
|
|
||||||
public string HasheousAPIKey { get; set; }
|
|
||||||
public bool HasheousSubmitFixes { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,80 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using gaseous_server.Classes;
|
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
using IGDB.Models;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.CodeAnalysis.Scripting;
|
|
||||||
using static gaseous_server.Classes.Metadata.AgeRatings;
|
|
||||||
using Asp.Versioning;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers.v1_1
|
|
||||||
{
|
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
|
||||||
[ApiVersion("1.1")]
|
|
||||||
[ApiController]
|
|
||||||
public class FileSystemController : ControllerBase
|
|
||||||
{
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpGet]
|
|
||||||
[Authorize(Roles = "Admin")]
|
|
||||||
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
public ActionResult GetFileSystem(string path, bool showFiles = false)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (path.Contains(".."))
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists(path))
|
|
||||||
{
|
|
||||||
Dictionary<string, List<Dictionary<string, string>>> allFiles = new Dictionary<string, List<Dictionary<string, string>>>();
|
|
||||||
List<Dictionary<string, string>> directories = new List<Dictionary<string, string>>();
|
|
||||||
string[] dirs = Directory.GetDirectories(path);
|
|
||||||
Array.Sort(dirs);
|
|
||||||
foreach (string dir in dirs)
|
|
||||||
{
|
|
||||||
DirectoryInfo directoryInfo = new DirectoryInfo(dir);
|
|
||||||
directories.Add(new Dictionary<string, string> { { "name", directoryInfo.Name }, { "path", directoryInfo.FullName } });
|
|
||||||
}
|
|
||||||
allFiles.Add("directories", directories);
|
|
||||||
|
|
||||||
if (showFiles == true)
|
|
||||||
{
|
|
||||||
List<Dictionary<string, string>> files = new List<Dictionary<string, string>>();
|
|
||||||
string[] filePaths = Directory.GetFiles(path);
|
|
||||||
Array.Sort(filePaths);
|
|
||||||
foreach (string file in filePaths)
|
|
||||||
{
|
|
||||||
FileInfo fileInfo = new FileInfo(file);
|
|
||||||
files.Add(new Dictionary<string, string> { { "name", fileInfo.Name }, { "path", fileInfo.FullName } });
|
|
||||||
}
|
|
||||||
allFiles.Add("files", files);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(allFiles);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -106,8 +106,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
string IncludeUnrated = "";
|
string IncludeUnrated = "";
|
||||||
if (user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated == true)
|
if (user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated == true) {
|
||||||
{
|
|
||||||
IncludeUnrated = " OR view_Games.AgeGroupId IS NULL";
|
IncludeUnrated = " OR view_Games.AgeGroupId IS NULL";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +302,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
string platformWhereClause = "";
|
string platformWhereClause = "";
|
||||||
if (model.Platform.Count > 0)
|
if (model.Platform.Count > 0)
|
||||||
{
|
{
|
||||||
tempVal = " AND view_Games_Roms.PlatformId IN (";
|
tempVal = " AND Games_Roms.PlatformId IN (";
|
||||||
for (int i = 0; i < model.Platform.Count; i++)
|
for (int i = 0; i < model.Platform.Count; i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
@@ -486,7 +485,6 @@ SELECT DISTINCT
|
|||||||
Game.`Name`,
|
Game.`Name`,
|
||||||
Game.NameThe,
|
Game.NameThe,
|
||||||
Game.Slug,
|
Game.Slug,
|
||||||
Game.Summary,
|
|
||||||
Game.PlatformId,
|
Game.PlatformId,
|
||||||
Game.TotalRating,
|
Game.TotalRating,
|
||||||
Game.TotalRatingCount,
|
Game.TotalRatingCount,
|
||||||
@@ -511,26 +509,26 @@ FROM
|
|||||||
WHEN Game.`Name` LIKE 'The %' THEN CONCAT(TRIM(SUBSTR(Game.`Name` FROM 4)), ', The')
|
WHEN Game.`Name` LIKE 'The %' THEN CONCAT(TRIM(SUBSTR(Game.`Name` FROM 4)), ', The')
|
||||||
ELSE Game.`Name`
|
ELSE Game.`Name`
|
||||||
END AS NameThe,
|
END AS NameThe,
|
||||||
view_Games_Roms.PlatformId,
|
Games_Roms.PlatformId,
|
||||||
AgeGroup.AgeGroupId,
|
AgeGroup.AgeGroupId,
|
||||||
COUNT(view_Games_Roms.Id) AS RomCount
|
COUNT(Games_Roms.Id) AS RomCount
|
||||||
FROM
|
FROM
|
||||||
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 Games_Roms ON Game.Id = Games_Roms.GameId" + platformWhereClause + @"
|
||||||
LEFT JOIN AlternativeName ON Game.Id = AlternativeName.Game " + nameWhereClause + @"
|
LEFT JOIN AlternativeName ON Game.Id = AlternativeName.Game " + nameWhereClause + @"
|
||||||
GROUP BY Game.Id
|
GROUP BY Game.Id
|
||||||
HAVING RomCount > 0) Game
|
HAVING RomCount > 0) Game
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
(SELECT
|
(SELECT
|
||||||
view_Games_Roms.GameId, COUNT(GameState.Id) AS RomSaveCount
|
Games_Roms.GameId, COUNT(GameState.Id) AS RomSaveCount
|
||||||
FROM
|
FROM
|
||||||
GameState
|
GameState
|
||||||
JOIN view_Games_Roms ON GameState.RomId = view_Games_Roms.Id
|
JOIN Games_Roms ON GameState.RomId = Games_Roms.Id
|
||||||
WHERE
|
WHERE
|
||||||
GameState.IsMediaGroup = 0
|
GameState.IsMediaGroup = 0
|
||||||
AND GameState.UserId = @userid
|
AND GameState.UserId = @userid
|
||||||
GROUP BY view_Games_Roms.GameId) RomSavedStates ON Game.Id = RomSavedStates.GameId
|
GROUP BY Games_Roms.GameId) RomSavedStates ON Game.Id = RomSavedStates.GameId
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
(SELECT
|
(SELECT
|
||||||
RomMediaGroup.GameId,
|
RomMediaGroup.GameId,
|
||||||
@@ -553,7 +551,7 @@ FROM
|
|||||||
Favourites ON Game.Id = 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>();
|
List<Games.MinimalGameItem> RetVal = new List<Games.MinimalGameItem>();
|
||||||
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, whereParams, new Database.DatabaseMemoryCacheOptions(CacheEnabled: true, ExpirationSeconds: 60));
|
DataTable dbResponse = db.ExecuteCMD(sql, whereParams);
|
||||||
|
|
||||||
// get count
|
// get count
|
||||||
int RecordCount = dbResponse.Rows.Count;
|
int RecordCount = dbResponse.Rows.Count;
|
||||||
@@ -595,44 +593,29 @@ FROM
|
|||||||
|
|
||||||
// build alpha list
|
// build alpha list
|
||||||
Dictionary<string, int> AlphaList = new Dictionary<string, int>();
|
Dictionary<string, int> AlphaList = new Dictionary<string, int>();
|
||||||
if (orderByField == "NameThe" || orderByField == "Name")
|
|
||||||
{
|
|
||||||
int CurrentPage = 1;
|
int CurrentPage = 1;
|
||||||
int NextPageIndex = pageSize;
|
int NextPageIndex = pageSize;
|
||||||
|
|
||||||
string alphaSearchField;
|
|
||||||
if (orderByField == "NameThe")
|
|
||||||
{
|
|
||||||
alphaSearchField = "NameThe";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alphaSearchField = "Name";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < dbResponse.Rows.Count; i++)
|
for (int i = 0; i < dbResponse.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
if (NextPageIndex == i + 1)
|
string firstChar = dbResponse.Rows[i]["NameThe"].ToString().Substring(0, 1).ToUpperInvariant();
|
||||||
{
|
if (!"ABCDEFGHIJKLMNOPQRSTUVWXYZ".Contains(firstChar))
|
||||||
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
|
|
||||||
{
|
{
|
||||||
if (!AlphaList.ContainsKey("#"))
|
if (!AlphaList.ContainsKey("#"))
|
||||||
{
|
{
|
||||||
AlphaList.Add("#", 1);
|
AlphaList.Add("#", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!AlphaList.ContainsKey(firstChar))
|
||||||
|
{
|
||||||
|
AlphaList.Add(firstChar, CurrentPage);
|
||||||
|
}
|
||||||
|
if (NextPageIndex == i + 1)
|
||||||
|
{
|
||||||
|
NextPageIndex += pageSize;
|
||||||
|
CurrentPage += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
gaseous-server/Controllers/V1.1/HealthCheckController.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Asp.Versioning;
|
||||||
|
|
||||||
|
namespace gaseous_server.Controllers.v1_1
|
||||||
|
{
|
||||||
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
|
[ApiVersion("1.1")]
|
||||||
|
[ApiController]
|
||||||
|
public class HealthCheckController : ControllerBase
|
||||||
|
{
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public ActionResult Healthcheck()
|
||||||
|
{
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7,12 +7,11 @@ using Microsoft.AspNetCore.Identity;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Asp.Versioning;
|
using Asp.Versioning;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using gaseous_server.Classes.Metadata;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers.v1_1
|
namespace gaseous_server.Controllers.v1_1
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class StateManagerController : ControllerBase
|
public class StateManagerController : ControllerBase
|
||||||
@@ -257,25 +256,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// get rom data
|
// get rom data
|
||||||
string romName = "";
|
|
||||||
string romMd5 = "";
|
|
||||||
string romSha1 = "";
|
|
||||||
if (IsMediaGroup == false)
|
|
||||||
{
|
|
||||||
Roms.GameRomItem romItem = Roms.GetRom(RomId);
|
Roms.GameRomItem romItem = Roms.GetRom(RomId);
|
||||||
romName = romItem.Name;
|
|
||||||
romMd5 = romItem.Md5;
|
|
||||||
romSha1 = romItem.Sha1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RomMediaGroup.GameRomMediaGroupItem mediaGroupItem = RomMediaGroup.GetMediaGroup(RomId);
|
|
||||||
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"));
|
|
||||||
romName = game.Name;
|
|
||||||
romMd5 = hashObject.md5hash;
|
|
||||||
romSha1 = hashObject.sha1hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
if ((bool)data.Rows[0]["Zipped"] == false)
|
if ((bool)data.Rows[0]["Zipped"] == false)
|
||||||
@@ -286,8 +267,9 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
{
|
{
|
||||||
bytes = Common.Decompress((byte[])data.Rows[0]["State"]);
|
bytes = Common.Decompress((byte[])data.Rows[0]["State"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
string contentType = "";
|
string contentType = "";
|
||||||
string filename = ((DateTime)data.Rows[0]["StateDateTime"]).ToString("yyyy-MM-ddTHH-mm-ss") + "-" + Path.GetFileNameWithoutExtension(romName);
|
string filename = ((DateTime)data.Rows[0]["StateDateTime"]).ToString("yyyy-MM-ddTHH-mm-ss") + "-" + Path.GetFileNameWithoutExtension(romItem.Name);
|
||||||
|
|
||||||
|
|
||||||
if (StateOnly == true)
|
if (StateOnly == true)
|
||||||
@@ -302,14 +284,14 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
|
|
||||||
Dictionary<string, object> RomInfo = new Dictionary<string, object>
|
Dictionary<string, object> RomInfo = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "Name", romName },
|
{ "Name", romItem.Name },
|
||||||
{ "StateDateTime", data.Rows[0]["StateDateTime"] },
|
{ "StateDateTime", data.Rows[0]["StateDateTime"] },
|
||||||
{ "StateName", data.Rows[0]["Name"] }
|
{ "StateName", data.Rows[0]["Name"] }
|
||||||
};
|
};
|
||||||
if ((int)data.Rows[0]["IsMediaGroup"] == 0)
|
if ((int)data.Rows[0]["IsMediaGroup"] == 0)
|
||||||
{
|
{
|
||||||
RomInfo.Add("MD5", romMd5);
|
RomInfo.Add("MD5", romItem.Md5);
|
||||||
RomInfo.Add("SHA1", romSha1);
|
RomInfo.Add("SHA1", romItem.Sha1);
|
||||||
RomInfo.Add("Type", "ROM");
|
RomInfo.Add("Type", "ROM");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -9,7 +9,7 @@ using Asp.Versioning;
|
|||||||
namespace gaseous_server.Controllers.v1_1
|
namespace gaseous_server.Controllers.v1_1
|
||||||
{
|
{
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
[Route("api/v{version:apiVersion}/[controller]")]
|
||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0", Deprecated = true)]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class StatisticsController : ControllerBase
|
public class StatisticsController : ControllerBase
|
||||||
@@ -32,15 +32,15 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
[ProducesResponseType(typeof(Models.StatisticsModel), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(Models.StatisticsModel), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[Route("Games/{GameId}/{PlatformId}/{RomId}")]
|
[Route("Games/{GameId}/")]
|
||||||
public async Task<ActionResult> NewRecordStatistics(long GameId, long PlatformId, long RomId, bool IsMediaGroup)
|
public async Task<ActionResult> NewRecordStatistics(long GameId)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
Statistics statistics = new Statistics();
|
Statistics statistics = new Statistics();
|
||||||
return Ok(statistics.RecordSession(Guid.Empty, GameId, PlatformId, RomId, IsMediaGroup, user.Id));
|
return Ok(statistics.RecordSession(Guid.Empty, GameId, user.Id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -54,15 +54,15 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
[ProducesResponseType(typeof(Models.StatisticsModel), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(Models.StatisticsModel), StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[Route("Games/{GameId}/{PlatformId}/{RomId}/{SessionId}")]
|
[Route("Games/{GameId}/{SessionId}")]
|
||||||
public async Task<ActionResult> SubsequentRecordStatistics(long GameId, long PlatformId, long RomId, Guid SessionId, bool IsMediaGroup)
|
public async Task<ActionResult> SubsequentRecordStatistics(long GameId, Guid SessionId)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
Statistics statistics = new Statistics();
|
Statistics statistics = new Statistics();
|
||||||
return Ok(statistics.RecordSession(SessionId, GameId, PlatformId, RomId, IsMediaGroup, user.Id));
|
return Ok(statistics.RecordSession(SessionId, GameId, user.Id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -1,137 +0,0 @@
|
|||||||
using Asp.Versioning;
|
|
||||||
using Authentication;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Identity;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
|
||||||
{
|
|
||||||
[ApiController]
|
|
||||||
[Route("api/v{version:apiVersion}/[controller]")]
|
|
||||||
[ApiVersion("1.0")]
|
|
||||||
[ApiVersion("1.1")]
|
|
||||||
[Authorize]
|
|
||||||
public class UserProfileController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
|
||||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
|
||||||
|
|
||||||
public UserProfileController(
|
|
||||||
UserManager<ApplicationUser> userManager,
|
|
||||||
SignInManager<ApplicationUser> signInManager
|
|
||||||
)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_signInManager = signInManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{UserId}")]
|
|
||||||
[ProducesResponseType(typeof(Models.UserProfile), StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
||||||
[ResponseCache(CacheProfileName = "Default30")]
|
|
||||||
public ActionResult GetUserProfile(string UserId)
|
|
||||||
{
|
|
||||||
Classes.UserProfile profile = new Classes.UserProfile();
|
|
||||||
Models.UserProfile RetVal = profile.GetUserProfile(UserId);
|
|
||||||
return Ok(RetVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpPut]
|
|
||||||
[Route("{UserId}")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
public async Task<ActionResult> UpdateUserProfileAsync(string UserId, Models.UserProfile profile)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user.ProfileId.ToString() != UserId)
|
|
||||||
{
|
|
||||||
return Unauthorized();
|
|
||||||
}
|
|
||||||
|
|
||||||
Classes.UserProfile userProfile = new Classes.UserProfile();
|
|
||||||
userProfile.UpdateUserProfile(user.Id, profile);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpPut]
|
|
||||||
[ProducesResponseType(typeof(List<IFormFile>), StatusCodes.Status200OK)]
|
|
||||||
[RequestSizeLimit(long.MaxValue)]
|
|
||||||
[Consumes("multipart/form-data")]
|
|
||||||
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue, ValueLengthLimit = int.MaxValue)]
|
|
||||||
[Route("{UserId}/{ProfileImageType}")]
|
|
||||||
public async Task<ActionResult> UpdateAvatarAsync(string UserId, Classes.UserProfile.ImageType ProfileImageType, IFormFile file)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user.ProfileId.ToString() != UserId)
|
|
||||||
{
|
|
||||||
return Unauthorized();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.Length > 0)
|
|
||||||
{
|
|
||||||
using (var ms = new MemoryStream())
|
|
||||||
{
|
|
||||||
file.CopyTo(ms);
|
|
||||||
byte[] fileBytes = ms.ToArray();
|
|
||||||
|
|
||||||
Classes.UserProfile userProfile = new Classes.UserProfile();
|
|
||||||
userProfile.UpdateImage(ProfileImageType, UserId, user.Id, file.FileName, fileBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpGet]
|
|
||||||
[Route("{UserId}/{ProfileImageType}")]
|
|
||||||
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
||||||
[ResponseCache(CacheProfileName = "5Minute")]
|
|
||||||
public async Task<ActionResult> GetAvatarAsync(string UserId, Classes.UserProfile.ImageType ProfileImageType)
|
|
||||||
{
|
|
||||||
Classes.UserProfile userProfile = new Classes.UserProfile();
|
|
||||||
|
|
||||||
Models.ImageItem image = userProfile.GetImage(ProfileImageType, UserId);
|
|
||||||
|
|
||||||
if (image == null)
|
|
||||||
{
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return File(image.content, image.mimeType, UserId + image.extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[MapToApiVersion("1.1")]
|
|
||||||
[HttpDelete]
|
|
||||||
[Route("{UserId}/{ProfileImageType}")]
|
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
||||||
public async Task<ActionResult> DeleteAvatarAsync(string UserId, Classes.UserProfile.ImageType ProfileImageType)
|
|
||||||
{
|
|
||||||
var user = await _userManager.GetUserAsync(User);
|
|
||||||
|
|
||||||
if (user.ProfileId.ToString() != UserId)
|
|
||||||
{
|
|
||||||
return Unauthorized();
|
|
||||||
}
|
|
||||||
|
|
||||||
Classes.UserProfile userProfile = new Classes.UserProfile();
|
|
||||||
userProfile.DeleteImage(ProfileImageType, user.Id);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -44,6 +44,8 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
Id = this.Cover.Id
|
Id = this.Cover.Id
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +0,0 @@
|
|||||||
namespace gaseous_server.Models
|
|
||||||
{
|
|
||||||
public class ImageItem
|
|
||||||
{
|
|
||||||
public byte[] content { get; set; }
|
|
||||||
public string mimeType { get; set; }
|
|
||||||
public string extension { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@@ -15,6 +15,8 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
public class PlatformMapping
|
public class PlatformMapping
|
||||||
{
|
{
|
||||||
|
private static Dictionary<string, PlatformMapItem> PlatformMapCache = new Dictionary<string, PlatformMapItem>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the platform map from the embedded platform map resource
|
/// Updates the platform map from the embedded platform map resource
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -72,8 +74,8 @@ namespace gaseous_server.Models
|
|||||||
|
|
||||||
foreach (PlatformMapItem mapItem in platforms)
|
foreach (PlatformMapItem mapItem in platforms)
|
||||||
{
|
{
|
||||||
// insert dummy platform data - it'll be cleaned up on the first metadata refresh
|
// get the IGDB platform data
|
||||||
Platform platform = CreateDummyPlatform(mapItem);
|
Platform platform = Platforms.GetPlatform(mapItem.IGDBId, false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -92,57 +94,49 @@ namespace gaseous_server.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDB.Models.Platform CreateDummyPlatform(PlatformMapItem mapItem)
|
|
||||||
{
|
|
||||||
IGDB.Models.Platform platform = new IGDB.Models.Platform
|
|
||||||
{
|
|
||||||
Id = mapItem.IGDBId,
|
|
||||||
Name = mapItem.IGDBName,
|
|
||||||
Slug = mapItem.IGDBSlug,
|
|
||||||
AlternativeName = mapItem.AlternateNames.FirstOrDefault()
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Storage.GetCacheStatus("Platform", mapItem.IGDBId) == Storage.CacheStatus.NotPresent)
|
|
||||||
{
|
|
||||||
Storage.NewCacheValue(platform);
|
|
||||||
}
|
|
||||||
|
|
||||||
return platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<PlatformMapItem> PlatformMap
|
public static List<PlatformMapItem> PlatformMap
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// if (Database.DatabaseMemoryCache.GetCacheObject("PlatformMap") != null)
|
|
||||||
// {
|
|
||||||
// return (List<PlatformMapItem>)Database.DatabaseMemoryCache.GetCacheObject("PlatformMap");
|
|
||||||
// }
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT * FROM PlatformMap";
|
string sql = "SELECT * FROM PlatformMap";
|
||||||
DataTable data = db.ExecuteCMD(sql); //, new Database.DatabaseMemoryCacheOptions(true, (int)TimeSpan.FromSeconds(5).Ticks));
|
DataTable data = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
List<PlatformMapItem> platformMaps = new List<PlatformMapItem>();
|
List<PlatformMapItem> platformMaps = new List<PlatformMapItem>();
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
long mapId = (long)row["Id"];
|
long mapId = (long)row["Id"];
|
||||||
|
if (PlatformMapCache.ContainsKey(mapId.ToString()))
|
||||||
|
{
|
||||||
|
PlatformMapItem mapItem = PlatformMapCache[mapId.ToString()];
|
||||||
|
if (mapItem != null)
|
||||||
|
{
|
||||||
|
platformMaps.Add(mapItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
PlatformMapItem mapItem = BuildPlatformMapItem(row);
|
PlatformMapItem mapItem = BuildPlatformMapItem(row);
|
||||||
if (mapItem != null)
|
if (mapItem != null)
|
||||||
{
|
{
|
||||||
platformMaps.Add(mapItem);
|
platformMaps.Add(mapItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
platformMaps.Sort((x, y) => x.IGDBName.CompareTo(y.IGDBName));
|
platformMaps.Sort((x, y) => x.IGDBName.CompareTo(y.IGDBName));
|
||||||
|
|
||||||
//Database.DatabaseMemoryCache.SetCacheObject("PlatformMap", platformMaps, 600);
|
|
||||||
|
|
||||||
return platformMaps;
|
return platformMaps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlatformMapItem GetPlatformMap(long Id)
|
public static PlatformMapItem GetPlatformMap(long Id)
|
||||||
|
{
|
||||||
|
if (PlatformMapCache.ContainsKey(Id.ToString()))
|
||||||
|
{
|
||||||
|
return PlatformMapCache[Id.ToString()];
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT * FROM PlatformMap WHERE Id = @Id";
|
string sql = "SELECT * FROM PlatformMap WHERE Id = @Id";
|
||||||
@@ -163,11 +157,10 @@ namespace gaseous_server.Models
|
|||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void WritePlatformMap(PlatformMapItem item, bool Update, bool AllowAvailableEmulatorOverwrite)
|
public static void WritePlatformMap(PlatformMapItem item, bool Update, bool AllowAvailableEmulatorOverwrite)
|
||||||
{
|
{
|
||||||
CreateDummyPlatform(item);
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
@@ -246,29 +239,20 @@ namespace gaseous_server.Models
|
|||||||
{
|
{
|
||||||
foreach (PlatformMapItem.EmulatorBiosItem biosItem in item.Bios)
|
foreach (PlatformMapItem.EmulatorBiosItem biosItem in item.Bios)
|
||||||
{
|
{
|
||||||
bool isEnabled = false;
|
sql = "INSERT INTO PlatformMap_Bios (Id, Filename, Description, Hash) VALUES (@Id, @Filename, @Description, @Hash);";
|
||||||
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);";
|
|
||||||
dbDict.Clear();
|
dbDict.Clear();
|
||||||
dbDict.Add("Id", item.IGDBId);
|
dbDict.Add("Id", item.IGDBId);
|
||||||
dbDict.Add("Filename", biosItem.filename);
|
dbDict.Add("Filename", biosItem.filename);
|
||||||
dbDict.Add("Description", biosItem.description);
|
dbDict.Add("Description", biosItem.description);
|
||||||
dbDict.Add("Hash", biosItem.hash);
|
dbDict.Add("Hash", biosItem.hash);
|
||||||
dbDict.Add("Enabled", isEnabled);
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear cache
|
if (PlatformMapCache.ContainsKey(item.IGDBId.ToString()))
|
||||||
Database.DatabaseMemoryCache.RemoveCacheObject("PlatformMap");
|
{
|
||||||
|
PlatformMapCache.Remove(item.IGDBId.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteAvailableEmulators(PlatformMapItem item)
|
public static void WriteAvailableEmulators(PlatformMapItem item)
|
||||||
@@ -303,16 +287,7 @@ namespace gaseous_server.Models
|
|||||||
string sql = "";
|
string sql = "";
|
||||||
|
|
||||||
// get platform data
|
// get platform data
|
||||||
// IGDB.Models.Platform? platform = Platforms.GetPlatform(IGDBId, false);
|
IGDB.Models.Platform? platform = Platforms.GetPlatform(IGDBId, false);
|
||||||
IGDB.Models.Platform? platform = null;
|
|
||||||
if (Storage.GetCacheStatus("Platform", IGDBId) == Storage.CacheStatus.NotPresent)
|
|
||||||
{
|
|
||||||
//platform = Platforms.GetPlatform(IGDBId, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
platform = (IGDB.Models.Platform)Storage.GetCacheValue<IGDB.Models.Platform>(new Platform(), "id", IGDBId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform != null)
|
if (platform != null)
|
||||||
{
|
{
|
||||||
@@ -378,7 +353,6 @@ namespace gaseous_server.Models
|
|||||||
DataTable biosTable = db.ExecuteCMD(sql, dbDict);
|
DataTable biosTable = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
List<PlatformMapItem.EmulatorBiosItem> bioss = new List<PlatformMapItem.EmulatorBiosItem>();
|
List<PlatformMapItem.EmulatorBiosItem> bioss = new List<PlatformMapItem.EmulatorBiosItem>();
|
||||||
List<string> enabledBios = new List<string>();
|
|
||||||
foreach (DataRow biosRow in biosTable.Rows)
|
foreach (DataRow biosRow in biosTable.Rows)
|
||||||
{
|
{
|
||||||
PlatformMapItem.EmulatorBiosItem bios = new PlatformMapItem.EmulatorBiosItem
|
PlatformMapItem.EmulatorBiosItem bios = new PlatformMapItem.EmulatorBiosItem
|
||||||
@@ -388,11 +362,6 @@ namespace gaseous_server.Models
|
|||||||
hash = ((string)Common.ReturnValueIfNull(biosRow["Hash"], "")).ToLower()
|
hash = ((string)Common.ReturnValueIfNull(biosRow["Hash"], "")).ToLower()
|
||||||
};
|
};
|
||||||
bioss.Add(bios);
|
bioss.Add(bios);
|
||||||
|
|
||||||
if ((bool)Common.ReturnValueIfNull(biosRow["Enabled"], true) == true)
|
|
||||||
{
|
|
||||||
enabledBios.Add(bios.hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build item
|
// build item
|
||||||
@@ -414,7 +383,15 @@ namespace gaseous_server.Models
|
|||||||
AvailableWebEmulators = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem.WebEmulatorItem.AvailableWebEmulatorItem>>((string)Common.ReturnValueIfNull(row["AvailableWebEmulators"], "[]"))
|
AvailableWebEmulators = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem.WebEmulatorItem.AvailableWebEmulatorItem>>((string)Common.ReturnValueIfNull(row["AvailableWebEmulators"], "[]"))
|
||||||
};
|
};
|
||||||
mapItem.Bios = bioss;
|
mapItem.Bios = bioss;
|
||||||
mapItem.EnabledBIOSHashes = enabledBios;
|
|
||||||
|
if (PlatformMapCache.ContainsKey(IGDBId.ToString()))
|
||||||
|
{
|
||||||
|
PlatformMapCache[IGDBId.ToString()] = mapItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlatformMapCache.Add(IGDBId.ToString(), mapItem);
|
||||||
|
}
|
||||||
|
|
||||||
return mapItem;
|
return mapItem;
|
||||||
}
|
}
|
||||||
@@ -481,74 +458,6 @@ namespace gaseous_server.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlatformMapItem GetUserPlatformMap(string UserId, long PlatformId, long GameId)
|
|
||||||
{
|
|
||||||
// get the system enabled bios hashes
|
|
||||||
Models.PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(PlatformId);
|
|
||||||
|
|
||||||
// get the user enabled bios hashes
|
|
||||||
PlatformMapping.UserEmulatorConfiguration userEmulatorConfiguration = GetUserEmulator(UserId, GameId, PlatformId);
|
|
||||||
if (userEmulatorConfiguration != null)
|
|
||||||
{
|
|
||||||
platformMapItem.WebEmulator.Type = userEmulatorConfiguration.EmulatorType;
|
|
||||||
platformMapItem.WebEmulator.Core = userEmulatorConfiguration.Core;
|
|
||||||
platformMapItem.EnabledBIOSHashes = userEmulatorConfiguration.EnableBIOSFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
return platformMapItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserEmulatorConfiguration GetUserEmulator(string UserId, long GameId, long PlatformId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "SELECT Mapping FROM User_PlatformMap WHERE id = @UserId AND GameId = @GameId AND PlatformId = @PlatformId;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "UserId", UserId },
|
|
||||||
{ "GameId", GameId },
|
|
||||||
{ "PlatformId", PlatformId }
|
|
||||||
};
|
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (data.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
UserEmulatorConfiguration emulator = Newtonsoft.Json.JsonConvert.DeserializeObject<UserEmulatorConfiguration>((string)data.Rows[0]["Mapping"]);
|
|
||||||
|
|
||||||
return emulator;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetUserEmulator(string UserId, long GameId, long PlatformId, UserEmulatorConfiguration Mapping)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "INSERT INTO User_PlatformMap (id, GameId, PlatformId, Mapping) VALUES (@UserId, @GameId, @PlatformId, @Mapping) ON DUPLICATE KEY UPDATE Mapping = @Mapping;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "UserId", UserId },
|
|
||||||
{ "GameId", GameId },
|
|
||||||
{ "PlatformId", PlatformId },
|
|
||||||
{ "Mapping", Newtonsoft.Json.JsonConvert.SerializeObject(Mapping) }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteUserEmulator(string UserId, long GameId, long PlatformId)
|
|
||||||
{
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "DELETE FROM User_PlatformMap WHERE id = @UserId AND GameId = @GameId AND PlatformId = @PlatformId;";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
{ "UserId", UserId },
|
|
||||||
{ "GameId", GameId },
|
|
||||||
{ "PlatformId", PlatformId }
|
|
||||||
};
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PlatformMapItem
|
public class PlatformMapItem
|
||||||
{
|
{
|
||||||
public long IGDBId { get; set; }
|
public long IGDBId { get; set; }
|
||||||
@@ -596,15 +505,6 @@ namespace gaseous_server.Models
|
|||||||
public string description { get; set; }
|
public string description { get; set; }
|
||||||
public string filename { get; set; }
|
public string filename { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<string> EnabledBIOSHashes { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UserEmulatorConfiguration
|
|
||||||
{
|
|
||||||
public string EmulatorType { get; set; }
|
|
||||||
public string Core { get; set; }
|
|
||||||
public List<string> EnableBIOSFiles { get; set; } = new List<string>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,36 +4,12 @@ using gaseous_signature_parser.models.RomSignatureObject;
|
|||||||
|
|
||||||
namespace gaseous_server.Models
|
namespace gaseous_server.Models
|
||||||
{
|
{
|
||||||
public class Signatures_Games : HasheousClient.Models.SignatureModel
|
public class Signatures_Games : HasheousClient.Models.LookupResponseModel
|
||||||
{
|
{
|
||||||
public Signatures_Games()
|
public Signatures_Games()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public int Score
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
int _score = 0;
|
|
||||||
|
|
||||||
if (Game != null)
|
|
||||||
{
|
|
||||||
_score = _score + Game.Score;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Rom != null)
|
|
||||||
{
|
|
||||||
_score = _score + Rom.Score;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameItem Game = new GameItem();
|
|
||||||
public RomItem Rom = new RomItem();
|
|
||||||
|
|
||||||
public SignatureFlags Flags = new SignatureFlags();
|
public SignatureFlags Flags = new SignatureFlags();
|
||||||
|
|
||||||
public class SignatureFlags
|
public class SignatureFlags
|
||||||
@@ -42,213 +18,5 @@ namespace gaseous_server.Models
|
|||||||
public string IGDBPlatformName { get; set; }
|
public string IGDBPlatformName { get; set; }
|
||||||
public long IGDBGameId { get; set; }
|
public long IGDBGameId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameItem : HasheousClient.Models.SignatureModel.GameItem
|
|
||||||
{
|
|
||||||
public GameItem()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public int Score
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// calculate a score based on the availablility of data
|
|
||||||
int _score = 0;
|
|
||||||
var properties = this.GetType().GetProperties();
|
|
||||||
foreach (var prop in properties)
|
|
||||||
{
|
|
||||||
if (prop.GetGetMethod() != null)
|
|
||||||
{
|
|
||||||
switch (prop.Name.ToLower())
|
|
||||||
{
|
|
||||||
case "id":
|
|
||||||
case "score":
|
|
||||||
break;
|
|
||||||
case "name":
|
|
||||||
case "year":
|
|
||||||
case "publisher":
|
|
||||||
case "system":
|
|
||||||
if (prop.PropertyType == typeof(string))
|
|
||||||
{
|
|
||||||
if (prop.GetValue(this) != null)
|
|
||||||
{
|
|
||||||
string propVal = prop.GetValue(this).ToString();
|
|
||||||
if (propVal.Length > 0)
|
|
||||||
{
|
|
||||||
_score = _score + 10;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (prop.PropertyType == typeof(string))
|
|
||||||
{
|
|
||||||
if (prop.GetValue(this) != null)
|
|
||||||
{
|
|
||||||
string propVal = prop.GetValue(this).ToString();
|
|
||||||
if (propVal.Length > 0)
|
|
||||||
{
|
|
||||||
_score = _score + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RomItem : HasheousClient.Models.SignatureModel.RomItem
|
|
||||||
{
|
|
||||||
[JsonIgnore]
|
|
||||||
public int Score
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// calculate a score based on the availablility of data
|
|
||||||
int _score = 0;
|
|
||||||
var properties = this.GetType().GetProperties();
|
|
||||||
foreach (var prop in properties)
|
|
||||||
{
|
|
||||||
if (prop.GetGetMethod() != null)
|
|
||||||
{
|
|
||||||
switch (prop.Name.ToLower())
|
|
||||||
{
|
|
||||||
case "name":
|
|
||||||
case "size":
|
|
||||||
case "crc":
|
|
||||||
case "developmentstatus":
|
|
||||||
case "flags":
|
|
||||||
case "attributes":
|
|
||||||
case "romtypemedia":
|
|
||||||
case "medialabel":
|
|
||||||
if (prop.PropertyType == typeof(string) || prop.PropertyType == typeof(Int64) || prop.PropertyType == typeof(List<string>))
|
|
||||||
{
|
|
||||||
if (prop.GetValue(this) != null)
|
|
||||||
{
|
|
||||||
string propVal = prop.GetValue(this).ToString();
|
|
||||||
if (propVal.Length > 0)
|
|
||||||
{
|
|
||||||
_score = _score + 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (prop.PropertyType == typeof(string))
|
|
||||||
{
|
|
||||||
if (prop.GetValue(this) != null)
|
|
||||||
{
|
|
||||||
string propVal = prop.GetValue(this).ToString();
|
|
||||||
if (propVal.Length > 0)
|
|
||||||
{
|
|
||||||
_score = _score + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MediaType
|
|
||||||
{
|
|
||||||
public MediaType(SignatureSourceType Source, string MediaTypeString)
|
|
||||||
{
|
|
||||||
switch (Source)
|
|
||||||
{
|
|
||||||
case RomItem.SignatureSourceType.TOSEC:
|
|
||||||
string[] typeString = MediaTypeString.Split(" ");
|
|
||||||
|
|
||||||
string inType = "";
|
|
||||||
foreach (string typeStringVal in typeString)
|
|
||||||
{
|
|
||||||
if (inType == "")
|
|
||||||
{
|
|
||||||
switch (typeStringVal.ToLower())
|
|
||||||
{
|
|
||||||
case "disk":
|
|
||||||
Media = RomItem.RomTypes.Disk;
|
|
||||||
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "disc":
|
|
||||||
Media = RomItem.RomTypes.Disc;
|
|
||||||
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "file":
|
|
||||||
Media = RomItem.RomTypes.File;
|
|
||||||
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "part":
|
|
||||||
Media = RomItem.RomTypes.Part;
|
|
||||||
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "tape":
|
|
||||||
Media = RomItem.RomTypes.Tape;
|
|
||||||
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "of":
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
case "side":
|
|
||||||
inType = typeStringVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (inType.ToLower())
|
|
||||||
{
|
|
||||||
case "disk":
|
|
||||||
case "disc":
|
|
||||||
case "file":
|
|
||||||
case "part":
|
|
||||||
case "tape":
|
|
||||||
Number = int.Parse(typeStringVal);
|
|
||||||
break;
|
|
||||||
case "of":
|
|
||||||
Count = int.Parse(typeStringVal);
|
|
||||||
break;
|
|
||||||
case "side":
|
|
||||||
Side = typeStringVal;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
inType = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RomItem.RomTypes? Media { get; set; }
|
|
||||||
|
|
||||||
public int? Number { get; set; }
|
|
||||||
|
|
||||||
public int? Count { get; set; }
|
|
||||||
|
|
||||||
public string? Side { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
using IGDB.Models;
|
|
||||||
|
|
||||||
namespace gaseous_server.Models
|
|
||||||
{
|
|
||||||
public class UserProfile
|
|
||||||
{
|
|
||||||
public Guid UserId { get; set; }
|
|
||||||
public string DisplayName { get; set; }
|
|
||||||
public string Quip { get; set; }
|
|
||||||
public NowPlayingItem? NowPlaying { get; set; }
|
|
||||||
public class NowPlayingItem
|
|
||||||
{
|
|
||||||
public Game Game { get; set; }
|
|
||||||
public Platform Platform { get; set; }
|
|
||||||
public long Duration { get; set; }
|
|
||||||
}
|
|
||||||
public ProfileImageItem? Avatar { get; set; }
|
|
||||||
public ProfileImageItem? ProfileBackground { get; set; }
|
|
||||||
public Dictionary<string, object> Data { get; set; }
|
|
||||||
public class ProfileImageItem
|
|
||||||
{
|
|
||||||
public string MimeType { get; set; }
|
|
||||||
public string Extension { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -255,8 +255,8 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing " + parserType + " files");
|
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing " + parserType + " files");
|
||||||
|
|
||||||
string SignaturePath = Path.Combine(Config.LibraryConfiguration.LibrarySignaturesDirectory, parserType.ToString());
|
string SignaturePath = Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, parserType.ToString());
|
||||||
string SignatureProcessedPath = Path.Combine(Config.LibraryConfiguration.LibrarySignaturesProcessedDirectory, parserType.ToString());
|
string SignatureProcessedPath = Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, parserType.ToString());
|
||||||
|
|
||||||
if (!Directory.Exists(SignaturePath))
|
if (!Directory.Exists(SignaturePath))
|
||||||
{
|
{
|
||||||
@@ -368,7 +368,8 @@ 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();
|
||||||
@@ -379,7 +380,8 @@ 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();
|
||||||
|
@@ -45,12 +45,21 @@ AgeRatings.PopulateAgeMap();
|
|||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
Config.InitSettings();
|
Config.InitSettings();
|
||||||
|
|
||||||
|
// set default search settings
|
||||||
|
Config.SetSetting<List<gaseous_server.Classes.Metadata.Games.SearchType>>("DefaultSearchMethods", new List<gaseous_server.Classes.Metadata.Games.SearchType>() {
|
||||||
|
Games.SearchType.where,
|
||||||
|
Games.SearchType.wherefuzzy,
|
||||||
|
Games.SearchType.search,
|
||||||
|
Games.SearchType.searchNoPlatform
|
||||||
|
});
|
||||||
|
|
||||||
|
// disable hasheous
|
||||||
|
Config.MetadataConfiguration.SignatureSource = HasheousClient.Models.MetadataModel.SignatureSources.LocalOnly;
|
||||||
|
|
||||||
// write updated settings back to the config file
|
// write updated settings back to the config file
|
||||||
Config.UpdateConfig();
|
Config.UpdateConfig();
|
||||||
|
|
||||||
// update default library path
|
|
||||||
GameLibrary.UpdateDefaultLibraryPath();
|
|
||||||
|
|
||||||
// set api metadata source from config
|
// set api metadata source from config
|
||||||
Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource;
|
Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource;
|
||||||
|
|
||||||
@@ -70,14 +79,13 @@ if (Directory.Exists(Config.LibraryConfiguration.LibraryUploadDirectory))
|
|||||||
// kick off any delayed upgrade tasks
|
// kick off any delayed upgrade tasks
|
||||||
// run 1002 background updates in the background on every start
|
// run 1002 background updates in the background on every start
|
||||||
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1002);
|
||||||
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1023);
|
|
||||||
// start the task
|
// start the task
|
||||||
ProcessQueue.QueueItem queueItem = new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItem queueItem = new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade,
|
ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade,
|
||||||
1,
|
1,
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.SignatureIngestor
|
ProcessQueue.QueueItemType.All
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
@@ -128,7 +136,7 @@ builder.Services.AddControllers(options =>
|
|||||||
});
|
});
|
||||||
builder.Services.AddApiVersioning(config =>
|
builder.Services.AddApiVersioning(config =>
|
||||||
{
|
{
|
||||||
config.DefaultApiVersion = new ApiVersion(1, 0);
|
config.DefaultApiVersion = new ApiVersion(1, 1);
|
||||||
config.AssumeDefaultVersionWhenUnspecified = true;
|
config.AssumeDefaultVersionWhenUnspecified = true;
|
||||||
config.ReportApiVersions = true;
|
config.ReportApiVersions = true;
|
||||||
config.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
|
config.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
|
||||||
@@ -199,6 +207,9 @@ builder.Services.AddSwaggerGen(options =>
|
|||||||
// using System.Reflection;
|
// using System.Reflection;
|
||||||
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
||||||
|
|
||||||
|
// sort the endpoints
|
||||||
|
options.OrderActionsBy((apiDesc) => $"{apiDesc.RelativePath}_{apiDesc.HttpMethod}");
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
builder.Services.AddHostedService<TimedHostedService>();
|
builder.Services.AddHostedService<TimedHostedService>();
|
||||||
@@ -262,12 +273,15 @@ app.UseSwaggerUI(options =>
|
|||||||
|
|
||||||
var descriptions = app.DescribeApiVersions();
|
var descriptions = app.DescribeApiVersions();
|
||||||
foreach (var description in descriptions)
|
foreach (var description in descriptions)
|
||||||
|
{
|
||||||
|
if (description.IsDeprecated == false)
|
||||||
{
|
{
|
||||||
var url = $"/swagger/{description.GroupName}/swagger.json";
|
var url = $"/swagger/{description.GroupName}/swagger.json";
|
||||||
var name = description.GroupName.ToUpperInvariant();
|
var name = description.GroupName.ToUpperInvariant();
|
||||||
options.SwaggerEndpoint(url, name);
|
options.SwaggerEndpoint(url, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@@ -326,6 +340,72 @@ app.Use(async (context, next) =>
|
|||||||
await next();
|
await next();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// emergency password recovery if environment variable is set
|
||||||
|
// process:
|
||||||
|
// - set the environment variable "recoveraccount" to the email address of the account to be recovered
|
||||||
|
// - when the server starts the password will be reset to a random string and saved in the library
|
||||||
|
// directory with the name RecoverAccount.txt
|
||||||
|
// - user should copy this password and remove the "recoveraccount" environment variable and the
|
||||||
|
// RecoverAccount.txt file
|
||||||
|
// - the server will not start while the RecoverAccount.txt file exists
|
||||||
|
string PasswordRecoveryFile = Path.Combine(Config.LibraryConfiguration.LibraryRootDirectory, "RecoverAccount.txt");
|
||||||
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("recoveraccount")))
|
||||||
|
{
|
||||||
|
if (File.Exists(PasswordRecoveryFile))
|
||||||
|
{
|
||||||
|
// password has already been set - do nothing and just exit
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Server Startup", "Unable to start while recoveraccount environment varibale is set and RecoverAccount.txt file exists.", null, true);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// generate and save the password to disk
|
||||||
|
int length = 10;
|
||||||
|
string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+";
|
||||||
|
var random = new Random();
|
||||||
|
string password = new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
|
||||||
|
|
||||||
|
File.WriteAllText(PasswordRecoveryFile, password);
|
||||||
|
|
||||||
|
// reset the password
|
||||||
|
using (var scope = app.Services.CreateScope())
|
||||||
|
{
|
||||||
|
var userManager = scope.ServiceProvider.GetRequiredService<UserStore>();
|
||||||
|
if (await userManager.FindByNameAsync(Environment.GetEnvironmentVariable("recoveraccount"), CancellationToken.None) != null)
|
||||||
|
{
|
||||||
|
ApplicationUser User = await userManager.FindByEmailAsync(Environment.GetEnvironmentVariable("recoveraccount"), CancellationToken.None);
|
||||||
|
|
||||||
|
//set user password
|
||||||
|
PasswordHasher<ApplicationUser> ph = new PasswordHasher<ApplicationUser>();
|
||||||
|
User.PasswordHash = ph.HashPassword(User, password);
|
||||||
|
|
||||||
|
await userManager.SetPasswordHashAsync(User, User.PasswordHash, CancellationToken.None);
|
||||||
|
|
||||||
|
Logging.Log(Logging.LogType.Information, "Server Startup", "Password reset complete, remove the recoveraccount environment variable and RecoverAccount.text file to allow server start.", null, true);
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Server Startup", "Account to recover not found.", null, true);
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check if RecoverAccount.text file is present
|
||||||
|
if (File.Exists(PasswordRecoveryFile))
|
||||||
|
{
|
||||||
|
// cannot start while password recovery file exists
|
||||||
|
Logging.Log(Logging.LogType.Critical, "Server Startup", "Unable to start while RecoverAccount.txt file exists. Remove the file and try again.", null, true);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setup library directories
|
// setup library directories
|
||||||
Config.LibraryConfiguration.InitLibrary();
|
Config.LibraryConfiguration.InitLibrary();
|
||||||
|
|
||||||
@@ -338,8 +418,8 @@ gaseous_server.Classes.Metadata.Platforms.AssignAllPlatformsToGameIdZero();
|
|||||||
// extract platform map if not present
|
// extract platform map if not present
|
||||||
PlatformMapping.ExtractPlatformMap();
|
PlatformMapping.ExtractPlatformMap();
|
||||||
|
|
||||||
// migrate old firmware directory structure to new style
|
// force load platform map into cache
|
||||||
Bios.MigrateToNewFolderStructure();
|
var platformMap = PlatformMapping.PlatformMap;
|
||||||
|
|
||||||
// add background tasks
|
// add background tasks
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
|
@@ -15,3 +15,23 @@ CREATE TABLE `Language` (
|
|||||||
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
||||||
INDEX `id_Value` (`Value` ASC) VISIBLE
|
INDEX `id_Value` (`Value` ASC) VISIBLE
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Signatures_RomToSource` (
|
||||||
|
`SourceId` int NOT NULL,
|
||||||
|
`RomId` int NOT NULL,
|
||||||
|
PRIMARY KEY (`SourceId`, `RomId`)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Signatures_Games_Countries` (
|
||||||
|
`GameId` INT NOT NULL,
|
||||||
|
`CountryId` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`GameId`, `CountryId`),
|
||||||
|
CONSTRAINT `GameCountry` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `Signatures_Games_Languages` (
|
||||||
|
`GameId` INT NOT NULL,
|
||||||
|
`LanguageId` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`GameId`, `LanguageId`),
|
||||||
|
CONSTRAINT `GameLanguage` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
||||||
|
);
|
@@ -1,99 +0,0 @@
|
|||||||
CREATE TABLE `Signatures_RomToSource` (
|
|
||||||
`SourceId` int NOT NULL,
|
|
||||||
`RomId` int NOT NULL,
|
|
||||||
PRIMARY KEY (`SourceId`, `RomId`)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE `Signatures_Games_Countries` (
|
|
||||||
`GameId` INT NOT NULL,
|
|
||||||
`CountryId` INT NOT NULL,
|
|
||||||
PRIMARY KEY (`GameId`, `CountryId`),
|
|
||||||
CONSTRAINT `GameCountry` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE `Signatures_Games_Languages` (
|
|
||||||
`GameId` INT NOT NULL,
|
|
||||||
`LanguageId` INT NOT NULL,
|
|
||||||
PRIMARY KEY (`GameId`, `LanguageId`),
|
|
||||||
CONSTRAINT `GameLanguage` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms` ADD COLUMN `RomDataVersion` INT DEFAULT 1;
|
|
||||||
|
|
||||||
CREATE TABLE UserProfiles (
|
|
||||||
`Id` VARCHAR(45) NOT NULL,
|
|
||||||
`UserId` VARCHAR(45) NOT NULL,
|
|
||||||
`DisplayName` VARCHAR(255) NOT NULL,
|
|
||||||
`Quip` VARCHAR(255) NOT NULL,
|
|
||||||
`Avatar` LONGBLOB,
|
|
||||||
`AvatarExtension` CHAR(6),
|
|
||||||
`ProfileBackground` LONGBLOB,
|
|
||||||
`ProfileBackgroundExtension` CHAR(6),
|
|
||||||
`UnstructuredData` LONGTEXT NOT NULL,
|
|
||||||
PRIMARY KEY (`Id`, `UserId`)
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE `PlatformMap_Bios`
|
|
||||||
ADD COLUMN `Enabled` BOOLEAN DEFAULT TRUE;
|
|
||||||
|
|
||||||
CREATE TABLE `User_PlatformMap` (
|
|
||||||
`id` VARCHAR(128) NOT NULL,
|
|
||||||
`GameId` BIGINT NOT NULL,
|
|
||||||
`PlatformId` BIGINT NOT NULL,
|
|
||||||
`Mapping` LONGTEXT,
|
|
||||||
PRIMARY KEY (`id`, `GameId`, `PlatformId`),
|
|
||||||
CONSTRAINT `User_PlatformMap_UserId` FOREIGN KEY (`id`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE `UserTimeTracking`
|
|
||||||
ADD COLUMN `PlatformId` BIGINT,
|
|
||||||
ADD COLUMN `IsMediaGroup` BOOLEAN DEFAULT FALSE,
|
|
||||||
ADD COLUMN `RomId` BIGINT;
|
|
||||||
|
|
||||||
CREATE TABLE `User_RecentPlayedRoms` (
|
|
||||||
`UserId` varchar(128) NOT NULL,
|
|
||||||
`GameId` bigint(20) NOT NULL,
|
|
||||||
`PlatformId` bigint(20) NOT NULL,
|
|
||||||
`RomId` bigint(20) NOT NULL,
|
|
||||||
`IsMediaGroup` tinyint(1) DEFAULT NULL,
|
|
||||||
PRIMARY KEY (
|
|
||||||
`UserId`,
|
|
||||||
`GameId`,
|
|
||||||
`PlatformId`
|
|
||||||
),
|
|
||||||
CONSTRAINT `RecentPlayedRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE `User_GameFavouriteRoms` (
|
|
||||||
`UserId` varchar(128) NOT NULL,
|
|
||||||
`GameId` bigint(20) NOT NULL,
|
|
||||||
`PlatformId` bigint(20) NOT NULL,
|
|
||||||
`RomId` bigint(20) NOT NULL,
|
|
||||||
`IsMediaGroup` tinyint(1) DEFAULT NULL,
|
|
||||||
PRIMARY KEY (
|
|
||||||
`UserId`,
|
|
||||||
`GameId`,
|
|
||||||
`PlatformId`
|
|
||||||
),
|
|
||||||
CONSTRAINT `GameFavouriteRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms`
|
|
||||||
CHANGE `Path` `RelativePath` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL;
|
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms`
|
|
||||||
ADD CONSTRAINT Games_Roms_LibraryId FOREIGN KEY (`LibraryId`) REFERENCES `GameLibraries` (`Id`) ON DELETE CASCADE;
|
|
||||||
|
|
||||||
CREATE VIEW view_Games_Roms AS
|
|
||||||
SELECT `Games_Roms`.*, CONCAT(
|
|
||||||
`GameLibraries`.`Path`, '/', `Games_Roms`.`RelativePath`
|
|
||||||
) AS `Path`, `GameLibraries`.`Name` AS `LibraryName`
|
|
||||||
FROM
|
|
||||||
`Games_Roms`
|
|
||||||
JOIN `GameLibraries` ON `Games_Roms`.`LibraryId` = `GameLibraries`.`Id`;
|
|
||||||
|
|
||||||
CREATE VIEW view_UserTimeTracking AS
|
|
||||||
SELECT *, DATE_ADD(
|
|
||||||
SessionTime, INTERVAL SessionLength MINUTE
|
|
||||||
) AS SessionEnd
|
|
||||||
FROM UserTimeTracking;
|
|
@@ -18,18 +18,18 @@
|
|||||||
<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.2.1" />
|
<PackageReference Include="gaseous-signature-parser" Version="2.3.0" />
|
||||||
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
||||||
<PackageReference Include="hasheous-client" Version="1.0.2" />
|
<PackageReference Include="hasheous-client" Version="0.1.0" />
|
||||||
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.8.0" />
|
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.5.0" />
|
||||||
<PackageReference Include="sharpcompress" Version="0.37.2" />
|
<PackageReference Include="sharpcompress" Version="0.38.0" />
|
||||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
|
||||||
<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.10" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
|
||||||
<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>
|
||||||
@@ -39,8 +39,6 @@
|
|||||||
<None Remove="Classes\" />
|
<None Remove="Classes\" />
|
||||||
<None Remove="Classes\SignatureIngestors\" />
|
<None Remove="Classes\SignatureIngestors\" />
|
||||||
<None Remove="Support\" />
|
<None Remove="Support\" />
|
||||||
<None Remove="Support\Country.txt" />
|
|
||||||
<None Remove="Support\Language.txt" />
|
|
||||||
<None Remove="Support\Database\" />
|
<None Remove="Support\Database\" />
|
||||||
<None Remove="Support\Database\MySQL\" />
|
<None Remove="Support\Database\MySQL\" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1000.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1000.sql" />
|
||||||
@@ -68,7 +66,6 @@
|
|||||||
<None Remove="Support\Database\MySQL\gaseous-1021.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1021.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1022.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1022.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1023.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1023.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1024.sql" />
|
|
||||||
<None Remove="Classes\Metadata\" />
|
<None Remove="Classes\Metadata\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -117,6 +114,5 @@
|
|||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1021.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1021.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1022.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1022.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1023.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1023.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1024.sql" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
BIN
gaseous-server/wwwroot/.DS_Store
vendored
Normal file
@@ -22,10 +22,8 @@
|
|||||||
if (StateUrl) {
|
if (StateUrl) {
|
||||||
console.log('Loading saved state from: ' + StateUrl);
|
console.log('Loading saved state from: ' + StateUrl);
|
||||||
EJS_loadStateURL = StateUrl;
|
EJS_loadStateURL = StateUrl;
|
||||||
}
|
|
||||||
|
|
||||||
// start the emulator automatically when loaded
|
|
||||||
EJS_startOnLoaded = true;
|
EJS_startOnLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Path to the data directory
|
// Path to the data directory
|
||||||
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
||||||
@@ -43,8 +41,6 @@
|
|||||||
EJS_threads = false;
|
EJS_threads = false;
|
||||||
|
|
||||||
EJS_Buttons = {
|
EJS_Buttons = {
|
||||||
saveSavFiles: false,
|
|
||||||
loadSavFiles: false,
|
|
||||||
exitEmulation: false
|
exitEmulation: false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,11 +72,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
EJS_onLoadState = function (e) {
|
EJS_onLoadState = function (e) {
|
||||||
let rompath = decodeURIComponent(getQueryString('rompath', 'string'));
|
showDialog('emulatorloadstate', { "romId": romId, "IsMediaGroup": IsMediaGroup });
|
||||||
rompath = rompath.substring(rompath.lastIndexOf('/') + 1);
|
|
||||||
console.log(rompath);
|
|
||||||
let stateManager = new EmulatorStateManager(romId, IsMediaGroup, getQueryString('engine', 'string'), getQueryString('core', 'string'), platformId, gameId, rompath);
|
|
||||||
stateManager.open();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src='/emulators/EmulatorJS/data/loader.js'></script>
|
<script src='/emulators/EmulatorJS/data/loader.js'></script>
|
@@ -1,16 +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 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<title>stop-warning</title>
|
|
||||||
<g id="Layer_2" data-name="Layer 2">
|
|
||||||
<g id="invisible_box" data-name="invisible box">
|
|
||||||
<rect width="48" height="48" fill="none"/>
|
|
||||||
</g>
|
|
||||||
<g id="icons_Q2" data-name="icons Q2">
|
|
||||||
<g>
|
|
||||||
<path d="M43.4,15.1,32.9,4.6A2,2,0,0,0,31.5,4h-15a2,2,0,0,0-1.4.6L4.6,15.1A2,2,0,0,0,4,16.5v15a2,2,0,0,0,.6,1.4L15.1,43.4a2,2,0,0,0,1.4.6h15a2,2,0,0,0,1.4-.6L43.4,32.9a2,2,0,0,0,.6-1.4v-15A2,2,0,0,0,43.4,15.1ZM40,30.6,30.6,40H17.4L8,30.6V17.4L17.4,8H30.6L40,17.4Z"/>
|
|
||||||
<path d="M26.8,24l5.6-5.6a2,2,0,0,0-2.8-2.8L24,21.2l-5.6-5.6a2,2,0,0,0-2.8,2.8L21.2,24l-5.6,5.6a1.9,1.9,0,0,0,0,2.8,1.9,1.9,0,0,0,2.8,0L24,26.8l5.6,5.6a1.9,1.9,0,0,0,2.8,0,1.9,1.9,0,0,0,0-2.8Z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
Before Width: | Height: | Size: 969 B |
Before Width: | Height: | Size: 8.3 KiB |
@@ -1,17 +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 48 48" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<title>warning</title>
|
|
||||||
<g id="Layer_2" data-name="Layer 2">
|
|
||||||
<g id="invisible_box" data-name="invisible box">
|
|
||||||
<rect width="48" height="48" fill="none"/>
|
|
||||||
</g>
|
|
||||||
<g id="icons_Q2" data-name="icons Q2">
|
|
||||||
<g>
|
|
||||||
<path d="M24,9,40.6,39H7.5L24,9M2.3,40A2,2,0,0,0,4,43H44a2,2,0,0,0,1.7-3L25.7,4a2,2,0,0,0-3.4,0Z"/>
|
|
||||||
<path d="M22,19v9a2,2,0,0,0,4,0V19a2,2,0,0,0-4,0Z"/>
|
|
||||||
<circle cx="24" cy="34" r="2"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
Before Width: | Height: | Size: 695 B |
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512.011 512.011" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M505.755,123.592c-8.341-8.341-21.824-8.341-30.165,0L256.005,343.176L36.421,123.592c-8.341-8.341-21.824-8.341-30.165,0
|
|
||||||
s-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251c5.462,0,10.923-2.091,15.083-6.251l234.667-234.667
|
|
||||||
C514.096,145.416,514.096,131.933,505.755,123.592z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 684 B |
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512.006 512.006" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M388.419,475.59L168.834,256.005L388.418,36.421c8.341-8.341,8.341-21.824,0-30.165s-21.824-8.341-30.165,0
|
|
||||||
L123.586,240.923c-8.341,8.341-8.341,21.824,0,30.165l234.667,234.667c4.16,4.16,9.621,6.251,15.083,6.251
|
|
||||||
c5.461,0,10.923-2.091,15.083-6.251C396.76,497.414,396.76,483.931,388.419,475.59z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 679 B |
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512.005 512.005" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M388.418,240.923L153.751,6.256c-8.341-8.341-21.824-8.341-30.165,0s-8.341,21.824,0,30.165L343.17,256.005
|
|
||||||
L123.586,475.589c-8.341,8.341-8.341,21.824,0,30.165c4.16,4.16,9.621,6.251,15.083,6.251c5.461,0,10.923-2.091,15.083-6.251
|
|
||||||
l234.667-234.667C396.759,262.747,396.759,249.264,388.418,240.923z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 682 B |
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512 512" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<g>
|
|
||||||
<path d="M505.752,358.248L271.085,123.582c-8.331-8.331-21.839-8.331-30.17,0L6.248,358.248c-8.331,8.331-8.331,21.839,0,30.17
|
|
||||||
s21.839,8.331,30.17,0L256,168.837l219.582,219.582c8.331,8.331,21.839,8.331,30.17,0S514.083,366.58,505.752,358.248z"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 609 B |
@@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512 512" xml:space="preserve">
|
|
||||||
<g>
|
|
||||||
<rect x="342.232" y="460.8" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="234.442" y="460.8" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="126.653" y="460.8" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="8.084" y="234.442" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
<rect x="8.084" y="342.232" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
<rect x="460.8" y="342.232" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
<rect x="460.8" y="234.442" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
<rect x="460.8" y="126.653" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
<rect x="342.232" y="13.474" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="234.442" y="13.474" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="126.653" y="13.474" style="fill:#AFB6BB;" width="43.116" height="37.726"/>
|
|
||||||
<rect x="8.084" y="126.653" style="fill:#AFB6BB;" width="43.116" height="43.116"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<rect x="51.2" y="126.653" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="51.2" y="234.442" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="51.2" y="342.232" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="126.653" y="428.463" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
<rect x="234.442" y="428.463" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
<rect x="342.232" y="428.463" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
<rect x="428.463" y="342.232" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="428.463" y="234.442" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="428.463" y="126.653" style="fill:#E7ECED;" width="32.337" height="43.116"/>
|
|
||||||
<rect x="342.232" y="51.2" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
<rect x="234.442" y="51.2" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
<rect x="126.653" y="51.2" style="fill:#E7ECED;" width="43.116" height="32.337"/>
|
|
||||||
</g>
|
|
||||||
<path style="fill:#595E62;" d="M428.463,385.347v32.337c0,5.928-4.851,10.779-10.779,10.779h-32.337h-43.116h-64.674h-43.116
|
|
||||||
h-64.674h-43.116H94.316c-5.928,0-10.779-4.851-10.779-10.779v-32.337v-43.116v-64.674v-43.116v-64.674v-43.116V94.316
|
|
||||||
c0-5.928,4.851-10.779,10.779-10.779h32.337h43.116h64.674h43.116h64.674h43.116h32.337c5.928,0,10.779,4.851,10.779,10.779v32.337
|
|
||||||
v43.116v64.674v43.116v64.674V385.347z M385.347,385.347V126.653H126.653v258.695H385.347z"/>
|
|
||||||
<rect x="126.653" y="126.653" style="fill:#36C63F;" width="258.695" height="258.695"/>
|
|
||||||
<path style="fill:#00AB4E;" d="M173.785,126.653h-47.132v258.695h258.695v-47.132C284.709,306.659,205.341,227.291,173.785,126.653z
|
|
||||||
"/>
|
|
||||||
<path style="fill:#44494C;" d="M126.653,385.347V126.653H256V83.537h-21.558h-64.674h-43.116H94.316
|
|
||||||
c-5.928,0-10.779,4.851-10.779,10.779v32.337v43.116v64.674v43.116v64.674v43.116v32.337c0,5.928,4.851,10.779,10.779,10.779h32.337
|
|
||||||
h43.116h64.674H256v-43.116H126.653z"/>
|
|
||||||
<g>
|
|
||||||
<rect x="180.547" y="161.684" style="fill:#FFFFFF;" width="150.905" height="16.168"/>
|
|
||||||
<rect x="180.547" y="237.137" style="fill:#FFFFFF;" width="150.905" height="16.168"/>
|
|
||||||
<rect x="180.547" y="199.411" style="fill:#FFFFFF;" width="26.947" height="16.168"/>
|
|
||||||
<rect x="180.547" y="334.147" style="fill:#FFFFFF;" width="26.947" height="16.168"/>
|
|
||||||
<rect x="223.663" y="334.147" style="fill:#FFFFFF;" width="26.947" height="16.168"/>
|
|
||||||
<rect x="299.116" y="334.147" style="fill:#FFFFFF;" width="26.947" height="16.168"/>
|
|
||||||
<rect x="239.832" y="199.411" style="fill:#FFFFFF;" width="91.621" height="16.168"/>
|
|
||||||
</g>
|
|
||||||
<path d="M118.568,393.432h274.863V118.568H118.568V393.432z M134.737,134.737h242.526v242.526H134.737V134.737z"/>
|
|
||||||
<path d="M512,177.853v-59.284h-75.453V94.316c0-10.401-8.463-18.863-18.863-18.863h-24.253V5.389h-59.284v70.063h-48.505V5.389
|
|
||||||
h-59.284v70.063h-48.505V5.389h-59.284v70.063H94.316c-10.401,0-18.863,8.463-18.863,18.863v24.253H0v59.284h75.453v48.505H0v59.284
|
|
||||||
h75.453v48.505H0v59.284h75.453v24.253c0,10.401,8.463,18.863,18.863,18.863h24.253v70.063h59.284v-70.063h48.505v70.063h59.284
|
|
||||||
v-70.063h48.505v70.063h59.284v-70.063h24.253c10.401,0,18.863-8.463,18.863-18.863v-24.253H512v-59.284h-75.453v-48.505H512
|
|
||||||
v-59.284h-75.453v-48.505H512z M436.547,134.737h16.168v26.947h-16.168V134.737z M495.832,161.684h-26.947v-26.947h26.947V161.684z
|
|
||||||
M350.316,59.284h26.947v16.168h-26.947V59.284z M377.263,21.558v21.558h-26.947V21.558H377.263z M242.526,59.284h26.947v16.168
|
|
||||||
h-26.947V59.284z M269.474,21.558v21.558h-26.947V21.558H269.474z M134.737,59.284h26.947v16.168h-26.947V59.284z M161.684,21.558
|
|
||||||
v21.558h-26.947V21.558H161.684z M75.453,161.684H59.284v-26.947h16.168V161.684z M16.168,134.737h26.947v26.947H16.168V134.737z
|
|
||||||
M75.453,269.474H59.284v-26.947h16.168V269.474z M16.168,242.526h26.947v26.947H16.168V242.526z M75.453,377.263H59.284v-26.947
|
|
||||||
h16.168V377.263z M16.168,350.316h26.947v26.947H16.168V350.316z M161.684,452.716h-26.947v-16.168h26.947V452.716z
|
|
||||||
M134.737,490.442v-21.558h26.947v21.558H134.737z M269.474,452.716h-26.947v-16.168h26.947V452.716z M242.526,490.442v-21.558
|
|
||||||
h26.947v21.558H242.526z M377.263,452.716h-26.947v-16.168h26.947V452.716z M350.316,490.442v-21.558h26.947v21.558H350.316z
|
|
||||||
M436.547,350.316h16.168v26.947h-16.168V350.316z M495.832,377.263h-26.947v-26.947h26.947V377.263z M436.547,242.526h16.168
|
|
||||||
v26.947h-16.168V242.526z M495.832,269.474h-26.947v-26.947h26.947V269.474z M420.379,417.684c0,1.461-1.234,2.695-2.695,2.695
|
|
||||||
H94.316c-1.461,0-2.695-1.234-2.695-2.695V94.316c0-1.461,1.234-2.695,2.695-2.695h323.368c1.461,0,2.695,1.234,2.695,2.695V417.684
|
|
||||||
z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.8 KiB |
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg width="800px" height="800px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
|
||||||
|
|
||||||
<title>cross-circle</title>
|
|
||||||
<desc>Created with Sketch Beta.</desc>
|
|
||||||
<defs>
|
|
||||||
|
|
||||||
</defs>
|
|
||||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
|
||||||
<g id="Icon-Set" sketch:type="MSLayerGroup" transform="translate(-568.000000, -1087.000000)" fill="red">
|
|
||||||
<path d="M584,1117 C576.268,1117 570,1110.73 570,1103 C570,1095.27 576.268,1089 584,1089 C591.732,1089 598,1095.27 598,1103 C598,1110.73 591.732,1117 584,1117 L584,1117 Z M584,1087 C575.163,1087 568,1094.16 568,1103 C568,1111.84 575.163,1119 584,1119 C592.837,1119 600,1111.84 600,1103 C600,1094.16 592.837,1087 584,1087 L584,1087 Z M589.717,1097.28 C589.323,1096.89 588.686,1096.89 588.292,1097.28 L583.994,1101.58 L579.758,1097.34 C579.367,1096.95 578.733,1096.95 578.344,1097.34 C577.953,1097.73 577.953,1098.37 578.344,1098.76 L582.58,1102.99 L578.314,1107.26 C577.921,1107.65 577.921,1108.29 578.314,1108.69 C578.708,1109.08 579.346,1109.08 579.74,1108.69 L584.006,1104.42 L588.242,1108.66 C588.633,1109.05 589.267,1109.05 589.657,1108.66 C590.048,1108.27 590.048,1107.63 589.657,1107.24 L585.42,1103.01 L589.717,1098.71 C590.11,1098.31 590.11,1097.68 589.717,1097.28 L589.717,1097.28 Z" id="cross-circle" sketch:type="MSShapeGroup">
|
|
||||||
|
|
||||||
</path>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,4 +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 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M18.59 5.88997C17.36 5.31997 16.05 4.89997 14.67 4.65997C14.5 4.95997 14.3 5.36997 14.17 5.69997C12.71 5.47997 11.26 5.47997 9.83001 5.69997C9.69001 5.36997 9.49001 4.95997 9.32001 4.65997C7.94001 4.89997 6.63001 5.31997 5.40001 5.88997C2.92001 9.62997 2.25001 13.28 2.58001 16.87C4.23001 18.1 5.82001 18.84 7.39001 19.33C7.78001 18.8 8.12001 18.23 8.42001 17.64C7.85001 17.43 7.31001 17.16 6.80001 16.85C6.94001 16.75 7.07001 16.64 7.20001 16.54C10.33 18 13.72 18 16.81 16.54C16.94 16.65 17.07 16.75 17.21 16.85C16.7 17.16 16.15 17.42 15.59 17.64C15.89 18.23 16.23 18.8 16.62 19.33C18.19 18.84 19.79 18.1 21.43 16.87C21.82 12.7 20.76 9.08997 18.61 5.88997H18.59ZM8.84001 14.67C7.90001 14.67 7.13001 13.8 7.13001 12.73C7.13001 11.66 7.88001 10.79 8.84001 10.79C9.80001 10.79 10.56 11.66 10.55 12.73C10.55 13.79 9.80001 14.67 8.84001 14.67ZM15.15 14.67C14.21 14.67 13.44 13.8 13.44 12.73C13.44 11.66 14.19 10.79 15.15 10.79C16.11 10.79 16.87 11.66 16.86 12.73C16.86 13.79 16.11 14.67 15.15 14.67Z" fill="#000000"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1 +0,0 @@
|
|||||||
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
|
|
Before Width: | Height: | Size: 963 B |
Before Width: | Height: | Size: 567 KiB |
@@ -1,4 +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 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3103 1.77586C11.6966 1.40805 12.3034 1.40805 12.6897 1.77586L20.6897 9.39491L23.1897 11.7759C23.5896 12.1567 23.605 12.7897 23.2241 13.1897C22.8433 13.5896 22.2103 13.605 21.8103 13.2241L21 12.4524V20C21 21.1046 20.1046 22 19 22H14H10H5C3.89543 22 3 21.1046 3 20V12.4524L2.18966 13.2241C1.78972 13.605 1.15675 13.5896 0.775862 13.1897C0.394976 12.7897 0.410414 12.1567 0.810345 11.7759L3.31034 9.39491L11.3103 1.77586ZM5 10.5476V20H9V15C9 13.3431 10.3431 12 12 12C13.6569 12 15 13.3431 15 15V20H19V10.5476L12 3.88095L5 10.5476ZM13 20V15C13 14.4477 12.5523 14 12 14C11.4477 14 11 14.4477 11 15V20H13Z" fill="#000000"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 901 B |