Compare commits
27 Commits
v1.7.4-pre
...
branch-v1.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9922e61b44 | ||
![]() |
98a09c32f8 | ||
![]() |
81b58e9b9f | ||
![]() |
928a1538ea | ||
![]() |
f4a8892cbb | ||
![]() |
c4435628e0 | ||
![]() |
933c624885 | ||
![]() |
06e344c74a | ||
![]() |
9150ce7377 | ||
![]() |
08a40e3dd9 | ||
![]() |
d7fca42057 | ||
![]() |
1672520a29 | ||
![]() |
3366d926f4 | ||
![]() |
6d7f6f63c6 | ||
![]() |
590a7829b1 | ||
![]() |
ae75fc1490 | ||
![]() |
0c645d04aa | ||
![]() |
13b3764fcf | ||
![]() |
57d4fe7cf9 | ||
![]() |
fd7b354571 | ||
![]() |
be1d53b3b1 | ||
![]() |
e0cff36819 | ||
![]() |
cea654692e | ||
![]() |
c82ffb6c97 | ||
![]() |
7400a8c040 | ||
![]() |
eda171efa1 | ||
![]() |
f881459c0b |
@@ -1,6 +1,10 @@
|
||||
FROM mcr.microsoft.com/devcontainers/dotnet:1-8.0-bookworm
|
||||
|
||||
RUN apt-get update && apt-get install -y p7zip-full
|
||||
RUN mkdir -p /workspace/gaseous-server/wwwroot/emulators/EmulatorJS
|
||||
RUN wget https://cdn.emulatorjs.org/releases/4.0.11.7z
|
||||
RUN 7z x -y -o/workspace/gaseous-server/wwwroot/emulators/EmulatorJS 4.0.11.7z
|
||||
# update apt-get
|
||||
RUN apt-get update
|
||||
|
||||
# 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
|
@@ -59,5 +59,7 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
gaseousgames/gaseousserver:latest-embeddeddb
|
||||
gaseousgames/gaseousserver:${{ github.ref_name}}-embeddeddb
|
||||
ghcr.io/gaseous-project/gaseousserver:latest-embeddeddb
|
||||
ghcr.io/gaseous-project/gaseousserver:${{ github.ref_name}}-embeddeddb
|
||||
|
13
.github/workflows/BuildOnTestBranch.yml
vendored
13
.github/workflows/BuildOnTestBranch.yml
vendored
@@ -27,10 +27,19 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
- 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/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
|
85
.github/workflows/codeql.yml
vendored
85
.github/workflows/codeql.yml
vendored
@@ -1,85 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main", "branch-v*.*.*" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "main" ]
|
||||
schedule:
|
||||
- cron: '21 11 * * 2'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp', 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- 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"
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
3
.vscode/launch.json
vendored
3
.vscode/launch.json
vendored
@@ -24,7 +24,8 @@
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
"enableStepFiltering": false
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
|
20
Gaseous.sln
20
Gaseous.sln
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 25.0.1704.4
|
||||
@@ -27,30 +27,18 @@ Global
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{08699C93-15CD-4E39-9053-D3C8056CE938}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FFCEC386-033F-4772-A45B-D33579F2E5EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.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.Build.0 = Release|Any CPU
|
||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {979BF092-AFBC-4F19-B55F-32E73959BD1A}
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F1A847C7-57BC-4DA9-8F83-CD060A7F5122} = {17FA6F12-8532-420C-9489-CB8FDE42137C}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {979BF092-AFBC-4F19-B55F-32E73959BD1A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
147
LICENSE
147
LICENSE
@@ -1,5 +1,5 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@@ -7,17 +7,15 @@
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@@ -72,7 +60,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@@ -631,44 +629,33 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
Gaseous
|
||||
Copyright (C) 2023 Gaseous
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) 2023 Gaseous
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
@@ -14,19 +14,14 @@ RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
||||
# 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
|
||||
|
||||
# disabled for 1.7.4 as the next version EmulatorJS is not yet available
|
||||
# # update apt-get
|
||||
# RUN apt-get update
|
||||
# update apt-get
|
||||
RUN apt-get update
|
||||
|
||||
# # 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.0.12.7z
|
||||
# RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
|
||||
RUN wget --recursive --no-parent https://cdn.emulatorjs.org/latest/
|
||||
# download and unzip EmulatorJS from CDN
|
||||
RUN apt-get install -y p7zip-full
|
||||
RUN mkdir -p out/wwwroot/emulators/EmulatorJS
|
||||
RUN cp -fr cdn.emulatorjs.org/latest/* out/wwwroot/emulators/EmulatorJS
|
||||
RUN rm -Rf cdn.emulatorjs.org
|
||||
RUN wget https://cdn.emulatorjs.org/releases/4.1.1.7z
|
||||
RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.1.1.7z
|
||||
|
||||
# clean up apt-get
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists
|
||||
@@ -37,5 +32,8 @@ ENV INDOCKER=1
|
||||
WORKDIR /App
|
||||
COPY --from=build-env /App/out .
|
||||
|
||||
# Configure healthcheck
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 CMD curl --fail http://localhost:80/healthCheck || exit 1
|
||||
|
||||
# start gaseous-server
|
||||
ENTRYPOINT ["dotnet", "gaseous-server.dll"]
|
||||
|
@@ -14,15 +14,15 @@ RUN dotnet restore "gaseous-server/gaseous-server.csproj" -a $TARGETARCH
|
||||
# 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
|
||||
|
||||
# disabled for 1.7.4 as the next version EmulatorJS is not yet available
|
||||
# # update apt-get
|
||||
# RUN apt-get update
|
||||
# update apt-get
|
||||
RUN apt-get update
|
||||
|
||||
# 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
|
||||
|
||||
# # 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.0.12.7z
|
||||
# RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.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
|
||||
@@ -35,10 +35,19 @@ WORKDIR /App
|
||||
COPY --from=build-env /App/out .
|
||||
|
||||
# variables
|
||||
ENV dbhost=localhost
|
||||
ENV dbuser=root
|
||||
ENV dbpass=gaseous
|
||||
ENV MARIADB_ROOT_PASSWORD=$dbpass
|
||||
ARG PUID=1000
|
||||
ARG PGID=1000
|
||||
ARG dbhost=localhost
|
||||
ARG dbuser=root
|
||||
ARG dbpass=gaseous
|
||||
ARG MARIADB_ROOT_PASSWORD=$dbpass
|
||||
|
||||
ENV PUID=${PUID}
|
||||
ENV PGID=${PGID}
|
||||
ENV dbhost=${dbhost}
|
||||
ENV dbuser=${dbuser}
|
||||
ENV dbpass=${dbpass}
|
||||
ENV MARIADB_ROOT_PASSWORD=${dbpass}
|
||||
|
||||
# install mariadb
|
||||
RUN DEBIAN_FRONTEND=noninteractive && \
|
||||
@@ -50,12 +59,18 @@ RUN chmod +x /usr/sbin/start-mariadb.sh
|
||||
# install supervisord
|
||||
RUN apt-get install -y supervisor
|
||||
COPY ../build/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/entrypoint.sh /usr/sbin/entrypoint.sh
|
||||
RUN chmod +x /usr/sbin/entrypoint.sh
|
||||
|
||||
# volumes
|
||||
VOLUME /root/.gaseous-server /var/lib/mysql
|
||||
VOLUME /home/gaseous/.gaseous-server /var/lib/mysql
|
||||
|
||||
# start services
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||
ENTRYPOINT [ "/usr/sbin/entrypoint.sh" ]
|
||||
|
13
build/entrypoint.sh
Normal file
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,9 +1,20 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
|
||||
# Wait for the service to start
|
||||
while ! mysqladmin ping -h localhost --silent; do
|
||||
sleep 1
|
||||
done
|
||||
# install the database
|
||||
/usr/bin/mariadb-install-db --datadir=/var/lib/mysql --user=gaseous
|
||||
|
||||
# Set the root password
|
||||
mariadb -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD';"
|
||||
# start the database server without network or grant tables
|
||||
/usr/sbin/mariadbd --datadir=/var/lib/mysql --skip-grant-tables --skip-networking &
|
||||
|
||||
# wait for the server to start
|
||||
sleep 5
|
||||
|
||||
# change the 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;"
|
||||
|
||||
# stop the server
|
||||
sleep 5
|
||||
killall mariadbd
|
||||
|
||||
# start the server normally
|
||||
/usr/sbin/mariadbd --datadir=/var/lib/mysql
|
||||
|
@@ -1,29 +1,35 @@
|
||||
[supervisord]
|
||||
user=root
|
||||
nodaemon=true
|
||||
logfile=/dev/null
|
||||
logfile_maxbytes=0
|
||||
pidfile=/var/run/supervisord.pid
|
||||
loglevel = INFO
|
||||
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:mariadb]
|
||||
command=/usr/sbin/mariadbd --user=root
|
||||
autostart=true
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
|
||||
[program:mariadb-setup]
|
||||
user=gaseous
|
||||
command=bash -c "/usr/sbin/start-mariadb.sh"
|
||||
autostart=true
|
||||
autorestart=false
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stdout_logfile=/dev/fd/1
|
||||
stdout_logfile_maxbytes=0
|
||||
|
||||
[program:gaseous-server]
|
||||
user=gaseous
|
||||
command=dotnet /App/gaseous-server.dll
|
||||
environment=HOME="/home/gaseous",USER="gaseous"
|
||||
autostart=true
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
@@ -158,6 +159,50 @@ namespace gaseous_server.Classes
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetLookupByCode(LookupTypes LookupType, string Code)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT Id FROM " + LookupType.ToString() + " WHERE Code = @code";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||
{ "code", Code }
|
||||
};
|
||||
|
||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||
if (data.Rows.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)data.Rows[0]["Id"];
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetLookupByValue(LookupTypes LookupType, string Value)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT Id FROM " + LookupType.ToString() + " WHERE Value = @value";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>{
|
||||
{ "value", Value }
|
||||
};
|
||||
|
||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||
if (data.Rows.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)data.Rows[0]["Id"];
|
||||
}
|
||||
}
|
||||
|
||||
public enum LookupTypes
|
||||
{
|
||||
Country,
|
||||
Language
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -80,7 +80,8 @@ namespace gaseous_server.Classes
|
||||
get
|
||||
{
|
||||
string logPath = Path.Combine(ConfigurationPath, "Logs");
|
||||
if (!Directory.Exists(logPath)) {
|
||||
if (!Directory.Exists(logPath))
|
||||
{
|
||||
Directory.CreateDirectory(logPath);
|
||||
}
|
||||
return logPath;
|
||||
@@ -360,8 +361,10 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
||||
Type type = typeof(T);
|
||||
if (type.ToString() == "System.DateTime")
|
||||
|
||||
switch (type.ToString())
|
||||
{
|
||||
case "System.DateTime":
|
||||
dbDict = new Dictionary<string, object>
|
||||
{
|
||||
{ "SettingName", SettingName },
|
||||
@@ -369,9 +372,19 @@ namespace gaseous_server.Classes
|
||||
{ "Value", null },
|
||||
{ "ValueDate", Value }
|
||||
};
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
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>
|
||||
{
|
||||
{ "SettingName", SettingName },
|
||||
@@ -379,6 +392,7 @@ namespace gaseous_server.Classes
|
||||
{ "Value", Value },
|
||||
{ "ValueDate", null }
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -427,7 +441,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
public class Database
|
||||
{
|
||||
private static string _DefaultHostName {
|
||||
private static string _DefaultHostName
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("dbhost")))
|
||||
|
@@ -64,6 +64,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
public static void PostUpgradeScript(int TargetSchemaVersion, Database.databaseType? DatabaseType)
|
||||
{
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
@@ -103,6 +105,48 @@ namespace gaseous_server.Classes
|
||||
sql = "DELETE FROM Settings WHERE Setting LIKE 'LastRun_%';";
|
||||
db.ExecuteNonQuery(sql);
|
||||
break;
|
||||
|
||||
case 1023:
|
||||
// load country list
|
||||
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Adding country look up table contents");
|
||||
|
||||
string countryResourceName = "gaseous_server.Support.Country.txt";
|
||||
using (Stream stream = assembly.GetManifestResourceStream(countryResourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
do
|
||||
{
|
||||
string[] line = reader.ReadLine().Split("|");
|
||||
|
||||
sql = "INSERT INTO Country (Code, Value) VALUES (@code, @value);";
|
||||
dbDict = new Dictionary<string, object>{
|
||||
{ "code", line[0] },
|
||||
{ "value", line[1] }
|
||||
};
|
||||
db.ExecuteNonQuery(sql, dbDict);
|
||||
} while (reader.EndOfStream == false);
|
||||
}
|
||||
|
||||
// load language list
|
||||
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Adding language look up table contents");
|
||||
|
||||
string languageResourceName = "gaseous_server.Support.Language.txt";
|
||||
using (Stream stream = assembly.GetManifestResourceStream(languageResourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
do
|
||||
{
|
||||
string[] line = reader.ReadLine().Split("|");
|
||||
|
||||
sql = "INSERT INTO Language (Code, Value) VALUES (@code, @value);";
|
||||
dbDict = new Dictionary<string, object>{
|
||||
{ "code", line[0] },
|
||||
{ "value", line[1] }
|
||||
};
|
||||
db.ExecuteNonQuery(sql, dbDict);
|
||||
} while (reader.EndOfStream == false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -121,7 +165,8 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
|
||||
public static void MySql_1002_MigrateMetadataVersion() {
|
||||
public static void MySql_1002_MigrateMetadataVersion()
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
|
@@ -121,7 +121,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
if (zfi != null)
|
||||
{
|
||||
ArchiveData archiveData = new ArchiveData{
|
||||
ArchiveData archiveData = new ArchiveData
|
||||
{
|
||||
FileName = Path.GetFileName(file),
|
||||
FilePath = zfi.Directory.FullName.Replace(ExtractPath, ""),
|
||||
Size = zfi.Length,
|
||||
|
@@ -28,7 +28,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
// import files first
|
||||
int importCount = 1;
|
||||
foreach (string importContent in importContents) {
|
||||
foreach (string importContent in importContents)
|
||||
{
|
||||
SetStatus(importCount, importContents.Length, "Importing file: " + importContent);
|
||||
|
||||
ImportGameFile(importContent, null);
|
||||
@@ -180,7 +181,13 @@ namespace gaseous_server.Classes
|
||||
|
||||
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());
|
||||
IGDB.Models.Game[] games = Metadata.Games.SearchForGame(SearchCandidate, PlatformId, searchType);
|
||||
@@ -197,8 +204,10 @@ namespace gaseous_server.Classes
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + games.Length + " search results found");
|
||||
|
||||
// quite likely we've found sequels and alternate types
|
||||
foreach (Game game in games) {
|
||||
if (game.Name == SearchCandidate) {
|
||||
foreach (Game game in games)
|
||||
{
|
||||
if (game.Name == SearchCandidate)
|
||||
{
|
||||
// found game title matches the search candidate
|
||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false, false);
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", "Found exact match!");
|
||||
@@ -236,7 +245,13 @@ namespace gaseous_server.Classes
|
||||
|
||||
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))
|
||||
{
|
||||
@@ -273,7 +288,8 @@ namespace gaseous_server.Classes
|
||||
|
||||
// assumption: no games have () in their titles so we'll remove them
|
||||
int idx = GameName.IndexOf('(');
|
||||
if (idx >= 0) {
|
||||
if (idx >= 0)
|
||||
{
|
||||
GameName = GameName.Substring(0, idx);
|
||||
}
|
||||
|
||||
@@ -305,7 +321,8 @@ namespace gaseous_server.Classes
|
||||
if (UpdateId == 0)
|
||||
{
|
||||
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, Path, MetadataSource, MetadataGameName, MetadataVersion, LibraryId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion WHERE Id=@id;";
|
||||
dbDict.Add("id", UpdateId);
|
||||
@@ -348,7 +365,8 @@ namespace gaseous_server.Classes
|
||||
if (UpdateId == 0)
|
||||
{
|
||||
romId = (long)romInsert.Rows[0][0];
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
romId = UpdateId;
|
||||
}
|
||||
@@ -411,12 +429,10 @@ namespace gaseous_server.Classes
|
||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "Moving " + romPath + " to " + DestinationPath);
|
||||
if (File.Exists(DestinationPath))
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - aborting");
|
||||
return false;
|
||||
Logging.Log(Logging.LogType.Information, "Move Game ROM", "A file with the same name exists at the destination - overwriting");
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Move(romPath, DestinationPath);
|
||||
|
||||
File.Move(romPath, DestinationPath, true);
|
||||
|
||||
// update the db
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
@@ -429,7 +445,6 @@ namespace gaseous_server.Classes
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Move Game ROM", "File " + romPath + " appears to be missing!");
|
||||
|
@@ -38,10 +38,10 @@ namespace gaseous_server.Classes
|
||||
long deletedCount = 1;
|
||||
long deletedEventCount = 0;
|
||||
long maxLoops = 1000;
|
||||
while (deletedCount > 0)
|
||||
{
|
||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRetentionDate LIMIT 1000; SELECT ROW_COUNT() AS Count;";
|
||||
dbDict.Add("EventRetentionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||
while (deletedCount > 0)
|
||||
{
|
||||
DataTable deletedCountTable = db.ExecuteCMD(sql, dbDict);
|
||||
deletedCount = (long)deletedCountTable.Rows[0][0];
|
||||
deletedEventCount += deletedCount;
|
||||
|
@@ -7,7 +7,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class Games
|
||||
{
|
||||
const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collection,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
||||
const string fieldList = "fields age_ratings,aggregated_rating,aggregated_rating_count,alternative_names,artworks,bundles,category,checksum,collections,cover,created_at,dlcs,expanded_games,expansions,external_games,first_release_date,follows,forks,franchise,franchises,game_engines,game_localizations,game_modes,genres,hypes,involved_companies,keywords,language_supports,multiplayer_modes,name,parent_game,platforms,player_perspectives,ports,rating,rating_count,release_dates,remakes,remasters,screenshots,similar_games,slug,standalone_expansions,status,storyline,summary,tags,themes,total_rating,total_rating_count,updated_at,url,version_parent,version_title,videos,websites;";
|
||||
|
||||
public Games()
|
||||
{
|
||||
@@ -78,15 +78,17 @@ namespace gaseous_server.Classes.Metadata
|
||||
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
string searchField = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
searchField = "id";
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||
searchField = "slug";
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
@@ -110,11 +112,11 @@ namespace gaseous_server.Classes.Metadata
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||
returnValue = Storage.GetCacheValue<Game>(returnValue, "id", (long)searchValue);
|
||||
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||
}
|
||||
return returnValue;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<Game>(returnValue, "id", (long)searchValue);
|
||||
returnValue = Storage.GetCacheValue<Game>(returnValue, searchField, searchValue);
|
||||
UpdateSubClasses(returnValue, false, false, false);
|
||||
return returnValue;
|
||||
default:
|
||||
|
@@ -78,13 +78,16 @@ namespace gaseous_server.Classes.Metadata
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
string searchField = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
searchField = "id";
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
WhereClause = "where slug = \"" + searchValue + "\"";
|
||||
searchField = "slug";
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
@@ -111,10 +114,10 @@ namespace gaseous_server.Classes.Metadata
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||
return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue);
|
||||
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||
}
|
||||
case Storage.CacheStatus.Current:
|
||||
return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue);
|
||||
return Storage.GetCacheValue<Platform>(returnValue, searchField, searchValue);
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
@@ -236,4 +236,3 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -8,21 +8,49 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
{
|
||||
public class XMLIngestor : QueueItemStatus
|
||||
{
|
||||
public void Import(string SearchPath, gaseous_signature_parser.parser.SignatureParser XMLType)
|
||||
public void Import(string SearchPath, string ProcessedDirectory, gaseous_signature_parser.parser.SignatureParser XMLType)
|
||||
{
|
||||
// connect to database
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
|
||||
string? XMLDBSearchPath = null;
|
||||
string? XMLDBProcessedDirectory = null;
|
||||
if (XMLType == gaseous_signature_parser.parser.SignatureParser.NoIntro)
|
||||
{
|
||||
XMLDBSearchPath = Path.Combine(SearchPath, "DB");
|
||||
XMLDBProcessedDirectory = Path.Combine(ProcessedDirectory, "DB");
|
||||
SearchPath = Path.Combine(SearchPath, "DAT");
|
||||
ProcessedDirectory = Path.Combine(ProcessedDirectory, "DAT");
|
||||
}
|
||||
|
||||
// process provided files
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing from " + SearchPath);
|
||||
if (!Directory.Exists(SearchPath))
|
||||
{
|
||||
Directory.CreateDirectory(SearchPath);
|
||||
}
|
||||
if (!Directory.Exists(ProcessedDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(ProcessedDirectory);
|
||||
}
|
||||
|
||||
string[] PathContents = Directory.GetFiles(SearchPath);
|
||||
Array.Sort(PathContents);
|
||||
|
||||
string[]? DBPathContents = null;
|
||||
if (XMLDBSearchPath != null)
|
||||
{
|
||||
if (!Directory.Exists(XMLDBSearchPath))
|
||||
{
|
||||
Directory.CreateDirectory(XMLDBSearchPath);
|
||||
}
|
||||
if (!Directory.Exists(XMLDBProcessedDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(XMLDBProcessedDirectory);
|
||||
}
|
||||
|
||||
DBPathContents = Directory.GetFiles(XMLDBSearchPath);
|
||||
}
|
||||
|
||||
string sql = "";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
System.Data.DataTable sigDB;
|
||||
@@ -33,12 +61,28 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
|
||||
SetStatus(i + 1, PathContents.Length, "Processing signature file: " + XMLFile);
|
||||
|
||||
if (Common.SkippableFiles.Contains(Path.GetFileName(XMLFile), StringComparer.OrdinalIgnoreCase))
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingest", "(" + (i + 1) + " / " + PathContents.Length + ") Processing " + XMLType.ToString() + " DAT file: " + XMLFile);
|
||||
|
||||
string? DBFile = null;
|
||||
if (XMLDBSearchPath != null)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Skipping file: " + XMLFile);
|
||||
switch (XMLType)
|
||||
{
|
||||
case gaseous_signature_parser.parser.SignatureParser.NoIntro:
|
||||
for (UInt16 x = 0; x < DBPathContents.Length; x++)
|
||||
{
|
||||
string tempDBFileName = Path.GetFileNameWithoutExtension(DBPathContents[x].Replace(" (DB Export)", ""));
|
||||
if (tempDBFileName == Path.GetFileNameWithoutExtension(XMLFile))
|
||||
{
|
||||
DBFile = DBPathContents[x];
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingest", "Using DB file: " + DBFile);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check xml file md5
|
||||
Common.hashObject hashObject = new Common.hashObject(XMLFile);
|
||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
||||
@@ -50,11 +94,9 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
{
|
||||
try
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing file: " + XMLFile);
|
||||
|
||||
// start parsing file
|
||||
gaseous_signature_parser.parser Parser = new gaseous_signature_parser.parser();
|
||||
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, XMLType);
|
||||
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, DBFile, XMLType);
|
||||
|
||||
// store in database
|
||||
string[] flipNameAndDescription = {
|
||||
@@ -66,21 +108,27 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
bool processGames = false;
|
||||
if (Object.SourceMd5 != null)
|
||||
{
|
||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
||||
dbDict = new Dictionary<string, object>();
|
||||
string sourceUriStr = "";
|
||||
if (Object.Url != null)
|
||||
int sourceId = 0;
|
||||
|
||||
sql = "SELECT * FROM Signatures_Sources WHERE `SourceMD5`=@sourcemd5";
|
||||
dbDict = new Dictionary<string, object>
|
||||
{
|
||||
sourceUriStr = Object.Url.ToString();
|
||||
{ "name", Common.ReturnValueIfNull(Object.Name, "") },
|
||||
{ "description", Common.ReturnValueIfNull(Object.Description, "") },
|
||||
{ "category", Common.ReturnValueIfNull(Object.Category, "") },
|
||||
{ "version", Common.ReturnValueIfNull(Object.Version, "") },
|
||||
{ "author", Common.ReturnValueIfNull(Object.Author, "") },
|
||||
{ "email", Common.ReturnValueIfNull(Object.Email, "") },
|
||||
{ "homepage", Common.ReturnValueIfNull(Object.Homepage, "") }
|
||||
};
|
||||
if (Object.Url == null)
|
||||
{
|
||||
dbDict.Add("uri", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
dbDict.Add("uri", Common.ReturnValueIfNull(Object.Url.ToString(), ""));
|
||||
}
|
||||
dbDict.Add("name", Common.ReturnValueIfNull(Object.Name, ""));
|
||||
dbDict.Add("description", Common.ReturnValueIfNull(Object.Description, ""));
|
||||
dbDict.Add("category", Common.ReturnValueIfNull(Object.Category, ""));
|
||||
dbDict.Add("version", Common.ReturnValueIfNull(Object.Version, ""));
|
||||
dbDict.Add("author", Common.ReturnValueIfNull(Object.Author, ""));
|
||||
dbDict.Add("email", Common.ReturnValueIfNull(Object.Email, ""));
|
||||
dbDict.Add("homepage", Common.ReturnValueIfNull(Object.Homepage, ""));
|
||||
dbDict.Add("uri", sourceUriStr);
|
||||
dbDict.Add("sourcetype", Common.ReturnValueIfNull(Object.SourceType, ""));
|
||||
dbDict.Add("sourcemd5", Object.SourceMd5);
|
||||
dbDict.Add("sourcesha1", Object.SourceSHA1);
|
||||
@@ -89,9 +137,11 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
// entry not present, insert it
|
||||
sql = "INSERT INTO Signatures_Sources (Name, Description, Category, Version, Author, Email, Homepage, Url, SourceType, SourceMD5, SourceSHA1) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1)";
|
||||
sql = "INSERT INTO Signatures_Sources (`Name`, `Description`, `Category`, `Version`, `Author`, `Email`, `Homepage`, `Url`, `SourceType`, `SourceMD5`, `SourceSHA1`) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
sourceId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||
|
||||
processGames = true;
|
||||
}
|
||||
@@ -121,21 +171,88 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
||||
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
||||
dbDict.Add("country", Common.ReturnValueIfNull(gameObject.Country, ""));
|
||||
dbDict.Add("language", Common.ReturnValueIfNull(gameObject.Language, ""));
|
||||
|
||||
List<int> gameCountries = new List<int>();
|
||||
if (
|
||||
gameObject.Country != null &&
|
||||
gameObject.Country != "Unknown"
|
||||
)
|
||||
{
|
||||
string[] countries = gameObject.Country.Split(",");
|
||||
foreach (string country in countries)
|
||||
{
|
||||
int countryId = -1;
|
||||
countryId = Common.GetLookupByCode(Common.LookupTypes.Country, (string)Common.ReturnValueIfNull(country.Trim(), ""));
|
||||
if (countryId == -1)
|
||||
{
|
||||
countryId = Common.GetLookupByValue(Common.LookupTypes.Country, (string)Common.ReturnValueIfNull(country.Trim(), ""));
|
||||
|
||||
if (countryId == -1)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Unable to locate country id for " + country.Trim());
|
||||
sql = "INSERT INTO Country (`Code`, `Value`) VALUES (@code, @name); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
Dictionary<string, object> countryDict = new Dictionary<string, object>{
|
||||
{ "code", country.Trim() },
|
||||
{ "name", country.Trim() }
|
||||
};
|
||||
countryId = int.Parse(db.ExecuteCMD(sql, countryDict).Rows[0][0].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (countryId > 0)
|
||||
{
|
||||
gameCountries.Add(countryId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<int> gameLanguages = new List<int>();
|
||||
if (
|
||||
gameObject.Language != null &&
|
||||
gameObject.Language != "nolang"
|
||||
)
|
||||
{
|
||||
string[] languages = gameObject.Language.Split(",");
|
||||
foreach (string language in languages)
|
||||
{
|
||||
int languageId = -1;
|
||||
languageId = Common.GetLookupByCode(Common.LookupTypes.Language, (string)Common.ReturnValueIfNull(language.Trim(), ""));
|
||||
if (languageId == -1)
|
||||
{
|
||||
languageId = Common.GetLookupByValue(Common.LookupTypes.Language, (string)Common.ReturnValueIfNull(language.Trim(), ""));
|
||||
|
||||
if (languageId == -1)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Unable to locate language id for " + language.Trim());
|
||||
sql = "INSERT INTO Language (`Code`, `Value`) VALUES (@code, @name); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
Dictionary<string, object> langDict = new Dictionary<string, object>{
|
||||
{ "code", language.Trim() },
|
||||
{ "name", language.Trim() }
|
||||
};
|
||||
languageId = int.Parse(db.ExecuteCMD(sql, langDict).Rows[0][0].ToString());
|
||||
}
|
||||
}
|
||||
|
||||
if (languageId > 0)
|
||||
{
|
||||
gameLanguages.Add(languageId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
||||
|
||||
// store platform
|
||||
int gameSystem = 0;
|
||||
if (gameObject.System != null)
|
||||
{
|
||||
sql = "SELECT Id FROM Signatures_Platforms WHERE Platform=@platform";
|
||||
sql = "SELECT `Id` FROM Signatures_Platforms WHERE `Platform`=@platform";
|
||||
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
// entry not present, insert it
|
||||
sql = "INSERT INTO Signatures_Platforms (Platform) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sql = "INSERT INTO Signatures_Platforms (`Platform`) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
gameSystem = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||
@@ -151,13 +268,13 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
int gamePublisher = 0;
|
||||
if (gameObject.Publisher != null)
|
||||
{
|
||||
sql = "SELECT * FROM Signatures_Publishers WHERE Publisher=@publisher";
|
||||
sql = "SELECT * FROM Signatures_Publishers WHERE `Publisher`=@publisher";
|
||||
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
// entry not present, insert it
|
||||
sql = "INSERT INTO Signatures_Publishers (Publisher) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sql = "INSERT INTO Signatures_Publishers (`Publisher`) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||
}
|
||||
@@ -169,16 +286,16 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
dbDict.Add("publisherid", gamePublisher);
|
||||
|
||||
// store game
|
||||
int gameId = 0;
|
||||
sql = "SELECT * FROM Signatures_Games WHERE Name=@name AND Year=@year AND Publisherid=@publisher AND Systemid=@systemid AND Country=@country AND Language=@language";
|
||||
long gameId = 0;
|
||||
sql = "SELECT * FROM Signatures_Games WHERE `Name`=@name AND `Year`=@year AND `PublisherId`=@publisherid AND `SystemId`=@systemid";
|
||||
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
// entry not present, insert it
|
||||
sql = "INSERT INTO Signatures_Games " +
|
||||
"(Name, Description, Year, PublisherId, Demo, SystemId, SystemVariant, Video, Country, Language, Copyright) VALUES " +
|
||||
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
"(`Name`, `Description`, `Year`, `PublisherId`, `Demo`, `SystemId`, `SystemVariant`, `Video`, `Copyright`) VALUES " +
|
||||
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
gameId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||
@@ -188,13 +305,57 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
gameId = (int)sigDB.Rows[0][0];
|
||||
}
|
||||
|
||||
// insert countries
|
||||
foreach (int gameCountry in gameCountries)
|
||||
{
|
||||
try
|
||||
{
|
||||
sql = "SELECT * FROM Signatures_Games_Countries WHERE GameId = @gameid AND CountryId = @Countryid";
|
||||
Dictionary<string, object> countryDict = new Dictionary<string, object>{
|
||||
{ "gameid", gameId },
|
||||
{ "Countryid", gameCountry }
|
||||
};
|
||||
if (db.ExecuteCMD(sql, countryDict).Rows.Count == 0)
|
||||
{
|
||||
sql = "INSERT INTO Signatures_Games_Countries (GameId, CountryId) VALUES (@gameid, @Countryid)";
|
||||
db.ExecuteCMD(sql, countryDict);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Game id: " + gameId + " with Country " + gameCountry);
|
||||
}
|
||||
}
|
||||
|
||||
// insert languages
|
||||
foreach (int gameLanguage in gameLanguages)
|
||||
{
|
||||
try
|
||||
{
|
||||
sql = "SELECT * FROM Signatures_Games_Languages WHERE GameId = @gameid AND LanguageId = @languageid";
|
||||
Dictionary<string, object> langDict = new Dictionary<string, object>{
|
||||
{ "gameid", gameId },
|
||||
{ "languageid", gameLanguage }
|
||||
};
|
||||
if (db.ExecuteCMD(sql, langDict).Rows.Count == 0)
|
||||
{
|
||||
sql = "INSERT INTO Signatures_Games_Languages (GameId, LanguageId) VALUES (@gameid, @languageid)";
|
||||
db.ExecuteCMD(sql, langDict);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Game id: " + gameId + " with language " + gameLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
// store rom
|
||||
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||
{
|
||||
if (romObject.Md5 != null || romObject.Sha1 != null)
|
||||
{
|
||||
int romId = 0;
|
||||
sql = "SELECT * FROM Signatures_Roms WHERE GameId=@gameid AND MD5=@md5";
|
||||
long romId = 0;
|
||||
sql = "SELECT * FROM Signatures_Roms WHERE `GameId`=@gameid AND (`MD5`=@md5 OR `SHA1`=@sha1)";
|
||||
dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("gameid", gameId);
|
||||
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
||||
@@ -212,12 +373,12 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
}
|
||||
else
|
||||
{
|
||||
dbDict.Add("attributes", "[ ]");
|
||||
dbDict.Add("attributes", "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dbDict.Add("attributes", "[ ]");
|
||||
dbDict.Add("attributes", "");
|
||||
}
|
||||
dbDict.Add("romtype", (int)romObject.RomType);
|
||||
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
||||
@@ -229,30 +390,51 @@ namespace gaseous_server.SignatureIngestors.XML
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
// entry not present, insert it
|
||||
sql = "INSERT INTO Signatures_Roms (GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, MetadataSource, IngestorVersion) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sql = "INSERT INTO Signatures_Roms (`GameId`, `Name`, `Size`, `CRC`, `MD5`, `SHA1`, `DevelopmentStatus`, `Attributes`, `RomType`, `RomTypeMedia`, `MediaLabel`, `MetadataSource`, `IngestorVersion`) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
|
||||
romId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
romId = (int)sigDB.Rows[0][0];
|
||||
}
|
||||
|
||||
// map the rom to the source
|
||||
sql = "SELECT * FROM Signatures_RomToSource WHERE SourceId=@sourceid AND RomId=@romid;";
|
||||
dbDict.Add("romid", romId);
|
||||
dbDict.Add("sourceId", sourceId);
|
||||
|
||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||
if (sigDB.Rows.Count == 0)
|
||||
{
|
||||
sql = "INSERT INTO Signatures_RomToSource (`SourceId`, `RomId`) VALUES (@sourceid, @romid);";
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File.Move(XMLFile, Path.Combine(ProcessedDirectory, Path.GetFileName(XMLFile)));
|
||||
if (DBFile != null)
|
||||
{
|
||||
File.Move(DBFile, Path.Combine(XMLDBProcessedDirectory, Path.GetFileName(DBFile)));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Signature Ingestor - XML", "Invalid import file: " + XMLFile, ex);
|
||||
Logging.Log(Logging.LogType.Warning, "Signature Ingest", "Error ingesting " + XMLType.ToString() + " file: " + XMLFile, ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(Logging.LogType.Debug, "Signature Ingestor - XML", "Rejecting already imported file: " + XMLFile);
|
||||
Logging.Log(Logging.LogType.Information, "Signature Ingest", "Rejecting already imported " + XMLType.ToString() + " file: " + XMLFile);
|
||||
File.Move(XMLFile, Path.Combine(ProcessedDirectory, Path.GetFileName(XMLFile)));
|
||||
if (DBFile != null)
|
||||
{
|
||||
File.Move(DBFile, Path.Combine(XMLDBProcessedDirectory, Path.GetFileName(DBFile)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System.Data;
|
||||
using gaseous_server.Models;
|
||||
using gaseous_signature_parser.models.RomSignatureObject;
|
||||
|
||||
namespace gaseous_server.Classes
|
||||
@@ -10,7 +11,8 @@ namespace gaseous_server.Classes
|
||||
if (md5.Length > 0)
|
||||
{
|
||||
return _GetSignature("Signatures_Roms.md5 = @searchstring", md5);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return _GetSignature("Signatures_Roms.sha1 = @searchstring", sha1);
|
||||
}
|
||||
@@ -21,7 +23,8 @@ namespace gaseous_server.Classes
|
||||
if (TosecName.Length > 0)
|
||||
{
|
||||
return _GetSignature("Signatures_Roms.name = @searchstring", TosecName);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -53,8 +56,8 @@ namespace gaseous_server.Classes
|
||||
System = (string)sigDbRow["Platform"],
|
||||
SystemVariant = (string)sigDbRow["SystemVariant"],
|
||||
Video = (string)sigDbRow["Video"],
|
||||
Country = (string)sigDbRow["Country"],
|
||||
Language = (string)sigDbRow["Language"],
|
||||
Country = "",
|
||||
Language = "",
|
||||
Copyright = (string)sigDbRow["Copyright"]
|
||||
},
|
||||
Rom = new gaseous_server.Models.Signatures_Games.RomItem
|
||||
@@ -66,16 +69,66 @@ namespace gaseous_server.Classes
|
||||
Md5 = ((string)sigDbRow["MD5"]).ToLower(),
|
||||
Sha1 = ((string)sigDbRow["SHA1"]).ToLower(),
|
||||
DevelopmentStatus = (string)sigDbRow["DevelopmentStatus"],
|
||||
Attributes = Newtonsoft.Json.JsonConvert.DeserializeObject<List<KeyValuePair<string, object>>>((string)Common.ReturnValueIfNull(sigDbRow["Attributes"], "[]")),
|
||||
RomType = (gaseous_server.Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["RomType"],
|
||||
RomTypeMedia = (string)sigDbRow["RomTypeMedia"],
|
||||
MediaLabel = (string)sigDbRow["MediaLabel"],
|
||||
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);
|
||||
}
|
||||
return GamesList;
|
||||
}
|
||||
|
||||
public List<Signatures_Sources> GetSources()
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT * FROM Signatures_Sources ORDER BY `SourceType`, `Name`;";
|
||||
DataTable sigDb = db.ExecuteCMD(sql);
|
||||
|
||||
List<Signatures_Sources> SourcesList = new List<Signatures_Sources>();
|
||||
|
||||
foreach (DataRow sigDbRow in sigDb.Rows)
|
||||
{
|
||||
Signatures_Sources sourceItem = new Signatures_Sources
|
||||
{
|
||||
Id = (int)sigDbRow["Id"],
|
||||
Name = (string)sigDbRow["Name"],
|
||||
Description = (string)sigDbRow["Description"],
|
||||
URL = (string)sigDbRow["URL"],
|
||||
Category = (string)sigDbRow["Category"],
|
||||
Version = (string)sigDbRow["Version"],
|
||||
Author = (string)sigDbRow["Author"],
|
||||
Email = (string)sigDbRow["Email"],
|
||||
Homepage = (string)sigDbRow["Homepage"],
|
||||
SourceType = (gaseous_signature_parser.parser.SignatureParser)Enum.Parse(typeof(gaseous_signature_parser.parser.SignatureParser), sigDbRow["SourceType"].ToString()),
|
||||
MD5 = (string)sigDbRow["SourceMD5"],
|
||||
SHA1 = (string)sigDbRow["SourceSHA1"]
|
||||
};
|
||||
SourcesList.Add(sourceItem);
|
||||
}
|
||||
return SourcesList;
|
||||
}
|
||||
|
||||
public void DeleteSource(int sourceId)
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "DELETE FROM Signatures_Sources WHERE Id = @sourceId;";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||
{
|
||||
{ "sourceId", sourceId }
|
||||
};
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
}
|
||||
}
|
||||
}
|
@@ -15,7 +15,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class AccountController : Controller
|
||||
|
@@ -10,7 +10,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize(Roles = "Admin,Gamer,Player")]
|
||||
public class BackgroundTasksController : Controller
|
||||
|
@@ -12,7 +12,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class BiosController : Controller
|
||||
|
@@ -14,7 +14,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class CollectionsController : Controller
|
||||
|
@@ -15,7 +15,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
|
@@ -22,7 +22,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
@@ -474,7 +474,8 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
IGDB.Models.Artwork artworkObject = Artworks.GetArtwork(ArtworkId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), true);
|
||||
|
||||
if (artworkObject != null) {
|
||||
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");
|
||||
@@ -584,7 +585,8 @@ namespace gaseous_server.Controllers
|
||||
|
||||
string coverFilePath = ImgFetch.Result;
|
||||
|
||||
if (System.IO.File.Exists(coverFilePath)) {
|
||||
if (System.IO.File.Exists(coverFilePath))
|
||||
{
|
||||
string filename = cover.ImageId + ".jpg";
|
||||
string filepath = coverFilePath;
|
||||
byte[] filedata = System.IO.File.ReadAllBytes(filepath);
|
||||
@@ -796,7 +798,8 @@ namespace gaseous_server.Controllers
|
||||
companyData.Add("company", company);
|
||||
|
||||
return Ok(companyData);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
@@ -1388,7 +1391,8 @@ namespace gaseous_server.Controllers
|
||||
try
|
||||
{
|
||||
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||
if (gameObject != null) {
|
||||
if (gameObject != null)
|
||||
{
|
||||
IGDB.Models.Screenshot screenshotObject = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(gameObject), false);
|
||||
if (screenshotObject != null)
|
||||
{
|
||||
|
@@ -11,7 +11,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public class LibraryController : Controller
|
||||
|
@@ -11,7 +11,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize(Roles = "Admin")]
|
||||
public class LogsController : Controller
|
||||
|
@@ -19,7 +19,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
|
@@ -18,7 +18,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
|
@@ -19,7 +19,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
[ApiController]
|
||||
|
@@ -18,7 +18,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class SearchController : Controller
|
||||
|
@@ -9,6 +9,7 @@ using gaseous_signature_parser.models.RomSignatureObject;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Asp.Versioning;
|
||||
using gaseous_server.Models;
|
||||
|
||||
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||
|
||||
@@ -16,7 +17,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]/[action]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class SignaturesController : Controller
|
||||
@@ -54,11 +55,34 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
SignatureManagement signatureManagement = new SignatureManagement();
|
||||
return signatureManagement.GetByTosecName(TosecName);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public List<Signatures_Sources> GetSignatureSources()
|
||||
{
|
||||
SignatureManagement signatureManagement = new SignatureManagement();
|
||||
return signatureManagement.GetSources();
|
||||
}
|
||||
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpDelete]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public IActionResult DeleteSignatureSource(int Id)
|
||||
{
|
||||
SignatureManagement signatureManagement = new SignatureManagement();
|
||||
signatureManagement.DeleteSource(Id);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,7 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[Authorize]
|
||||
public class SystemController : Controller
|
||||
@@ -260,7 +260,13 @@ namespace gaseous_server.Controllers
|
||||
{
|
||||
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
||||
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention,
|
||||
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString()))
|
||||
EmulatorDebugMode = Boolean.Parse(Config.ReadSetting<string>("emulatorDebugMode", false.ToString())),
|
||||
SearchTypes = Config.ReadSetting<List<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
|
||||
})
|
||||
};
|
||||
|
||||
return Ok(systemSettingsModel);
|
||||
@@ -279,6 +285,7 @@ namespace gaseous_server.Controllers
|
||||
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
||||
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
||||
Config.SetSetting<string>("emulatorDebugMode", model.EmulatorDebugMode.ToString());
|
||||
Config.SetSetting<List<Classes.Metadata.Games.SearchType>>("DefaultSearchMethods", model.SearchTypes);
|
||||
Config.UpdateConfig();
|
||||
}
|
||||
|
||||
@@ -719,5 +726,6 @@ namespace gaseous_server.Controllers
|
||||
public bool AlwaysLogToDisk { get; set; }
|
||||
public int MinimumLogRetentionPeriod { get; set; }
|
||||
public bool EmulatorDebugMode { get; set; }
|
||||
public List<Classes.Metadata.Games.SearchType> SearchTypes { get; set; }
|
||||
}
|
||||
}
|
19
gaseous-server/Controllers/V1.1/HealthCheckController.cs
Normal file
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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,7 +11,7 @@ using System.IO.Compression;
|
||||
namespace gaseous_server.Controllers.v1_1
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[ApiController]
|
||||
public class StateManagerController : ControllerBase
|
||||
|
@@ -9,7 +9,7 @@ using Asp.Versioning;
|
||||
namespace gaseous_server.Controllers.v1_1
|
||||
{
|
||||
[Route("api/v{version:apiVersion}/[controller]")]
|
||||
[ApiVersion("1.0")]
|
||||
[ApiVersion("1.0", Deprecated = true)]
|
||||
[ApiVersion("1.1")]
|
||||
[ApiController]
|
||||
public class StatisticsController : ControllerBase
|
||||
|
@@ -20,4 +20,3 @@ namespace gaseous_server.Models
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
20
gaseous-server/Models/Signatures_Sources.cs
Normal file
20
gaseous-server/Models/Signatures_Sources.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using NuGet.Protocol.Core.Types;
|
||||
|
||||
namespace gaseous_server.Models
|
||||
{
|
||||
public class Signatures_Sources
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string URL { get; set; }
|
||||
public string Category { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Author { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Homepage { get; set; }
|
||||
public gaseous_signature_parser.parser.SignatureParser SourceType { get; set; }
|
||||
public string MD5 { get; set; }
|
||||
public string SHA1 { get; set; }
|
||||
}
|
||||
}
|
@@ -245,14 +245,32 @@ namespace gaseous_server
|
||||
CallingQueueItem = this
|
||||
};
|
||||
|
||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing TOSEC files");
|
||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "TOSEC"), gaseous_signature_parser.parser.SignatureParser.TOSEC);
|
||||
foreach (int i in Enum.GetValues(typeof(gaseous_signature_parser.parser.SignatureParser)))
|
||||
{
|
||||
gaseous_signature_parser.parser.SignatureParser parserType = (gaseous_signature_parser.parser.SignatureParser)i;
|
||||
if (
|
||||
parserType != gaseous_signature_parser.parser.SignatureParser.Auto &&
|
||||
parserType != gaseous_signature_parser.parser.SignatureParser.Unknown
|
||||
)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing " + parserType + " files");
|
||||
|
||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing MAME Arcade files");
|
||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "MAME Arcade"), gaseous_signature_parser.parser.SignatureParser.MAMEArcade);
|
||||
string SignaturePath = Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, parserType.ToString());
|
||||
string SignatureProcessedPath = Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, parserType.ToString());
|
||||
|
||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing MAME MESS files");
|
||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "MAME MESS"), gaseous_signature_parser.parser.SignatureParser.MAMEMess);
|
||||
if (!Directory.Exists(SignaturePath))
|
||||
{
|
||||
Directory.CreateDirectory(SignaturePath);
|
||||
}
|
||||
|
||||
if (!Directory.Exists(SignatureProcessedPath))
|
||||
{
|
||||
Directory.CreateDirectory(SignatureProcessedPath);
|
||||
}
|
||||
|
||||
tIngest.Import(SignaturePath, SignatureProcessedPath, parserType);
|
||||
}
|
||||
}
|
||||
|
||||
_SaveLastRunTime = true;
|
||||
|
||||
@@ -350,7 +368,8 @@ namespace gaseous_server
|
||||
|
||||
case QueueItemType.DailyMaintainer:
|
||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Daily Maintenance");
|
||||
Classes.Maintenance maintenance = new Maintenance{
|
||||
Classes.Maintenance maintenance = new Maintenance
|
||||
{
|
||||
CallingQueueItem = this
|
||||
};
|
||||
maintenance.RunDailyMaintenance();
|
||||
@@ -361,7 +380,8 @@ namespace gaseous_server
|
||||
|
||||
case QueueItemType.WeeklyMaintainer:
|
||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Weekly Maintenance");
|
||||
Classes.Maintenance weeklyMaintenance = new Maintenance{
|
||||
Classes.Maintenance weeklyMaintenance = new Maintenance
|
||||
{
|
||||
CallingQueueItem = this
|
||||
};
|
||||
weeklyMaintenance.RunWeeklyMaintenance();
|
||||
|
@@ -46,6 +46,14 @@ AgeRatings.PopulateAgeMap();
|
||||
// load app settings
|
||||
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;
|
||||
|
||||
@@ -128,7 +136,7 @@ builder.Services.AddControllers(options =>
|
||||
});
|
||||
builder.Services.AddApiVersioning(config =>
|
||||
{
|
||||
config.DefaultApiVersion = new ApiVersion(1, 0);
|
||||
config.DefaultApiVersion = new ApiVersion(1, 1);
|
||||
config.AssumeDefaultVersionWhenUnspecified = true;
|
||||
config.ReportApiVersions = true;
|
||||
config.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
|
||||
@@ -199,6 +207,9 @@ builder.Services.AddSwaggerGen(options =>
|
||||
// using System.Reflection;
|
||||
var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
|
||||
|
||||
// sort the endpoints
|
||||
options.OrderActionsBy((apiDesc) => $"{apiDesc.RelativePath}_{apiDesc.HttpMethod}");
|
||||
}
|
||||
);
|
||||
builder.Services.AddHostedService<TimedHostedService>();
|
||||
@@ -262,12 +273,15 @@ app.UseSwaggerUI(options =>
|
||||
|
||||
var descriptions = app.DescribeApiVersions();
|
||||
foreach (var description in descriptions)
|
||||
{
|
||||
if (description.IsDeprecated == false)
|
||||
{
|
||||
var url = $"/swagger/{description.GroupName}/swagger.json";
|
||||
var name = description.GroupName.ToUpperInvariant();
|
||||
options.SwaggerEndpoint(url, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//}
|
||||
|
||||
|
73
gaseous-server/Support/Country.txt
Normal file
73
gaseous-server/Support/Country.txt
Normal file
@@ -0,0 +1,73 @@
|
||||
AE|United Arab Emirates
|
||||
AL|Albania
|
||||
AS|Asia
|
||||
AT|Austria
|
||||
AU|Australia
|
||||
BA|Bosnia and Herzegovina
|
||||
BE|Belgium
|
||||
BG|Bulgaria
|
||||
BR|Brazil
|
||||
CA|Canada
|
||||
CH|Switzerland
|
||||
CL|Chile
|
||||
CN|China
|
||||
CS|Serbia and Montenegro
|
||||
CY|Cyprus
|
||||
CZ|Czech Republic
|
||||
DE|Germany
|
||||
DK|Denmark
|
||||
EE|Estonia
|
||||
EG|Egypt
|
||||
ES|Spain
|
||||
EU|Europe
|
||||
FI|Finland
|
||||
FR|France
|
||||
GB|United Kingdom
|
||||
GR|Greece
|
||||
HK|Hong Kong
|
||||
HR|Croatia
|
||||
HU|Hungary
|
||||
ID|Indonesia
|
||||
IE|Ireland
|
||||
IL|Israel
|
||||
IN|India
|
||||
IR|Iran
|
||||
IS|Iceland
|
||||
IT|Italy
|
||||
JO|Jordan
|
||||
JP|Japan
|
||||
KR|Korea
|
||||
KR|South Korea
|
||||
LT|Lithuania
|
||||
LU|Luxembourg
|
||||
LV|Latvia
|
||||
MN|Mongolia
|
||||
MX|Mexico
|
||||
MY|Malaysia
|
||||
NL|Netherlands
|
||||
NO|Norway
|
||||
NP|Nepal
|
||||
NZ|New Zealand
|
||||
OM|Oman
|
||||
PE|Peru
|
||||
PH|Philippines
|
||||
PL|Poland
|
||||
PT|Portugal
|
||||
QA|Qatar
|
||||
RO|Romania
|
||||
RU|Russia
|
||||
SE|Sweden
|
||||
SG|Singapore
|
||||
SI|Slovenia
|
||||
SK|Slovakia
|
||||
TH|Thailand
|
||||
TR|Turkey
|
||||
TW|Taiwan
|
||||
US|United States
|
||||
USA|United States
|
||||
VN|Vietnam
|
||||
YU|Yugoslavia
|
||||
ZA|South Africa
|
||||
World|World
|
||||
Europe|Europe
|
||||
Asia|Asia
|
1
gaseous-server/Support/Database/MySQL/gaseous-1022.sql
Normal file
1
gaseous-server/Support/Database/MySQL/gaseous-1022.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `Platform` CHANGE `Name` `Name` varchar(255);
|
37
gaseous-server/Support/Database/MySQL/gaseous-1023.sql
Normal file
37
gaseous-server/Support/Database/MySQL/gaseous-1023.sql
Normal file
@@ -0,0 +1,37 @@
|
||||
CREATE TABLE `Country` (
|
||||
`Id` INT NOT NULL AUTO_INCREMENT,
|
||||
`Code` VARCHAR(20) NULL,
|
||||
`Value` VARCHAR(255) NULL,
|
||||
PRIMARY KEY (`Id`),
|
||||
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
||||
INDEX `id_Value` (`Value` ASC) VISIBLE
|
||||
);
|
||||
|
||||
CREATE TABLE `Language` (
|
||||
`Id` INT NOT NULL AUTO_INCREMENT,
|
||||
`Code` VARCHAR(20) NULL,
|
||||
`Value` VARCHAR(255) NULL,
|
||||
PRIMARY KEY (`Id`),
|
||||
INDEX `id_Code` (`Code` ASC) VISIBLE,
|
||||
INDEX `id_Value` (`Value` ASC) VISIBLE
|
||||
);
|
||||
|
||||
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
|
||||
);
|
47
gaseous-server/Support/Language.txt
Normal file
47
gaseous-server/Support/Language.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
ar|Arabic
|
||||
bg|Bulgarian
|
||||
bs|Bosnian
|
||||
cs|Czech
|
||||
cy|Welsh
|
||||
da|Danish
|
||||
de|German
|
||||
el|Greek
|
||||
en|English
|
||||
eo|Esperanto
|
||||
es|Spanish
|
||||
et|Estonian
|
||||
fa|Persian
|
||||
fi|Finnish
|
||||
fr|French
|
||||
fr-ca|French Canadian
|
||||
ga|Irish
|
||||
gd|Gaelic
|
||||
gu|Gujarati
|
||||
he|Hebrew
|
||||
hi|Hindi
|
||||
hr|Croatian
|
||||
hu|Hungarian
|
||||
is|Icelandic
|
||||
it|Italian
|
||||
ja|Japanese
|
||||
ko|Korean
|
||||
lt|Lithuanian
|
||||
lv|Latvian
|
||||
ms|Malay
|
||||
nl|Dutch
|
||||
no|Norwegian
|
||||
pl|Polish
|
||||
pt|Portuguese
|
||||
ro|Romanian
|
||||
ru|Russian
|
||||
sk|Slovakian
|
||||
sl|Slovenian
|
||||
sq|Albanian
|
||||
sr|Serbian
|
||||
sv|Swedish
|
||||
th|Thai
|
||||
tr|Turkish
|
||||
ur|Urdu
|
||||
vi|Vietnamese
|
||||
yi|Yiddish
|
||||
zh|Chinese
|
File diff suppressed because it is too large
Load Diff
@@ -16,20 +16,20 @@
|
||||
<DocumentationFile>bin\Release\net8.0\gaseous-server.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.0.0" />
|
||||
<PackageReference Include="gaseous-signature-parser" Version="2.1.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||
<PackageReference Include="gaseous-signature-parser" Version="2.3.0" />
|
||||
<PackageReference Include="gaseous.IGDB" Version="1.0.2" />
|
||||
<PackageReference Include="hasheous-client" Version="0.1.0" />
|
||||
<PackageReference Include="Magick.NET-Q8-AnyCPU" Version="13.5.0" />
|
||||
<PackageReference Include="sharpcompress" Version="0.36.0" />
|
||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.1.23" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.3.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.0" />
|
||||
<PackageReference Include="sharpcompress" Version="0.38.0" />
|
||||
<PackageReference Include="Squid-Box.SevenZipSharp" Version="1.6.2.24" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.3.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -64,6 +64,8 @@
|
||||
<None Remove="Support\Database\MySQL\gaseous-1019.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1020.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1021.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1022.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1023.sql" />
|
||||
<None Remove="Classes\Metadata\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -85,6 +87,8 @@
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Support\Country.txt" />
|
||||
<EmbeddedResource Include="Support\Language.txt" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1000.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1001.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1002.sql" />
|
||||
@@ -108,5 +112,7 @@
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1019.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1020.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1021.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1022.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1023.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -41,8 +41,7 @@
|
||||
EJS_threads = false;
|
||||
|
||||
EJS_Buttons = {
|
||||
saveSavFiles: false,
|
||||
loadSavFiles: false
|
||||
exitEmulation: false
|
||||
}
|
||||
|
||||
EJS_onSaveState = function (e) {
|
||||
|
8
gaseous-server/wwwroot/images/NoIntro-logo.svg
Normal file
8
gaseous-server/wwwroot/images/NoIntro-logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 480 KiB |
BIN
gaseous-server/wwwroot/images/redump.png
Normal file
BIN
gaseous-server/wwwroot/images/redump.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
@@ -5,15 +5,17 @@
|
||||
<table style="width: 100%;">
|
||||
<tr>
|
||||
<th style="width: 20%;">Home Page</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server" class="romlink">https://github.com/gaseous-project/gaseous-server</a></td>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server"
|
||||
class="romlink">https://github.com/gaseous-project/gaseous-server</a></td>
|
||||
<td rowspan="5" style="text-align: center; width: 128px;">
|
||||
<img src="/images/logo.png" style="display: block; margin: 20px auto; width: 100px;" />
|
||||
<span style="display: block;">The Gaseous logo was designed by Tom2.0</span>
|
||||
<span style="display: block;">The Gaseous logo was designed by Tom1243</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Bugs and Feature Requests</th>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server/issues" class="romlink">https://github.com/gaseous-project/gaseous-server/issues</a></td>
|
||||
<td><a href="https://github.com/gaseous-project/gaseous-server/issues"
|
||||
class="romlink">https://github.com/gaseous-project/gaseous-server/issues</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Join our Discord</th>
|
||||
@@ -33,10 +35,12 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"><a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank"><img src="/images/EmulatorJS.png" style="height: 36px;" /></a></td>
|
||||
<td style="text-align: center;"><a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank"><img
|
||||
src="/images/EmulatorJS.png" style="height: 36px;" /></a></td>
|
||||
<td colspan="3">
|
||||
The EmulatorJS Project<br />
|
||||
<a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank" class="romlink">https://github.com/EmulatorJS/EmulatorJS</a>
|
||||
<a href="https://github.com/EmulatorJS/EmulatorJS" target="_blank"
|
||||
class="romlink">https://github.com/EmulatorJS/EmulatorJS</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -47,7 +51,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.igdb.com/" target="_blank"><img src="/images/IGDB_logo.svg" style="filter: invert(100%); height: 36px;" /></a>
|
||||
<a href="https://www.igdb.com/" target="_blank"><img src="/images/IGDB_logo.svg"
|
||||
style="filter: invert(100%); height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Internet Game Database<br />
|
||||
@@ -61,7 +66,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.tosecdev.org/" target="_blank"><img src="/images/TOSEC_logo.gif" style="height: 36px;" /></a>
|
||||
<a href="https://www.tosecdev.org/" target="_blank"><img src="/images/TOSEC_logo.gif"
|
||||
style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
The Old School Emulation Center<br />
|
||||
@@ -70,11 +76,34 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank"><img src="/images/ProgettoSnaps.gif" style="height: 36px;" /></a>
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank"><img src="/images/ProgettoSnaps.gif"
|
||||
style="height: 36px;" /></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
Progetto-Snaps<br />
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank" class="romlink">https://www.progettosnaps.net/index.php</a>
|
||||
<a href="https://www.progettosnaps.net/index.php" target="_blank"
|
||||
class="romlink">https://www.progettosnaps.net/index.php</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="https://no-intro.org" target="_blank" rel="noopener noreferrer"><img src="/images/NoIntro-logo.svg"
|
||||
style="height: 36px;"></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
No-Intro<br>
|
||||
<a href="https://no-intro.org" target="_blank" rel="noopener noreferrer"
|
||||
class="romlink">https://no-intro.org</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">
|
||||
<a href="http://redump.org" target="_blank" rel="noopener noreferrer"><img src="/images/redump.png"
|
||||
style="height: 36px;"></a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
Redump<br>
|
||||
<a href="http://redump.org" target="_blank" rel="noopener noreferrer" class="romlink">http://redump.org</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@@ -6,7 +6,8 @@
|
||||
<table id="settings_libraries" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showDialog('librarynew');">New Library</button></div>
|
||||
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showDialog('librarynew');">New
|
||||
Library</button></div>
|
||||
|
||||
<h2>Advanced Settings</h2>
|
||||
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
||||
@@ -14,7 +15,8 @@
|
||||
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to
|
||||
Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||
|
||||
<h3>System Settings</h3>
|
||||
<table cellspacing="0" style="width: 100%;">
|
||||
@@ -26,13 +28,15 @@
|
||||
Write logs
|
||||
</th>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false" checked="checked"><label for="settings_logs_write_db"> To database only (default)</label>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false"
|
||||
checked="checked"><label for="settings_logs_write_db"> To database only (default)</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label for="settings_logs_write_fs"> To database and disk</label>
|
||||
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label
|
||||
for="settings_logs_write_fs"> To database and disk</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -46,6 +50,58 @@
|
||||
<input type="number" min="1" id="settings_logs_retention" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Allowed metadata search modes:
|
||||
</th>
|
||||
<td>
|
||||
<input type="checkbox" name="settings_metadata_search" id="settings_metadata_search_where" /><label
|
||||
for="settings_metadata_search_where">
|
||||
Exact:
|
||||
<i>
|
||||
Searches for exact matches only. Example search: name = "Super Mario Bros."
|
||||
</i>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input type="checkbox" name="settings_metadata_search" id="settings_metadata_search_wherefuzzy" /><label
|
||||
for="settings_metadata_search_wherefuzzy">
|
||||
Partial:
|
||||
<i>
|
||||
Searches for partial matches. Example search: name = "Mario"
|
||||
</i>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input type="checkbox" name="settings_metadata_search" id="settings_metadata_search_search" /><label
|
||||
for="settings_metadata_search_search">
|
||||
Search:
|
||||
<i>
|
||||
Searches for partial matches using full text search. Example search: name = "Mario"
|
||||
</i>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<input type="checkbox" name="settings_metadata_search"
|
||||
id="settings_metadata_search_searchNoPlatform" /><label for="settings_metadata_search_searchNoPlatform">
|
||||
Search (no platform
|
||||
contraint):
|
||||
<i>
|
||||
Searches for partial matches using full text search, but without a platform constraint. Example
|
||||
search: name = "Mario"
|
||||
</i>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th colspan="2">Emulator</th>
|
||||
</tr>
|
||||
@@ -403,6 +459,11 @@
|
||||
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
||||
|
||||
document.getElementById('settings_emulator_debug').checked = result.emulatorDebugMode;
|
||||
|
||||
for (let i = 0; i < result.searchTypes.length; i++) {
|
||||
const element = result.searchTypes[i];
|
||||
document.getElementById('settings_metadata_search_' + element).checked = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -421,10 +482,20 @@
|
||||
retentionValue = 7;
|
||||
}
|
||||
|
||||
let searchTypes = [];
|
||||
let searchTypeElements = document.getElementsByName('settings_metadata_search');
|
||||
for (let i = 0; i < searchTypeElements.length; i++) {
|
||||
const element = searchTypeElements[i];
|
||||
if (element.checked) {
|
||||
searchTypes.push(element.id.replace('settings_metadata_search_', ''));
|
||||
}
|
||||
}
|
||||
|
||||
var model = {
|
||||
"alwaysLogToDisk": alwaysLogToDisk,
|
||||
"minimumLogRetentionPeriod": retentionValue,
|
||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked
|
||||
"emulatorDebugMode": document.getElementById('settings_emulator_debug').checked,
|
||||
"searchTypes": searchTypes
|
||||
};
|
||||
|
||||
ajaxCall(
|
||||
|
Reference in New Issue
Block a user