diff --git a/.gitignore b/.gitignore index 1e2fd1a7..d6ee8a61 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ gitVersion.txt gitRemotes.txt gitUnpushed.txt logs/* +npTicket* # MSBuild stuff bin/ diff --git a/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml b/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml index 6dc843df..c41892bf 100644 --- a/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml +++ b/.idea/.idea.ProjectLighthouse/.idea/indexLayout.xml @@ -6,6 +6,7 @@ .github .gitignore .idea + CONTRIBUTING.md DatabaseMigrations ProjectLighthouse.sln.DotSettings ProjectLighthouse.sln.DotSettings.user diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..3d72edc6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,100 @@ +# Contributing + +## Setting up MySQL + +Project Lighthouse requires a MySQL database. For Linux users running docker, one can be set up using +the `docker-compose.yml` file in the root of the project folder. + +Next, make sure the `LIGHTHOUSE_DB_CONNECTION_STRING` environment variable is set correctly. By default, it +is `server=127.0.0.1;uid=root;pwd=lighthouse;database=lighthouse`. If you are running the database via the +above `docker-compose.yml` you shouldn't need to change this. For other development/especially production environments +you will need to change this. + +Once you've gotten MySQL running you can run Lighthouse. It will take care of the rest. + +## Connecting + +PS3 is difficult to set up, so I will be going over how to set up RPCS3 instead. A guide will be coming for PS3 closer +to release. You can also follow this guide if you want to learn how to modify your EBOOT. + +*Note: This requires a patched copy of RPCS3. You can find a working +version [on our GitHub](https://github.com/LBPUnion/rpcs3).* + +Start by getting a copy of LittleBigPlanet 1/2 installed. (Check the LittleBigPlanet 1 section, since you'll need to do +extra steps for your game to not crash upon entering pod computer). + +The game can be a digital copy (NPUA80472/NPUA80662) or a disc copy ( +BCUS98148/BCUS98245). + +Next, download [UnionPatcher](https://github.com/LBPUnion/UnionPatcher/). Binaries can be found by reading the `README.md` +file. + +You should have everything you need now, so open up RPCS3 and go to Utilities -> Decrypt PS3 Binaries. Point this +to `rpcs3/dev_hdd0/game/(title id)/USRDIR/EBOOT.BIN`. You can grab your title id by right clicking the game in RPCS3 and +clicking Copy Info -> Copy Serial. + + +This should give you a file named `EBOOT.elf` in the same folder. This is your decrypted eboot. + +Now that you have your decrypted eboot, open UnionPatcher and select the `EBOOT.elf` you got earlier in the top box, +enter `http://localhost:10060/LITTLEBIGPLANETPS3_XML` in the second, and the output filename in the third. For this +guide I'll use `EBOOTlocalhost.elf`. + +Now, copy the `EBOOTlocalhost.elf` file to where you got your `EBOOT.elf` file from, and you're now good to go. + +To launch the game with the patched EBOOT, open up RPCS3, go to File, Boot SELF/ELF, and open up `EBOOTlocalhost.elf`. + +Assuming you are running the patched version of RPCS3, you patched the file correctly, the database is migrated, and +Project Lighthouse is running, the game should now connect and you may begin contributing! + +### LittleBigPlanet 1 + +For LittleBigPlanet 1 to work with RPCS3, follow the steps above normally. + +First, open your favourite hex editor. We recommend [HxD](https://mh-nexus.de/en/hxd/). + +Once you have a hex editor open, open your `EBOOTlocalhost.elf` file and search for the hex +values `73 63 65 4E 70 43 6F 6D 6D 65 72 63 65 32`. In HxD, this would be done by clicking on Search -> Replace, +clicking on the `Hex-values` tab, and entering the hex there. + +Then, you can zero it out by replacing it with `00 00 00 00 00 00 00 00 00 00 00 00 00 00`. + +What this does is remove all the references to the `sceNpCommerce2` function. The function is used for purchasing DLC, +which at this moment in time crashes RPCS3. + +After saving the file your LBP1 EBOOT can be used with RPCS3. + +## Contributing Tips + +### Database migrations + +Some modifications may require updates to the database schema. You can automatically create a migration file by: + +1. Making sure the tools are installed. You can do this by running `dotnet tool restore`. +2. Making sure `LIGHTHOUSE_DB_CONNECTION_STRING` is set correctly. See the `Running` section for more details. +3. Modifying the database schema via the C# portion of the code. Do not modify the actual SQL database. +4. Running `dotnet ef migrations add --project ProjectLighthouse`. + +This process will create a migration file from the changes made in the C# code. + +The new migrations will automatically be applied upon starting Lighthouse. + +### Running tests + +You can run tests either through your IDE or by running `dotnet tests`. + +Keep in mind while running database tests (which most tests are) you need to have `LIGHTHOUSE_DB_CONNECTION_STRING` set. + +### Continuous Integration (CI) Tips + +- You can skip CI runs for a commit if you specify `[skip ci]` at the beginning of the commit name. This is useful for + formatting changes, etc. +- When creating your first pull request, CI will not run initially. A team member will have to approve you for use of + running CI on a pull request. This is because of GitHub policy. + +### API Documentation + +You can access API documentation by looking at the XMLDoc in the controllers under `ProjectLighthouse.Controllers.Api` + +You can also access an interactive version by starting Lighthouse and accessing Swagger +at `http://localhost:10060/swagger/index.html`. \ No newline at end of file diff --git a/ProjectLighthouse.Tests/LighthouseServerTest.cs b/ProjectLighthouse.Tests/LighthouseServerTest.cs index 6a926c23..7b37d188 100644 --- a/ProjectLighthouse.Tests/LighthouseServerTest.cs +++ b/ProjectLighthouse.Tests/LighthouseServerTest.cs @@ -37,7 +37,8 @@ public class LighthouseServerTest await database.CreateUser($"{username}{number}", HashHelper.BCryptHash($"unitTestPassword{number}")); } - string stringContent = $"{LoginData.UsernamePrefix}{username}{number}{(char)0x00}"; + //TODO: generate actual tickets + string stringContent = $"unitTestTicket{username}{number}"; HttpResponseMessage response = await this.Client.PostAsync ($"/LITTLEBIGPLANETPS3_XML/login?titleID={GameVersionHelper.LittleBigPlanet2TitleIds[0]}", new StringContent(stringContent)); diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings index b1e0b19f..105cfd7e 100644 --- a/ProjectLighthouse.sln.DotSettings +++ b/ProjectLighthouse.sln.DotSettings @@ -1,5 +1,8 @@  True + False + False + False FullFormat True HINT diff --git a/ProjectLighthouse/Controllers/Api/SlotEndpoints.cs b/ProjectLighthouse/Controllers/Api/SlotEndpoints.cs new file mode 100644 index 00000000..909f9a95 --- /dev/null +++ b/ProjectLighthouse/Controllers/Api/SlotEndpoints.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Levels; +using LBPUnion.ProjectLighthouse.Types.Settings; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Controllers.Api; + +/// +/// A collection of endpoints relating to slots. +/// +public class SlotEndpoints : ApiEndpointController +{ + private readonly Database database; + + public SlotEndpoints(Database database) + { + this.database = database; + } + + /// + /// Gets a list of (stripped down) slots from the database. + /// + /// How many slots you want to retrieve. + /// How many slots to skip. + /// The slot + /// The slot list, if successful. + [HttpGet("slots")] + [ProducesResponseType(typeof(List), StatusCodes.Status200OK)] + public async Task GetSlots([FromQuery] int limit = 20, [FromQuery] int skip = 0) + { + limit = Math.Min(ServerStatics.PageSize, limit); + + IEnumerable minimalSlots = (await this.database.Slots.OrderByDescending(s => s.FirstUploaded).Skip(skip).Take(limit).ToListAsync()).Select + (MinimalSlot.FromSlot); + + return this.Ok(minimalSlots); + } + + /// + /// Gets a slot (more commonly known as a level) and its information from the database. + /// + /// The ID of the slot + /// The slot + /// The slot, if successful. + /// The slot could not be found. + [HttpGet("slot/{id:int}")] + [ProducesResponseType(typeof(Slot), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetSlot(int id) + { + Slot? slot = await this.database.Slots.FirstOrDefaultAsync(u => u.SlotId == id); + if (slot == null) return this.NotFound(); + + return this.Ok(slot); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/Api/StatisticsEndpoints.cs b/ProjectLighthouse/Controllers/Api/StatisticsEndpoints.cs new file mode 100644 index 00000000..a89828ac --- /dev/null +++ b/ProjectLighthouse/Controllers/Api/StatisticsEndpoints.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Helpers; +using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Types.Api; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace LBPUnion.ProjectLighthouse.Controllers.Api; + +/// +/// A collection of endpoints relating to statistics. +/// +public class StatisticsEndpoints : ApiEndpointController +{ + /// + /// Gets everything that StatisticsHelper provides. + /// + /// An instance of StatisticsResponse + [HttpGet("statistics")] + [ProducesResponseType(typeof(StatisticsResponse), StatusCodes.Status200OK)] + public async Task GetStatistics() + => this.Ok + ( + new StatisticsResponse + { + Photos = await StatisticsHelper.PhotoCount(), + Slots = await StatisticsHelper.SlotCount(), + Users = await StatisticsHelper.UserCount(), + RecentMatches = await StatisticsHelper.RecentMatches(), + TeamPicks = await StatisticsHelper.TeamPickCount(), + } + ); +} \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/Api/UserEndpoints.cs b/ProjectLighthouse/Controllers/Api/UserEndpoints.cs new file mode 100644 index 00000000..7fc505eb --- /dev/null +++ b/ProjectLighthouse/Controllers/Api/UserEndpoints.cs @@ -0,0 +1,39 @@ +#nullable enable +using System.Threading.Tasks; +using LBPUnion.ProjectLighthouse.Types; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace LBPUnion.ProjectLighthouse.Controllers.Api; + +/// +/// A collection of endpoints relating to users. +/// +public class UserEndpoints : ApiEndpointController +{ + private readonly Database database; + + public UserEndpoints(Database database) + { + this.database = database; + } + + /// + /// Gets a user and their information from the database. + /// + /// The ID of the user + /// The user + /// The user, if successful. + /// The user could not be found. + [HttpGet("user/{id:int}")] + [ProducesResponseType(typeof(User), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetUser(int id) + { + User? user = await this.database.Users.FirstOrDefaultAsync(u => u.UserId == id); + if (user == null) return this.NotFound(); + + return this.Ok(user); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/ClientConfigurationController.cs b/ProjectLighthouse/Controllers/GameApi/ClientConfigurationController.cs similarity index 98% rename from ProjectLighthouse/Controllers/ClientConfigurationController.cs rename to ProjectLighthouse/Controllers/GameApi/ClientConfigurationController.cs index 52de611f..ad3d77e4 100644 --- a/ProjectLighthouse/Controllers/ClientConfigurationController.cs +++ b/ProjectLighthouse/Controllers/GameApi/ClientConfigurationController.cs @@ -6,7 +6,7 @@ using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/CommentController.cs b/ProjectLighthouse/Controllers/GameApi/CommentController.cs similarity index 98% rename from ProjectLighthouse/Controllers/CommentController.cs rename to ProjectLighthouse/Controllers/GameApi/CommentController.cs index 0e470ecc..334b7f04 100644 --- a/ProjectLighthouse/Controllers/CommentController.cs +++ b/ProjectLighthouse/Controllers/GameApi/CommentController.cs @@ -11,7 +11,7 @@ using LBPUnion.ProjectLighthouse.Types.Profiles; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/DeveloperController.cs b/ProjectLighthouse/Controllers/GameApi/DeveloperController.cs similarity index 79% rename from ProjectLighthouse/Controllers/DeveloperController.cs rename to ProjectLighthouse/Controllers/GameApi/DeveloperController.cs index 80c6881d..a12cdb00 100644 --- a/ProjectLighthouse/Controllers/DeveloperController.cs +++ b/ProjectLighthouse/Controllers/GameApi/DeveloperController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/FriendsController.cs b/ProjectLighthouse/Controllers/GameApi/FriendsController.cs similarity index 98% rename from ProjectLighthouse/Controllers/FriendsController.cs rename to ProjectLighthouse/Controllers/GameApi/FriendsController.cs index 794396c5..6fb6e1dc 100644 --- a/ProjectLighthouse/Controllers/FriendsController.cs +++ b/ProjectLighthouse/Controllers/GameApi/FriendsController.cs @@ -11,7 +11,7 @@ using LBPUnion.ProjectLighthouse.Types.Profiles; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/LoginController.cs b/ProjectLighthouse/Controllers/GameApi/LoginController.cs similarity index 83% rename from ProjectLighthouse/Controllers/LoginController.cs rename to ProjectLighthouse/Controllers/GameApi/LoginController.cs index 04a9d7df..739e5322 100644 --- a/ProjectLighthouse/Controllers/LoginController.cs +++ b/ProjectLighthouse/Controllers/GameApi/LoginController.cs @@ -8,10 +8,12 @@ using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Settings; +using LBPUnion.ProjectLighthouse.Types.Tickets; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using IOFile = System.IO.File; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/login")] @@ -26,25 +28,29 @@ public class LoginController : ControllerBase } [HttpPost] - public async Task Login([FromQuery] string? titleId) + public async Task Login() { - titleId ??= ""; + MemoryStream ms = new(); + await this.Request.Body.CopyToAsync(ms); + byte[] loginData = ms.ToArray(); - string body = await new StreamReader(this.Request.Body).ReadToEndAsync(); + #if DEBUG + await IOFile.WriteAllBytesAsync($"npTicket-{TimestampHelper.TimestampMillis}.txt", loginData); + #endif - LoginData? loginData; + NPTicket? npTicket; try { - loginData = LoginData.CreateFromString(body); + npTicket = NPTicket.CreateFromBytes(loginData); } catch { - loginData = null; + npTicket = null; } - if (loginData == null) + if (npTicket == null) { - Logger.Log("loginData was null, rejecting login", LoggerLevelLogin.Instance); + Logger.Log("npTicket was null, rejecting login", LoggerLevelLogin.Instance); return this.BadRequest(); } @@ -60,11 +66,11 @@ public class LoginController : ControllerBase // Get an existing token from the IP & username GameToken? token = await this.database.GameTokens.Include (t => t.User) - .FirstOrDefaultAsync(t => t.UserLocation == ipAddress && t.User.Username == loginData.Username && !t.Used); + .FirstOrDefaultAsync(t => t.UserLocation == ipAddress && t.User.Username == npTicket.Username && !t.Used); if (token == null) // If we cant find an existing token, try to generate a new one { - token = await this.database.AuthenticateUser(loginData, ipAddress, titleId); + token = await this.database.AuthenticateUser(npTicket, ipAddress); if (token == null) { Logger.Log("unable to find/generate a token, rejecting login", LoggerLevelLogin.Instance); @@ -110,7 +116,7 @@ public class LoginController : ControllerBase GameTokenId = token.TokenId, Timestamp = TimestampHelper.Timestamp, IPAddress = ipAddress, - Platform = token.GameVersion == GameVersion.LittleBigPlanetVita ? Platform.Vita : Platform.PS3, // TODO: properly identify RPCS3 + Platform = npTicket.Platform, }; this.database.AuthenticationAttempts.Add(authAttempt); @@ -129,7 +135,7 @@ public class LoginController : ControllerBase return this.StatusCode(403, ""); } - Logger.Log($"Successfully logged in user {user.Username} as {token.GameVersion} client ({titleId})", LoggerLevelLogin.Instance); + Logger.Log($"Successfully logged in user {user.Username} as {token.GameVersion} client", LoggerLevelLogin.Instance); // After this point we are now considering this session as logged in. // We just logged in with the token. Mark it as used so someone else doesnt try to use it, diff --git a/ProjectLighthouse/Controllers/EnterLevelController.cs b/ProjectLighthouse/Controllers/GameApi/Matching/EnterLevelController.cs similarity index 98% rename from ProjectLighthouse/Controllers/EnterLevelController.cs rename to ProjectLighthouse/Controllers/GameApi/Matching/EnterLevelController.cs index c5504ff5..824f2b5d 100644 --- a/ProjectLighthouse/Controllers/EnterLevelController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Matching/EnterLevelController.cs @@ -7,7 +7,7 @@ using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Matching; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/MatchController.cs b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs similarity index 98% rename from ProjectLighthouse/Controllers/MatchController.cs rename to ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs index b3a78d79..7ba10605 100644 --- a/ProjectLighthouse/Controllers/MatchController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs @@ -14,7 +14,7 @@ using LBPUnion.ProjectLighthouse.Types.Match; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Matching; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/MessageController.cs b/ProjectLighthouse/Controllers/GameApi/MessageController.cs similarity index 72% rename from ProjectLighthouse/Controllers/MessageController.cs rename to ProjectLighthouse/Controllers/GameApi/MessageController.cs index 46fd4520..6a5d653b 100644 --- a/ProjectLighthouse/Controllers/MessageController.cs +++ b/ProjectLighthouse/Controllers/GameApi/MessageController.cs @@ -8,7 +8,7 @@ using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -38,13 +38,13 @@ public class MessageController : ControllerBase User? user = await this.database.UserFromGameRequest(this.Request); if (user == null) return this.StatusCode(403, ""); #else - (User, GameToken)? userAndToken = await this.database.UserAndGameTokenFromRequest(this.Request); + (User, GameToken)? userAndToken = await this.database.UserAndGameTokenFromRequest(this.Request); - if (userAndToken == null) return this.StatusCode(403, ""); + if (userAndToken == null) return this.StatusCode(403, ""); - // ReSharper disable once PossibleInvalidOperationException - User user = userAndToken.Value.Item1; - GameToken gameToken = userAndToken.Value.Item2; + // ReSharper disable once PossibleInvalidOperationException + User user = userAndToken.Value.Item1; + GameToken gameToken = userAndToken.Value.Item2; #endif string announceText = ServerSettings.Instance.AnnounceText; @@ -56,13 +56,13 @@ public class MessageController : ControllerBase ( announceText + #if DEBUG - "\n\n---DEBUG INFO---\n" + - $"user.UserId: {user.UserId}\n" + - $"token.Approved: {gameToken.Approved}\n" + - $"token.Used: {gameToken.Used}\n" + - $"token.UserLocation: {gameToken.UserLocation}\n" + - $"token.GameVersion: {gameToken.GameVersion}\n" + - "---DEBUG INFO---" + + "\n\n---DEBUG INFO---\n" + + $"user.UserId: {user.UserId}\n" + + $"token.Approved: {gameToken.Approved}\n" + + $"token.Used: {gameToken.Used}\n" + + $"token.UserLocation: {gameToken.UserLocation}\n" + + $"token.GameVersion: {gameToken.GameVersion}\n" + + "---DEBUG INFO---" + #endif "\n" ); diff --git a/ProjectLighthouse/Controllers/PhotosController.cs b/ProjectLighthouse/Controllers/GameApi/Resources/PhotosController.cs similarity index 98% rename from ProjectLighthouse/Controllers/PhotosController.cs rename to ProjectLighthouse/Controllers/GameApi/Resources/PhotosController.cs index 850de160..c035c732 100644 --- a/ProjectLighthouse/Controllers/PhotosController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Resources/PhotosController.cs @@ -15,7 +15,7 @@ using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Resources; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/ResourcesController.cs b/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs similarity index 97% rename from ProjectLighthouse/Controllers/ResourcesController.cs rename to ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs index f9ff9346..cb528216 100644 --- a/ProjectLighthouse/Controllers/ResourcesController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Resources/ResourcesController.cs @@ -1,4 +1,5 @@ #nullable enable +using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -12,7 +13,7 @@ using LBPUnion.ProjectLighthouse.Types.Files; using Microsoft.AspNetCore.Mvc; using IOFile = System.IO.File; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Resources; [ApiController] [Produces("text/xml")] diff --git a/ProjectLighthouse/Controllers/CollectionController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/CollectionController.cs similarity index 98% rename from ProjectLighthouse/Controllers/CollectionController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/CollectionController.cs index 4925d80d..bcf0f382 100644 --- a/ProjectLighthouse/Controllers/CollectionController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/CollectionController.cs @@ -11,7 +11,7 @@ using LBPUnion.ProjectLighthouse.Types.Categories; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/LevelTagsController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/LevelTagsController.cs similarity index 89% rename from ProjectLighthouse/Controllers/LevelTagsController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/LevelTagsController.cs index 7c5370fa..99943993 100644 --- a/ProjectLighthouse/Controllers/LevelTagsController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/LevelTagsController.cs @@ -2,7 +2,7 @@ using System; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/tags")] diff --git a/ProjectLighthouse/Controllers/ListController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/ListController.cs similarity index 99% rename from ProjectLighthouse/Controllers/ListController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/ListController.cs index 289b2d83..d7afe176 100644 --- a/ProjectLighthouse/Controllers/ListController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/ListController.cs @@ -9,7 +9,7 @@ using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/PublishController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs similarity index 97% rename from ProjectLighthouse/Controllers/PublishController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs index ab004c2d..c0e3e6f4 100644 --- a/ProjectLighthouse/Controllers/PublishController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs @@ -13,7 +13,7 @@ using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -38,7 +38,7 @@ public class PublishController : ControllerBase if (user.UsedSlots >= ServerSettings.Instance.EntitledSlots) return this.BadRequest(); - Slot? slot = await this.GetSlotFromBody(); + Slot? slot = await this.getSlotFromBody(); if (slot == null) return this.BadRequest(); // if the level cant be parsed then it obviously cant be uploaded if (string.IsNullOrEmpty(slot.RootLevel)) return this.BadRequest(); @@ -79,7 +79,7 @@ public class PublishController : ControllerBase if (user.UsedSlots >= ServerSettings.Instance.EntitledSlots) return this.BadRequest(); - Slot? slot = await this.GetSlotFromBody(); + Slot? slot = await this.getSlotFromBody(); if (slot?.Location == null) return this.BadRequest(); // Republish logic @@ -186,7 +186,7 @@ public class PublishController : ControllerBase return this.Ok(); } - public async Task GetSlotFromBody() + private async Task getSlotFromBody() { this.Request.Body.Position = 0; string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync(); diff --git a/ProjectLighthouse/Controllers/ReviewController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs similarity index 98% rename from ProjectLighthouse/Controllers/ReviewController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs index bf741e27..6389d02f 100644 --- a/ProjectLighthouse/Controllers/ReviewController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs @@ -13,7 +13,7 @@ using LBPUnion.ProjectLighthouse.Types.Reviews; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -91,7 +91,7 @@ public class ReviewController : ControllerBase if (user == null) return this.StatusCode(403, ""); Review? review = await this.database.Reviews.FirstOrDefaultAsync(r => r.SlotId == slotId && r.ReviewerId == user.UserId); - Review? newReview = await this.GetReviewFromBody(); + Review? newReview = await this.getReviewFromBody(); if (newReview == null) return this.BadRequest(); if (review == null) @@ -317,7 +317,7 @@ public class ReviewController : ControllerBase return this.Ok(); } - public async Task GetReviewFromBody() + private async Task getReviewFromBody() { this.Request.Body.Position = 0; string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync(); diff --git a/ProjectLighthouse/Controllers/ScoreController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/ScoreController.cs similarity index 95% rename from ProjectLighthouse/Controllers/ScoreController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/ScoreController.cs index 8f521fc5..e92785ba 100644 --- a/ProjectLighthouse/Controllers/ScoreController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/ScoreController.cs @@ -11,7 +11,7 @@ using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -80,7 +80,7 @@ public class ScoreController : ControllerBase await this.database.SaveChangesAsync(); - string myRanking = this.GetScores(score.SlotId, score.Type, user); + string myRanking = this.getScores(score.SlotId, score.Type, user); return this.Ok(myRanking); } @@ -99,11 +99,11 @@ public class ScoreController : ControllerBase if (user == null) return this.StatusCode(403, ""); - return this.Ok(this.GetScores(slotId, type, user, pageStart, pageSize)); + return this.Ok(this.getScores(slotId, type, user, pageStart, pageSize)); } [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")] - public string GetScores(int slotId, int type, User user, int pageStart = -1, int pageSize = 5) + private string getScores(int slotId, int type, User user, int pageStart = -1, int pageSize = 5) { // This is hella ugly but it technically assigns the proper rank to a score // var needed for Anonymous type returned from SELECT diff --git a/ProjectLighthouse/Controllers/SearchController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/SearchController.cs similarity index 96% rename from ProjectLighthouse/Controllers/SearchController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/SearchController.cs index 62e80e51..f99e2322 100644 --- a/ProjectLighthouse/Controllers/SearchController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/SearchController.cs @@ -7,7 +7,7 @@ using LBPUnion.ProjectLighthouse.Types.Levels; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/SlotsController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs similarity index 95% rename from ProjectLighthouse/Controllers/SlotsController.cs rename to ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs index b5b69ae8..5cd7247a 100644 --- a/ProjectLighthouse/Controllers/SlotsController.cs +++ b/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs @@ -11,7 +11,7 @@ using LBPUnion.ProjectLighthouse.Types.Settings; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -177,7 +177,7 @@ public class SlotsController : ControllerBase "hint_start", pageStart + Math.Min(pageSize, ServerSettings.Instance.EntitledSlots) }, { - "total", await StatisticsHelper.MMPicksCount() + "total", await StatisticsHelper.TeamPickCount() }, } ) @@ -235,7 +235,7 @@ public class SlotsController : ControllerBase Random rand = new(); - IEnumerable slots = this.FilterByRequest(gameFilterType, dateFilterType, token.GameVersion) + IEnumerable slots = this.filterByRequest(gameFilterType, dateFilterType, token.GameVersion) .AsEnumerable() .OrderByDescending(s => s.Thumbsup) .ThenBy(_ => rand.Next()) @@ -279,14 +279,14 @@ public class SlotsController : ControllerBase Random rand = new(); - IEnumerable slots = this.FilterByRequest(gameFilterType, dateFilterType, token.GameVersion) + IEnumerable slots = this.filterByRequest(gameFilterType, dateFilterType, token.GameVersion) .AsEnumerable() .OrderByDescending ( // probably not the best way to do this? s => { - return this.GetGameFilter(gameFilterType, token.GameVersion) switch + return this.getGameFilter(gameFilterType, token.GameVersion) switch { GameVersion.LittleBigPlanet1 => s.PlaysLBP1Unique, GameVersion.LittleBigPlanet2 => s.PlaysLBP2Unique, @@ -337,7 +337,7 @@ public class SlotsController : ControllerBase Random rand = new(); - IEnumerable slots = this.FilterByRequest(gameFilterType, dateFilterType, token.GameVersion) + IEnumerable slots = this.filterByRequest(gameFilterType, dateFilterType, token.GameVersion) .AsEnumerable() .OrderByDescending(s => s.Hearts) .ThenBy(_ => rand.Next()) @@ -365,7 +365,7 @@ public class SlotsController : ControllerBase ); } - public GameVersion GetGameFilter(string? gameFilterType, GameVersion version) + private GameVersion getGameFilter(string? gameFilterType, GameVersion version) { if (version == GameVersion.LittleBigPlanetVita) return GameVersion.LittleBigPlanetVita; if (version == GameVersion.LittleBigPlanetPSP) return GameVersion.LittleBigPlanetPSP; @@ -381,7 +381,7 @@ public class SlotsController : ControllerBase }; } - public IQueryable FilterByRequest(string? gameFilterType, string? dateFilterType, GameVersion version) + private IQueryable filterByRequest(string? gameFilterType, string? dateFilterType, GameVersion version) { string _dateFilterType = dateFilterType ?? ""; @@ -392,7 +392,7 @@ public class SlotsController : ControllerBase _ => 0, }; - GameVersion gameVersion = this.GetGameFilter(gameFilterType, version); + GameVersion gameVersion = this.getGameFilter(gameFilterType, version); IQueryable whereSlots; diff --git a/ProjectLighthouse/Controllers/StatisticsController.cs b/ProjectLighthouse/Controllers/GameApi/StatisticsController.cs similarity index 90% rename from ProjectLighthouse/Controllers/StatisticsController.cs rename to ProjectLighthouse/Controllers/GameApi/StatisticsController.cs index d6cbee75..47d4b4f0 100644 --- a/ProjectLighthouse/Controllers/StatisticsController.cs +++ b/ProjectLighthouse/Controllers/GameApi/StatisticsController.cs @@ -3,7 +3,7 @@ using LBPUnion.ProjectLighthouse.Helpers; using LBPUnion.ProjectLighthouse.Serialization; using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -24,7 +24,7 @@ public class StatisticsController : ControllerBase public async Task PlanetStats() { int totalSlotCount = await StatisticsHelper.SlotCount(); - int mmPicksCount = await StatisticsHelper.MMPicksCount(); + int mmPicksCount = await StatisticsHelper.TeamPickCount(); return this.Ok ( diff --git a/ProjectLighthouse/Controllers/StoreController.cs b/ProjectLighthouse/Controllers/GameApi/StoreController.cs similarity index 80% rename from ProjectLighthouse/Controllers/StoreController.cs rename to ProjectLighthouse/Controllers/GameApi/StoreController.cs index 614f5c11..053dbf06 100644 --- a/ProjectLighthouse/Controllers/StoreController.cs +++ b/ProjectLighthouse/Controllers/GameApi/StoreController.cs @@ -1,6 +1,6 @@ using Microsoft.AspNetCore.Mvc; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] diff --git a/ProjectLighthouse/Controllers/UserController.cs b/ProjectLighthouse/Controllers/GameApi/UserController.cs similarity index 96% rename from ProjectLighthouse/Controllers/UserController.cs rename to ProjectLighthouse/Controllers/GameApi/UserController.cs index 4cd47c08..90c8f227 100644 --- a/ProjectLighthouse/Controllers/UserController.cs +++ b/ProjectLighthouse/Controllers/GameApi/UserController.cs @@ -12,7 +12,7 @@ using LBPUnion.ProjectLighthouse.Types.Profiles; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; -namespace LBPUnion.ProjectLighthouse.Controllers; +namespace LBPUnion.ProjectLighthouse.Controllers.GameApi; [ApiController] [Route("LITTLEBIGPLANETPS3_XML/")] @@ -26,7 +26,7 @@ public class UserController : ControllerBase this.database = database; } - public async Task GetSerializedUser(string username, GameVersion gameVersion = GameVersion.LittleBigPlanet1) + private async Task getSerializedUser(string username, GameVersion gameVersion = GameVersion.LittleBigPlanet1) { User? user = await this.database.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.Username == username); return user?.Serialize(gameVersion); @@ -38,7 +38,7 @@ public class UserController : ControllerBase GameToken? token = await this.database.GameTokenFromRequest(this.Request); if (token == null) return this.StatusCode(403, ""); - string? user = await this.GetSerializedUser(username, token.GameVersion); + string? user = await this.getSerializedUser(username, token.GameVersion); if (user == null) return this.NotFound(); return this.Ok(user); @@ -51,7 +51,7 @@ public class UserController : ControllerBase if (token == null) return this.StatusCode(403, ""); List serializedUsers = new(); - foreach (string userId in u) serializedUsers.Add(await this.GetSerializedUser(userId, token.GameVersion)); + foreach (string userId in u) serializedUsers.Add(await this.getSerializedUser(userId, token.GameVersion)); string serialized = serializedUsers.Aggregate(string.Empty, (current, user) => user == null ? current : current + user); diff --git a/ProjectLighthouse/Controllers/NewsController.cs b/ProjectLighthouse/Controllers/NewsController.cs deleted file mode 100644 index ab4a29a9..00000000 --- a/ProjectLighthouse/Controllers/NewsController.cs +++ /dev/null @@ -1,36 +0,0 @@ -using LBPUnion.ProjectLighthouse.Serialization; -using LBPUnion.ProjectLighthouse.Types.News; -using Microsoft.AspNetCore.Mvc; - -namespace LBPUnion.ProjectLighthouse.Controllers; - -[ApiController] -[Route("LITTLEBIGPLANETPS3_XML/news")] -[Produces("text/xml")] -public class NewsController : ControllerBase -{ - [HttpGet] - public IActionResult Get() - { - string newsEntry = LbpSerializer.StringElement - ( - "item", - new NewsEntry - { - Category = "no_category", - Summary = "test summary", - Image = new NewsImage - { - Hash = "4947269c5f7061b27225611ee58a9a91a8031bbe", - Alignment = "right", - }, - Id = 1, - Title = "Test Title", - Text = "Test Text", - Date = 1348755214000, - }.Serialize() - ); - - return this.Ok(LbpSerializer.StringElement("news", newsEntry)); - } -} \ No newline at end of file diff --git a/ProjectLighthouse/Controllers/Website/Admin/AdminPanelController.cs b/ProjectLighthouse/Controllers/Website/Admin/AdminPanelController.cs index c7e0e31a..d736fd44 100644 --- a/ProjectLighthouse/Controllers/Website/Admin/AdminPanelController.cs +++ b/ProjectLighthouse/Controllers/Website/Admin/AdminPanelController.cs @@ -1,7 +1,4 @@ #nullable enable -using System.Threading.Tasks; -using LBPUnion.ProjectLighthouse.Helpers; -using LBPUnion.ProjectLighthouse.Types; using Microsoft.AspNetCore.Mvc; namespace LBPUnion.ProjectLighthouse.Controllers.Website.Admin; @@ -16,14 +13,4 @@ public class AdminPanelController : ControllerBase { this.database = database; } - - [HttpGet("testWebhook")] - public async Task TestWebhook() - { - User? user = this.database.UserFromWebRequest(this.Request); - if (user == null || !user.IsAdmin) return this.NotFound(); - - await WebhookHelper.SendWebhook("Testing 123", "Someone is testing the Discord webhook from the admin panel."); - return this.Redirect("/admin"); - } } \ No newline at end of file diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs index 844fd6e5..365319fd 100644 --- a/ProjectLighthouse/Database.cs +++ b/ProjectLighthouse/Database.cs @@ -1,15 +1,14 @@ using System; using System.Linq; using System.Threading.Tasks; -using Kettu; using LBPUnion.ProjectLighthouse.Helpers; -using LBPUnion.ProjectLighthouse.Logging; using LBPUnion.ProjectLighthouse.Types; using LBPUnion.ProjectLighthouse.Types.Categories; using LBPUnion.ProjectLighthouse.Types.Levels; using LBPUnion.ProjectLighthouse.Types.Profiles; using LBPUnion.ProjectLighthouse.Types.Reviews; using LBPUnion.ProjectLighthouse.Types.Settings; +using LBPUnion.ProjectLighthouse.Types.Tickets; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; @@ -67,9 +66,9 @@ public class Database : DbContext } #nullable enable - public async Task AuthenticateUser(LoginData loginData, string userLocation, string titleId = "") + public async Task AuthenticateUser(NPTicket npTicket, string userLocation) { - User? user = await this.Users.FirstOrDefaultAsync(u => u.Username == loginData.Username); + User? user = await this.Users.FirstOrDefaultAsync(u => u.Username == npTicket.Username); if (user == null) return null; GameToken gameToken = new() @@ -78,15 +77,9 @@ public class Database : DbContext User = user, UserId = user.UserId, UserLocation = userLocation, - GameVersion = GameVersionHelper.FromTitleId(titleId), + GameVersion = npTicket.GameVersion, }; - if (gameToken.GameVersion == GameVersion.Unknown) - { - Logger.Log($"Unknown GameVersion for TitleId {titleId}", LoggerLevelLogin.Instance); - return null; - } - this.GameTokens.Add(gameToken); await this.SaveChangesAsync(); diff --git a/ProjectLighthouse/Helpers/Extensions/BinaryReaderExtensions.cs b/ProjectLighthouse/Helpers/Extensions/BinaryReaderExtensions.cs index feacec19..4a83bf42 100644 --- a/ProjectLighthouse/Helpers/Extensions/BinaryReaderExtensions.cs +++ b/ProjectLighthouse/Helpers/Extensions/BinaryReaderExtensions.cs @@ -23,6 +23,10 @@ public static class BinaryReaderExtensions public static int ReadInt32BE(this BinaryReader binRdr) => BitConverter.ToInt32(binRdr.ReadBytesRequired(sizeof(int)).Reverse(), 0); + public static ulong ReadUInt64BE(this BinaryReader binRdr) => BitConverter.ToUInt32(binRdr.ReadBytesRequired(sizeof(ulong)).Reverse(), 0); + + public static long ReadInt64BE(this BinaryReader binRdr) => BitConverter.ToInt32(binRdr.ReadBytesRequired(sizeof(long)).Reverse(), 0); + public static byte[] ReadBytesRequired(this BinaryReader binRdr, int byteCount) { byte[] result = binRdr.ReadBytes(byteCount); diff --git a/ProjectLighthouse/Helpers/GameVersionHelper.cs b/ProjectLighthouse/Helpers/GameVersionHelper.cs index 4c13604f..537a634e 100644 --- a/ProjectLighthouse/Helpers/GameVersionHelper.cs +++ b/ProjectLighthouse/Helpers/GameVersionHelper.cs @@ -99,6 +99,6 @@ public class GameVersionHelper if (LittleBigPlanetVitaTitleIds.Contains(titleId)) return GameVersion.LittleBigPlanetVita; if (LittleBigPlanetPSPTitleIds.Contains(titleId)) return GameVersion.LittleBigPlanetPSP; - return GameVersion.LittleBigPlanet1; + return GameVersion.Unknown; } } diff --git a/ProjectLighthouse/Helpers/StatisticsHelper.cs b/ProjectLighthouse/Helpers/StatisticsHelper.cs index a2a27d6a..7051fda0 100644 --- a/ProjectLighthouse/Helpers/StatisticsHelper.cs +++ b/ProjectLighthouse/Helpers/StatisticsHelper.cs @@ -14,7 +14,7 @@ public static class StatisticsHelper public static async Task UserCount() => await database.Users.CountAsync(u => !u.Banned); - public static async Task MMPicksCount() => await database.Slots.CountAsync(s => s.TeamPick); + public static async Task TeamPickCount() => await database.Slots.CountAsync(s => s.TeamPick); public static async Task PhotoCount() => await database.Photos.CountAsync(); } \ No newline at end of file diff --git a/ProjectLighthouse/Helpers/SwaggerFilter.cs b/ProjectLighthouse/Helpers/SwaggerFilter.cs new file mode 100644 index 00000000..90b333c9 --- /dev/null +++ b/ProjectLighthouse/Helpers/SwaggerFilter.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; + +namespace LBPUnion.ProjectLighthouse.Helpers; + +public class SwaggerFilter : IDocumentFilter +{ + public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) + { + List> nonApiRoutes = swaggerDoc.Paths.Where(x => !x.Key.ToLower().StartsWith("/api/v1")).ToList(); + nonApiRoutes.ForEach(x => swaggerDoc.Paths.Remove(x.Key)); + } +} \ No newline at end of file diff --git a/ProjectLighthouse/Helpers/WebhookHelper.cs b/ProjectLighthouse/Helpers/WebhookHelper.cs index c624fc45..9d0ea1c2 100644 --- a/ProjectLighthouse/Helpers/WebhookHelper.cs +++ b/ProjectLighthouse/Helpers/WebhookHelper.cs @@ -7,7 +7,7 @@ namespace LBPUnion.ProjectLighthouse.Helpers; public static class WebhookHelper { - private static readonly DiscordWebhookClient client = new(ServerSettings.Instance.DiscordWebhookUrl); + private static readonly DiscordWebhookClient client = (ServerSettings.Instance.DiscordWebhookEnabled ? new DiscordWebhookClient(ServerSettings.Instance.DiscordWebhookUrl) : null); public static readonly Color UnionColor = new(0, 140, 255); public static Task SendWebhook(EmbedBuilder builder) => SendWebhook(builder.Build()); diff --git a/ProjectLighthouse/Maintenance/Commands/TestWebhookCommand.cs b/ProjectLighthouse/Maintenance/Commands/TestWebhookCommand.cs new file mode 100644 index 00000000..93ed05b5 --- /dev/null +++ b/ProjectLighthouse/Maintenance/Commands/TestWebhookCommand.cs @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; +using LBPUnion.ProjectLighthouse.Helpers; + +namespace LBPUnion.ProjectLighthouse.Maintenance.Commands; + +[UsedImplicitly] +public class TestWebhookCommand : ICommand +{ + public async Task Run(string[] args) + { + await WebhookHelper.SendWebhook("Testing 123", "Someone is testing the Discord webhook from the admin panel."); + } + public string Name() => "Test Discord Webhook"; + public string[] Aliases() + => new[] + { + "testWebhook", "testDiscordWebhook", + }; + public string Arguments() => ""; + public int RequiredArgs() => 0; +} \ No newline at end of file diff --git a/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml b/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml index cb28e826..97228b43 100644 --- a/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml +++ b/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml @@ -1,7 +1,8 @@ @page "/admin" @using LBPUnion.ProjectLighthouse.Helpers +@using LBPUnion.ProjectLighthouse.Helpers.Extensions @using LBPUnion.ProjectLighthouse.Maintenance -@using LBPUnion.ProjectLighthouse.Types.Settings +@using LBPUnion.ProjectLighthouse.Types @model LBPUnion.ProjectLighthouse.Pages.Admin.AdminPanelPage @{ @@ -9,61 +10,63 @@ Model.Title = "Admin Panel"; } - -
- View Users -
-
-@if (ServerSettings.Instance.DiscordWebhookEnabled) +@if (!this.Request.IsMobile()) { - -
- Test Discord Webhook -
-
+
+ @foreach (AdminPanelStatistic statistic in Model.Statistics) + { + @await Html.PartialAsync("Partials/AdminPanelStatisticPartial", statistic) + } +
+
+} +else +{ + @foreach (AdminPanelStatistic statistic in Model.Statistics) + { + @await Html.PartialAsync("Partials/AdminPanelStatisticPartial", statistic) +
+ } }

Commands

-
- @foreach (ICommand command in MaintenanceHelper.Commands) - { -
-
-

@command.Name()

-
-
- -


- - -
-
-
- } -
+@foreach (ICommand command in MaintenanceHelper.Commands) +{ +
+

@command.Name()

+
+ @if (command.RequiredArgs() > 0) + { +
+ +
+
+
+ } + + +
+
+}

Maintenance Jobs

Warning: Interrupting Lighthouse during maintenance may leave the database in an unclean state.

-
- @foreach (IMaintenanceJob job in MaintenanceHelper.MaintenanceJobs) - { -
-
-

@job.Name()

-

@job.Description()

-
- - -
-
-
- } -
\ No newline at end of file +@foreach (IMaintenanceJob job in MaintenanceHelper.MaintenanceJobs) +{ +
+

@job.Name()

+

@job.Description()

+
+ + +
+
+} \ No newline at end of file diff --git a/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml.cs b/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml.cs index 4df3a805..92e5a5b0 100644 --- a/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml.cs +++ b/ProjectLighthouse/Pages/Admin/AdminPanelPage.cshtml.cs @@ -15,12 +15,18 @@ public class AdminPanelPage : BaseLayout public AdminPanelPage(Database database) : base(database) {} + public List Statistics = new(); + public async Task OnGet([FromQuery] string? args, [FromQuery] string? command, [FromQuery] string? maintenanceJob) { User? user = this.Database.UserFromWebRequest(this.Request); if (user == null) return this.Redirect("~/login"); if (!user.IsAdmin) return this.NotFound(); + this.Statistics.Add(new AdminPanelStatistic("Users", await StatisticsHelper.UserCount(), "users")); + this.Statistics.Add(new AdminPanelStatistic("Slots", await StatisticsHelper.SlotCount())); + this.Statistics.Add(new AdminPanelStatistic("Photos", await StatisticsHelper.PhotoCount())); + if (!string.IsNullOrEmpty(command)) { args ??= ""; diff --git a/ProjectLighthouse/Pages/LoginForm.cshtml b/ProjectLighthouse/Pages/LoginForm.cshtml index ede86b66..2e5494a4 100644 --- a/ProjectLighthouse/Pages/LoginForm.cshtml +++ b/ProjectLighthouse/Pages/LoginForm.cshtml @@ -11,9 +11,10 @@