Skip to content

Commit

Permalink
Update documentation
Browse files Browse the repository at this point in the history
* Update documentation
Fixes #279

* Merge remote-tracking branch 'origin/main' into michael-j-green/issue279
  • Loading branch information
michael-j-green authored Feb 2, 2024
1 parent 36938ed commit 5e45fc1
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 194 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.9.7z

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
ENV INDOCKER=1
WORKDIR /App
COPY --from=build-env /App/out .
ENTRYPOINT ["dotnet", "gaseous-server.dll"]
127 changes: 19 additions & 108 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,33 @@ This is the server for the Gaseous system. It offers ROM and title management, a

## Warning

This project is currently not suitable for being exposed to the internet.
1. there is currently no authentication support, meaning anyone could trash your library
Versions 1.6.1 and earlier are not suitable for being exposed to the internet, as:
1. there is no authentication support, meaning anyone could trash your library
2. the server has not been hardened for exposure to the internet - so there maybe unknown vulnerabilities

If you expose the server to the internet, **you do so at your own risk**.
If you expose one of these earlier versions of the server to the internet, **you do so at your own risk**.

Version 1.7.0 and later contain user authentication, and can be exposed to the internet. However, it is recommended to no expose the server to the internet if you're not actively using it remotely, or if you have alternative means to access it remotely like a VPN.

While we do our best to stay on top of server security, if you expose the server to the internet **you do so at your own risk**.

## Screenshots
![Library](./screenshots/Library.png)
![Game](./screenshots/Game.png)
![Emulator](./screenshots/Emulator.png)
| | |
| ------- | --------------------------------------- |
| Game Library | ![Library](./screenshots/Library.png) |
| Game metadata and ROM display | ![Game](./screenshots/Game.png) |
| Emulator | ![Emulator](./screenshots/Emulator.png) |


## Requirements
* MariaDB 11.1.2 or MySQL Server 8+
* MariaDB 11.1.2 (preferred) or MySQL Server 8+
* These are the database versions Gaseous has been tested and developed against. Your mileage may vary with earlier versions.
* Currently MariaDB is the preferred database server, while MySQL will continue to be supported for existing users (they should be interchangable).
* MariaDB is the preferred database server, while MySQL will continue to be supported for existing users (they should be interchangable).
* Note that due to the earlier database schema using MySQL specific features, moving to MariaDB from MySQL will require rebuilding your database from scratch. The "Library Scan" background task can be used to re-import all titles.
* Internet Game Database API Key. See: https://api-docs.igdb.com/#account-creation

If using the provided docker-compose.yml, MariaDB will be installed for you.

## Third Party Projects
The following projects are used by Gaseous
* https://dotnet.microsoft.com/en-us/apps/aspnet
Expand All @@ -33,107 +42,9 @@ The following projects are used by Gaseous
## Discord Server
[![Join our Discord server!](https://invite.casperiv.dev/?inviteCode=Nhu7wpT3k4&format=svg)](https://discord.gg/Nhu7wpT3k4)

# Setup

## Configuration File
When Gaseous-Server is started for the first time, it creates a configuration file at ~/.gaseous-server/config.json if it doesn't exist. Some values can be filled in using environment variables (such as in the case of using docker).

### DatabaseConfiguration
| Attribute | Environment Variable |
| --------- | -------------------- |
| HostName | dbhost |
| UserName | dbuser |
| Password | dbpass |

### IGDBConfiguration
| Attribute | Environment Variable |
| --------- | -------------------- |
| ClientId | igdbclientid |
| Secret. | igdbclientsecret |

### config.json
```json
{
"DatabaseConfiguration": {
"HostName": "localhost",
"UserName": "gaseous",
"Password": "gaseous",
"DatabaseName": "gaseous",
"Port": 3306
},
"IGDBConfiguration": {
"ClientId": "<clientid>",
"Secret": "<secret>"
},
"LoggingConfiguration": {
"DebugLogging": false,
"LogRetention": 7
}
}

```

# Installation
See https://github.com/gaseous-project/gaseous-server/wiki/Installation for installation instructions.

# Adding Content
While games can be added to the server without them, it is recommended adding some signature DAT files beforehand to allow for better matching of ROMs to games.

These signature DAT files contain a list of titles with hashes for many of the ROM images that have been found by the community.

Currently supported DAT's:
* TOSEC: https://www.tosecdev.org/downloads/category/56-2023-01-23
* MAME Arcade and MAME Mess: https://www.progettosnaps.net/dats/MAME

If there are other DAT's you'd like to see support for, please raise an issue with a link to the DAT's.

## Adding signature DAT files
### TOSEC
1. Download the DAT files from the source website. For example; from https://www.tosecdev.org/downloads/category/56-2023-01-23
2. Extract the archive
3. Copy the DAT files to ~/.gaseous-server/Data/Signatures/TOSEC/

### MAME Arcade
1. Download the DAT files from the source website. For example; from https://www.progettosnaps.net/dats/MAME
2. Extract the archive
3. Copy the file name "MAME 0.257 (arcade).dat" files to ~/.gaseous-server/Data/Signatures/MAME Arcade/

### MAME MESS
1. Download the DAT files from the source website. For example; from https://www.progettosnaps.net/dats/MAME
2. Extract the archive
3. Copy the file name "MAME 0.257 (mess).dat" files to ~/.gaseous-server/Data/Signatures/MAME MESS/

# Adding Game Images
1. Files can be presented as either stand alone files, or as zip files - currently 7z is unsupported.
2. Name the file appropriately.
* Attempting a search for the game name on https://www.igdb.com can help with file naming. If a hash search is unsuccessful, Gaseous will fall back to attempting to search by the file name.
3. Add the file to the server:
* Click the Upload button in the top right of the main Gaseous web page, and drag the files into the modal. The files will be uploaded and analyzed.
* Copy the file to ~/.gaseous-server/Data/Import

# Game Image Title Matching
Image to game matching follows the following order of operations, stopping the process at the first match:
### Get the file signature
1. Attempt a hash search
2. Attempt to search the signature database for a rom matching the file name - sometimes the hash can not be matched as a highscore table for example was saved to the image
3. Attempt to parse the file name - clues such as the extension being used to define which platform the file belongs to are used to create a search criteria

**Note**: If the file being scanned is a zip, the file will be extracted and searched. The first file whose signature can be found will be used to match the entire zip archive - be sure that the zip only contains files related to one game.

### Create a list of search candidates
Before beginning, remove any version numbers, and anything in the search string that is between ()
1. Add the full name of the image
2. Add the name of the image with any " - " replaced by ": "
3. Add the name of the image with text after a " - " removed
4. Add the name of the image with text after a ": " removed

### Search IGDB for a game match
Loop through each of the search candidates searching using:
1. "where" - exact match as the search candidate
2. "wherefuzzy" - partial match using wildcards
3. "search" - uses a more flexible search method
4. "searchNoPlatform" - uses the "search" method, but does not constrain the search to the determined platform

**Note**: If more than one result is found, the seach will loop through the returned results:
* If an exact (case-insensitive) match is found, that result is used for the match
* If still no match, the image will be set as "Unknown" as there is no way for Gaseous to know which title is the correct one.
1. Import signatures: see https://github.com/gaseous-project/gaseous-server/wiki/Signatures
2. Add ROMs: see https://github.com/gaseous-project/gaseous-server/wiki/Adding-ROMs
File renamed without changes.
40 changes: 0 additions & 40 deletions docker-compose-mysql-build.yml

This file was deleted.

39 changes: 0 additions & 39 deletions docker-compose-mysql.yml

This file was deleted.

File renamed without changes.
12 changes: 12 additions & 0 deletions gaseous-server/Classes/Common.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ public static byte[] Decompress(byte[] data)
}
return output.ToArray();
}

public static object GetEnvVar(string envName, string defaultValue)
{
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable(envName)))
{
return Environment.GetEnvironmentVariable(envName);
}
else
{
return defaultValue;
}
}
}

/// <summary>
Expand Down
73 changes: 66 additions & 7 deletions gaseous-server/Classes/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,33 @@ static Config()
if (_tempConfig != null)
{
_config = _tempConfig;
} else

// load environment variables if we're in a docker container
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("INDOCKER")))
{
if (Environment.GetEnvironmentVariable("INDOCKER") == "1")
{
Console.WriteLine("Running in Docker - setting configuration from variables");
_config.DatabaseConfiguration.HostName = (string)Common.GetEnvVar("dbhost", _config.DatabaseConfiguration.HostName);
_config.DatabaseConfiguration.UserName = (string)Common.GetEnvVar("dbuser", _config.DatabaseConfiguration.UserName);
_config.DatabaseConfiguration.Password = (string)Common.GetEnvVar("dbpass", _config.DatabaseConfiguration.Password);
_config.DatabaseConfiguration.DatabaseName = (string)Common.GetEnvVar("dbname", _config.DatabaseConfiguration.DatabaseName);
_config.DatabaseConfiguration.Port = int.Parse((string)Common.GetEnvVar("dbport", _config.DatabaseConfiguration.Port.ToString()));
_config.MetadataConfiguration.MetadataSource = (HasheousClient.Models.MetadataModel.MetadataSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.MetadataSources), (string)Common.GetEnvVar("metadatasource", _config.MetadataConfiguration.MetadataSource.ToString()));
_config.MetadataConfiguration.SignatureSource = (HasheousClient.Models.MetadataModel.SignatureSources)Enum.Parse(typeof(HasheousClient.Models.MetadataModel.SignatureSources), (string)Common.GetEnvVar("signaturesource", _config.MetadataConfiguration.SignatureSource.ToString()));;
_config.MetadataConfiguration.MaxLibraryScanWorkers = int.Parse((string)Common.GetEnvVar("maxlibraryscanworkers", _config.MetadataConfiguration.MaxLibraryScanWorkers.ToString()));
_config.MetadataConfiguration.HasheousHost = (string)Common.GetEnvVar("hasheoushost", _config.MetadataConfiguration.HasheousHost);
_config.IGDBConfiguration.ClientId = (string)Common.GetEnvVar("igdbclientid", _config.IGDBConfiguration.ClientId);
_config.IGDBConfiguration.Secret = (string)Common.GetEnvVar("igdbclientsecret", _config.IGDBConfiguration.Secret);
}
}
}
else
{
throw new Exception("There was an error reading the config file: Json returned null");
}
} else
}
else
{
// no config file!
// use defaults and save
Expand Down Expand Up @@ -399,11 +421,41 @@ private static string _DefaultPassword
}
}

private static string _DefaultDatabaseName
{
get
{
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("dbname")))
{
return Environment.GetEnvironmentVariable("dbname");
}
else
{
return "gaseous";
}
}
}

private static int _DefaultDatabasePort
{
get
{
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("dbport")))
{
return int.Parse(Environment.GetEnvironmentVariable("dbport"));
}
else
{
return 3306;
}
}
}

public string HostName = _DefaultHostName;
public string UserName = _DefaultUserName;
public string Password = _DefaultPassword;
public string DatabaseName = "gaseous";
public int Port = 3306;
public string DatabaseName = _DefaultDatabaseName;
public int Port = _DefaultDatabasePort;

[JsonIgnore]
public string ConnectionString
Expand Down Expand Up @@ -598,17 +650,24 @@ private static int _MaxLibraryScanWorkers
{
get
{
return 4;
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("maxlibraryscanworkers")))
{
return int.Parse(Environment.GetEnvironmentVariable("maxlibraryscanworkers"));
}
else
{
return 4;
}
}
}

private static string _HasheousHost
{
get
{
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("hasheoushoust")))
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("hasheoushost")))
{
return Environment.GetEnvironmentVariable("hasheoushoust");
return Environment.GetEnvironmentVariable("hasheoushost");
}
else
{
Expand Down
Binary file modified screenshots/Emulator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/Game.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/Library.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5e45fc1

Please sign in to comment.