Allow profile card to be actually moved

This commit is contained in:
jvyden 2021-10-06 17:41:43 -04:00
parent b2428b6ba8
commit af5871c135
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
2 changed files with 47 additions and 7 deletions

View file

@ -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:
// <updateUser>
// <location>
// <x>1234</x>
// <y>1234</y>
// </location>
// </updateUser>
//
// example for changing biography:
// <updateUser>
// <biography>biography stuff</biography>
// </updateUser>
//
// 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<string> path = new(); // you can think of this as a file path in the XML, like <updateUser> -> <location> -> <x>
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();
}
}

View file

@ -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) +