diff --git a/ProjectLighthouse.sln.DotSettings b/ProjectLighthouse.sln.DotSettings
index 698d69e9..cd0a7049 100644
--- a/ProjectLighthouse.sln.DotSettings
+++ b/ProjectLighthouse.sln.DotSettings
@@ -72,6 +72,7 @@
UseExplicitType
UseExplicitType
MM
+ NP
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy>
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
@@ -97,6 +98,7 @@
True
True
True
+ True
True
True
True
diff --git a/ProjectLighthouse/Controllers/FriendsController.cs b/ProjectLighthouse/Controllers/FriendsController.cs
new file mode 100644
index 00000000..6cd14fce
--- /dev/null
+++ b/ProjectLighthouse/Controllers/FriendsController.cs
@@ -0,0 +1,92 @@
+#nullable enable
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+using LBPUnion.ProjectLighthouse.Helpers;
+using LBPUnion.ProjectLighthouse.Serialization;
+using LBPUnion.ProjectLighthouse.Types;
+using LBPUnion.ProjectLighthouse.Types.Profiles;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace LBPUnion.ProjectLighthouse.Controllers
+{
+ [ApiController]
+ [Route("LITTLEBIGPLANETPS3_XML/")]
+ public class FriendsController : ControllerBase
+ {
+ private readonly Database database;
+
+ public FriendsController(Database database)
+ {
+ this.database = database;
+ }
+
+ [HttpPost("npdata")]
+ public async Task NPData()
+ {
+ User? user = await this.database.UserFromRequest(this.Request);
+ if (user == null) return this.StatusCode(403, "");
+
+ this.Request.Body.Position = 0;
+ string bodyString = await new StreamReader(this.Request.Body).ReadToEndAsync();
+
+ XmlSerializer serializer = new(typeof(NPData));
+ NPData? npData = (NPData?)serializer.Deserialize(new StringReader(bodyString));
+ if (npData == null) return this.BadRequest();
+
+ List friends = new();
+ foreach (string friendName in npData.Friends)
+ {
+ User? friend = await this.database.Users.FirstOrDefaultAsync(u => u.Username == friendName);
+ if (friend == null) continue;
+
+ friends.Add(friend.UserId);
+ }
+
+ List blockedUsers = new();
+ foreach (string blockedUserName in npData.BlockedUsers)
+ {
+ User? blockedUser = await this.database.Users.FirstOrDefaultAsync(u => u.Username == blockedUserName);
+ if (blockedUser == null) continue;
+
+ blockedUsers.Add(blockedUser.UserId);
+ }
+
+ if (FriendHelper.FriendIdsByUserId.ContainsKey(user.UserId))
+ {
+ FriendHelper.FriendIdsByUserId.Remove(user.UserId);
+ FriendHelper.BlockedIdsByUserId.Remove(user.UserId);
+ }
+
+ FriendHelper.FriendIdsByUserId.Add(user.UserId, friends.ToArray());
+ FriendHelper.BlockedIdsByUserId.Add(user.UserId, blockedUsers.ToArray());
+
+ return this.Ok();
+ }
+
+ [HttpGet("myFriends")]
+ public async Task MyFriends()
+ {
+ User? user = await this.database.UserFromRequest(this.Request);
+ if (user == null) return this.StatusCode(403, "");
+
+ if (!FriendHelper.FriendIdsByUserId.TryGetValue(user.UserId, out int[]? friendIds) || friendIds == null)
+ {
+ return this.NotFound();
+ }
+
+ string friends = "";
+ foreach (int friendId in friendIds)
+ {
+ User? friend = await this.database.Users.Include(u => u.Location).FirstOrDefaultAsync(u => u.UserId == friendId);
+ if (friend == null) continue;
+
+ friends += friend.Serialize();
+ }
+
+ return this.Ok(LbpSerializer.StringElement("myFriends", friends));
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/FriendHelper.cs b/ProjectLighthouse/Helpers/FriendHelper.cs
new file mode 100644
index 00000000..9475e582
--- /dev/null
+++ b/ProjectLighthouse/Helpers/FriendHelper.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace LBPUnion.ProjectLighthouse.Helpers
+{
+ [NotMapped]
+ public static class FriendHelper
+ {
+ public static Dictionary FriendIdsByUserId = new();
+ public static Dictionary BlockedIdsByUserId = new();
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Types/Profiles/NPData.cs b/ProjectLighthouse/Types/Profiles/NPData.cs
new file mode 100644
index 00000000..a117d6bf
--- /dev/null
+++ b/ProjectLighthouse/Types/Profiles/NPData.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace LBPUnion.ProjectLighthouse.Types.Profiles
+{
+ [XmlRoot("npdata")]
+ [XmlType("npdata")]
+ public class NPData
+ {
+ [XmlArray("friends")]
+ [XmlArrayItem("npHandle")]
+ public List Friends { get; set; }
+
+ [XmlArray("blocked")]
+ [XmlArrayItem("npHandle")]
+ public List BlockedUsers { get; set; }
+ }
+}
\ No newline at end of file