diff --git a/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj b/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj index 9c61a42..94bf156 100644 --- a/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj +++ b/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj @@ -5,8 +5,8 @@ - - + + diff --git a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj index bc92634..34f9081 100644 --- a/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj +++ b/LANCommander.Playnite.Extension/LANCommander.PlaynitePlugin.csproj @@ -34,8 +34,8 @@ ..\packages\rix0rrr.BeaconLib.1.0.2\lib\net40\BeaconLib.dll - - ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll + + ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll ..\packages\PlayniteSDK.6.9.0\lib\net462\Playnite.SDK.dll @@ -70,11 +70,11 @@ ..\packages\System.Text.Encoding.CodePages.7.0.0\lib\net462\System.Text.Encoding.CodePages.dll - - ..\packages\System.Text.Encodings.Web.5.0.0\lib\net461\System.Text.Encodings.Web.dll + + ..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll - - ..\packages\System.Text.Json.5.0.1\lib\net461\System.Text.Json.dll + + ..\packages\System.Text.Json.7.0.3\lib\net462\System.Text.Json.dll ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll diff --git a/LANCommander.Playnite.Extension/app.config b/LANCommander.Playnite.Extension/app.config index 8adb46d..f164a44 100644 --- a/LANCommander.Playnite.Extension/app.config +++ b/LANCommander.Playnite.Extension/app.config @@ -8,7 +8,7 @@ - + @@ -22,6 +22,14 @@ + + + + + + + + \ No newline at end of file diff --git a/LANCommander.Playnite.Extension/packages.config b/LANCommander.Playnite.Extension/packages.config index aa5952d..8aed914 100644 --- a/LANCommander.Playnite.Extension/packages.config +++ b/LANCommander.Playnite.Extension/packages.config @@ -1,7 +1,7 @@  - - + + @@ -12,8 +12,8 @@ - - + + diff --git a/LANCommander/Controllers/Api/GameSavesController.cs b/LANCommander/Controllers/Api/GameSavesController.cs index e9800c9..2717de5 100644 --- a/LANCommander/Controllers/Api/GameSavesController.cs +++ b/LANCommander/Controllers/Api/GameSavesController.cs @@ -18,12 +18,14 @@ namespace LANCommander.Controllers.Api private readonly GameSaveService GameSaveService; private readonly GameService GameService; private readonly UserManager UserManager; + private readonly LANCommanderSettings Settings; public GameSavesController(GameSaveService gameSaveService, GameService gameService, UserManager userManager) { GameSaveService = gameSaveService; GameService = gameService; UserManager = userManager; + Settings = SettingService.GetSettings(); } [HttpGet("{id}")] @@ -65,7 +67,7 @@ namespace LANCommander.Controllers.Api public async Task Upload(Guid id, [FromForm] SaveUpload save) { // Arbitrary file size limit of 25MB - if (save.File.Length > (ByteSizeLib.ByteSize.BytesInMebiByte * 25)) + if (save.File.Length > (ByteSizeLib.ByteSize.BytesInMebiByte * Settings.UserSaves.MaxSize)) return BadRequest("Save file archive is too large"); var game = await GameService.Get(id); diff --git a/LANCommander/Controllers/ServerController.cs b/LANCommander/Controllers/ServerController.cs new file mode 100644 index 0000000..54ba8b8 --- /dev/null +++ b/LANCommander/Controllers/ServerController.cs @@ -0,0 +1,33 @@ +using LANCommander.Services; +using Microsoft.AspNetCore.Mvc; + +namespace LANCommander.Controllers +{ + public class ServerController : Controller + { + private readonly ServerService ServerService; + + public ServerController(ServerService serverService) + { + this.ServerService = serverService; + } + + [HttpGet("/Server/{id:guid}/{*path}")] + public async Task Web(Guid id, string path) + { + var server = await ServerService.Get(id); + + if (server == null) + return NotFound(); + + path = path.Replace('/', Path.DirectorySeparatorChar); + + var filename = Path.Combine(server.HTTPRootPath, path); + + if (!System.IO.File.Exists(filename)) + return NotFound(); + + return File(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read), "application/octet-stream", Path.GetFileName(filename)); + } + } +} diff --git a/LANCommander/Data/Models/GameSave.cs b/LANCommander/Data/Models/GameSave.cs index 1e232d3..a42f4e8 100644 --- a/LANCommander/Data/Models/GameSave.cs +++ b/LANCommander/Data/Models/GameSave.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations.Schema; +using LANCommander.Services; +using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; namespace LANCommander.Data.Models @@ -19,7 +20,9 @@ namespace LANCommander.Data.Models public string GetUploadPath() { - return Path.Combine("Saves", UserId.ToString(), GameId.ToString(), Id.ToString()); + var settings = SettingService.GetSettings(); + + return Path.Combine(settings.UserSaves.StoragePath, UserId.ToString(), GameId.ToString(), Id.ToString()); } } } diff --git a/LANCommander/Data/Models/Server.cs b/LANCommander/Data/Models/Server.cs index f2541ba..07c1878 100644 --- a/LANCommander/Data/Models/Server.cs +++ b/LANCommander/Data/Models/Server.cs @@ -17,6 +17,9 @@ namespace LANCommander.Data.Models public bool Autostart { get; set; } public int AutostartDelay { get; set; } + public bool EnableHTTP { get; set; } + public string HTTPRootPath { get; set; } + public Guid? GameId { get; set; } [JsonIgnore] [ForeignKey(nameof(GameId))] diff --git a/LANCommander/Data/Models/User.cs b/LANCommander/Data/Models/User.cs index 7c98774..8cd057b 100644 --- a/LANCommander/Data/Models/User.cs +++ b/LANCommander/Data/Models/User.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Identity; +using LANCommander.Services; +using Microsoft.AspNetCore.Identity; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; @@ -53,7 +54,9 @@ namespace LANCommander.Data.Models public string GetGameSaveUploadPath() { - return Path.Combine("Saves", Id.ToString()); + var settings = SettingService.GetSettings(); + + return Path.Combine(settings.UserSaves.StoragePath, Id.ToString()); } } } diff --git a/LANCommander/LANCommander.csproj b/LANCommander/LANCommander.csproj index b35b9c1..7271e46 100644 --- a/LANCommander/LANCommander.csproj +++ b/LANCommander/LANCommander.csproj @@ -22,9 +22,9 @@ - + - + @@ -34,15 +34,14 @@ - - - - - - - - - + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -51,10 +50,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + diff --git a/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.Designer.cs b/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.Designer.cs new file mode 100644 index 0000000..1790bf5 --- /dev/null +++ b/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.Designer.cs @@ -0,0 +1,1441 @@ +// +using System; +using LANCommander.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace LANCommander.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20230914005736_AddServerHTTPSupport")] + partial class AddServerHTTPSupport + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true); + + modelBuilder.Entity("CategoryGame", b => + { + b.Property("CategoriesId") + .HasColumnType("TEXT"); + + b.Property("GamesId") + .HasColumnType("TEXT"); + + b.HasKey("CategoriesId", "GamesId"); + + b.HasIndex("GamesId"); + + b.ToTable("CategoryGame"); + }); + + modelBuilder.Entity("GameDeveloper", b => + { + b.Property("DeveloperId") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.HasKey("DeveloperId", "GameId"); + + b.HasIndex("GameId"); + + b.ToTable("GameDeveloper"); + }); + + modelBuilder.Entity("GameGenre", b => + { + b.Property("GamesId") + .HasColumnType("TEXT"); + + b.Property("GenresId") + .HasColumnType("TEXT"); + + b.HasKey("GamesId", "GenresId"); + + b.HasIndex("GenresId"); + + b.ToTable("GameGenre"); + }); + + modelBuilder.Entity("GamePublisher", b => + { + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("PublisherId") + .HasColumnType("TEXT"); + + b.HasKey("GameId", "PublisherId"); + + b.HasIndex("PublisherId"); + + b.ToTable("GamePublisher"); + }); + + modelBuilder.Entity("GameTag", b => + { + b.Property("GamesId") + .HasColumnType("TEXT"); + + b.Property("TagsId") + .HasColumnType("TEXT"); + + b.HasKey("GamesId", "TagsId"); + + b.HasIndex("TagsId"); + + b.ToTable("GameTag"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Action", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Arguments") + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("PrimaryAction") + .HasColumnType("INTEGER"); + + b.Property("SortOrder") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("WorkingDirectory") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Actions"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Archive", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Changelog") + .HasColumnType("TEXT"); + + b.Property("CompressedSize") + .HasColumnType("INTEGER"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("LastVersionId") + .HasColumnType("TEXT"); + + b.Property("ObjectKey") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UncompressedSize") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("LastVersionId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Archive"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ParentId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Companies"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Game", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("DirectoryName") + .HasColumnType("TEXT"); + + b.Property("IGDBId") + .HasColumnType("INTEGER"); + + b.Property("Icon") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasColumnType("TEXT"); + + b.Property("ReleasedOn") + .HasColumnType("TEXT"); + + b.Property("Singleplayer") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("ValidKeyRegex") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Games"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.GameSave", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.HasIndex("UserId"); + + b.ToTable("GameSaves"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Genres"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Key", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AllocationMethod") + .HasColumnType("INTEGER"); + + b.Property("ClaimedByComputerName") + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("ClaimedByIpv4Address") + .HasMaxLength(15) + .HasColumnType("TEXT"); + + b.Property("ClaimedByMacAddress") + .HasMaxLength(17) + .HasColumnType("TEXT"); + + b.Property("ClaimedByUserId") + .HasColumnType("TEXT"); + + b.Property("ClaimedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ClaimedByUserId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Keys"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.MultiplayerMode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GameId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("MaxPlayers") + .HasColumnType("INTEGER"); + + b.Property("MinPlayers") + .HasColumnType("INTEGER"); + + b.Property("NetworkProtocol") + .HasColumnType("INTEGER"); + + b.Property("Spectators") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("MultiplayerModes"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("LANCommander.Data.Models.SavePath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("SavePaths"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Script", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Contents") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("GameId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RequiresAdmin") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Scripts"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("Arguments") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Autostart") + .HasColumnType("INTEGER"); + + b.Property("AutostartDelay") + .HasColumnType("INTEGER"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EnableHTTP") + .HasColumnType("INTEGER"); + + b.Property("GameId") + .HasColumnType("TEXT"); + + b.Property("HTTPRootPath") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnStartScriptPath") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnStopScriptPath") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.Property("UseShellExecute") + .HasColumnType("INTEGER"); + + b.Property("WorkingDirectory") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("GameId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.ServerConsole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Host") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Path") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId1") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerId1"); + + b.HasIndex("UpdatedById"); + + b.ToTable("ServerConsoles"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedById") + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdatedById") + .HasColumnType("TEXT"); + + b.Property("UpdatedOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Tags"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ApprovedOn") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("RefreshToken") + .HasColumnType("TEXT"); + + b.Property("RefreshTokenExpiration") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("CategoryGame", b => + { + b.HasOne("LANCommander.Data.Models.Category", null) + .WithMany() + .HasForeignKey("CategoriesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Game", null) + .WithMany() + .HasForeignKey("GamesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GameDeveloper", b => + { + b.HasOne("LANCommander.Data.Models.Company", null) + .WithMany() + .HasForeignKey("DeveloperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Game", null) + .WithMany() + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GameGenre", b => + { + b.HasOne("LANCommander.Data.Models.Game", null) + .WithMany() + .HasForeignKey("GamesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Genre", null) + .WithMany() + .HasForeignKey("GenresId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GamePublisher", b => + { + b.HasOne("LANCommander.Data.Models.Game", null) + .WithMany() + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Company", null) + .WithMany() + .HasForeignKey("PublisherId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("GameTag", b => + { + b.HasOne("LANCommander.Data.Models.Game", null) + .WithMany() + .HasForeignKey("GamesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Tag", null) + .WithMany() + .HasForeignKey("TagsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Action", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("Actions") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Archive", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("Archives") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Archive", "LastVersion") + .WithMany() + .HasForeignKey("LastVersionId"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("LastVersion"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Category", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Category", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Parent"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Company", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Game", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.GameSave", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("GameSaves") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.HasOne("LANCommander.Data.Models.User", "User") + .WithMany("GameSaves") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Genre", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Key", b => + { + b.HasOne("LANCommander.Data.Models.User", "ClaimedByUser") + .WithMany() + .HasForeignKey("ClaimedByUserId"); + + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("Keys") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("ClaimedByUser"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.MultiplayerMode", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("MultiplayerModes") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.SavePath", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("SavePaths") + .HasForeignKey("GameId"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Script", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("Scripts") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Server", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Game", "Game") + .WithMany("Servers") + .HasForeignKey("GameId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Game"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.ServerConsole", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.Server", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.Server", null) + .WithMany("ServerConsoles") + .HasForeignKey("ServerId1"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Server"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Tag", b => + { + b.HasOne("LANCommander.Data.Models.User", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById"); + + b.HasOne("LANCommander.Data.Models.User", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("LANCommander.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("LANCommander.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("LANCommander.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("LANCommander.Data.Models.Role", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("LANCommander.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("LANCommander.Data.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Category", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Game", b => + { + b.Navigation("Actions"); + + b.Navigation("Archives"); + + b.Navigation("GameSaves"); + + b.Navigation("Keys"); + + b.Navigation("MultiplayerModes"); + + b.Navigation("SavePaths"); + + b.Navigation("Scripts"); + + b.Navigation("Servers"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.Server", b => + { + b.Navigation("ServerConsoles"); + }); + + modelBuilder.Entity("LANCommander.Data.Models.User", b => + { + b.Navigation("GameSaves"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.cs b/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.cs new file mode 100644 index 0000000..b572b00 --- /dev/null +++ b/LANCommander/Migrations/20230914005736_AddServerHTTPSupport.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace LANCommander.Migrations +{ + /// + public partial class AddServerHTTPSupport : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "EnableHTTP", + table: "Servers", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "HTTPRootPath", + table: "Servers", + type: "TEXT", + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "EnableHTTP", + table: "Servers"); + + migrationBuilder.DropColumn( + name: "HTTPRootPath", + table: "Servers"); + } + } +} diff --git a/LANCommander/Migrations/DatabaseContextModelSnapshot.cs b/LANCommander/Migrations/DatabaseContextModelSnapshot.cs index 6dc4f98..e288ecb 100644 --- a/LANCommander/Migrations/DatabaseContextModelSnapshot.cs +++ b/LANCommander/Migrations/DatabaseContextModelSnapshot.cs @@ -678,9 +678,16 @@ namespace LANCommander.Migrations b.Property("CreatedOn") .HasColumnType("TEXT"); + b.Property("EnableHTTP") + .HasColumnType("INTEGER"); + b.Property("GameId") .HasColumnType("TEXT"); + b.Property("HTTPRootPath") + .IsRequired() + .HasColumnType("TEXT"); + b.Property("Name") .IsRequired() .HasColumnType("TEXT"); diff --git a/LANCommander/Models/Settings.cs b/LANCommander/Models/Settings.cs index e1184b8..83828b8 100644 --- a/LANCommander/Models/Settings.cs +++ b/LANCommander/Models/Settings.cs @@ -18,6 +18,7 @@ namespace LANCommander.Models public LANCommanderTheme Theme { get; set; } = LANCommanderTheme.Light; public LANCommanderAuthenticationSettings Authentication { get; set; } = new LANCommanderAuthenticationSettings(); + public LANCommanderUserSaveSettings UserSaves { get; set; } = new LANCommanderUserSaveSettings(); public LANCommanderArchiveSettings Archives { get; set; } = new LANCommanderArchiveSettings(); public LANCommanderIPXRelaySettings IPXRelay { get; set; } = new LANCommanderIPXRelaySettings(); public LANCommanderDHCPServerSettings DHCPServer { get; set; } = new LANCommanderDHCPServerSettings(); @@ -35,6 +36,12 @@ namespace LANCommander.Models public int PasswordRequiredLength { get; set; } = 8; } + public class LANCommanderUserSaveSettings + { + public string StoragePath { get; set; } = "Saves"; + public int MaxSize { get; set; } = 25; + } + public class LANCommanderArchiveSettings { public bool EnablePatching { get; set; } = false; diff --git a/LANCommander/Pages/Dashboard/Charts/StorageUsage.razor b/LANCommander/Pages/Dashboard/Charts/StorageUsage.razor index 3913cea..be31623 100644 --- a/LANCommander/Pages/Dashboard/Charts/StorageUsage.razor +++ b/LANCommander/Pages/Dashboard/Charts/StorageUsage.razor @@ -39,7 +39,7 @@ var totalStorageSize = drives.Where(d => d.IsReady && d.Name == root).Sum(d => d.TotalSize); var totalAvailableFreeSpace = drives.Where(d => d.IsReady && d.Name == root).Sum(d => d.AvailableFreeSpace); var totalUploadDirectorySize = new DirectoryInfo(settings.Archives.StoragePath).EnumerateFiles().Sum(f => f.Length); - var totalSaveDirectorySize = new DirectoryInfo("Saves").EnumerateFiles().Sum(f => f.Length); + var totalSaveDirectorySize = new DirectoryInfo(settings.UserSaves.StoragePath).EnumerateFiles().Sum(f => f.Length); Data = new object[] { diff --git a/LANCommander/Pages/Servers/Edit.razor b/LANCommander/Pages/Servers/Edit.razor index c6972f6..f9e1734 100644 --- a/LANCommander/Pages/Servers/Edit.razor +++ b/LANCommander/Pages/Servers/Edit.razor @@ -14,7 +14,7 @@ General - + HTTP @if (Server != null && Server.Id != Guid.Empty) { Consoles @@ -116,6 +116,23 @@ } + @if (Panel == "HTTP") + { +
+ + + + + + + + + + + +
+ } + @if (Panel == "Monitor") { @if (LogId == "Console") { diff --git a/LANCommander/Pages/Settings/SettingsLayout.razor b/LANCommander/Pages/Settings/SettingsLayout.razor index 4aa2338..ca0ccd0 100644 --- a/LANCommander/Pages/Settings/SettingsLayout.razor +++ b/LANCommander/Pages/Settings/SettingsLayout.razor @@ -8,6 +8,7 @@ General Users Authentication + User Saves Archives IPX Relay diff --git a/LANCommander/Pages/Settings/UserSaves.razor b/LANCommander/Pages/Settings/UserSaves.razor new file mode 100644 index 0000000..e00e81f --- /dev/null +++ b/LANCommander/Pages/Settings/UserSaves.razor @@ -0,0 +1,59 @@ +@page "/Settings/UserSaves" +@using LANCommander.Components.FileManagerComponents; +@using LANCommander.Models; +@layout SettingsLayout +@inject SettingService SettingService +@inject IMessageService MessageService +@attribute [Authorize(Roles = "Administrator")] + + + +
+
+ + + + + + + + + + + +
+
+ +@code { + LANCommanderSettings Settings; + + string RootPath = Path.GetPathRoot(Directory.GetCurrentDirectory()); + + protected override async Task OnInitializedAsync() + { + Settings = SettingService.GetSettings(); + } + + private void Save() + { + try + { + SettingService.SaveSettings(Settings); + MessageService.Success("Settings saved!"); + } + catch + { + MessageService.Error("An unknown error occurred."); + } + } + + private void OnPathSelected(string path) + { + var appPath = Directory.GetCurrentDirectory(); + + if (path != null && path.StartsWith(appPath)) + path = path.Substring(appPath.Length).TrimStart(Path.DirectorySeparatorChar).TrimEnd(Path.DirectorySeparatorChar); + + Settings.UserSaves.StoragePath = path; + } +} diff --git a/LANCommander/Program.cs b/LANCommander/Program.cs index 342a166..10f6eb6 100644 --- a/LANCommander/Program.cs +++ b/LANCommander/Program.cs @@ -191,8 +191,8 @@ if (!Directory.Exists(settings.Archives.StoragePath)) if (!Directory.Exists("Icon")) Directory.CreateDirectory("Icon"); -if (!Directory.Exists("Saves")) - Directory.CreateDirectory("Saves"); +if (!Directory.Exists(settings.UserSaves.StoragePath)) + Directory.CreateDirectory(settings.UserSaves.StoragePath); if (!Directory.Exists("Snippets")) Directory.CreateDirectory("Snippets"); diff --git a/LANCommander/Services/GameSaveService.cs b/LANCommander/Services/GameSaveService.cs index d838359..65e6a57 100644 --- a/LANCommander/Services/GameSaveService.cs +++ b/LANCommander/Services/GameSaveService.cs @@ -1,16 +1,17 @@ using LANCommander.Data; using LANCommander.Data.Models; using LANCommander.Helpers; +using LANCommander.Models; namespace LANCommander.Services { public class GameSaveService : BaseDatabaseService { - private readonly SettingService SettingService; + private readonly LANCommanderSettings Settings; - public GameSaveService(DatabaseContext dbContext, IHttpContextAccessor httpContextAccessor, SettingService settingService) : base(dbContext, httpContextAccessor) + public GameSaveService(DatabaseContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor) { - SettingService = settingService; + Settings = SettingService.GetSettings(); } public override Task Delete(GameSave entity) @@ -36,14 +37,14 @@ namespace LANCommander.Services var save = Get(gs => gs.Id == id).FirstOrDefault(); if (save == null) - return null;; + return null; return GetSavePath(save); } public string GetSavePath(GameSave save) { - return Path.Combine("Save", save.UserId.ToString(), $"{save.Id}.zip"); + return Path.Combine(Settings.UserSaves.StoragePath, save.UserId.ToString(), $"{save.Id}.zip"); } } }