From 8fdd464e2e8d34838146664942d615acaad780db Mon Sep 17 00:00:00 2001
From: jvyden
Date: Wed, 16 Feb 2022 19:02:07 -0500
Subject: [PATCH 01/26] [skip ci] Don't log nptickets in debug builds
---
ProjectLighthouse/Controllers/GameApi/LoginController.cs | 4 ----
1 file changed, 4 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/LoginController.cs b/ProjectLighthouse/Controllers/GameApi/LoginController.cs
index 739e5322..8e95ed4e 100644
--- a/ProjectLighthouse/Controllers/GameApi/LoginController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/LoginController.cs
@@ -34,10 +34,6 @@ public class LoginController : ControllerBase
await this.Request.Body.CopyToAsync(ms);
byte[] loginData = ms.ToArray();
- #if DEBUG
- await IOFile.WriteAllBytesAsync($"npTicket-{TimestampHelper.TimestampMillis}.txt", loginData);
- #endif
-
NPTicket? npTicket;
try
{
From 2b521be45c22542faa04e256ffbbc98176d6a97b Mon Sep 17 00:00:00 2001
From: jvyden
Date: Wed, 16 Feb 2022 20:24:57 -0500
Subject: [PATCH 02/26] Add user status api endpoint
---
.../Controllers/Api/UserEndpoints.cs | 20 +++++++++
.../Controllers/GameApi/CommentController.cs | 23 +++++-----
.../Types/ApiEndpointController.cs | 2 +-
.../Types/Profiles/StatusType.cs | 7 ++++
.../Types/Profiles/UserStatus.cs | 42 +++++++++++++++++++
ProjectLighthouse/Types/User.cs | 11 +----
6 files changed, 83 insertions(+), 22 deletions(-)
create mode 100644 ProjectLighthouse/Types/Profiles/StatusType.cs
create mode 100644 ProjectLighthouse/Types/Profiles/UserStatus.cs
diff --git a/ProjectLighthouse/Controllers/Api/UserEndpoints.cs b/ProjectLighthouse/Controllers/Api/UserEndpoints.cs
index 7fc505eb..63510326 100644
--- a/ProjectLighthouse/Controllers/Api/UserEndpoints.cs
+++ b/ProjectLighthouse/Controllers/Api/UserEndpoints.cs
@@ -1,10 +1,13 @@
#nullable enable
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Types;
+using LBPUnion.ProjectLighthouse.Types.Profiles;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
+// ReSharper disable RouteTemplates.ActionRoutePrefixCanBeExtractedToControllerRoute
+
namespace LBPUnion.ProjectLighthouse.Controllers.Api;
///
@@ -36,4 +39,21 @@ public class UserEndpoints : ApiEndpointController
return this.Ok(user);
}
+
+ ///
+ /// Gets a user and their information from the database.
+ ///
+ /// The ID of the user
+ /// The user's status
+ /// The user's status, if successful.
+ /// The user could not be found.
+ [HttpGet("user/{id:int}/status")]
+ [ProducesResponseType(typeof(UserStatus), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public async Task GetUserStatus(int id)
+ {
+ UserStatus userStatus = new(this.database, id);
+
+ return this.Ok(userStatus);
+ }
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Controllers/GameApi/CommentController.cs b/ProjectLighthouse/Controllers/GameApi/CommentController.cs
index cfca4f09..e2ca484c 100644
--- a/ProjectLighthouse/Controllers/GameApi/CommentController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/CommentController.cs
@@ -5,7 +5,6 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml.Serialization;
-using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Serialization;
using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Types.Levels;
@@ -39,14 +38,13 @@ public class CommentController : ControllerBase
return this.Ok();
}
-
[HttpGet("comments/user/{slotId:int}")]
[HttpGet("userComments/{username}")]
public async Task GetComments([FromQuery] int pageStart, [FromQuery] int pageSize, string? username, int? slotId)
{
User? user = await this.database.UserFromGameRequest(this.Request);
if (user == null) return this.StatusCode(403, "");
-
+
int targetId = slotId.GetValueOrDefault();
CommentType type = CommentType.Level;
if (!string.IsNullOrWhiteSpace(username))
@@ -55,24 +53,24 @@ public class CommentController : ControllerBase
type = CommentType.Profile;
}
- List comments = await this.database.Comments
- .Include(c => c.Poster)
+ List comments = await this.database.Comments.Include
+ (c => c.Poster)
.Where(c => c.TargetId == targetId && c.Type == type)
.OrderByDescending(c => c.Timestamp)
.Skip(pageStart - 1)
- .Take(Math.Min(pageSize,
- 30))
+ .Take(Math.Min(pageSize, 30))
.ToListAsync();
- string outputXml = comments.Aggregate(string.Empty, (current, comment) => current +
- comment.Serialize(this.getReaction(user.UserId, comment.CommentId).Result));
+ string outputXml = comments.Aggregate
+ (string.Empty, (current, comment) => current + comment.Serialize(this.getReaction(user.UserId, comment.CommentId).Result));
return this.Ok(LbpSerializer.StringElement("comments", outputXml));
}
- public async Task getReaction(int userId, int commentId)
+ private async Task getReaction(int userId, int commentId)
{
Reaction? reaction = await this.database.Reactions.FirstOrDefaultAsync(r => r.UserId == userId && r.TargetId == commentId);
if (reaction == null) return 0;
+
return reaction.Rating;
}
@@ -80,11 +78,11 @@ public class CommentController : ControllerBase
[HttpPost("postComment/user/{slotId:int}")]
public async Task PostComment(string? username, int? slotId)
{
- this.Request.Body.Position = 0;
+ this.Request.Body.Position = 0;
string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync();
XmlSerializer serializer = new(typeof(Comment));
- Comment? comment = (Comment?) serializer.Deserialize(new StringReader(bodyString));
+ Comment? comment = (Comment?)serializer.Deserialize(new StringReader(bodyString));
CommentType type = (slotId.GetValueOrDefault() == 0 ? CommentType.Profile : CommentType.Level);
@@ -112,6 +110,7 @@ public class CommentController : ControllerBase
Comment? comment = await this.database.Comments.FirstOrDefaultAsync(c => c.CommentId == commentId);
if (comment == null) return this.NotFound();
+
// if you are not the poster
if (comment.PosterUserId != user.UserId)
{
diff --git a/ProjectLighthouse/Types/ApiEndpointController.cs b/ProjectLighthouse/Types/ApiEndpointController.cs
index e026df83..7a717cab 100644
--- a/ProjectLighthouse/Types/ApiEndpointController.cs
+++ b/ProjectLighthouse/Types/ApiEndpointController.cs
@@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
namespace LBPUnion.ProjectLighthouse.Types;
[ApiController]
-[Route("/api/v1/")]
+[Route("/api/v1")]
[Produces("application/json")]
public class ApiEndpointController : ControllerBase
{}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Profiles/StatusType.cs b/ProjectLighthouse/Types/Profiles/StatusType.cs
new file mode 100644
index 00000000..ea7d99a6
--- /dev/null
+++ b/ProjectLighthouse/Types/Profiles/StatusType.cs
@@ -0,0 +1,7 @@
+namespace LBPUnion.ProjectLighthouse.Types.Profiles;
+
+public enum StatusType
+{
+ Offline = 0,
+ Online = 1,
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Profiles/UserStatus.cs b/ProjectLighthouse/Types/Profiles/UserStatus.cs
new file mode 100644
index 00000000..67cde0f6
--- /dev/null
+++ b/ProjectLighthouse/Types/Profiles/UserStatus.cs
@@ -0,0 +1,42 @@
+#nullable enable
+using System.Linq;
+using LBPUnion.ProjectLighthouse.Helpers;
+
+namespace LBPUnion.ProjectLighthouse.Types.Profiles;
+
+public class UserStatus
+{
+ public StatusType StatusType { get; set; }
+ public GameVersion? CurrentVersion { get; set; }
+
+ public UserStatus()
+ {}
+
+ public UserStatus(Database database, int userId)
+ {
+ LastContact? lastContact = database.LastContacts.Where(l => l.UserId == userId).FirstOrDefault(l => TimestampHelper.Timestamp - l.Timestamp < 300);
+
+ if (lastContact == null)
+ {
+ StatusType = StatusType.Offline;
+ CurrentVersion = null;
+ }
+ else
+ {
+ StatusType = StatusType.Online;
+ CurrentVersion = lastContact.GameVersion;
+ }
+ }
+
+ public override string ToString()
+ {
+ CurrentVersion ??= GameVersion.Unknown;
+
+ return this.StatusType switch
+ {
+ StatusType.Online => $"Currently online on {((GameVersion)this.CurrentVersion).ToPrettyString()}",
+ StatusType.Offline => "Offline",
+ _ => "Unknown",
+ };
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs
index 7b730d49..a370aaef 100644
--- a/ProjectLighthouse/Types/User.cs
+++ b/ProjectLighthouse/Types/User.cs
@@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.Json.Serialization;
-using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Serialization;
using LBPUnion.ProjectLighthouse.Types.Profiles;
using LBPUnion.ProjectLighthouse.Types.Settings;
@@ -153,16 +152,10 @@ public class User
#nullable enable
[NotMapped]
[JsonIgnore]
- public string Status {
+ public UserStatus Status {
get {
using Database database = new();
- LastContact? lastMatch = database.LastContacts.Where
- (l => l.UserId == this.UserId)
- .FirstOrDefault(l => TimestampHelper.Timestamp - l.Timestamp < 300);
-
- if (lastMatch == null) return "Offline";
-
- return "Currently online on " + lastMatch.GameVersion.ToPrettyString();
+ return new UserStatus(database, this.UserId);
}
}
#nullable disable
From aeeb819759a4372f4406f387691dcaef3f13c6ee Mon Sep 17 00:00:00 2001
From: jvyden
Date: Thu, 17 Feb 2022 00:57:02 -0500
Subject: [PATCH 03/26] Increase information in UserStatus, add platform for
lastcontacts and gametokens
---
.../GameApi/Matching/MatchController.cs | 2 +-
ProjectLighthouse/Database.cs | 3 +-
.../Helpers/LastContactHelper.cs | 3 +-
ProjectLighthouse/Helpers/RoomHelper.cs | 9 ++++
...AddPlatformForLastContactsAndGameTokens.cs | 41 +++++++++++++++++++
.../Migrations/DatabaseModelSnapshot.cs | 6 +++
ProjectLighthouse/Startup/Startup.cs | 3 +-
ProjectLighthouse/Types/GameToken.cs | 2 +
ProjectLighthouse/Types/Match/Room.cs | 21 +++++++---
ProjectLighthouse/Types/Match/RoomSlot.cs | 4 +-
.../Types/Profiles/LastContact.cs | 2 +
.../Types/Profiles/UserStatus.cs | 10 ++++-
12 files changed, 93 insertions(+), 13 deletions(-)
create mode 100644 ProjectLighthouse/Migrations/20220217045519_AddPlatformForLastContactsAndGameTokens.cs
diff --git a/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
index 7ba10605..f173e1bc 100644
--- a/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
@@ -74,7 +74,7 @@ public class MatchController : ControllerBase
#endregion
- await LastContactHelper.SetLastContact(user, gameToken.GameVersion);
+ await LastContactHelper.SetLastContact(user, gameToken.GameVersion, gameToken.Platform);
#region Process match data
diff --git a/ProjectLighthouse/Database.cs b/ProjectLighthouse/Database.cs
index 6ae7f4e2..abb0977a 100644
--- a/ProjectLighthouse/Database.cs
+++ b/ProjectLighthouse/Database.cs
@@ -82,6 +82,7 @@ public class Database : DbContext
UserId = user.UserId,
UserLocation = userLocation,
GameVersion = npTicket.GameVersion,
+ Platform = npTicket.Platform,
};
this.GameTokens.Add(gameToken);
@@ -151,7 +152,7 @@ public class Database : DbContext
else
{
Slot? targetSlot = await this.Slots.FirstOrDefaultAsync(u => u.SlotId == targetId);
- if(targetSlot == null) return false;
+ if (targetSlot == null) return false;
}
this.Comments.Add
diff --git a/ProjectLighthouse/Helpers/LastContactHelper.cs b/ProjectLighthouse/Helpers/LastContactHelper.cs
index cdc7a06d..8f76bf22 100644
--- a/ProjectLighthouse/Helpers/LastContactHelper.cs
+++ b/ProjectLighthouse/Helpers/LastContactHelper.cs
@@ -11,7 +11,7 @@ public static class LastContactHelper
{
private static readonly Database database = new();
- public static async Task SetLastContact(User user, GameVersion gameVersion)
+ public static async Task SetLastContact(User user, GameVersion gameVersion, Platform platform)
{
LastContact? lastContact = await database.LastContacts.Where(l => l.UserId == user.UserId).FirstOrDefaultAsync();
@@ -28,6 +28,7 @@ public static class LastContactHelper
lastContact.Timestamp = TimestampHelper.Timestamp;
lastContact.GameVersion = gameVersion;
+ lastContact.Platform = platform;
await database.SaveChangesAsync();
}
diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs
index 7cca021b..cc81af01 100644
--- a/ProjectLighthouse/Helpers/RoomHelper.cs
+++ b/ProjectLighthouse/Helpers/RoomHelper.cs
@@ -152,6 +152,15 @@ public class RoomHelper
return createIfDoesNotExist ? CreateRoom(user, roomVersion) : null;
}
+ public static Room? FindRoomByUserId(int userId)
+ {
+ lock(Rooms)
+ foreach (Room room in Rooms.Where(room => room.Players.Any(player => player.UserId == userId)))
+ return room;
+
+ return null;
+ }
+
[SuppressMessage("ReSharper", "InvertIf")]
public static void CleanupRooms(User? host = null, Room? newRoom = null)
{
diff --git a/ProjectLighthouse/Migrations/20220217045519_AddPlatformForLastContactsAndGameTokens.cs b/ProjectLighthouse/Migrations/20220217045519_AddPlatformForLastContactsAndGameTokens.cs
new file mode 100644
index 00000000..78342cfe
--- /dev/null
+++ b/ProjectLighthouse/Migrations/20220217045519_AddPlatformForLastContactsAndGameTokens.cs
@@ -0,0 +1,41 @@
+using LBPUnion.ProjectLighthouse;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace ProjectLighthouse.Migrations
+{
+ [DbContext(typeof(Database))]
+ [Migration("20220217045519_AddPlatformForLastContactsAndGameTokens")]
+ public partial class AddPlatformForLastContactsAndGameTokens : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "Platform",
+ table: "LastContacts",
+ type: "int",
+ nullable: false,
+ defaultValue: -1);
+
+ migrationBuilder.AddColumn(
+ name: "Platform",
+ table: "GameTokens",
+ type: "int",
+ nullable: false,
+ defaultValue: -1);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Platform",
+ table: "LastContacts");
+
+ migrationBuilder.DropColumn(
+ name: "Platform",
+ table: "GameTokens");
+ }
+ }
+}
diff --git a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
index 21676d01..23e9069d 100644
--- a/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
+++ b/ProjectLighthouse/Migrations/DatabaseModelSnapshot.cs
@@ -81,6 +81,9 @@ namespace ProjectLighthouse.Migrations
b.Property("GameVersion")
.HasColumnType("int");
+ b.Property("Platform")
+ .HasColumnType("int");
+
b.Property("Used")
.HasColumnType("tinyint(1)");
@@ -458,6 +461,9 @@ namespace ProjectLighthouse.Migrations
b.Property("GameVersion")
.HasColumnType("int");
+ b.Property("Platform")
+ .HasColumnType("int");
+
b.Property("Timestamp")
.HasColumnType("bigint");
diff --git a/ProjectLighthouse/Startup/Startup.cs b/ProjectLighthouse/Startup/Startup.cs
index 5cc33fe0..97c6833f 100644
--- a/ProjectLighthouse/Startup/Startup.cs
+++ b/ProjectLighthouse/Startup/Startup.cs
@@ -250,7 +250,8 @@ public class Startup
if (gameToken != null && gameToken.GameVersion == GameVersion.LittleBigPlanet1)
// Ignore UserFromGameToken null because user must exist for a token to exist
- await LastContactHelper.SetLastContact((await database.UserFromGameToken(gameToken))!, GameVersion.LittleBigPlanet1);
+ await LastContactHelper.SetLastContact
+ ((await database.UserFromGameToken(gameToken))!, GameVersion.LittleBigPlanet1, gameToken.Platform);
}
#nullable disable
diff --git a/ProjectLighthouse/Types/GameToken.cs b/ProjectLighthouse/Types/GameToken.cs
index d084c034..0e57d7fd 100644
--- a/ProjectLighthouse/Types/GameToken.cs
+++ b/ProjectLighthouse/Types/GameToken.cs
@@ -20,6 +20,8 @@ public class GameToken
public GameVersion GameVersion { get; set; }
+ public Platform Platform { get; set; }
+
// Set by /authentication webpage
public bool Approved { get; set; }
diff --git a/ProjectLighthouse/Types/Match/Room.cs b/ProjectLighthouse/Types/Match/Room.cs
index aa659041..1541cb10 100644
--- a/ProjectLighthouse/Types/Match/Room.cs
+++ b/ProjectLighthouse/Types/Match/Room.cs
@@ -1,23 +1,34 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
using LBPUnion.ProjectLighthouse.Types.Levels;
namespace LBPUnion.ProjectLighthouse.Types.Match;
public class Room
{
- public List Players;
- public int RoomId;
+ [JsonIgnore]
+ public List Players { get; set; }
- public GameVersion RoomVersion;
- public RoomSlot Slot;
- public RoomState State;
+ public int RoomId { get; set; }
+ [JsonIgnore]
+ public GameVersion RoomVersion { get; set; }
+
+ public RoomSlot Slot { get; set; }
+ public RoomState State { get; set; }
+
+ [JsonIgnore]
public bool IsInPod => this.Slot.SlotType == SlotType.Pod;
+
+ [JsonIgnore]
public bool IsLookingForPlayers => this.State == RoomState.PlayingLevel || this.State == RoomState.DivingInWaiting;
+ [JsonIgnore]
public User Host => this.Players[0];
+ public int PlayerCount => this.Players.Count;
+
#nullable enable
public override bool Equals(object? obj)
{
diff --git a/ProjectLighthouse/Types/Match/RoomSlot.cs b/ProjectLighthouse/Types/Match/RoomSlot.cs
index 063715d4..b3d2c0e4 100644
--- a/ProjectLighthouse/Types/Match/RoomSlot.cs
+++ b/ProjectLighthouse/Types/Match/RoomSlot.cs
@@ -4,6 +4,6 @@ namespace LBPUnion.ProjectLighthouse.Types.Match;
public class RoomSlot
{
- public int SlotId;
- public SlotType SlotType;
+ public int SlotId { get; set; }
+ public SlotType SlotType { get; set; }
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Profiles/LastContact.cs b/ProjectLighthouse/Types/Profiles/LastContact.cs
index 7fb0593a..14073106 100644
--- a/ProjectLighthouse/Types/Profiles/LastContact.cs
+++ b/ProjectLighthouse/Types/Profiles/LastContact.cs
@@ -10,4 +10,6 @@ public class LastContact
public long Timestamp { get; set; }
public GameVersion GameVersion { get; set; } = GameVersion.Unknown;
+
+ public Platform Platform { get; set; } = Platform.Unknown;
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Profiles/UserStatus.cs b/ProjectLighthouse/Types/Profiles/UserStatus.cs
index 67cde0f6..c9192a35 100644
--- a/ProjectLighthouse/Types/Profiles/UserStatus.cs
+++ b/ProjectLighthouse/Types/Profiles/UserStatus.cs
@@ -1,6 +1,7 @@
#nullable enable
using System.Linq;
using LBPUnion.ProjectLighthouse.Helpers;
+using LBPUnion.ProjectLighthouse.Types.Match;
namespace LBPUnion.ProjectLighthouse.Types.Profiles;
@@ -8,6 +9,8 @@ public class UserStatus
{
public StatusType StatusType { get; set; }
public GameVersion? CurrentVersion { get; set; }
+ public Platform? CurrentPlatform { get; set; }
+ public Room? CurrentRoom { get; set; }
public UserStatus()
{}
@@ -25,16 +28,19 @@ public class UserStatus
{
StatusType = StatusType.Online;
CurrentVersion = lastContact.GameVersion;
+ CurrentPlatform = lastContact.Platform;
}
+
+ CurrentRoom = RoomHelper.FindRoomByUserId(userId);
}
public override string ToString()
{
CurrentVersion ??= GameVersion.Unknown;
-
+ CurrentPlatform ??= Platform.Unknown;
return this.StatusType switch
{
- StatusType.Online => $"Currently online on {((GameVersion)this.CurrentVersion).ToPrettyString()}",
+ StatusType.Online => $"Currently online on {((GameVersion)this.CurrentVersion).ToPrettyString()} on {((Platform)this.CurrentPlatform)}",
StatusType.Offline => "Offline",
_ => "Unknown",
};
From fcdbd46c987bf6d4390e58ade087cc63cf2742bb Mon Sep 17 00:00:00 2001
From: jvyden
Date: Thu, 17 Feb 2022 12:36:53 -0500
Subject: [PATCH 04/26] Remove offline players from rooms
---
ProjectLighthouse/Helpers/RoomHelper.cs | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs
index cc81af01..cf22d8a4 100644
--- a/ProjectLighthouse/Helpers/RoomHelper.cs
+++ b/ProjectLighthouse/Helpers/RoomHelper.cs
@@ -7,6 +7,7 @@ using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Types.Levels;
using LBPUnion.ProjectLighthouse.Types.Match;
+using LBPUnion.ProjectLighthouse.Types.Profiles;
namespace LBPUnion.ProjectLighthouse.Helpers;
@@ -166,6 +167,15 @@ public class RoomHelper
{
lock(Rooms)
{
+ // Remove offline players from rooms
+ foreach (Room room in Rooms)
+ {
+ foreach (User player in room.Players.Where(player => player.Status.StatusType == StatusType.Offline))
+ {
+ room.Players.Remove(player);
+ }
+ }
+
// Delete old rooms based on host
if (host != null)
try
From 487ec5bc8fb3f3fc840fb454a271e0be8039a469 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Thu, 17 Feb 2022 16:12:21 -0500
Subject: [PATCH 05/26] Move PNG conversion to FileHelper
---
ProjectLighthouse/Helpers/FileHelper.cs | 46 +++++++++++++++++++++++++
ProjectLighthouse/Program.cs | 40 +--------------------
2 files changed, 47 insertions(+), 39 deletions(-)
diff --git a/ProjectLighthouse/Helpers/FileHelper.cs b/ProjectLighthouse/Helpers/FileHelper.cs
index 9d8c4f20..e3e39d17 100644
--- a/ProjectLighthouse/Helpers/FileHelper.cs
+++ b/ProjectLighthouse/Helpers/FileHelper.cs
@@ -1,7 +1,13 @@
+#nullable enable
using System;
+using System.Collections.Concurrent;
using System.IO;
using System.Linq;
using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Kettu;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types.Files;
using LBPUnion.ProjectLighthouse.Types.Settings;
@@ -101,4 +107,44 @@ public static class FileHelper
}
public static string[] ResourcesNotUploaded(params string[] hashes) => hashes.Where(hash => !ResourceExists(hash)).ToArray();
+
+ public static void ConvertAllTexturesToPng()
+ {
+ EnsureDirectoryCreated(Path.Combine(Environment.CurrentDirectory, "png"));
+ if (Directory.Exists("r"))
+ {
+ Logger.Log
+ ("Converting all textures to PNG. This may take a while if this is the first time running this operation...", LoggerLevelStartup.Instance);
+
+ ConcurrentQueue fileQueue = new();
+
+ foreach (string filename in Directory.GetFiles("r")) fileQueue.Enqueue(filename);
+
+ for(int i = 0; i < Environment.ProcessorCount; i++)
+ {
+ Task.Factory.StartNew
+ (
+ () =>
+ {
+ while (fileQueue.TryDequeue(out string? filename))
+ {
+ LbpFile? file = LbpFile.FromHash(filename.Replace("r" + Path.DirectorySeparatorChar, ""));
+ if (file == null) continue;
+
+ if (file.FileType == LbpFileType.Jpeg || file.FileType == LbpFileType.Png || file.FileType == LbpFileType.Texture)
+ {
+ ImageHelper.LbpFileToPNG(file);
+ }
+ }
+ }
+ );
+ }
+
+ while (!fileQueue.IsEmpty)
+ {
+ Thread.Sleep(100);
+ }
+ }
+ }
+
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Program.cs b/ProjectLighthouse/Program.cs
index eda0cb43..65a7077f 100644
--- a/ProjectLighthouse/Program.cs
+++ b/ProjectLighthouse/Program.cs
@@ -1,14 +1,10 @@
#nullable enable
using System;
-using System.Collections.Concurrent;
using System.Diagnostics;
-using System.IO;
using System.Threading;
-using System.Threading.Tasks;
using Kettu;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
-using LBPUnion.ProjectLighthouse.Types.Files;
using LBPUnion.ProjectLighthouse.Types.Settings;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@@ -82,41 +78,7 @@ public static class Program
return;
}
- FileHelper.EnsureDirectoryCreated(Path.Combine(Environment.CurrentDirectory, "png"));
- if (Directory.Exists("r"))
- {
- Logger.Log
- ("Converting all textures to PNG. This may take a while if this is the first time running this operation...", LoggerLevelStartup.Instance);
-
- ConcurrentQueue fileQueue = new();
-
- foreach (string filename in Directory.GetFiles("r")) fileQueue.Enqueue(filename);
-
- for(int i = 0; i < Environment.ProcessorCount; i++)
- {
- Task.Factory.StartNew
- (
- () =>
- {
- while (fileQueue.TryDequeue(out string? filename))
- {
- LbpFile? file = LbpFile.FromHash(filename.Replace("r" + Path.DirectorySeparatorChar, ""));
- if (file == null) continue;
-
- if (file.FileType == LbpFileType.Jpeg || file.FileType == LbpFileType.Png || file.FileType == LbpFileType.Texture)
- {
- ImageHelper.LbpFileToPNG(file);
- }
- }
- }
- );
- }
-
- while (!fileQueue.IsEmpty)
- {
- Thread.Sleep(100);
- }
- }
+ FileHelper.ConvertAllTexturesToPng();
stopwatch.Stop();
Logger.Log($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LoggerLevelStartup.Instance);
From 3f2993462818e2e5d75c752d079d8458cb7d7438 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Thu, 17 Feb 2022 16:16:55 -0500
Subject: [PATCH 06/26] Add automatic room cleanup
---
ProjectLighthouse/Helpers/RoomHelper.cs | 26 +++++++++++++++++++++++++
ProjectLighthouse/Program.cs | 3 +++
2 files changed, 29 insertions(+)
diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs
index cf22d8a4..0ae4343c 100644
--- a/ProjectLighthouse/Helpers/RoomHelper.cs
+++ b/ProjectLighthouse/Helpers/RoomHelper.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using System.Threading.Tasks;
using Kettu;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Types;
@@ -23,6 +24,22 @@ public class RoomHelper
private static int roomIdIncrement;
+ public static void StartCleanupThread()
+ {
+ // ReSharper disable once FunctionNeverReturns
+ Task.Factory.StartNew
+ (
+ async () =>
+ {
+ while (true)
+ {
+ CleanupRooms();
+ await Task.Delay(10000);
+ }
+ }
+ );
+ }
+
internal static int RoomIdIncrement => roomIdIncrement++;
public static FindBestRoomResponse? FindBestRoom(User? user, GameVersion roomVersion, string? location)
@@ -167,6 +184,8 @@ public class RoomHelper
{
lock(Rooms)
{
+ int roomCountBeforeCleanup = Rooms.Count;
+
// Remove offline players from rooms
foreach (Room room in Rooms)
{
@@ -198,6 +217,13 @@ public class RoomHelper
Rooms.RemoveAll(r => r.Players.Count == 0); // Remove empty rooms
Rooms.RemoveAll(r => r.Players.Count > 4); // Remove obviously bogus rooms
+
+ int roomCountAfterCleanup = Rooms.Count;
+
+ if (roomCountBeforeCleanup != roomCountAfterCleanup)
+ {
+ Logger.Log($"Cleaned up {roomCountBeforeCleanup - roomCountAfterCleanup} rooms.", LoggerLevelMatch.Instance);
+ }
}
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Program.cs b/ProjectLighthouse/Program.cs
index 65a7077f..0fcfaab5 100644
--- a/ProjectLighthouse/Program.cs
+++ b/ProjectLighthouse/Program.cs
@@ -80,6 +80,9 @@ public static class Program
FileHelper.ConvertAllTexturesToPng();
+ Logger.Log("Starting room cleanup thread...", LoggerLevelStartup.Instance);
+ RoomHelper.StartCleanupThread();
+
stopwatch.Stop();
Logger.Log($"Ready! Startup took {stopwatch.ElapsedMilliseconds}ms. Passing off control to ASP.NET...", LoggerLevelStartup.Instance);
From 41dde8eed2f64f61c6fa23c8367fa332ce3f8ec2 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Thu, 17 Feb 2022 16:23:09 -0500
Subject: [PATCH 07/26] Add platform matching to rooms
---
.../Controllers/GameApi/LoginController.cs | 2 +-
.../Controllers/GameApi/Matching/MatchController.cs | 6 +++---
.../Website/Debug/RoomVisualizerController.cs | 2 +-
ProjectLighthouse/Helpers/RoomHelper.cs | 13 ++++++++-----
.../Pages/Debug/RoomVisualizerPage.cshtml | 4 ++--
ProjectLighthouse/Types/Match/Room.cs | 3 +++
6 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/LoginController.cs b/ProjectLighthouse/Controllers/GameApi/LoginController.cs
index 8e95ed4e..20ec33ae 100644
--- a/ProjectLighthouse/Controllers/GameApi/LoginController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/LoginController.cs
@@ -141,7 +141,7 @@ public class LoginController : ControllerBase
await this.database.SaveChangesAsync();
// Create a new room on LBP2/3/Vita
- if (token.GameVersion != GameVersion.LittleBigPlanet1) RoomHelper.CreateRoom(user, token.GameVersion);
+ if (token.GameVersion != GameVersion.LittleBigPlanet1) RoomHelper.CreateRoom(user, token.GameVersion, token.Platform);
return this.Ok
(
diff --git a/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
index f173e1bc..d250fb44 100644
--- a/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Matching/MatchController.cs
@@ -81,7 +81,7 @@ public class MatchController : ControllerBase
if (matchData is UpdateMyPlayerData playerData)
{
MatchHelper.SetUserLocation(user.UserId, gameToken.UserLocation);
- Room? room = RoomHelper.FindRoomByUser(user, gameToken.GameVersion, true);
+ Room? room = RoomHelper.FindRoomByUser(user, gameToken.GameVersion, gameToken.Platform, true);
if (playerData.RoomState != null)
if (room != null && Equals(room.Host, user))
@@ -90,7 +90,7 @@ public class MatchController : ControllerBase
if (matchData is FindBestRoom && MatchHelper.UserLocations.Count > 1)
{
- FindBestRoomResponse? response = RoomHelper.FindBestRoom(user, gameToken.GameVersion, gameToken.UserLocation);
+ FindBestRoomResponse? response = RoomHelper.FindBestRoom(user, gameToken.GameVersion, gameToken.Platform, gameToken.UserLocation);
if (response == null) return this.NotFound();
@@ -112,7 +112,7 @@ public class MatchController : ControllerBase
}
// Create a new one as requested
- RoomHelper.CreateRoom(users, gameToken.GameVersion, createRoom.RoomSlot);
+ RoomHelper.CreateRoom(users, gameToken.GameVersion, gameToken.Platform, createRoom.RoomSlot);
}
if (matchData is UpdatePlayersInRoom updatePlayersInRoom)
diff --git a/ProjectLighthouse/Controllers/Website/Debug/RoomVisualizerController.cs b/ProjectLighthouse/Controllers/Website/Debug/RoomVisualizerController.cs
index 854f05c9..cc690c93 100644
--- a/ProjectLighthouse/Controllers/Website/Debug/RoomVisualizerController.cs
+++ b/ProjectLighthouse/Controllers/Website/Debug/RoomVisualizerController.cs
@@ -26,7 +26,7 @@ public class RoomVisualizerController : ControllerBase
return this.NotFound();
#else
List users = await this.database.Users.OrderByDescending(_ => EF.Functions.Random()).Take(2).ToListAsync();
- RoomHelper.CreateRoom(users, GameVersion.LittleBigPlanet2);
+ RoomHelper.CreateRoom(users, GameVersion.LittleBigPlanet2, Platform.PS3);
foreach (User user in users)
{
diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs
index 0ae4343c..cbf3dc8a 100644
--- a/ProjectLighthouse/Helpers/RoomHelper.cs
+++ b/ProjectLighthouse/Helpers/RoomHelper.cs
@@ -42,7 +42,7 @@ public class RoomHelper
internal static int RoomIdIncrement => roomIdIncrement++;
- public static FindBestRoomResponse? FindBestRoom(User? user, GameVersion roomVersion, string? location)
+ public static FindBestRoomResponse? FindBestRoom(User? user, GameVersion roomVersion, Platform? platform, string? location)
{
if (roomVersion == GameVersion.LittleBigPlanet1 || roomVersion == GameVersion.LittleBigPlanetPSP)
{
@@ -60,6 +60,7 @@ public class RoomHelper
}
rooms = rooms.Where(r => r.RoomVersion == roomVersion).ToList();
+ if (platform != null) rooms = rooms.Where(r => r.RoomPlatform == platform).ToList();
foreach (Room room in rooms)
// Look for rooms looking for players before moving on to rooms that are idle.
@@ -133,7 +134,7 @@ public class RoomHelper
return null;
}
- public static Room CreateRoom(User user, GameVersion roomVersion, RoomSlot? slot = null)
+ public static Room CreateRoom(User user, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
=> CreateRoom
(
new List
@@ -141,9 +142,10 @@ public class RoomHelper
user,
},
roomVersion,
+ roomPlatform,
slot
);
- public static Room CreateRoom(List users, GameVersion roomVersion, RoomSlot? slot = null)
+ public static Room CreateRoom(List users, GameVersion roomVersion, Platform roomPlatform, RoomSlot? slot = null)
{
Room room = new()
{
@@ -152,6 +154,7 @@ public class RoomHelper
State = RoomState.Idle,
Slot = slot ?? PodSlot,
RoomVersion = roomVersion,
+ RoomPlatform = roomPlatform,
};
CleanupRooms(room.Host, room);
@@ -161,13 +164,13 @@ public class RoomHelper
return room;
}
- public static Room? FindRoomByUser(User user, GameVersion roomVersion, bool createIfDoesNotExist = false)
+ public static Room? FindRoomByUser(User user, GameVersion roomVersion, Platform roomPlatform, bool createIfDoesNotExist = false)
{
lock(Rooms)
foreach (Room room in Rooms.Where(room => room.Players.Any(player => user == player)))
return room;
- return createIfDoesNotExist ? CreateRoom(user, roomVersion) : null;
+ return createIfDoesNotExist ? CreateRoom(user, roomVersion, roomPlatform) : null;
}
public static Room? FindRoomByUserId(int userId)
diff --git a/ProjectLighthouse/Pages/Debug/RoomVisualizerPage.cshtml b/ProjectLighthouse/Pages/Debug/RoomVisualizerPage.cshtml
index 0316b86c..265b4951 100644
--- a/ProjectLighthouse/Pages/Debug/RoomVisualizerPage.cshtml
+++ b/ProjectLighthouse/Pages/Debug/RoomVisualizerPage.cshtml
@@ -52,7 +52,7 @@
{
if (version == GameVersion.LittleBigPlanet1 || version == GameVersion.LittleBigPlanetPSP || version == GameVersion.Unknown) continue;
- FindBestRoomResponse? response = RoomHelper.FindBestRoom(null, version, null);
+ FindBestRoomResponse? response = RoomHelper.FindBestRoom(null, version, null, null);
string text = response == null ? "No room found." : "Room " + response.RoomId;
Best room for @version.ToPrettyString(): @text
@@ -72,7 +72,7 @@
You are currently in this room.
}
- @room.Players.Count players, state is @room.State, version is @room.RoomVersion.ToPrettyString()
+ @room.Players.Count players, state is @room.State, version is @room.RoomVersion.ToPrettyString()on paltform @room.RoomPlatform
Slot type: @room.Slot.SlotType, slot id: @room.Slot.SlotId
@foreach (User player in room.Players)
{
diff --git a/ProjectLighthouse/Types/Match/Room.cs b/ProjectLighthouse/Types/Match/Room.cs
index 1541cb10..63128150 100644
--- a/ProjectLighthouse/Types/Match/Room.cs
+++ b/ProjectLighthouse/Types/Match/Room.cs
@@ -15,6 +15,9 @@ public class Room
[JsonIgnore]
public GameVersion RoomVersion { get; set; }
+ [JsonIgnore]
+ public Platform RoomPlatform { get; set; }
+
public RoomSlot Slot { get; set; }
public RoomState State { get; set; }
From 7b5ce09fb471ee73497c39be25e841797f4400f9 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Fri, 18 Feb 2022 16:32:33 -0500
Subject: [PATCH 08/26] Fix collection modified error when cleaning up rooms
---
ProjectLighthouse/Helpers/RoomHelper.cs | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/ProjectLighthouse/Helpers/RoomHelper.cs b/ProjectLighthouse/Helpers/RoomHelper.cs
index cbf3dc8a..81db373a 100644
--- a/ProjectLighthouse/Helpers/RoomHelper.cs
+++ b/ProjectLighthouse/Helpers/RoomHelper.cs
@@ -192,10 +192,9 @@ public class RoomHelper
// Remove offline players from rooms
foreach (Room room in Rooms)
{
- foreach (User player in room.Players.Where(player => player.Status.StatusType == StatusType.Offline))
- {
- room.Players.Remove(player);
- }
+ // do not shorten, this prevents collection modified errors
+ List playersToRemove = room.Players.Where(player => player.Status.StatusType == StatusType.Offline).ToList();
+ foreach (User user in playersToRemove) room.Players.Remove(user);
}
// Delete old rooms based on host
From a3e8c291420089cf8bb20c781bd65fa61590da72 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Fri, 18 Feb 2022 17:42:53 -0500
Subject: [PATCH 09/26] Check used slots for version on upload, not for all
versions
---
.../Controllers/GameApi/Slots/PublishController.cs | 14 +++++++++++---
ProjectLighthouse/Types/User.cs | 7 +++++--
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
index b7128d8d..564a0607 100644
--- a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
@@ -33,10 +33,18 @@ public class PublishController : ControllerBase
[HttpPost("startPublish")]
public async Task StartPublish()
{
- User? user = await this.database.UserFromGameRequest(this.Request);
- if (user == null) return this.StatusCode(403, "");
+ (User, GameToken)? userAndToken = await this.database.UserAndGameTokenFromRequest(this.Request);
- if (user.UsedSlots >= ServerSettings.Instance.EntitledSlots) return this.BadRequest();
+ if (userAndToken == null) return this.StatusCode(403, "");
+
+ // ReSharper disable once PossibleInvalidOperationException
+ User user = userAndToken.Value.Item1;
+ GameToken gameToken = userAndToken.Value.Item2;
+
+ if (user.GetUsedSlotsForGame(gameToken.GameVersion, database) > 50)
+ {
+ return this.StatusCode(403, "");
+ }
Slot? slot = await this.getSlotFromBody();
if (slot == null) return this.BadRequest(); // if the level cant be parsed then it obviously cant be uploaded
diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs
index a370aaef..0678209d 100644
--- a/ProjectLighthouse/Types/User.cs
+++ b/ProjectLighthouse/Types/User.cs
@@ -223,11 +223,14 @@ public class User
}
}
- public int GetUsedSlotsForGame(GameVersion version)
+ #nullable enable
+ public int GetUsedSlotsForGame(GameVersion version, Database? database = null)
{
- using Database database = new();
+ database ??= new Database();
+
return database.Slots.Count(s => s.CreatorId == this.UserId && s.GameVersion == version);
}
+ #nullable disable
///
/// The number of slots remaining on the earth
From 3cda95447b509f0575cb12f1cde936a6705cd8ad Mon Sep 17 00:00:00 2001
From: jvyden
Date: Fri, 18 Feb 2022 17:51:40 -0500
Subject: [PATCH 10/26] Show sublevels for creators of sublevels
---
.../Controllers/GameApi/Slots/SlotsController.cs | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs
index 04d94441..950be32c 100644
--- a/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Slots/SlotsController.cs
@@ -24,16 +24,22 @@ public class SlotsController : ControllerBase
this.database = database;
}
- private IQueryable getSlots(GameVersion gameVersion)
+ private IQueryable getSlots(GameVersion gameVersion, bool includeSublevels = false)
{
IQueryable query = this.database.Slots.Include(s => s.Creator).Include(s => s.Location);
if (gameVersion == GameVersion.LittleBigPlanetVita || gameVersion == GameVersion.LittleBigPlanetPSP || gameVersion == GameVersion.Unknown)
{
- return query.Where(s => s.GameVersion == gameVersion && !s.SubLevel);
+ query = query.Where(s => s.GameVersion == gameVersion);
+ }
+ else
+ {
+ query = query.Where(s => s.GameVersion <= gameVersion);
}
- return query.Where(s => s.GameVersion <= gameVersion && !s.SubLevel);
+ if (!includeSublevels) query = query.Where(s => !s.SubLevel);
+
+ return query;
}
[HttpGet("slots/by")]
@@ -49,8 +55,7 @@ public class SlotsController : ControllerBase
string response = Enumerable.Aggregate
(
- this.getSlots
- (gameVersion)
+ this.getSlots(gameVersion, token.UserId == user.UserId)
.Where(s => s.Creator!.Username == user.Username)
.Skip(pageStart - 1)
.Take(Math.Min(pageSize, ServerSettings.Instance.EntitledSlots)),
From be9e3edef546a0a74326361389f2ac8bec93e0ab Mon Sep 17 00:00:00 2001
From: Josh
Date: Mon, 21 Feb 2022 11:03:25 -0600
Subject: [PATCH 11/26] Fix review button not showing up (#180)
---
.../GameApi/Slots/ReviewController.cs | 38 ++-----------------
ProjectLighthouse/Types/Levels/Slot.cs | 9 ++---
2 files changed, 7 insertions(+), 40 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs
index e7ad7d7f..71bbc3f4 100644
--- a/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Slots/ReviewController.cs
@@ -17,7 +17,7 @@ namespace LBPUnion.ProjectLighthouse.Controllers.GameApi.Slots;
[ApiController]
[Route("LITTLEBIGPLANETPS3_XML/")]
-[Produces("text/plain")]
+[Produces("text/xml")]
public class ReviewController : ControllerBase
{
private readonly Database database;
@@ -141,51 +141,19 @@ public class ReviewController : ControllerBase
GameVersion gameVersion = gameToken.GameVersion;
- Random rand = new();
-
- Review? yourReview = await this.database.Reviews.FirstOrDefaultAsync
- (r => r.ReviewerId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
-
- VisitedLevel? visitedLevel = await this.database.VisitedLevels.FirstOrDefaultAsync
- (v => v.UserId == user.UserId && v.SlotId == slotId && v.Slot.GameVersion <= gameVersion);
-
Slot? slot = await this.database.Slots.FirstOrDefaultAsync(s => s.SlotId == slotId);
if (slot == null) return this.BadRequest();
- bool canNowReviewLevel = slot.CreatorId != user.UserId && visitedLevel != null && yourReview == null;
- if (canNowReviewLevel)
- {
- RatedLevel? ratedLevel = await this.database.RatedLevels.FirstOrDefaultAsync
- (r => r.UserId == user.UserId && r.SlotId == slotId && r.Slot.GameVersion <= gameVersion);
-
- yourReview = new Review();
- yourReview.ReviewerId = user.UserId;
- yourReview.Reviewer = user;
- yourReview.Thumb = ratedLevel?.Rating ?? 0;
- yourReview.Slot = slot;
- yourReview.SlotId = slotId;
- yourReview.Deleted = false;
- yourReview.DeletedBy = DeletedBy.None;
- yourReview.Text = "You haven't reviewed this level yet. Edit this to write one!";
- yourReview.LabelCollection = "";
- yourReview.Timestamp = TimeHelper.UnixTimeMilliseconds();
- }
-
IQueryable reviews = this.database.Reviews.Where(r => r.SlotId == slotId && r.Slot.GameVersion <= gameVersion)
.Include(r => r.Reviewer)
.Include(r => r.Slot)
.OrderByDescending(r => r.ThumbsUp)
- .ThenByDescending(_ => EF.Functions.Random())
+ .ThenByDescending(r => r.Timestamp)
.Skip(pageStart - 1)
.Take(pageSize);
- IEnumerable prependedReviews;
- if (canNowReviewLevel) // this can only be true if you have not posted a review but have visited the level
- // prepend the fake review to the top of the list to be easily edited
- prependedReviews = reviews.ToList().Prepend(yourReview);
- else prependedReviews = reviews.ToList();
- string inner = prependedReviews.Aggregate
+ string inner = reviews.ToList().Aggregate
(
string.Empty,
(current, review) =>
diff --git a/ProjectLighthouse/Types/Levels/Slot.cs b/ProjectLighthouse/Types/Levels/Slot.cs
index 23a9d495..f2a35c21 100644
--- a/ProjectLighthouse/Types/Levels/Slot.cs
+++ b/ProjectLighthouse/Types/Levels/Slot.cs
@@ -299,9 +299,8 @@ public class Slot
LbpSerializer.StringElement("leveltype", this.LevelType) +
LbpSerializer.StringElement("yourRating", yourRatingStats?.RatingLBP1) +
LbpSerializer.StringElement("yourDPadRating", yourRatingStats?.Rating) +
- LbpSerializer.StringElement("yourLBP1PlayCount", yourVisitedStats?.PlaysLBP1) +
- LbpSerializer.StringElement("yourLBP2PlayCount", yourVisitedStats?.PlaysLBP2) +
- LbpSerializer.StringElement("yourLBP3PlayCount", yourVisitedStats?.PlaysLBP3) +
+ LbpSerializer.StringElement("yourlbpPlayCount", yourVisitedStats?.PlaysLBP1) +
+ LbpSerializer.StringElement("yourlbp3PlayCount", yourVisitedStats?.PlaysLBP3) +
yourReview?.Serialize("yourReview") +
LbpSerializer.StringElement("reviewsEnabled", ServerSettings.Instance.LevelReviewsEnabled) +
LbpSerializer.StringElement("commentsEnabled", ServerSettings.Instance.LevelCommentsEnabled) +
@@ -309,14 +308,14 @@ public class Slot
if (gameVersion == GameVersion.LittleBigPlanetVita)
{
- slotData += LbpSerializer.StringElement("yourLBP2PlayCount", yourVisitedStats?.PlaysLBPVita) +
+ slotData += LbpSerializer.StringElement("yourlbp2PlayCount", yourVisitedStats?.PlaysLBPVita) +
LbpSerializer.StringElement("lbp2PlayCount", this.PlaysLBPVita) +
LbpSerializer.StringElement("lbp2CompletionCount", this.PlaysLBPVitaComplete) +
LbpSerializer.StringElement("lbp2UniquePlayCount", this.PlaysLBPVitaUnique);
}
else
{
- slotData += LbpSerializer.StringElement("yourLBP2PlayCount", yourVisitedStats?.PlaysLBPVita) +
+ slotData += LbpSerializer.StringElement("yourlbp2PlayCount", yourVisitedStats?.PlaysLBP2) +
LbpSerializer.StringElement("lbp2PlayCount", this.PlaysLBP2) +
LbpSerializer.StringElement("lbp2CompletionCount", this.PlaysLBP2Complete) +
LbpSerializer.StringElement("lbp2UniquePlayCount", this.PlaysLBP2Unique); // not actually used ingame, as per above comment
From 40ce3edba7347ebfe2772e007c1f994c6d1cfc40 Mon Sep 17 00:00:00 2001
From: jvyden
Date: Mon, 21 Feb 2022 19:18:57 -0500
Subject: [PATCH 12/26] Use Database.RemoveSlot when removing slot on website
---
.../Controllers/Website/Admin/AdminSlotController.cs | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/ProjectLighthouse/Controllers/Website/Admin/AdminSlotController.cs b/ProjectLighthouse/Controllers/Website/Admin/AdminSlotController.cs
index 3f84078f..ad99952e 100644
--- a/ProjectLighthouse/Controllers/Website/Admin/AdminSlotController.cs
+++ b/ProjectLighthouse/Controllers/Website/Admin/AdminSlotController.cs
@@ -62,10 +62,7 @@ public class AdminSlotController : ControllerBase
if (slot.Location == null) throw new ArgumentNullException();
- this.database.Locations.Remove(slot.Location);
- this.database.Slots.Remove(slot);
-
- await this.database.SaveChangesAsync();
+ await this.database.RemoveSlot(slot);
return this.Ok();
}
From 3e3d6b74aa622c42452388b7a0b780ac466ee6cf Mon Sep 17 00:00:00 2001
From: jvyden
Date: Mon, 21 Feb 2022 19:22:26 -0500
Subject: [PATCH 13/26] Check if there are no free slots *after* handling
republished levels
Closes #179
---
.../GameApi/Slots/PublishController.cs | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
index 564a0607..bcfdd34a 100644
--- a/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
+++ b/ProjectLighthouse/Controllers/GameApi/Slots/PublishController.cs
@@ -41,11 +41,6 @@ public class PublishController : ControllerBase
User user = userAndToken.Value.Item1;
GameToken gameToken = userAndToken.Value.Item2;
- if (user.GetUsedSlotsForGame(gameToken.GameVersion, database) > 50)
- {
- return this.StatusCode(403, "");
- }
-
Slot? slot = await this.getSlotFromBody();
if (slot == null) return this.BadRequest(); // if the level cant be parsed then it obviously cant be uploaded
@@ -60,6 +55,10 @@ public class PublishController : ControllerBase
if (oldSlot == null) return this.NotFound();
if (oldSlot.CreatorId != user.UserId) return this.BadRequest();
}
+ else if (user.GetUsedSlotsForGame(gameToken.GameVersion, database) > ServerSettings.Instance.EntitledSlots)
+ {
+ return this.StatusCode(403, "");
+ }
slot.ResourceCollection += "," + slot.IconHash; // tells LBP to upload icon after we process resources here
@@ -84,9 +83,6 @@ public class PublishController : ControllerBase
// ReSharper disable once PossibleInvalidOperationException
User user = userAndToken.Value.Item1;
GameToken gameToken = userAndToken.Value.Item2;
-
- if (user.UsedSlots >= ServerSettings.Instance.EntitledSlots) return this.BadRequest();
-
Slot? slot = await this.getSlotFromBody();
if (slot?.Location == null) return this.BadRequest();
@@ -141,6 +137,11 @@ public class PublishController : ControllerBase
return this.Ok(oldSlot.Serialize(gameToken.GameVersion));
}
+ if (user.GetUsedSlotsForGame(gameToken.GameVersion, database) > ServerSettings.Instance.EntitledSlots)
+ {
+ return this.StatusCode(403, "");
+ }
+
//TODO: parse location in body
Location l = new()
{
From 81622441be21c064ad178d0db014a6a9bf64994b Mon Sep 17 00:00:00 2001
From: jvyden
Date: Mon, 21 Feb 2022 19:36:23 -0500
Subject: [PATCH 14/26] Move comment input bar to the top of the segment
Closes #170
---
.../Pages/Partials/CommentsPartial.cshtml | 31 +++++++++++--------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml b/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml
index 7d038558..a4a50ec2 100644
--- a/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml
+++ b/ProjectLighthouse/Pages/Partials/CommentsPartial.cshtml
@@ -1,7 +1,6 @@
@using System.IO
@using System.Web
@using LBPUnion.ProjectLighthouse.Types.Profiles
-