Simplify model. New route.
This commit is contained in:
@@ -27,43 +27,43 @@ public class GamesController : Controller
|
||||
return Ok(games);
|
||||
}
|
||||
|
||||
[Route("{id:int}")]
|
||||
[Route("{id:int}.json")]
|
||||
public IActionResult GetInfo([FromRoute] int id)
|
||||
{
|
||||
var game = _database.GetOrAddBoard(id);
|
||||
var game = _database.GetOrAddGame(id);
|
||||
return Ok(new
|
||||
{
|
||||
Turn = game.Turn.AsChar,
|
||||
Ended = game.IsEndGame,
|
||||
End = game.EndGame?.EndgameType,
|
||||
Won = game.EndGame?.WonSide,
|
||||
game.MoveIndex,
|
||||
game.WhiteKingChecked,
|
||||
game.BlackKingChecked,
|
||||
Turn = game.Board.Turn.AsChar,
|
||||
Ended = game.Board.IsEndGame,
|
||||
End = game.Board.EndGame?.EndgameType,
|
||||
Won = game.Board.EndGame?.WonSide,
|
||||
game.Board.MoveIndex,
|
||||
game.Board.WhiteKingChecked,
|
||||
game.Board.BlackKingChecked,
|
||||
links = new Dictionary<string, string>
|
||||
{
|
||||
{ "ascii", $"games/{id}/ascii" },
|
||||
{ "fen", $"games/{id}/fen" },
|
||||
{ "pgn", $"games/{id}/pgn" },
|
||||
{ "html", $"games/{id}/html" },
|
||||
{ "websocket", $"games/{id}/websocket" },
|
||||
{ "ascii", $"games/{id}.ascii" },
|
||||
{ "fen", $"games/{id}.fen" },
|
||||
{ "pgn", $"games/{id}.pgn" },
|
||||
{ "html", $"games/{id}.html" },
|
||||
{ "websocket", $"games/{id}.ws" },
|
||||
{ "move-post", $"games/{id}/move/{{player}}/{{move_algebraic_notation}}" }
|
||||
},
|
||||
Listeners = _database.GetOrAddChannel(id).GetListenerCount()
|
||||
Listeners = game.Channel.GetListenerCount()
|
||||
});
|
||||
}
|
||||
|
||||
[Route("{id:int}/ws")]
|
||||
[Route("{id:int}.ws")]
|
||||
public async Task GetWebSocket([FromRoute] int id)
|
||||
{
|
||||
var channel = _database.GetOrAddChannel(id);
|
||||
var game = _database.GetOrAddGame(id);
|
||||
IDisposable? subscription = null;
|
||||
|
||||
await _pusher.Accept(HttpContext);
|
||||
try
|
||||
{
|
||||
await Task.Factory.StartNew(_pusher.PendingClose);
|
||||
subscription = channel.Subscribe(async t => { await _pusher.SendMessage(t.Content); });
|
||||
subscription = game.Channel.Subscribe(async t => { await _pusher.SendMessage(t.Content); });
|
||||
while (_pusher.Connected)
|
||||
{
|
||||
try
|
||||
@@ -83,49 +83,48 @@ public class GamesController : Controller
|
||||
}
|
||||
}
|
||||
|
||||
[Route("{id:int}/ascii")]
|
||||
[Route("{id:int}.ascii")]
|
||||
public IActionResult GetAscii([FromRoute] int id)
|
||||
{
|
||||
var game = _database.GetOrAddBoard(id);
|
||||
return Ok(game.ToAscii());
|
||||
var game = _database.GetOrAddGame(id);
|
||||
return Ok(game.Board.ToAscii());
|
||||
}
|
||||
|
||||
[Route("{id:int}/html")]
|
||||
[Route("{id:int}.html")]
|
||||
public IActionResult GetHtml([FromRoute] int id)
|
||||
{
|
||||
return View(id);
|
||||
}
|
||||
|
||||
[Route("{id:int}/fen")]
|
||||
[Route("{id:int}.fen")]
|
||||
public IActionResult GetFen([FromRoute] int id)
|
||||
{
|
||||
var game = _database.GetOrAddBoard(id);
|
||||
return Ok(game.ToFen());
|
||||
var game = _database.GetOrAddGame(id);
|
||||
return Ok(game.Board.ToFen());
|
||||
}
|
||||
|
||||
[Route("{id:int}/pgn")]
|
||||
[Route("{id:int}.pgn")]
|
||||
public IActionResult GetPgn([FromRoute] int id)
|
||||
{
|
||||
var game = _database.GetOrAddBoard(id);
|
||||
return Ok(game.ToPgn());
|
||||
var game = _database.GetOrAddGame(id);
|
||||
return Ok(game.Board.ToPgn());
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("{id:int}/move/{player}/{move}")]
|
||||
public async Task<IActionResult> Move([FromRoute] int id, [FromRoute] string player, [FromRoute] string move)
|
||||
{
|
||||
var game = _database.GetOrAddBoard(id);
|
||||
var game = _database.GetOrAddGame(id);
|
||||
try
|
||||
{
|
||||
if (!game.IsValidMove(move) || game.IsEndGame || game.Turn.AsChar.ToString() != player)
|
||||
if (!game.Board.IsValidMove(move) || game.Board.IsEndGame || game.Board.Turn.AsChar.ToString() != player)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
game.Move(move);
|
||||
var fen = game.ToFen();
|
||||
var channel = _database.GetOrAddChannel(id);
|
||||
await channel.Push(new Message(fen));
|
||||
game.Board.Move(move);
|
||||
var fen = game.Board.ToFen();
|
||||
await game.Channel.Push(new Message(fen));
|
||||
return Ok(fen);
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -6,6 +6,6 @@ public class HomeController : ControllerBase
|
||||
{
|
||||
public IActionResult Index()
|
||||
{
|
||||
return this.Ok("Welcome to chess server! Please go to '/games/12345' to view more.");
|
||||
return this.Ok("Welcome to chess server! Please go to '/games/12345.json' to view more.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,20 @@
|
||||
using Aiursoft.Scanner.Abstractions;
|
||||
using Chess;
|
||||
using System.Collections.Concurrent;
|
||||
using Aiursoft.ChessServer.Models;
|
||||
|
||||
namespace Aiursoft.ChessServer.Data;
|
||||
|
||||
public class Game
|
||||
{
|
||||
public bool Ended { get; set; }
|
||||
public int Key { get; set; }
|
||||
}
|
||||
|
||||
public class InMemoryDatabase : ISingletonDependency
|
||||
{
|
||||
private ConcurrentDictionary<int, ChessBoard> Boards { get; } = new();
|
||||
private ConcurrentDictionary<int, Channel> Channels { get; } = new();
|
||||
private ConcurrentDictionary<int, Game> Games { get; } = new();
|
||||
|
||||
public Game[] GetActiveGames()
|
||||
{
|
||||
return Boards.Select(t => new Game
|
||||
{
|
||||
Ended = t.Value.IsEndGame,
|
||||
Key = t.Key
|
||||
}).ToArray();
|
||||
return Games.Values.ToArray();
|
||||
}
|
||||
|
||||
public ChessBoard GetOrAddBoard(int id)
|
||||
public Game GetOrAddGame(int id)
|
||||
{
|
||||
return Boards.GetOrAdd(id, _ => new ChessBoard());
|
||||
}
|
||||
|
||||
public Channel GetOrAddChannel(int id)
|
||||
{
|
||||
return Channels.GetOrAdd(id, _ => new Channel());
|
||||
return Games.GetOrAdd(id, _ => new Game());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,6 @@
|
||||
|
||||
namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class Message
|
||||
{
|
||||
public Message(string content)
|
||||
{
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public string Content { get; set; }
|
||||
}
|
||||
|
||||
public class Channel : AsyncObservable<Message>
|
||||
{
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using Chess;
|
||||
|
||||
namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class Game
|
||||
{
|
||||
public ChessBoard Board { get; set; } = new ChessBoard();
|
||||
|
||||
public Channel Channel { get; set; } = new Channel();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Aiursoft.ChessServer.Models;
|
||||
|
||||
public class Message
|
||||
{
|
||||
public Message(string content)
|
||||
{
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public string Content { get; set; }
|
||||
}
|
||||
@@ -4,7 +4,7 @@ const statusControl = $('#status');
|
||||
const fenControl = $('#fen');
|
||||
|
||||
const initGameBoard = function (player, gameId) {
|
||||
$.get("/games/" + gameId + "/fen", function (fen) {
|
||||
$.get("/games/" + gameId + ".fen", function (fen) {
|
||||
let board = null;
|
||||
let game = null;
|
||||
|
||||
@@ -86,7 +86,7 @@ const initGameBoard = function (player, gameId) {
|
||||
refresh(fen);
|
||||
|
||||
const wsScheme = window.location.protocol === "https:" ? "wss://" : "ws://";
|
||||
const socket = new WebSocket(wsScheme + window.location.host + "/games/" + gameId + "/ws");
|
||||
const socket = new WebSocket(wsScheme + window.location.host + "/games/" + gameId + ".ws");
|
||||
socket.onmessage = function (event) {
|
||||
refresh(event.data);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user