diff --git a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ScoreController.cs b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ScoreController.cs
index 79ae3163..8a859fd7 100644
--- a/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ScoreController.cs
+++ b/ProjectLighthouse.Servers.GameServer/Controllers/Slots/ScoreController.cs
@@ -5,6 +5,7 @@ using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.StorableLists.Stores;
using LBPUnion.ProjectLighthouse.Types.Entities.Level;
+using LBPUnion.ProjectLighthouse.Types.Entities.Profile;
using LBPUnion.ProjectLighthouse.Types.Entities.Token;
using LBPUnion.ProjectLighthouse.Types.Levels;
using LBPUnion.ProjectLighthouse.Types.Logging;
@@ -159,7 +160,7 @@ public class ScoreController : ControllerBase
await this.database.SaveChangesAsync();
- return this.Ok(await this.GetScores(new LeaderboardOptions
+ ScoreboardResponse scores = await this.GetScores(new LeaderboardOptions
{
RootName = "scoreboardSegment",
PageSize = 5,
@@ -169,7 +170,17 @@ public class ScoreController : ControllerBase
ScoreType = score.Type,
TargetUser = token.UserId,
TargetPlayerIds = null,
- }));
+ });
+
+ if (score.Type == 1 && scores.YourRank == 1 && scores.Total > 1)
+ {
+ GameScore? second = scores.Scores[1];
+ UserEntity? user = await this.database.UserFromGameToken(token);
+
+ await this.database.SendNotification(second.UserId, $"{user?.InfoXml} beat your highscore ({second.Points}) on {slot.InfoXml} with a score of {score.Points}.", true);
+ }
+
+ return this.Ok(scores);
}
[HttpGet("scoreboard/{slotType}/{id:int}")]
diff --git a/ProjectLighthouse/Database/DatabaseContext.Notifications.cs b/ProjectLighthouse/Database/DatabaseContext.Notifications.cs
index 8fefaec8..d22af72e 100644
--- a/ProjectLighthouse/Database/DatabaseContext.Notifications.cs
+++ b/ProjectLighthouse/Database/DatabaseContext.Notifications.cs
@@ -15,9 +15,10 @@ public partial class DatabaseContext
///
/// The user ID of the target user.
/// The message to send.
+ /// Prepend server name/timestamp.
/// The for the notification. Defaults to ModerationNotification.
public async Task SendNotification
- (int userId, string text, NotificationType type = NotificationType.ModerationNotification)
+ (int userId, string text, bool prefix = true, NotificationType type = NotificationType.ModerationNotification)
{
if (!await this.Users.AnyAsync(u => u.UserId == userId))
{
@@ -31,15 +32,19 @@ public partial class DatabaseContext
StringBuilder builder = new(text);
- // Prepend server name to notification text if enabled
- if (ServerConfiguration.Instance.NotificationConfiguration.ShowServerNameInText)
+ if (prefix)
{
- builder.Insert(0, $"[{ServerConfiguration.Instance.Customization.ServerName}] ");
- }
- // Prepend timestamp to notification text if enabled
- if (ServerConfiguration.Instance.NotificationConfiguration.ShowTimestampInText)
- {
- builder.Insert(0, $"[{DateTime.Now:g}] ");
+ // Prepend server name to notification text if enabled
+ if (ServerConfiguration.Instance.NotificationConfiguration.ShowServerNameInText)
+ {
+ builder.Insert(0, $"[{ServerConfiguration.Instance.Customization.ServerName}] ");
+ }
+
+ // Prepend timestamp to notification text if enabled
+ if (ServerConfiguration.Instance.NotificationConfiguration.ShowTimestampInText)
+ {
+ builder.Insert(0, $"[{DateTime.Now:g}] ");
+ }
}
NotificationEntity notification = new()
diff --git a/ProjectLighthouse/Types/Entities/Level/SlotEntity.cs b/ProjectLighthouse/Types/Entities/Level/SlotEntity.cs
index 693bf4aa..07d65c04 100644
--- a/ProjectLighthouse/Types/Entities/Level/SlotEntity.cs
+++ b/ProjectLighthouse/Types/Entities/Level/SlotEntity.cs
@@ -29,6 +29,13 @@ public class SlotEntity
public string IconHash { get; set; } = "";
+ ///
+ /// Markup that displays the level name next to its badge.
+ /// This can be used everywhere markup works ingame, e.g. news or notifications
+ ///
+ [NotMapped]
+ public string InfoXml => $"{this.Name}";
+
public bool IsAdventurePlanet { get; set; }
public string RootLevel { get; set; } = "";
diff --git a/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs b/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
index 998c63b8..6fb65301 100644
--- a/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
+++ b/ProjectLighthouse/Types/Entities/Profile/UserEntity.cs
@@ -28,6 +28,13 @@ public class UserEntity
public string IconHash { get; set; }
+ ///
+ /// Markup that displays the username next to a polaroid with the user's icon.
+ /// This can be used everywhere markup works ingame, e.g. news or notifications
+ ///
+ [NotMapped]
+ public string InfoXml => $"{this.Username}";
+
///
/// A user-customizable biography shown on the profile card
///