Remove some hacks.
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Aiursoft.ChessServer.Controllers;
|
||||
|
||||
[Route("challenges")]
|
||||
public class ChallengeController : ControllerBase
|
||||
{
|
||||
[HttpPost]
|
||||
[Route("create")]
|
||||
public IActionResult Create(Guid userId)
|
||||
{
|
||||
// Create a new challenge. Add to database.
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("list")]
|
||||
public IActionResult List()
|
||||
{
|
||||
// Show all public challenges.
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("accept/{id:int}")]
|
||||
public IActionResult Accept(int id, Guid userId)
|
||||
{
|
||||
// Accept a challenge. Remove the challenge from database.
|
||||
// Create a new game. Redirect both players to the game.
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("reject/{id:int}")]
|
||||
public IActionResult Edit(int id, Guid userId)
|
||||
{
|
||||
// If challenge owner is the same as user id,
|
||||
// Edit a challenge in database.
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,10 @@ public class HomeController : Controller
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var model = new IndexViewModel(_database.Challenges);
|
||||
var model = new IndexViewModel
|
||||
{
|
||||
Challenges = _database.GetPublicChallenges()
|
||||
};
|
||||
return View(model);
|
||||
}
|
||||
|
||||
@@ -29,17 +32,17 @@ public class HomeController : Controller
|
||||
public IActionResult Auto(Guid playerId)
|
||||
{
|
||||
// I created a challenge. Go to my challenge.
|
||||
var iHaveAChallenge = _database.Challenges.FirstOrDefault(t => t.Value.Creator.Id == playerId);
|
||||
if (iHaveAChallenge.Value != null)
|
||||
var myChallengeKey = _database.GetMyChallengeKey(playerId);
|
||||
if (myChallengeKey != null)
|
||||
{
|
||||
return RedirectToAction(nameof(Challenge), new { id = iHaveAChallenge.Key, playerId });
|
||||
return RedirectToAction(nameof(Challenge), new { id = (int)myChallengeKey, playerId });
|
||||
}
|
||||
|
||||
// Exists a public challenge. Go to that challenge.
|
||||
var otherChallenge = _database.Challenges.FirstOrDefault(t => t.Value.Permission == ChallengePermission.Public);
|
||||
if (otherChallenge.Value != null)
|
||||
var otherChallenge = _database.GetFirstPublicChallengeKey();
|
||||
if (otherChallenge != null)
|
||||
{
|
||||
return RedirectToAction(nameof(Challenge), new { id = otherChallenge.Key, playerId });
|
||||
return RedirectToAction(nameof(Challenge), new { id = (int)otherChallenge, playerId });
|
||||
}
|
||||
|
||||
// Create a new challenge.
|
||||
@@ -49,10 +52,10 @@ public class HomeController : Controller
|
||||
[HttpGet]
|
||||
public IActionResult Create(Guid playerId)
|
||||
{
|
||||
var iHaveAChallenge = _database.Challenges.FirstOrDefault(t => t.Value.Creator.Id == playerId);
|
||||
if (iHaveAChallenge.Value != null)
|
||||
var myChallengeKey = _database.GetMyChallengeKey(playerId);
|
||||
if (myChallengeKey != null)
|
||||
{
|
||||
return RedirectToAction(nameof(Challenge), new { id = iHaveAChallenge.Key, playerId });
|
||||
return RedirectToAction(nameof(Challenge), new { id = myChallengeKey, playerId });
|
||||
}
|
||||
var model = new CreateChallengeViewModel();
|
||||
return View(model);
|
||||
@@ -75,20 +78,21 @@ public class HomeController : Controller
|
||||
TimeLimit = model.TimeLimit,
|
||||
};
|
||||
var roomId = _counter.GetUniqueNo();
|
||||
_database.Challenges.TryAdd(roomId, challenge);
|
||||
return RedirectToAction(nameof(Challenge), new { id = roomId, playerId = model.CreatorId });
|
||||
_database.CreateChallenge(roomId, challenge);
|
||||
return RedirectToAction(nameof(Challenge), new { id = roomId });
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public IActionResult Challenge(int id, Guid playerId)
|
||||
public IActionResult Challenge(int id)
|
||||
{
|
||||
var player = _database.GetOrAddPlayer(playerId);
|
||||
var challenge = _database.GetOrAddChallenge(id, player);
|
||||
var model = new ChallengeViewModel()
|
||||
var challenge = _database.GetChallenge(id);
|
||||
if (challenge == null)
|
||||
{
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
var model = new ChallengeViewModel
|
||||
{
|
||||
RoomId = id,
|
||||
PlayerId = playerId,
|
||||
IsCreator = challenge.Creator.Id == playerId,
|
||||
};
|
||||
return View(model);
|
||||
}
|
||||
@@ -100,11 +104,10 @@ public class HomeController : Controller
|
||||
{
|
||||
return RedirectToAction(nameof(Challenge), new { id = model.Id, playerId = model.PlayerId });
|
||||
}
|
||||
var player = _database.GetOrAddPlayer(model.PlayerId);
|
||||
var challenge = _database.GetOrAddChallenge(model.Id, player);
|
||||
if (challenge.Creator.Id == model.PlayerId)
|
||||
var challenge = _database.GetChallenge(model.Id);
|
||||
if (challenge != null && challenge.Creator.Id == model.PlayerId)
|
||||
{
|
||||
_database.Challenges.TryRemove(model.Id, out _);
|
||||
_database.DeleteChallenge(model.Id);
|
||||
}
|
||||
return RedirectToAction(nameof(Index));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class InMemoryDatabase : ISingletonDependency
|
||||
|
||||
private ConcurrentDictionary<Guid, Player> Players { get; } = new();
|
||||
|
||||
public ConcurrentDictionary<int, Challenge> Challenges { get; } = new();
|
||||
private ConcurrentDictionary<int, Challenge> Challenges { get; } = new();
|
||||
|
||||
public GameContext[] GetActiveGames()
|
||||
{
|
||||
@@ -36,11 +36,66 @@ public class InMemoryDatabase : ISingletonDependency
|
||||
}
|
||||
}
|
||||
|
||||
public Challenge GetOrAddChallenge(int id, Player creator)
|
||||
public IReadOnlyCollection<KeyValuePair<int, Challenge>> GetPublicChallenges()
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
return Challenges.GetOrAdd(id, _ => new Challenge(creator));
|
||||
return Challenges
|
||||
.Where(t => t.Value.Permission == ChallengePermission.Public)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public Challenge? GetChallenge(int id)
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
return Challenges.GetValueOrDefault(id);
|
||||
}
|
||||
}
|
||||
|
||||
public int? GetMyChallengeKey(Guid playerId)
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
if (Challenges.All(t => t.Value.Creator.Id != playerId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Challenges
|
||||
.FirstOrDefault(t => t.Value.Creator.Id == playerId)
|
||||
.Key;
|
||||
}
|
||||
}
|
||||
|
||||
public int? GetFirstPublicChallengeKey()
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
return Challenges
|
||||
.FirstOrDefault(t => t.Value.Permission == ChallengePermission.Public)
|
||||
.Key;
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteChallenge(int id)
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
Challenges.TryRemove(id, out _);
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateChallenge(int id, Challenge challenge)
|
||||
{
|
||||
lock (Challenges)
|
||||
{
|
||||
var result = Challenges.TryAdd(id, challenge);
|
||||
if (!result)
|
||||
{
|
||||
throw new InvalidOperationException("Challenge already exists!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,4 +44,13 @@ public class Challenge
|
||||
public TimeSpan TimeLimit { get; set; } = TimeSpan.FromMinutes(10);
|
||||
|
||||
public ChallengePermission Permission { get; set; } = ChallengePermission.Public;
|
||||
|
||||
// Possible messages:
|
||||
// Player joined: p-joined-{player-nick-name}
|
||||
// Player left: p-left-{player-nick-name}
|
||||
// Room dropped: room-dropped
|
||||
// Game started: game-started
|
||||
// Creator transferred: creator-transferred-{new-owner-player-nick-name}
|
||||
// Settings changed: settings-changed
|
||||
public AsyncObservable<string> ChallengeChangedChannel { get; } = new();
|
||||
}
|
||||
@@ -2,9 +2,5 @@
|
||||
|
||||
public class ChallengeViewModel
|
||||
{
|
||||
public int RoomId { get; set; }
|
||||
|
||||
public Guid PlayerId { get; set; }
|
||||
|
||||
public bool IsCreator { get; set; }
|
||||
public int RoomId { get; init; }
|
||||
}
|
||||
@@ -4,10 +4,5 @@ namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class IndexViewModel
|
||||
{
|
||||
public ConcurrentDictionary<int, Challenge> Challenges { get; }
|
||||
|
||||
public IndexViewModel(ConcurrentDictionary<int, Challenge> challenges)
|
||||
{
|
||||
Challenges = challenges;
|
||||
}
|
||||
public required IReadOnlyCollection<KeyValuePair<int, Challenge>> Challenges { get; init; }
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
@model Aiursoft.ChessServer.Models.ChallengeViewModel
|
||||
@using Aiursoft.ChessServer.Controllers
|
||||
@model Aiursoft.ChessServer.Models.ChallengeViewModel
|
||||
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1 class="display-4">Waiting for joining...</h1>
|
||||
<p class="lead">Please share the link of this room to your friend!</p>
|
||||
@{
|
||||
var link = $"{Context.Request.Scheme}://{Context.Request.Host}/Home/Room/{Model.RoomId}";
|
||||
var link = $"{Context.Request.Scheme}://{Context.Request.Host}/Home/{nameof(HomeController.Challenge)}/{Model.RoomId}";
|
||||
}
|
||||
<form asp-controller="Home" asp-action="DropChallenge" asp-route-id="@Model.RoomId" method="post" class="d-inline" asp-antiforgery="false">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
<input type="hidden" name="playerId" value="@Model.PlayerId"/>
|
||||
<input type="hidden" name="playerId" value=""/>
|
||||
|
||||
<input type="text" class="form-control" value="@link" readonly>
|
||||
<a class="btn btn-secondary btn-lg mt-4" data-clipboard-text="@link" role="button" data-toggle="tooltip" data-placement="top" title="Copied!">
|
||||
@@ -24,6 +25,12 @@
|
||||
|
||||
@section scripts
|
||||
{
|
||||
<script type="module">
|
||||
import { getUserId } from "/scripts/player.js";
|
||||
const playerId = getUserId();
|
||||
const playerIdControl = document.querySelector('input[name="playerId"]');
|
||||
playerIdControl.value = playerId;
|
||||
</script>
|
||||
<script src="/node_modules/clipboard/dist/clipboard.min.js"></script>
|
||||
<script>
|
||||
// Initialize clipboard.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
<script type="module">
|
||||
import { getUserId } from "/scripts/player.js";
|
||||
const playerId = getUserId();
|
||||
if (playerId) {
|
||||
window.location.href = window.location.href.toLowerCase().replace("challengenoid", "Challenge") + `?playerId=${playerId}`;
|
||||
}
|
||||
</script>
|
||||
@@ -1,4 +1,5 @@
|
||||
@model Aiursoft.ChessServer.Models.IndexViewModel
|
||||
@using Aiursoft.ChessServer.Models
|
||||
@model Aiursoft.ChessServer.Models.IndexViewModel
|
||||
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
@@ -24,7 +25,7 @@
|
||||
<th>Creator</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
@foreach (var item in Model.Challenges)
|
||||
@foreach (var item in Model.Challenges.Where(t => t.Value.Permission == ChallengePermission.Public))
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Value.Message</td>
|
||||
|
||||
Reference in New Issue
Block a user