diff --git a/ProjectLighthouse/Controllers/UserController.cs b/ProjectLighthouse/Controllers/UserController.cs
index 48c1fec1..790f1c32 100644
--- a/ProjectLighthouse/Controllers/UserController.cs
+++ b/ProjectLighthouse/Controllers/UserController.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
@@ -35,32 +36,71 @@ namespace ProjectLighthouse.Controllers {
if(user == null) return this.BadRequest();
XmlReaderSettings settings = new() {
- Async = true
+ Async = true // this is apparently not default
};
+ bool locationChanged = false;
+
+ // this is an absolute mess, but necessary because LBP only sends what changed
+ //
+ // example for changing profile card location:
+ //
+ //
+ // 1234
+ // 1234
+ //
+ //
+ //
+ // example for changing biography:
+ //
+ // biography stuff
+ //
+ //
+ // if you find a way to make it not stupid feel free to replace this
using(XmlReader reader = XmlReader.Create(Request.Body, settings)) {
- string currentElement = "";
+ List path = new(); // you can think of this as a file path in the XML, like -> ->
while(await reader.ReadAsync()) {
switch(reader.NodeType) {
case XmlNodeType.Element:
- currentElement = reader.Name;
+ path.Add(reader.Name);
break;
case XmlNodeType.Text:
- switch(currentElement) {
+ switch(path[1]) {
case "biography": {
user.Biography = await reader.GetValueAsync();
break;
}
+ case "location": {
+ locationChanged = true; // if we're here then we're probably about to change the location.
+ // ReSharper disable once ConvertIfStatementToSwitchStatement
+ if(path[2] == "x") {
+ user.Location.X = Convert.ToInt32(await reader.GetValueAsync()); // GetValue only returns a string, i guess we just hope its a number lol
+ } else if(path[2] == "y") {
+ user.Location.Y = Convert.ToInt32(await reader.GetValueAsync());
+ }
+ break;
+ }
}
break;
case XmlNodeType.EndElement:
- currentElement = "";
+ path.RemoveAt(path.Count - 1);
break;
}
}
}
+
+ // the way location on a user card works is stupid and will not save with the way below as-is, so we do the following:
+ if(locationChanged) { // only modify the database if we modify here
+ Location l = await database.Locations.Where(l => l.Id == user.LocationId).FirstOrDefaultAsync(); // find the location in the database again
- if(database.ChangeTracker.HasChanges()) await database.SaveChangesAsync();
+ // set the location in the database to the one we modified above
+ l.X = user.Location.X;
+ l.Y = user.Location.Y;
+
+ // now both are in sync, and will update in the database.
+ }
+
+ if(database.ChangeTracker.HasChanges()) await database.SaveChangesAsync(); // save the user to the database if we changed anything
return this.Ok();
}
}
diff --git a/ProjectLighthouse/Types/User.cs b/ProjectLighthouse/Types/User.cs
index cd7af5ca..c269268e 100644
--- a/ProjectLighthouse/Types/User.cs
+++ b/ProjectLighthouse/Types/User.cs
@@ -100,7 +100,7 @@ namespace ProjectLighthouse.Types {
LbpSerializer.StringElement("photosByMeCount", this.PhotosByMeCount) +
LbpSerializer.StringElement("photosWithMeCount", this.PhotosWithMeCount) +
LbpSerializer.StringElement("commentsEnabled", this.CommentsEnabled) +
- this.Location.Serialize() +
+ LbpSerializer.StringElement("location", this.Location.Serialize()) +
LbpSerializer.StringElement("favouriteSlotCount", this.FavouriteSlotCount) +
LbpSerializer.StringElement("favouriteUserCount", this.FavouriteUserCount) +
LbpSerializer.StringElement("lolcatftwCount", this.lolcatftwCount) +