mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 15:38:45 -07:00
4edf25b2d5
Targets Rec Room 2020.12.18 client.
Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces the dorknet-clientpatch-{key}.zip
Release asset the launcher fetches.
- .github/workflows/release.yml — auto-publishes both Release assets
on v1-december-* tag push.
Scrubbed via maintainer-side scrub-for-public.ps1: same drop rules as
the prior import, plus build-patcher-zip.ps1 added to the tools/
allow-list so it survives the scrub.
70 lines
2.4 KiB
C#
70 lines
2.4 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using DorkNet.Server.Auth;
|
|
using DorkNet.Server.Data;
|
|
using DorkNet.Server.Data.Entities;
|
|
|
|
namespace DorkNet.Server.Controllers.API.PlayerElo;
|
|
|
|
/// <summary>
|
|
/// api.rec.net/api/PlayerElo/* — match-result Elo deltas. The 2020
|
|
/// client posts after each ranked match (Royale, Paintball, Soccer)
|
|
/// with a delta the server applies to the per-player Elo row.
|
|
///
|
|
/// Wire request matches <c>RecNet.Elo.ReportPlayerElo</c>:
|
|
/// <c>{GameMode(int), EloDelta(int), Won(bool)}</c>
|
|
/// (we tolerate a few synonym fields). Response: the new Elo as a
|
|
/// JSON primitive int.
|
|
/// </summary>
|
|
[ApiController]
|
|
public class PlayerEloController(DorkNetDbContext db) : ControllerBase
|
|
{
|
|
private long Me => this.RequireCurrentPlayerId();
|
|
|
|
public sealed class ReportEloRequest
|
|
{
|
|
public int GameMode { get; set; }
|
|
public int EloDelta { get; set; }
|
|
public bool Won { get; set; }
|
|
}
|
|
|
|
[HttpPost("api/PlayerElo/v1/reportPlayerElo")]
|
|
[Authorize]
|
|
public async Task<IActionResult> ReportPlayerElo([FromBody] ReportEloRequest req)
|
|
{
|
|
var pid = Me;
|
|
var row = await db.PlayerElo.FirstOrDefaultAsync(p =>
|
|
p.PlayerId == pid && p.GameMode == req.GameMode);
|
|
if (row is null)
|
|
{
|
|
row = new PlayerEloEntity
|
|
{
|
|
PlayerId = pid,
|
|
GameMode = req.GameMode,
|
|
};
|
|
db.PlayerElo.Add(row);
|
|
}
|
|
// Clamp Elo to a reasonable range to avoid overflow exploits.
|
|
row.Elo = Math.Clamp(row.Elo + req.EloDelta, 0, 5000);
|
|
row.MatchesPlayed += 1;
|
|
if (req.Won) row.Wins += 1; else row.Losses += 1;
|
|
row.UpdatedAt = DateTime.UtcNow;
|
|
await db.SaveChangesAsync();
|
|
return Ok(row.Elo);
|
|
}
|
|
|
|
[HttpGet("api/PlayerElo/v1/get")]
|
|
public async Task<IActionResult> Get(
|
|
[FromQuery] long? playerId, [FromQuery] int gameMode = 0)
|
|
{
|
|
var pid = playerId ?? this.CurrentPlayerId() ?? 0;
|
|
if (pid == 0) return Ok(new { Elo = 1000, Wins = 0, Losses = 0 });
|
|
var row = await db.PlayerElo.FirstOrDefaultAsync(p =>
|
|
p.PlayerId == pid && p.GameMode == gameMode);
|
|
return Ok(row is null
|
|
? new { Elo = 1000, Wins = 0, Losses = 0 }
|
|
: new { row.Elo, row.Wins, row.Losses });
|
|
}
|
|
}
|