mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-05-20 16:22:27 +00:00
126 lines
No EOL
5.4 KiB
C#
126 lines
No EOL
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Xml;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using ProjectLighthouse.Types;
|
|
|
|
namespace ProjectLighthouse.Controllers {
|
|
[ApiController]
|
|
[Route("LITTLEBIGPLANETPS3_XML/")]
|
|
[Produces("text/xml")]
|
|
public class UserController : ControllerBase {
|
|
private readonly Database database;
|
|
public UserController(Database database) {
|
|
this.database = database;
|
|
}
|
|
|
|
[HttpGet("user/{username}")]
|
|
public async Task<IActionResult> GetUser(string username) {
|
|
User user = await database.Users
|
|
.Include(u => u.Location)
|
|
.FirstOrDefaultAsync(u => u.Username == username);
|
|
|
|
if(user == null) return this.NotFound();
|
|
return this.Ok(user.Serialize());
|
|
}
|
|
|
|
// [HttpPost("user/{username}")]
|
|
// public async Task<IActionResult> CreateUser(string username) {
|
|
// await new Database().CreateUser(username);
|
|
// return await GetUser(username);
|
|
// }
|
|
|
|
[HttpPost("updateUser")]
|
|
public async Task<IActionResult> UpdateUser() {
|
|
User user = await database.UserFromRequest(Request);
|
|
|
|
if(user == null) return this.StatusCode(403, "");
|
|
|
|
XmlReaderSettings settings = new() {
|
|
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)) {
|
|
List<string> path = new(); // you can think of this as a file path in the XML, like <updateUser> -> <location> -> <x>
|
|
while(await reader.ReadAsync()) {
|
|
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
|
|
switch(reader.NodeType) {
|
|
case XmlNodeType.Element:
|
|
path.Add(reader.Name);
|
|
break;
|
|
case XmlNodeType.Text:
|
|
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;
|
|
}
|
|
case "icon": {
|
|
user.IconHash = await reader.GetValueAsync();
|
|
break;
|
|
}
|
|
case "planets": {
|
|
user.PlanetHash = await reader.GetValueAsync();
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
case XmlNodeType.EndElement:
|
|
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
|
|
|
|
// 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();
|
|
}
|
|
|
|
[HttpPost("match")]
|
|
[Produces("text/json")]
|
|
public IActionResult Match() {
|
|
return this.Ok("[{\"StatusCode\":200}]");
|
|
}
|
|
}
|
|
} |