From af5871c1356a835ce3d5d5a44943e542cf97d3e4 Mon Sep 17 00:00:00 2001 From: jvyden Date: Wed, 6 Oct 2021 17:41:43 -0400 Subject: [PATCH] Allow profile card to be actually moved --- .../Controllers/UserController.cs | 52 ++++++++++++++++--- ProjectLighthouse/Types/User.cs | 2 +- 2 files changed, 47 insertions(+), 7 deletions(-) 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) +