108 lines
3.4 KiB
C#
108 lines
3.4 KiB
C#
using CharacterApi.Models;
|
|
using CharacterApi.Services;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Security.Claims;
|
|
|
|
namespace CharacterApi.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class CharactersController : ControllerBase
|
|
{
|
|
private readonly CharacterStore _characters;
|
|
private readonly LocationsClient _locations;
|
|
|
|
public CharactersController(CharacterStore characters, LocationsClient locations)
|
|
{
|
|
_characters = characters;
|
|
_locations = locations;
|
|
}
|
|
|
|
[HttpPost]
|
|
[Authorize(Roles = "USER,SUPER")]
|
|
public async Task<IActionResult> Create([FromBody] CreateCharacterRequest req)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(req.Name))
|
|
return BadRequest("Name required");
|
|
|
|
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
if (string.IsNullOrWhiteSpace(userId))
|
|
return Unauthorized();
|
|
|
|
var character = new Character
|
|
{
|
|
OwnerUserId = userId,
|
|
Name = req.Name.Trim(),
|
|
Coord = new Coord { X = 0, Y = 0 },
|
|
CreatedUtc = DateTime.UtcNow
|
|
};
|
|
|
|
await _characters.CreateAsync(character);
|
|
return Ok(character);
|
|
}
|
|
|
|
[HttpGet]
|
|
[Authorize(Roles = "USER,SUPER")]
|
|
public async Task<IActionResult> ListMine()
|
|
{
|
|
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
if (string.IsNullOrWhiteSpace(userId))
|
|
return Unauthorized();
|
|
|
|
var characters = await _characters.GetForOwnerAsync(userId);
|
|
return Ok(characters);
|
|
}
|
|
|
|
[HttpDelete("{id}")]
|
|
[Authorize(Roles = "USER,SUPER")]
|
|
public async Task<IActionResult> Delete(string id)
|
|
{
|
|
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
if (string.IsNullOrWhiteSpace(userId))
|
|
return Unauthorized();
|
|
|
|
var allowAnyOwner = User.IsInRole("SUPER");
|
|
var deleted = await _characters.DeleteForOwnerAsync(id, userId, allowAnyOwner);
|
|
if (!deleted)
|
|
return NotFound();
|
|
|
|
return Ok("Deleted");
|
|
}
|
|
|
|
[HttpPut("{id}/move")]
|
|
[Authorize(Roles = "USER,SUPER")]
|
|
public async Task<IActionResult> Move(string id, [FromBody] MoveCharacterRequest req, CancellationToken ct)
|
|
{
|
|
if (req?.Coord is null)
|
|
return BadRequest("Coord required");
|
|
|
|
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
if (string.IsNullOrWhiteSpace(userId))
|
|
return Unauthorized();
|
|
|
|
var allowAnyOwner = User.IsInRole("SUPER");
|
|
var existing = await _characters.GetForOwnerByIdAsync(id, userId, allowAnyOwner);
|
|
if (existing is null)
|
|
return NotFound();
|
|
|
|
var presence = await _locations.UpdatePresenceAsync(id, req.Coord, ct);
|
|
if (!presence.Ok)
|
|
{
|
|
var message = string.IsNullOrWhiteSpace(presence.Body)
|
|
? "Location presence update failed"
|
|
: presence.Body;
|
|
return StatusCode((int)presence.Status, message);
|
|
}
|
|
|
|
var updated = await _characters.UpdateCoordAsync(id, userId, allowAnyOwner, req.Coord);
|
|
if (!updated)
|
|
{
|
|
await _locations.UpdatePresenceAsync(id, existing.Coord, ct);
|
|
return StatusCode(500, "Failed to update character coord");
|
|
}
|
|
|
|
return Ok("Moved");
|
|
}
|
|
}
|