Resolved many database errors (#377)

* Resolved missing table errors.
* These were due to some dynamically created tables being queried before
they were created.
  * These tables are now created at start up.
* Resolved many "INSERT" errors that were polluting the logs:
* These were due to a race condition where sometimes the database would
return the data as not being in the database causing Gaseous to try to
insert it - even though the data was already there.
This commit is contained in:
Michael Green
2024-06-26 15:00:09 +10:00
committed by GitHub
parent ccf9afd561
commit 787bb47bd3
8 changed files with 341 additions and 241 deletions

View File

@@ -17,7 +17,7 @@ namespace gaseous_server.Classes.Metadata
public class InvalidGameId : Exception public class InvalidGameId : Exception
{ {
public InvalidGameId(long Id) : base("Unable to find Game by id " + Id) public InvalidGameId(long Id) : base("Unable to find Game by id " + Id)
{} { }
} }
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh) public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
@@ -125,17 +125,17 @@ namespace gaseous_server.Classes.Metadata
private static void UpdateSubClasses(Game Game, bool getAllMetadata, bool followSubGames, bool forceRefresh) private static void UpdateSubClasses(Game Game, bool getAllMetadata, bool followSubGames, bool forceRefresh)
{ {
// required metadata // required metadata
if (Game.Cover != null) // if (Game.Cover != null)
{ // {
try // try
{ // {
Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh); // Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game), forceRefresh);
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Logging.Log(Logging.LogType.Critical, "Game Metadata", "Unable to fetch cover artwork.", ex); // Logging.Log(Logging.LogType.Critical, "Game Metadata", "Unable to fetch cover artwork.", ex);
} // }
} // }
if (Game.Genres != null) if (Game.Genres != null)
{ {
@@ -439,7 +439,8 @@ namespace gaseous_server.Classes.Metadata
DataTable data = db.ExecuteCMD(sql, dbDict); DataTable data = db.ExecuteCMD(sql, dbDict);
foreach (DataRow row in data.Rows) foreach (DataRow row in data.Rows)
{ {
Game game = new Game{ Game game = new Game
{
Id = (long)row["Id"], Id = (long)row["Id"],
Name = (string)Common.ReturnValueIfNull(row["Name"], ""), Name = (string)Common.ReturnValueIfNull(row["Name"], ""),
Slug = (string)Common.ReturnValueIfNull(row["Slug"], ""), Slug = (string)Common.ReturnValueIfNull(row["Slug"], ""),

View File

@@ -428,6 +428,30 @@ namespace gaseous_server.Classes.Metadata
} }
} }
public static void CreateRelationsTables<T>()
{
string PrimaryTable = typeof(T).Name;
foreach (PropertyInfo property in typeof(T).GetProperties())
{
string SecondaryTable = property.Name;
if (property.PropertyType.Name == "IdentitiesOrValues`1")
{
string TableName = "Relation_" + PrimaryTable + "_" + SecondaryTable;
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "SELECT * FROM information_schema.tables WHERE table_schema = '" + Config.DatabaseConfiguration.DatabaseName + "' AND table_name = '" + TableName + "';";
DataTable data = db.ExecuteCMD(sql);
if (data.Rows.Count == 0)
{
// table doesn't exist, create it
sql = "CREATE TABLE `" + Config.DatabaseConfiguration.DatabaseName + "`.`" + TableName + "` (`" + PrimaryTable + "Id` BIGINT NOT NULL, `" + SecondaryTable + "Id` BIGINT NOT NULL, PRIMARY KEY (`" + PrimaryTable + "Id`, `" + SecondaryTable + "Id`), INDEX `idx_PrimaryColumn` (`" + PrimaryTable + "Id` ASC) VISIBLE);";
db.ExecuteCMD(sql);
}
}
}
}
private class MemoryCacheObject private class MemoryCacheObject
{ {
public object Object { get; set; } public object Object { get; set; }

View File

@@ -73,7 +73,8 @@ namespace gaseous_server.Controllers
private static async Task<List<GaseousGame>> _SearchForGame(long PlatformId, string SearchString) private static async Task<List<GaseousGame>> _SearchForGame(long PlatformId, string SearchString)
{ {
string searchBody = ""; string searchBody = "";
string searchFields = "fields cover,first_release_date,name,platforms,slug; "; // string searchFields = "fields cover,first_release_date,name,platforms,slug; ";
string searchFields = "fields *; ";
searchBody += "search \"" + SearchString + "\";"; searchBody += "search \"" + SearchString + "\";";
searchBody += "where platforms = (" + PlatformId + ");"; searchBody += "where platforms = (" + PlatformId + ");";
searchBody += "limit 100;"; searchBody += "limit 100;";
@@ -91,7 +92,7 @@ namespace gaseous_server.Controllers
foreach (Game game in results.ToList()) foreach (Game game in results.ToList())
{ {
Storage.CacheStatus cacheStatus = Storage.GetCacheStatus("Game", (long)game.Id); Storage.CacheStatus cacheStatus = Storage.GetCacheStatus("Game", (long)game.Id);
switch(cacheStatus) switch (cacheStatus)
{ {
case Storage.CacheStatus.NotPresent: case Storage.CacheStatus.NotPresent:
Storage.NewCacheValue(game, false); Storage.NewCacheValue(game, false);

View File

@@ -16,7 +16,7 @@ namespace gaseous_server.Models
{ {
var targetType = this.GetType(); var targetType = this.GetType();
var sourceType = game.GetType(); var sourceType = game.GetType();
foreach(var prop in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public| BindingFlags.SetProperty)) foreach (var prop in targetType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty))
{ {
// check whether source object has the the property // check whether source object has the the property
var sp = sourceType.GetProperty(prop.Name); var sp = sourceType.GetProperty(prop.Name);
@@ -39,7 +39,11 @@ namespace gaseous_server.Models
{ {
if (this.Cover.Id != null) if (this.Cover.Id != null)
{ {
IGDB.Models.Cover cover = Covers.GetCover(Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false); // IGDB.Models.Cover cover = Covers.GetCover(Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(this), false);
IGDB.Models.Cover cover = new IGDB.Models.Cover()
{
Id = this.Cover.Id
};
return cover; return cover;
} }

View File

@@ -36,6 +36,9 @@ db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.Conn
// set up db // set up db
db.InitDB(); db.InitDB();
// create relation tables if they don't exist
Storage.CreateRelationsTables<IGDB.Models.Game>();
Storage.CreateRelationsTables<IGDB.Models.Platform>();
// populate db with static data for lookups // populate db with static data for lookups
AgeRatings.PopulateAgeMap(); AgeRatings.PopulateAgeMap();
@@ -307,7 +310,7 @@ app.Use(async (context, next) =>
string userIdentity; string userIdentity;
try try
{ {
userIdentity = context.User.Claims.Where(x=>x.Type==System.Security.Claims.ClaimTypes.NameIdentifier).FirstOrDefault().Value; userIdentity = context.User.Claims.Where(x => x.Type == System.Security.Claims.ClaimTypes.NameIdentifier).FirstOrDefault().Value;
} }
catch catch
{ {

View File

@@ -63,9 +63,9 @@ function getQueryString(stringName, type) {
function setCookie(cname, cvalue, exdays) { function setCookie(cname, cvalue, exdays) {
const d = new Date(); const d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000)); d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
if (exdays) { if (exdays) {
let expires = "expires="+ d.toUTCString(); let expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
} else { } else {
document.cookie = cname + "=" + cvalue + ";path=/"; document.cookie = cname + "=" + cvalue + ";path=/";
@@ -76,7 +76,7 @@ function getCookie(cname) {
let name = cname + "="; let name = cname + "=";
let decodedCookie = decodeURIComponent(document.cookie); let decodedCookie = decodeURIComponent(document.cookie);
let ca = decodedCookie.split(';'); let ca = decodedCookie.split(';');
for(let i = 0; i <ca.length; i++) { for (let i = 0; i < ca.length; i++) {
let c = ca[i]; let c = ca[i];
while (c.charAt(0) == ' ') { while (c.charAt(0) == ' ') {
c = c.substring(1); c = c.substring(1);
@@ -207,7 +207,7 @@ function createTableRow(isHeader, row, rowClass, cellClass) {
} }
var newCell = document.createElement(cellType); var newCell = document.createElement(cellType);
if (typeof(row[i]) != "object") { if (typeof (row[i]) != "object") {
newCell.innerHTML = row[i]; newCell.innerHTML = row[i];
newCell.className = cellClass; newCell.className = cellClass;
} else { } else {
@@ -258,7 +258,7 @@ function DropDownRenderGameOption(state) {
if (state.cover) { if (state.cover) {
response = $( response = $(
'<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="/api/v1.1/Games/' + state.id + '/cover/image/cover_small/' + state.cover.imageId + '.jpg" /></td><td class="dropdown-label"><span class="dropdown-title">' + state.text + '</span><span class="dropdown-releasedate">' + releaseDate + '</span></td></tr></table>' '<table class="dropdown-div"><tr><td class="dropdown-cover"><img src="/api/v1.1/Games/' + state.id + '/cover/image/cover_small/' + state.id + '.jpg" class="game_tile_small_search" /></td><td class="dropdown-label"><span class="dropdown-title">' + state.text + '</span><span class="dropdown-releasedate">' + releaseDate + '</span></td></tr></table>'
); );
} else { } else {
response = $( response = $(
@@ -318,7 +318,7 @@ function CreateEditableTable(TableName, Headers) {
addButton.value = 'Add Row'; addButton.value = 'Add Row';
addButton.innerHTML = 'Add Row'; addButton.innerHTML = 'Add Row';
$(addButton).click(function() { $(addButton).click(function () {
eTable.appendChild(AddEditableTableRow(Headers)); eTable.appendChild(AddEditableTableRow(Headers));
}); });
@@ -463,10 +463,10 @@ function SetPreference(Setting, Value) {
ajaxCall( ajaxCall(
'/api/v1.1/Account/Preferences', '/api/v1.1/Account/Preferences',
'POST', 'POST',
function(result) { function (result) {
SetPreference_Local(Setting, Value); SetPreference_Local(Setting, Value);
}, },
function(error) { function (error) {
SetPreference_Local(Setting, Value); SetPreference_Local(Setting, Value);
}, },
JSON.stringify(model) JSON.stringify(model)
@@ -478,12 +478,12 @@ function SetPreference_Batch(model) {
ajaxCall( ajaxCall(
'/api/v1.1/Account/Preferences', '/api/v1.1/Account/Preferences',
'POST', 'POST',
function(result) { function (result) {
for (var i = 0; i < model.length; i++) { for (var i = 0; i < model.length; i++) {
SetPreference_Local(model[i].setting, model[i].value.toString()); SetPreference_Local(model[i].setting, model[i].value.toString());
} }
}, },
function(error) { function (error) {
for (var i = 0; i < model.length; i++) { for (var i = 0; i < model.length; i++) {
SetPreference_Local(model[i].setting, model[i].value.toString()); SetPreference_Local(model[i].setting, model[i].value.toString());
} }
@@ -509,11 +509,11 @@ function SetPreference_Local(Setting, Value) {
} }
} }
function Uint8ToString(u8a){ function Uint8ToString(u8a) {
var CHUNK_SZ = 0x8000; var CHUNK_SZ = 0x8000;
var c = []; var c = [];
for (var i=0; i < u8a.length; i+=CHUNK_SZ) { for (var i = 0; i < u8a.length; i += CHUNK_SZ) {
c.push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ))); c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
} }
return c.join(""); return c.join("");
} }

View File

@@ -23,21 +23,29 @@ h3 {
border-bottom-width: 1px; border-bottom-width: 1px;
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/ /*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
border-image: linear-gradient(to right, rgba(255,0,0,1) 0%, rgba(251,255,0,1) 16%, rgba(0,255,250,1) 30%, rgba(0,16,255,1) 46%, rgba(250,0,255,1) 62%, rgba(255,0,0,1) 78%, rgba(255,237,0,1) 90%, rgba(20,255,0,1) 100%) 5; border-image: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(251, 255, 0, 1) 16%, rgba(0, 255, 250, 1) 30%, rgba(0, 16, 255, 1) 46%, rgba(250, 0, 255, 1) 62%, rgba(255, 0, 0, 1) 78%, rgba(255, 237, 0, 1) 90%, rgba(20, 255, 0, 1) 100%) 5;
} }
/* The Modal (background) */ /* The Modal (background) */
.modal { .modal {
display: none; /* Hidden by default */ display: none;
position: fixed; /* Stay in place */ /* Hidden by default */
z-index: 100; /* Sit on top */ position: fixed;
/* Stay in place */
z-index: 100;
/* Sit on top */
left: 0; left: 0;
top: 0; top: 0;
width: 100%; /* Full width */ width: 100%;
height: 100%; /* Full height */ /* Full width */
overflow: none; /* Enable scroll if needed */ height: 100%;
background-color: rgb(0,0,0); /* Fallback color */ /* Full height */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ overflow: none;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
filter: drop-shadow(5px 5px 10px #000); filter: drop-shadow(5px 5px 10px #000);
@@ -47,22 +55,28 @@ h3 {
/* Modal Content/Box */ /* Modal Content/Box */
.modal-content { .modal-content {
background-color: #383838; background-color: #383838;
margin: 10% auto; /* 15% from the top and centered */ margin: 10% auto;
/* 15% from the top and centered */
padding: 10px; padding: 10px;
border: 1px solid #888; border: 1px solid #888;
border-radius: 10px; border-radius: 10px;
width: 700px; /* Could be more or less, depending on screen size */ width: 700px;
/* Could be more or less, depending on screen size */
min-height: 358px; min-height: 358px;
} }
.modal-content-sub { .modal-content-sub {
background-color: #383838; background-color: #383838;
margin: 20% auto; /* 20% from the top and centered */ margin: 20% auto;
/* 20% from the top and centered */
padding: 10px; padding: 10px;
border: 1px solid #888; border: 1px solid #888;
border-radius: 10px; border-radius: 10px;
width: 300px; /* Could be more or less, depending on screen size */ width: 300px;
/* Could be more or less, depending on screen size */
min-height: 110px; min-height: 110px;
} }
#modal-heading { #modal-heading {
margin-block: 5px; margin-block: 5px;
border-bottom-style: solid; border-bottom-style: solid;
@@ -70,8 +84,9 @@ h3 {
border-bottom-width: 3px; border-bottom-width: 3px;
/*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/ /*border-image: linear-gradient(to right, blue 25%, yellow 25%, yellow 50%,red 50%, red 75%, teal 75%) 5;*/
border-image: linear-gradient(to right, rgba(255,0,0,1) 0%, rgba(251,255,0,1) 16%, rgba(0,255,250,1) 30%, rgba(0,16,255,1) 46%, rgba(250,0,255,1) 62%, rgba(255,0,0,1) 78%, rgba(255,237,0,1) 90%, rgba(20,255,0,1) 100%) 5; border-image: linear-gradient(to right, rgba(255, 0, 0, 1) 0%, rgba(251, 255, 0, 1) 16%, rgba(0, 255, 250, 1) 30%, rgba(0, 16, 255, 1) 46%, rgba(250, 0, 255, 1) 62%, rgba(255, 0, 0, 1) 78%, rgba(255, 237, 0, 1) 90%, rgba(20, 255, 0, 1) 100%) 5;
} }
#modal-content { #modal-content {
height: 100%; height: 100%;
} }
@@ -296,7 +311,11 @@ h3 {
z-index: 1; z-index: 1;
} }
input[type='text'], input[type='number'], input[type="email"], input[type="password"], input[type="datetime-local"] { input[type='text'],
input[type='number'],
input[type="email"],
input[type="password"],
input[type="datetime-local"] {
background-color: #2b2b2b; background-color: #2b2b2b;
color: white; color: white;
padding: 4px; padding: 4px;
@@ -313,7 +332,11 @@ input[type='text'], input[type='number'], input[type="email"], input[type="passw
height: 21px; height: 21px;
} }
input[type='text']:hover, input[type='number']:hover, input[type="email"]:hover, input[type="password"]:hover, input[type="datetime-local"]:hover { input[type='text']:hover,
input[type='number']:hover,
input[type="email"]:hover,
input[type="password"]:hover,
input[type="datetime-local"]:hover {
border-color: #939393; border-color: #939393;
} }
@@ -351,9 +374,7 @@ input[name='filter_panel_range_max'] {
background: #555; background: #555;
} }
.text_link { .text_link {}
}
.text_link:hover { .text_link:hover {
cursor: pointer; cursor: pointer;
@@ -390,9 +411,9 @@ input[name='filter_panel_range_max'] {
background-color: rgba(0, 22, 56, 0.8); background-color: rgba(0, 22, 56, 0.8);
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
.games_pager_number { .games_pager_number {
@@ -604,6 +625,12 @@ input[name='filter_panel_range_max'] {
border: 1px solid #2b2b2b; border: 1px solid #2b2b2b;
} }
.game_tile_small_search {
min-height: 50px;
min-width: 50px;
width: 80px;
}
.game_tile_row { .game_tile_row {
padding: 5px; padding: 5px;
display: block; display: block;
@@ -706,9 +733,9 @@ input[name='filter_panel_range_max'] {
} }
.game_tile_image_shadow { .game_tile_image_shadow {
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
.game_tile_image_row { .game_tile_image_row {
@@ -720,11 +747,13 @@ input[name='filter_panel_range_max'] {
background-color: transparent; background-color: transparent;
} }
.game_tile_image, .unknown { .game_tile_image,
.unknown {
background-color: transparent; background-color: transparent;
} }
.game_tile_image_row, .unknown { .game_tile_image_row,
.unknown {
background-color: transparent; background-color: transparent;
} }
@@ -790,9 +819,9 @@ input[name='filter_panel_range_max'] {
max-width: 250px; max-width: 250px;
max-height: 350px; max-height: 350px;
width: 100%; width: 100%;
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
.gamegenrelabel { .gamegenrelabel {
@@ -842,9 +871,9 @@ input[name='filter_panel_range_max'] {
padding: 10px; padding: 10px;
/*height: 350px;*/ /*height: 350px;*/
margin-bottom: 20px; margin-bottom: 20px;
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
#gamescreenshots_main { #gamescreenshots_main {
@@ -903,11 +932,16 @@ iframe {
background-color: #383838; background-color: #383838;
color: black; color: black;
text-align: center; text-align: center;
user-select: none; /* standard syntax */ user-select: none;
-webkit-user-select: none; /* webkit (safari, chrome) browsers */ /* standard syntax */
-moz-user-select: none; /* mozilla browsers */ -webkit-user-select: none;
-khtml-user-select: none; /* webkit (konqueror) browsers */ /* webkit (safari, chrome) browsers */
-ms-user-select: none; /* IE10+ */ -moz-user-select: none;
/* mozilla browsers */
-khtml-user-select: none;
/* webkit (konqueror) browsers */
-ms-user-select: none;
/* IE10+ */
} }
.gamescreenshots_arrows:hover { .gamescreenshots_arrows:hover {
@@ -981,9 +1015,7 @@ iframe {
background-color: rgba(56, 56, 56, 0.9); background-color: rgba(56, 56, 56, 0.9);
} }
#gamesummarytext_label { #gamesummarytext_label {}
}
.line-clamp-4 { .line-clamp-4 {
overflow: hidden; overflow: hidden;
@@ -1057,9 +1089,9 @@ th {
-webkit-border-radius: 5px 5px 5px 5px; -webkit-border-radius: 5px 5px 5px 5px;
-moz-border-radius: 5px 5px 5px 5px; -moz-border-radius: 5px 5px 5px 5px;
border: 1px solid #19d348; border: 1px solid #19d348;
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
.romstart:hover { .romstart:hover {
@@ -1084,9 +1116,9 @@ th {
border-color: white; border-color: white;
background-color: blue; background-color: blue;
outline-color: blue; outline-color: blue;
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
.properties_button:hover { .properties_button:hover {
@@ -1115,14 +1147,18 @@ th {
height: 100%; height: 100%;
} }
div[name="properties_toc_item"],div[name="properties_user_toc_item"],div[name="properties_profile_toc_item"] { div[name="properties_toc_item"],
div[name="properties_user_toc_item"],
div[name="properties_profile_toc_item"] {
padding: 10px; padding: 10px;
border-bottom-width: 1px; border-bottom-width: 1px;
border-bottom-style: solid; border-bottom-style: solid;
border-bottom-color: #2b2b2b; border-bottom-color: #2b2b2b;
} }
div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover,div[name="properties_profile_toc_item"]:hover { div[name="properties_toc_item"]:hover,
div[name="properties_user_toc_item"]:hover,
div[name="properties_profile_toc_item"]:hover {
background-color: #2b2b2b; background-color: #2b2b2b;
cursor: pointer; cursor: pointer;
} }
@@ -1150,7 +1186,8 @@ div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover
border-radius: 5px; border-radius: 5px;
} }
.select2-container--default:hover, .select2-selection--multiple:hover { .select2-container--default:hover,
.select2-selection--multiple:hover {
border-color: #939393; border-color: #939393;
} }
@@ -1197,7 +1234,8 @@ div[name="properties_toc_item"]:hover,div[name="properties_user_toc_item"]:hover
border-radius: 5px; border-radius: 5px;
} }
.select2-selection--single:hover, .select2-selection__rendered:hover { .select2-selection--single:hover,
.select2-selection__rendered:hover {
border-color: #939393; border-color: #939393;
} }
@@ -1302,9 +1340,7 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
background-color: #555; background-color: #555;
} }
#emulator { #emulator {}
}
.emulator_partscreen { .emulator_partscreen {
margin: 0 auto; margin: 0 auto;
@@ -1377,15 +1413,14 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
margin-left: 15px; margin-left: 15px;
} }
.rom_checkbox_box { .rom_checkbox_box {}
}
.rom_checkbox_box_hidden { .rom_checkbox_box_hidden {
display: none; display: none;
} }
#rom_edit, #rom_edit_delete { #rom_edit,
#rom_edit_delete {
float: right; float: right;
} }
@@ -1398,9 +1433,9 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
} }
#game { #game {
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -webkit-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44); -moz-box-shadow: 5px 5px 19px 0px rgba(0, 0, 0, 0.44);
} }
#gametitle_criticrating { #gametitle_criticrating {
@@ -1440,7 +1475,7 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
width: 1000px; width: 1000px;
height: 90%; height: 90%;
margin: 25px auto; margin: 25px auto;
/* overflow-x: scroll;*/ /* overflow-x: scroll;*/
position: relative; position: relative;
} }
@@ -1468,7 +1503,8 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
} }
.bgalt1 { .bgalt1 {
background-color: transparent;; background-color: transparent;
;
} }
.logs_table_cell_150px { .logs_table_cell_150px {
@@ -1520,13 +1556,33 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
background-color: #383838; background-color: #383838;
} }
.string { color: lightblue; } .string {
.number { color: lightblue; } color: lightblue;
.boolean { color: lightblue; } }
.null { color: magenta; }
.key { color: greenyellow; } .number {
.brace { color: #888; } color: lightblue;
.square { color: #fff000; } }
.boolean {
color: lightblue;
}
.null {
color: magenta;
}
.key {
color: greenyellow;
}
.brace {
color: #888;
}
.square {
color: #fff000;
}
.tagBox { .tagBox {
position: absolute; position: absolute;
@@ -1557,12 +1613,16 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
} }
.loginwindow { .loginwindow {
position: fixed; /* Stay in place */ position: fixed;
/* Stay in place */
left: 0; left: 0;
top: 0; top: 0;
width: 100%; /* Full width */ width: 100%;
height: 100%; /* Full height */ /* Full width */
overflow: auto; /* Enable scroll if needed */ height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
/*background-color: rgb(0,0,0); /* Fallback color */ /*background-color: rgb(0,0,0); /* Fallback color */
/*background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ /*background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
/*backdrop-filter: blur(8px); /*backdrop-filter: blur(8px);
@@ -1575,11 +1635,13 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
.loginwindow-content { .loginwindow-content {
position: relative; position: relative;
background-color: #383838; background-color: #383838;
margin: 15% auto; /* 15% from the top and centered */ margin: 15% auto;
/* 15% from the top and centered */
padding: 10px; padding: 10px;
border: 1px solid #888; border: 1px solid #888;
border-radius: 10px; border-radius: 10px;
width: 350px; /* Could be more or less, depending on screen size */ width: 350px;
/* Could be more or less, depending on screen size */
min-height: 250px; min-height: 250px;
} }
@@ -1615,7 +1677,8 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
} }
/* Links inside the dropdown */ /* Links inside the dropdown */
.dropdown-content a, .dropdown-content span { .dropdown-content a,
.dropdown-content span {
color: black; color: black;
padding: 12px 16px; padding: 12px 16px;
text-decoration: none; text-decoration: none;
@@ -1627,10 +1690,14 @@ button:not(.select2-selection__choice__remove):not(.ejs_menu_button):disabled {
} }
/* Change color of dropdown links on hover */ /* Change color of dropdown links on hover */
.dropdown-content a:hover {background-color: #ddd;} .dropdown-content a:hover {
background-color: #ddd;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ /* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;} .show {
display: block;
}
.dropdownroleitem { .dropdownroleitem {
text-transform: capitalize; text-transform: capitalize;