More index features.
This commit is contained in:
@@ -1,11 +1,59 @@
|
||||
using Aiursoft.ChessServer.Data;
|
||||
using Aiursoft.ChessServer.Models;
|
||||
using Aiursoft.CSTools.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Aiursoft.ChessServer.Controllers;
|
||||
|
||||
public class HomeController : ControllerBase
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly Counter _counter;
|
||||
private readonly InMemoryDatabase _database;
|
||||
|
||||
public HomeController(
|
||||
Counter counter,
|
||||
InMemoryDatabase database)
|
||||
{
|
||||
_counter = counter;
|
||||
_database = database;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return this.Ok("Welcome to chess server! Please go to '/games/12345.json' to view more.");
|
||||
var model = new IndexViewModel(_database.Challenges);
|
||||
return View(model);
|
||||
}
|
||||
}
|
||||
|
||||
public IActionResult Create(Guid playerId)
|
||||
{
|
||||
var iHaveAChallenge = _database.Challenges.FirstOrDefault(t => t.Value.Creator.Id == playerId);
|
||||
if (iHaveAChallenge.Value != null)
|
||||
{
|
||||
return RedirectToAction(nameof(Room), new { id = iHaveAChallenge.Key });
|
||||
}
|
||||
var model = new CreateChallengeViewModel();
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult Create(CreateChallengeViewModel model)
|
||||
{
|
||||
var player = _database.GetOrAddPlayer(model.CreatorId);
|
||||
var challenge = new Challenge(player)
|
||||
{
|
||||
RoleRule = model.RoleRule,
|
||||
Message = model.Message,
|
||||
Permission = model.Permission,
|
||||
TimeLimit = model.TimeLimit,
|
||||
};
|
||||
var uniqueId = _counter.GetUniqueNo();
|
||||
_database.Challenges.TryAdd(uniqueId, challenge);
|
||||
return RedirectToAction(nameof(Room), new { id = uniqueId });
|
||||
}
|
||||
|
||||
public IActionResult Room(int id)
|
||||
{
|
||||
// Not implemented.
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ public class InMemoryDatabase : ISingletonDependency
|
||||
private ConcurrentDictionary<int, Game> Games { get; } = new();
|
||||
|
||||
private ConcurrentDictionary<Guid, Player> Players { get; } = new();
|
||||
|
||||
public ConcurrentDictionary<int, Challenge> Challenges { get; } = new();
|
||||
|
||||
public GameContext[] GetActiveGames()
|
||||
{
|
||||
|
||||
@@ -27,9 +27,17 @@ public enum ChallengePermission
|
||||
|
||||
public class Challenge
|
||||
{
|
||||
public Guid CreatorId { get; set; }
|
||||
public Challenge(Player creator)
|
||||
{
|
||||
Creator = creator;
|
||||
}
|
||||
|
||||
public Guid? AccepterId { get; set; } = null;
|
||||
public Player Creator { get; set; }
|
||||
public string Message { get; set; } = "A chess room.";
|
||||
|
||||
public Player? Accepter { get; set; } = null;
|
||||
|
||||
public Game? Game { get; set; } = null;
|
||||
|
||||
public RoleRule RoleRule { get; set; } = RoleRule.Random;
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class CreateChallengeViewModel
|
||||
{
|
||||
public Guid CreatorId { get; set; }
|
||||
|
||||
public string Message { get; set; } = "A chess room.";
|
||||
|
||||
public RoleRule RoleRule { get; set; } = RoleRule.Random;
|
||||
|
||||
public TimeSpan TimeLimit { get; set; } = TimeSpan.FromMinutes(10);
|
||||
|
||||
public ChallengePermission Permission { get; set; } = ChallengePermission.Public;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class IndexViewModel
|
||||
{
|
||||
public ConcurrentDictionary<int, Challenge> Challenges { get; }
|
||||
|
||||
public IndexViewModel(ConcurrentDictionary<int, Challenge> challenges)
|
||||
{
|
||||
Challenges = challenges;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
@model Aiursoft.ChessServer.Models.CreateChallengeViewModel
|
||||
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1 class="display-4">Create a new room</h1>
|
||||
<p class="lead">Enter your room name and start a new game!</p>
|
||||
<p>
|
||||
<a class="btn btn-secondary btn-lg mt-4" asp-controller="Home" asp-action="Index">Back to list</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mt-4" id="functions">
|
||||
<div class="row no-gutters">
|
||||
<div class="card mb-2 col-sm-12 px-1">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Create a new room</h5>
|
||||
<form asp-controller="Home" asp-action="Create" method="post">
|
||||
<input type="hidden" asp-for="CreatorId"/>
|
||||
<div class="form-group">
|
||||
<label asp-for="Message"></label>
|
||||
<input asp-for="Message" class="form-control"/>
|
||||
<span asp-validation-for="Message" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="RoleRule"></label>
|
||||
<select asp-for="RoleRule" class="form-control">
|
||||
<option value="Random">Random</option>
|
||||
<option value="CreatorWhite">Creator White</option>
|
||||
<option value="AccepterWhite">Accepter White</option>
|
||||
</select>
|
||||
<span asp-validation-for="RoleRule" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="TimeLimit"></label>
|
||||
<select asp-for="TimeLimit" class="form-control">
|
||||
<option value="00:01:00">1 minutes</option>
|
||||
<option value="00:03:00">3 minutes</option>
|
||||
<option value="00:05:00">5 minutes</option>
|
||||
<option value="00:10:00">10 minutes</option>
|
||||
<option value="00:15:00">15 minutes</option>
|
||||
<option value="00:30:00">30 minutes</option>
|
||||
<option value="01:00:00">1 hour</option>
|
||||
<option value="02:00:00">2 hours</option>
|
||||
</select>
|
||||
<span asp-validation-for="TimeLimit" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label asp-for="Permission"></label>
|
||||
<select asp-for="Permission" class="form-control">
|
||||
<option value="Public">Public</option>
|
||||
<option value="Unlisted">Unlisted</option>
|
||||
</select>
|
||||
<span asp-validation-for="Permission" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section scripts
|
||||
{
|
||||
<script type="module">
|
||||
import { getUserId } from "/scripts/player.js";
|
||||
const playerId = getUserId();
|
||||
const hiddenInput = document.querySelector("#CreatorId");
|
||||
|
||||
if (playerId) {
|
||||
hiddenInput.value = playerId;
|
||||
}
|
||||
</script>
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
@model Aiursoft.ChessServer.Models.IndexViewModel
|
||||
|
||||
<div class="jumbotron">
|
||||
<div class="container">
|
||||
<h1 class="display-4">Welcome challenger!</h1>
|
||||
<p class="lead">Join a room, or create a room!</p>
|
||||
<p>
|
||||
<button class="btn btn-success btn-lg mt-4" role="button">Auto join</button>
|
||||
<a class="btn btn-secondary btn-lg mt-4" role="button" id="createButton" asp-controller="Home" asp-action="Create">Create a new room</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container mt-4">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-sm-12 px-1">
|
||||
<div class="card mb-2 tests-card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Public games</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover table-sm" id="logTable">
|
||||
<tr>
|
||||
<th>Room Name</th>
|
||||
<th>Creator</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
@foreach (var item in Model.Challenges)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.Value.Message</td>
|
||||
<td>@item.Value.Creator.NickName</td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-primary" data-room-id="@item.Key">Join</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section scripts
|
||||
{
|
||||
<script type="module">
|
||||
import { getUserId } from "/scripts/player.js";
|
||||
const createButton = document.getElementById("createButton");
|
||||
const playerId = getUserId();
|
||||
|
||||
// Append player id to create button.
|
||||
if (playerId) {
|
||||
createButton.href += `?playerId=${playerId}`;
|
||||
}
|
||||
</script>
|
||||
}
|
||||
@@ -2,69 +2,69 @@
|
||||
<html lang="en" class="h-100">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<link rel="icon" type="image/x-icon" href="~/favicon.ico" />
|
||||
<link rel="icon" type="image/x-icon" href="~/favicon.ico"/>
|
||||
<title>Game - Aiursoft Chess Server</title>
|
||||
<link rel="stylesheet" href="~/node_modules/bootstrap/dist/css/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="~/node_modules/@@aiursoft/autodark.js/dist/css/autodark.min.css" />
|
||||
<link rel="stylesheet" href="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.css" />
|
||||
<link rel="stylesheet" href="~/node_modules/bootstrap/dist/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="~/node_modules/@@aiursoft/autodark.js/dist/css/autodark.min.css"/>
|
||||
<link rel="stylesheet" href="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.css"/>
|
||||
</head>
|
||||
|
||||
<body class="d-flex flex-column h-100 pt-5">
|
||||
<header>
|
||||
<nav class="navbar fixed-top navbar-expand-md mb-3">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="https://www.aiursoft.cn">
|
||||
Aiursoft
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
||||
<header>
|
||||
<nav class="navbar fixed-top navbar-expand-md mb-3">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="https://www.aiursoft.cn">
|
||||
Aiursoft
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault"
|
||||
aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" asp-controller="Home" asp-action="Index">Chess</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-inline">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" asp-controller="Home" asp-action="Index">Chess</a>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" title="Manage" id="player-nick-name" href="#">未登录</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
|
||||
<i class="fab fa-gitlab"></i>
|
||||
View on GitLab
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-inline">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" title="Manage" id="player-nick-name" href="#">未登录</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
|
||||
<i class="fab fa-gitlab"></i>
|
||||
View on GitLab
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="container mt-5">
|
||||
<main role="main" class="pb-3">
|
||||
@RenderBody()
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<footer class="footer mt-auto py-3">
|
||||
<div class="container">
|
||||
© @DateTime.UtcNow.Year - Aiursoft.ChessServer - <a
|
||||
href="https://gitlab.aiursoft.cn/aiursoft/chessserver">GitLab</a>
|
||||
</div>
|
||||
</footer>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<script type="module" src="~/node_modules/jquery/dist/jquery.min.js" defer></script>
|
||||
<script type="module" src="~/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
|
||||
<script type="module" src="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.js" defer></script>
|
||||
<script type="module" src="~/scripts/layout.js" defer></script>
|
||||
@(await RenderSectionAsync("scripts", false))
|
||||
@RenderBody()
|
||||
|
||||
<footer class="footer mt-auto py-3">
|
||||
<div class="container">
|
||||
© @DateTime.UtcNow.Year - Aiursoft.ChessServer -
|
||||
<a
|
||||
href="https://gitlab.aiursoft.cn/aiursoft/chessserver">
|
||||
GitLab
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="module" src="~/node_modules/jquery/dist/jquery.min.js" defer></script>
|
||||
<script type="module" src="~/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" defer></script>
|
||||
<script type="module" src="~/node_modules/@@chrisoakman/chessboardjs/dist/chessboard-1.0.0.min.js" defer></script>
|
||||
<script type="module" src="~/scripts/layout.js" defer></script>
|
||||
@(await RenderSectionAsync("scripts", false))
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -22,4 +22,4 @@ const changeName = async function (newName) {
|
||||
await fetch(`/players/${getUserId()}/new-name/${newName}`, { method: 'PUT' });
|
||||
}
|
||||
|
||||
export { getUserName, changeName };
|
||||
export { getUserId, getUserName, changeName };
|
||||
Reference in New Issue
Block a user