Files
2026-10-16 23:33:13 -07:00

76 lines
2.5 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RadicadeServer.DB;
using RadicadeServer.Extensions;
using RadicadeServer.RecNet.Royale;
namespace RadicadeServer.API.Royale.V2
{
[Route("api/royale/v2")]
public class RoyaleV2(RecDBContext db) : Controller
{
private static int PlacementXp(int rank)
{
if (rank <= 0) return 10;
if (rank == 1) return 50;
if (rank <= 3) return 30;
if (rank <= 8) return 15;
return 10;
}
[HttpPost("matchcomplete"), Authorize]
public async Task<ActionResult<RoyaleMatchCompleteResponse>> MatchComplete([FromBody] RoyaleMatchCompleteStats? stats)
{
var userId = User.GetUserId();
if (userId == null) return Unauthorized();
if (stats == null) return BadRequest();
var awardStrings = new List<string>();
int totalXp = 0;
if (!stats.CustomGame)
{
int placement = PlacementXp(stats.Rank);
totalXp += placement;
awardStrings.Add($"Match finished: +{placement} XP");
if (stats.NumEliminations > 0)
{
int elimXp = Math.Min(stats.NumEliminations, 5) * 10;
totalXp += elimXp;
awardStrings.Add($"Eliminations: +{elimXp} XP");
}
if (stats.ChestsOpened > 0)
{
int chestXp = Math.Min(stats.ChestsOpened, 10) * 2;
totalXp += chestXp;
awardStrings.Add($"Chests opened: +{chestXp} XP");
}
}
else
{
awardStrings.Add("Custom game: no XP awarded");
}
long xpBefore = await CurrentXp(userId.Value);
var progress = await RoyaleShared.AwardXpAsync(db, userId.Value, totalXp, "Rec Royale match", awardStrings);
var response = new RoyaleMatchCompleteResponse
{
XPAwardStrings = awardStrings,
TotalXPAwarded = progress.TotalXP - xpBefore,
NewProgress = new List<RoyaleProgressDTO> { progress }
};
return Ok(response);
}
private async Task<long> CurrentXp(long playerId)
{
var data = await db.Progression.AsNoTracking().FirstOrDefaultAsync(x => x.PlayerId == playerId);
return data?.XP ?? 0;
}
}
}