Files
Radicade/Server/Avatars/EquipmentV1.cs
T
2026-10-16 23:33:13 -07:00

169 lines
5.9 KiB
C#

using System.Text.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RadicadeServer.DB;
using RadicadeServer.Extensions;
using RadicadeServer.RecNet.Accounts;
using RadicadeServer.RecNet.Avatar;
namespace RadicadeServer.API.Avatars.V1;
[Route("api/equipment/v1")]
[Route("econ/api/equipment/v1")]
[Authorize]
public class EquipmentV1(RecDBContext db) : Controller
{
[HttpPost("update")]
[HttpPut("update")]
public async Task<IActionResult> UpdateEquipment([FromBody] JsonElement body)
{
var userId = User.GetUserId();
if (userId == null) return Unauthorized();
if (!TryParse(body, out var entries))
return BadRequest();
var slots = entries.Where(entry => entry.HasSlot).ToList();
var favourites = entries.Where(entry => entry.Favorited.HasValue).ToList();
if (slots.Count == 0 && favourites.Count == 0)
return Ok();
if (slots.Count > 0)
{
var avatar = await db.Avatars.FirstOrDefaultAsync(x => x.AccountId == userId);
if (avatar != null)
{
avatar.EquipmentSlots = slots.Select(entry => (object)new
{
slotIndex = entry.SlotIndex,
equipmentPrefabName = entry.PrefabName ?? string.Empty,
equipmentModificationGuid = entry.ModificationGuid ?? string.Empty
}).ToList().ToJson();
}
}
if (favourites.Count > 0)
await ApplyFavouritesAsync(userId.Value, favourites);
await db.SaveChangesAsync();
return Ok();
}
private async Task ApplyFavouritesAsync(long userId, List<EquipmentUpdate> favourites)
{
var unlocks = await db.Unlocks.FirstOrDefaultAsync(x => x.AccountId == userId);
if (unlocks == null)
{
unlocks = new PlayerUnlocks { AccountId = userId };
db.Unlocks.Add(unlocks);
}
List<Equipment> equipment;
try
{
equipment = unlocks.GetEquipment() ?? new List<Equipment>();
}
catch (JsonException)
{
equipment = new List<Equipment>();
}
foreach (var update in favourites)
{
if (string.IsNullOrWhiteSpace(update.ModificationGuid)) continue;
var row = equipment.FirstOrDefault(item => string.Equals(
item.ModificationGuid, update.ModificationGuid, StringComparison.OrdinalIgnoreCase));
if (row == null)
{
continue;
}
row.Favorited = update.Favorited == true;
}
unlocks.Equipment = equipment.ToJson();
}
private sealed class EquipmentUpdate
{
public string? PrefabName { get; set; }
public string? ModificationGuid { get; set; }
public bool? Favorited { get; set; }
public int SlotIndex { get; set; }
public bool HasSlot { get; set; }
}
private static bool TryParse(JsonElement body, out List<EquipmentUpdate> entries)
{
entries = new List<EquipmentUpdate>();
JsonElement array;
if (body.ValueKind == JsonValueKind.Array)
{
array = body;
}
else if (body.ValueKind == JsonValueKind.Object)
{
var found = false;
array = default;
foreach (var prop in body.EnumerateObject())
{
if (string.Equals(prop.Name, "equipmentSlots", StringComparison.OrdinalIgnoreCase)
&& prop.Value.ValueKind == JsonValueKind.Array)
{
array = prop.Value;
found = true;
break;
}
}
if (!found) return false;
}
else
{
return false;
}
foreach (var item in array.EnumerateArray())
{
if (item.ValueKind != JsonValueKind.Object) continue;
var entry = new EquipmentUpdate();
foreach (var prop in item.EnumerateObject())
{
if (string.Equals(prop.Name, "slotIndex", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "slot", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "index", StringComparison.OrdinalIgnoreCase))
{
if (prop.Value.ValueKind == JsonValueKind.Number) entry.SlotIndex = prop.Value.GetInt32();
entry.HasSlot = true;
}
else if (string.Equals(prop.Name, "favorited", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "favourite", StringComparison.OrdinalIgnoreCase))
{
if (prop.Value.ValueKind == JsonValueKind.True) entry.Favorited = true;
else if (prop.Value.ValueKind == JsonValueKind.False) entry.Favorited = false;
}
else if (string.Equals(prop.Name, "modificationGuid", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "equipmentModificationGuid", StringComparison.OrdinalIgnoreCase))
{
if (prop.Value.ValueKind == JsonValueKind.String) entry.ModificationGuid = prop.Value.GetString();
}
else if (string.Equals(prop.Name, "prefabName", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "equipmentPrefabName", StringComparison.OrdinalIgnoreCase)
|| string.Equals(prop.Name, "equipment", StringComparison.OrdinalIgnoreCase))
{
if (prop.Value.ValueKind == JsonValueKind.String) entry.PrefabName = prop.Value.GetString();
}
}
entries.Add(entry);
}
return true;
}
}