From 7dfb0b54ebd94f074505260d5f74f07d8e577cc2 Mon Sep 17 00:00:00 2001
From: Michael Green <84688932+michael-j-green@users.noreply.github.com>
Date: Sun, 8 Sep 2024 00:14:29 +1000
Subject: [PATCH] All images now support rootless (#418)
---
build/Dockerfile | 48 ++++++++---
build/Dockerfile-EmbeddedDB | 46 ++++++-----
build/embeddeddb/entrypoint.sh | 18 +++++
build/embeddeddb/mariadb.sh | 25 ++++++
build/embeddeddb/supervisord.conf | 37 +++++++++
build/mariadb.sh | 9 ---
build/standard/entrypoint.sh | 13 +++
build/standard/supervisord.conf | 28 +++++++
build/supervisord.conf | 31 -------
docker-compose-build.yml | 3 +-
docker-compose.yml | 2 +-
gaseous-server/Classes/DatabaseMigration.cs | 12 +--
gaseous-server/Program.cs | 2 +-
.../Support/Database/MySQL/gaseous-1023.sql | 80 -------------------
.../Support/Database/MySQL/gaseous-1024.sql | 79 ++++++++++++++++++
gaseous-server/gaseous-server.csproj | 2 +
16 files changed, 276 insertions(+), 159 deletions(-)
create mode 100644 build/embeddeddb/entrypoint.sh
create mode 100644 build/embeddeddb/mariadb.sh
create mode 100644 build/embeddeddb/supervisord.conf
delete mode 100644 build/mariadb.sh
create mode 100644 build/standard/entrypoint.sh
create mode 100644 build/standard/supervisord.conf
delete mode 100644 build/supervisord.conf
create mode 100644 gaseous-server/Support/Database/MySQL/gaseous-1024.sql
diff --git a/build/Dockerfile b/build/Dockerfile
index 8132a75..e806e36 100644
--- a/build/Dockerfile
+++ b/build/Dockerfile
@@ -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/
+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.0.12.7z
+RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
# clean up apt-get
RUN apt-get clean && rm -rf /var/lib/apt/lists
@@ -37,5 +32,34 @@ ENV INDOCKER=1
WORKDIR /App
COPY --from=build-env /App/out .
-# start gaseous-server
-ENTRYPOINT ["dotnet", "gaseous-server.dll"]
\ No newline at end of file
+# variables
+ARG PUID=1000
+ARG PGID=1000
+ARG dbhost=localhost
+ARG dbuser=root
+ARG dbpass=gaseous
+
+ENV PUID=${PUID}
+ENV PGID=${PGID}
+ENV dbhost=${dbhost}
+ENV dbuser=${dbuser}
+ENV dbpass=${dbpass}
+
+# install supervisord
+RUN apt-get update && apt-get install -y supervisor
+COPY ../build/standard/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+RUN mkdir -p /var/run/supervisord
+RUN mkdir -p /var/log/supervisord
+
+# clean up apt-get
+RUN apt-get clean && rm -rf /var/lib/apt/lists
+
+# copy entrypoint
+COPY ../build/standard/entrypoint.sh /usr/sbin/entrypoint.sh
+RUN chmod +x /usr/sbin/entrypoint.sh
+
+# volumes
+VOLUME /home/gaseous/.gaseous-server
+
+# start services
+ENTRYPOINT [ "/usr/sbin/entrypoint.sh" ]
\ No newline at end of file
diff --git a/build/Dockerfile-EmbeddedDB b/build/Dockerfile-EmbeddedDB
index 61362cf..9be70af 100644
--- a/build/Dockerfile-EmbeddedDB
+++ b/build/Dockerfile-EmbeddedDB
@@ -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/
+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.0.12.7z
+RUN 7z x -y -oout/wwwroot/emulators/EmulatorJS 4.0.12.7z
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
@@ -35,27 +30,42 @@ 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 && \
apt-get update && apt-get install -y mariadb-server
RUN mkdir -p /run/mysqld
-COPY ../build/mariadb.sh /usr/sbin/start-mariadb.sh
+COPY ../build/embeddeddb/mariadb.sh /usr/sbin/start-mariadb.sh
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
+COPY ../build/embeddeddb/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/embeddeddb/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"]
\ No newline at end of file
+ENTRYPOINT [ "/usr/sbin/entrypoint.sh" ]
\ No newline at end of file
diff --git a/build/embeddeddb/entrypoint.sh b/build/embeddeddb/entrypoint.sh
new file mode 100644
index 0000000..89cb777
--- /dev/null
+++ b/build/embeddeddb/entrypoint.sh
@@ -0,0 +1,18 @@
+#!/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
+chown -R ${PUID} /App /home/gaseous/.gaseous-server
+chgrp -R ${PGID} /App /home/gaseous/.gaseous-server
+
+# Set MariaDB permissions
+mkdir -p /var/lib/mysql /var/log/mariadb /run/mysqld
+chown -R ${PUID} /var/lib/mysql /var/log/mariadb /run/mysqld
+chgrp -R ${PGID} /var/lib/mysql /var/log/mariadb /run/mysqld
+
+# Start supervisord and services
+/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
\ No newline at end of file
diff --git a/build/embeddeddb/mariadb.sh b/build/embeddeddb/mariadb.sh
new file mode 100644
index 0000000..54eee43
--- /dev/null
+++ b/build/embeddeddb/mariadb.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# install the database
+echo "Installing MariaDB"
+/usr/bin/mariadb-install-db --datadir=/var/lib/mysql --user=gaseous
+
+# start the database server without network or grant tables
+echo "Starting MariaDB"
+/usr/sbin/mariadbd --datadir=/var/lib/mysql --skip-grant-tables --skip-networking &
+
+# wait for the server to start
+sleep 5
+
+# change the root password
+echo "Setting MariaDB root password"
+mariadb -u root -e "FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; ALTER USER 'gaseous'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD'; FLUSH PRIVILEGES; SHUTDOWN;"
+
+# stop the server
+sleep 5
+echo "Stopping MariaDB"
+killall mariadbd
+
+# start the server normally
+echo "Starting MariaDB"
+/usr/sbin/mariadbd --datadir=/var/lib/mysql --user=gaseous
\ No newline at end of file
diff --git a/build/embeddeddb/supervisord.conf b/build/embeddeddb/supervisord.conf
new file mode 100644
index 0000000..a0f3aad
--- /dev/null
+++ b/build/embeddeddb/supervisord.conf
@@ -0,0 +1,37 @@
+[supervisord]
+user=root
+nodaemon=true
+logfile=/var/log/supervisord/supervisord.log
+logfile_maxbytes=50
+logfile_backups=5
+pidfile=/var/run/supervisord/supervisord.pid
+loglevel = info
+
+[unix_http_server]
+file=/var/run/supervisord/supervisor.sock
+chmod=0700
+
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
+
+[supervisorctl]
+serverurl=unix:///var/run/supervisord/supervisor.sock
+
+[program:mariadb]
+user=gaseous
+command=bash -c "/usr/sbin/start-mariadb.sh"
+autostart=true
+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
+stdout_logfile=/dev/fd/1
+stdout_logfile_maxbytes=0
\ No newline at end of file
diff --git a/build/mariadb.sh b/build/mariadb.sh
deleted file mode 100644
index 9851661..0000000
--- a/build/mariadb.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-# Wait for the service to start
-while ! mysqladmin ping -h localhost --silent; do
- sleep 1
-done
-
-# Set the root password
-mariadb -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$MARIADB_ROOT_PASSWORD';"
\ No newline at end of file
diff --git a/build/standard/entrypoint.sh b/build/standard/entrypoint.sh
new file mode 100644
index 0000000..8256268
--- /dev/null
+++ b/build/standard/entrypoint.sh
@@ -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
+chown -R ${PUID} /App /home/gaseous/.gaseous-server
+chgrp -R ${PGID} /App /home/gaseous/.gaseous-server
+
+# Start supervisord and services
+/usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
\ No newline at end of file
diff --git a/build/standard/supervisord.conf b/build/standard/supervisord.conf
new file mode 100644
index 0000000..10d8d43
--- /dev/null
+++ b/build/standard/supervisord.conf
@@ -0,0 +1,28 @@
+[supervisord]
+user=root
+nodaemon=true
+logfile=/var/log/supervisord/supervisord.log
+logfile_maxbytes=50
+logfile_backups=5
+pidfile=/var/run/supervisord/supervisord.pid
+loglevel = info
+
+[unix_http_server]
+file=/var/run/supervisord/supervisor.sock
+chmod=0700
+
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
+
+[supervisorctl]
+serverurl=unix:///var/run/supervisord/supervisor.sock
+
+[program:gaseous-server]
+user=gaseous
+command=dotnet /App/gaseous-server.dll
+environment=HOME="/home/gaseous",USER="gaseous"
+autostart=true
+autorestart=true
+redirect_stderr=true
+stdout_logfile=/dev/fd/1
+stdout_logfile_maxbytes=0
\ No newline at end of file
diff --git a/build/supervisord.conf b/build/supervisord.conf
deleted file mode 100644
index 533b4c6..0000000
--- a/build/supervisord.conf
+++ /dev/null
@@ -1,31 +0,0 @@
-[supervisord]
-user=root
-nodaemon=true
-logfile=/dev/null
-logfile_maxbytes=0
-pidfile=/var/run/supervisord.pid
-loglevel = INFO
-
-[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]
-command=bash -c "/usr/sbin/start-mariadb.sh"
-autostart=true
-autorestart=false
-redirect_stderr=true
-stdout_logfile=/dev/fd/1
-stdout_logfile_maxbytes=0
-
-[program:gaseous-server]
-command=dotnet /App/gaseous-server.dll
-autostart=true
-autorestart=true
-redirect_stderr=true
-stdout_logfile=/dev/fd/1
-stdout_logfile_maxbytes=0
\ No newline at end of file
diff --git a/docker-compose-build.yml b/docker-compose-build.yml
index 3c581ca..b46361f 100644
--- a/docker-compose-build.yml
+++ b/docker-compose-build.yml
@@ -4,6 +4,7 @@ services:
container_name: gaseous-server
build:
context: ./
+ dockerfile: ./build/Dockerfile
restart: unless-stopped
networks:
- gaseous
@@ -12,7 +13,7 @@ services:
ports:
- 5198:80
volumes:
- - gs:/root/.gaseous-server
+ - gs:/home/gaseous/.gaseous-server
environment:
- TZ=Australia/Sydney
- dbhost=gsdb
diff --git a/docker-compose.yml b/docker-compose.yml
index 883b6ad..238e733 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -11,7 +11,7 @@ services:
ports:
- 5198:80
volumes:
- - gs:/root/.gaseous-server
+ - gs:/home/gaseous/.gaseous-server
environment:
- TZ=Australia/Sydney
- dbhost=gsdb
diff --git a/gaseous-server/Classes/DatabaseMigration.cs b/gaseous-server/Classes/DatabaseMigration.cs
index 48a8f11..ba6a67d 100644
--- a/gaseous-server/Classes/DatabaseMigration.cs
+++ b/gaseous-server/Classes/DatabaseMigration.cs
@@ -109,7 +109,7 @@ namespace gaseous_server.Classes
db.ExecuteNonQuery(sql);
break;
- case 1022:
+ case 1023:
// load country list
Logging.Log(Logging.LogType.Information, "Database Upgrade", "Adding country look up table contents");
@@ -151,10 +151,10 @@ namespace gaseous_server.Classes
}
// this is a safe background task
- BackgroundUpgradeTargetSchemaVersions.Add(1022);
+ BackgroundUpgradeTargetSchemaVersions.Add(1023);
break;
- case 1023:
+ case 1024:
// create profiles for all existing users
sql = "SELECT * FROM Users;";
data = db.ExecuteCMD(sql);
@@ -197,8 +197,8 @@ namespace gaseous_server.Classes
MySql_1002_MigrateMetadataVersion();
break;
- case 1022:
- MySql_1022_MigrateMetadataVersion();
+ case 1023:
+ MySql_1023_MigrateMetadataVersion();
break;
}
}
@@ -301,7 +301,7 @@ namespace gaseous_server.Classes
}
}
- public static void MySql_1022_MigrateMetadataVersion()
+ public static void MySql_1023_MigrateMetadataVersion()
{
FileSignature fileSignature = new FileSignature();
diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs
index dcd556c..c44a51d 100644
--- a/gaseous-server/Program.cs
+++ b/gaseous-server/Program.cs
@@ -67,7 +67,7 @@ if (Directory.Exists(Config.LibraryConfiguration.LibraryUploadDirectory))
// kick off any delayed upgrade tasks
// run 1002 background updates in the background on every start
DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1002);
-DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1022);
+DatabaseMigration.BackgroundUpgradeTargetSchemaVersions.Add(1023);
// start the task
ProcessQueue.QueueItem queueItem = new ProcessQueue.QueueItem(
ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade,
diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1023.sql b/gaseous-server/Support/Database/MySQL/gaseous-1023.sql
index 9307882..67bba32 100644
--- a/gaseous-server/Support/Database/MySQL/gaseous-1023.sql
+++ b/gaseous-server/Support/Database/MySQL/gaseous-1023.sql
@@ -1,23 +1,3 @@
-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
-);
-
CREATE TABLE `Country` (
`Id` INT NOT NULL AUTO_INCREMENT,
`Code` VARCHAR(20) NULL,
@@ -34,64 +14,4 @@ CREATE TABLE `Language` (
PRIMARY KEY (`Id`),
INDEX `id_Code` (`Code` ASC) VISIBLE,
INDEX `id_Value` (`Value` ASC) VISIBLE
-);
-
-ALTER TABLE `Games_Roms` ADD COLUMN `RomDataVersion` INT DEFAULT 1;
-
-CREATE TABLE UserProfiles (
- `Id` VARCHAR(45) NOT NULL,
- `UserId` VARCHAR(45) NOT NULL,
- `DisplayName` VARCHAR(255) NOT NULL,
- `Quip` VARCHAR(255) NOT NULL,
- `Avatar` LONGBLOB,
- `AvatarExtension` CHAR(6),
- `ProfileBackground` LONGBLOB,
- `ProfileBackgroundExtension` CHAR(6),
- `UnstructuredData` LONGTEXT NOT NULL,
- PRIMARY KEY (`Id`, `UserId`)
-);
-
-ALTER TABLE `PlatformMap_Bios`
-ADD COLUMN `Enabled` BOOLEAN DEFAULT TRUE;
-
-CREATE TABLE `User_PlatformMap` (
- `id` VARCHAR(128) NOT NULL,
- `GameId` BIGINT NOT NULL,
- `PlatformId` BIGINT NOT NULL,
- `Mapping` LONGTEXT,
- PRIMARY KEY (`id`, `GameId`, `PlatformId`),
- CONSTRAINT `User_PlatformMap_UserId` FOREIGN KEY (`id`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
-);
-
-ALTER TABLE `UserTimeTracking`
-ADD COLUMN `PlatformId` BIGINT,
-ADD COLUMN `IsMediaGroup` BOOLEAN DEFAULT FALSE,
-ADD COLUMN `RomId` BIGINT;
-
-CREATE TABLE `User_RecentPlayedRoms` (
- `UserId` varchar(128) NOT NULL,
- `GameId` bigint(20) NOT NULL,
- `PlatformId` bigint(20) NOT NULL,
- `RomId` bigint(20) NOT NULL,
- `IsMediaGroup` tinyint(1) DEFAULT NULL,
- PRIMARY KEY (
- `UserId`,
- `GameId`,
- `PlatformId`
- ),
- CONSTRAINT `RecentPlayedRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
-);
-
-CREATE TABLE `User_GameFavouriteRoms` (
- `UserId` varchar(128) NOT NULL,
- `GameId` bigint(20) NOT NULL,
- `PlatformId` bigint(20) NOT NULL,
- `RomId` bigint(20) NOT NULL,
- `IsMediaGroup` tinyint(1) DEFAULT NULL,
- PRIMARY KEY (
- `UserId`,
- `GameId`,
- `PlatformId`
- ),
- CONSTRAINT `GameFavouriteRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
);
\ No newline at end of file
diff --git a/gaseous-server/Support/Database/MySQL/gaseous-1024.sql b/gaseous-server/Support/Database/MySQL/gaseous-1024.sql
new file mode 100644
index 0000000..e0e421d
--- /dev/null
+++ b/gaseous-server/Support/Database/MySQL/gaseous-1024.sql
@@ -0,0 +1,79 @@
+CREATE TABLE `Signatures_RomToSource` (
+ `SourceId` int NOT NULL,
+ `RomId` int NOT NULL,
+ PRIMARY KEY (`SourceId`, `RomId`)
+);
+
+CREATE TABLE `Signatures_Games_Countries` (
+ `GameId` INT NOT NULL,
+ `CountryId` INT NOT NULL,
+ PRIMARY KEY (`GameId`, `CountryId`),
+ CONSTRAINT `GameCountry` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE `Signatures_Games_Languages` (
+ `GameId` INT NOT NULL,
+ `LanguageId` INT NOT NULL,
+ PRIMARY KEY (`GameId`, `LanguageId`),
+ CONSTRAINT `GameLanguage` FOREIGN KEY (`GameId`) REFERENCES `Signatures_Games` (`Id`) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+ALTER TABLE `Games_Roms` ADD COLUMN `RomDataVersion` INT DEFAULT 1;
+
+CREATE TABLE UserProfiles (
+ `Id` VARCHAR(45) NOT NULL,
+ `UserId` VARCHAR(45) NOT NULL,
+ `DisplayName` VARCHAR(255) NOT NULL,
+ `Quip` VARCHAR(255) NOT NULL,
+ `Avatar` LONGBLOB,
+ `AvatarExtension` CHAR(6),
+ `ProfileBackground` LONGBLOB,
+ `ProfileBackgroundExtension` CHAR(6),
+ `UnstructuredData` LONGTEXT NOT NULL,
+ PRIMARY KEY (`Id`, `UserId`)
+);
+
+ALTER TABLE `PlatformMap_Bios`
+ADD COLUMN `Enabled` BOOLEAN DEFAULT TRUE;
+
+CREATE TABLE `User_PlatformMap` (
+ `id` VARCHAR(128) NOT NULL,
+ `GameId` BIGINT NOT NULL,
+ `PlatformId` BIGINT NOT NULL,
+ `Mapping` LONGTEXT,
+ PRIMARY KEY (`id`, `GameId`, `PlatformId`),
+ CONSTRAINT `User_PlatformMap_UserId` FOREIGN KEY (`id`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
+);
+
+ALTER TABLE `UserTimeTracking`
+ADD COLUMN `PlatformId` BIGINT,
+ADD COLUMN `IsMediaGroup` BOOLEAN DEFAULT FALSE,
+ADD COLUMN `RomId` BIGINT;
+
+CREATE TABLE `User_RecentPlayedRoms` (
+ `UserId` varchar(128) NOT NULL,
+ `GameId` bigint(20) NOT NULL,
+ `PlatformId` bigint(20) NOT NULL,
+ `RomId` bigint(20) NOT NULL,
+ `IsMediaGroup` tinyint(1) DEFAULT NULL,
+ PRIMARY KEY (
+ `UserId`,
+ `GameId`,
+ `PlatformId`
+ ),
+ CONSTRAINT `RecentPlayedRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
+);
+
+CREATE TABLE `User_GameFavouriteRoms` (
+ `UserId` varchar(128) NOT NULL,
+ `GameId` bigint(20) NOT NULL,
+ `PlatformId` bigint(20) NOT NULL,
+ `RomId` bigint(20) NOT NULL,
+ `IsMediaGroup` tinyint(1) DEFAULT NULL,
+ PRIMARY KEY (
+ `UserId`,
+ `GameId`,
+ `PlatformId`
+ ),
+ CONSTRAINT `GameFavouriteRoms_Users` FOREIGN KEY (`UserId`) REFERENCES `Users` (`Id`) ON DELETE CASCADE
+);
\ No newline at end of file
diff --git a/gaseous-server/gaseous-server.csproj b/gaseous-server/gaseous-server.csproj
index b4a8ce2..17579a3 100644
--- a/gaseous-server/gaseous-server.csproj
+++ b/gaseous-server/gaseous-server.csproj
@@ -68,6 +68,7 @@
+
@@ -116,5 +117,6 @@
+
\ No newline at end of file