Merged in development (pull request #43)

Development
This commit is contained in:
2021-01-26 23:25:09 +00:00
38 changed files with 268 additions and 208 deletions

View File

@@ -1,6 +1,6 @@
using System;
namespace AspShogiSockets.ServiceModels.Api.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages
{
public class GetGuestToken
{

View File

@@ -1,6 +1,6 @@
using System;
namespace Websockets.ServiceModels
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages
{
public class GetTokenResponse
{

View File

@@ -1,9 +1,14 @@
namespace AspShogiSockets.ServiceModels.Api.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages
{
public class PostGameInvitation
{
public string SessionName { get; set; }
}
public class PostGuestGameInvitation
{
public string GuestId { get; set; }
public string SessionName { get; set; }
}
public class PostGameInvitationResponse
{
public string Code { get; }

View File

@@ -1,6 +1,6 @@
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Interfaces
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces
{
public interface IRequest
{

View File

@@ -1,4 +1,4 @@
namespace Websockets.ServiceModels.Interfaces
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces
{
public interface IResponse
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class CreateGameRequest : IRequest
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class ErrorResponse : IResponse
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class JoinByCode : IRequest
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class JoinGameRequest : IRequest
{

View File

@@ -1,9 +1,8 @@
using System.Collections.Generic;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using System.Collections.Generic;
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class ListGamesRequest : IRequest
{

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using System.Collections.Generic;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class LoadGameRequest : IRequest
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets.ServiceModels.Messages
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages
{
public class MoveRequest : IRequest
{

View File

@@ -1,4 +1,4 @@
namespace Websockets.ServiceModels.Types
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types
{
public enum ClientAction
{

View File

@@ -1,4 +1,4 @@
namespace Websockets.ServiceModels.Types
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types
{
public class Coords
{

View File

@@ -1,4 +1,4 @@
namespace Websockets.ServiceModels.Types
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types
{
public class Game
{

View File

@@ -1,4 +1,4 @@
namespace Websockets.ServiceModels.Types
namespace Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types
{
public class Move
{

View File

@@ -1,30 +1,61 @@
using AspShogiSockets.ServiceModels.Api.Messages;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.Repositories.RepositoryManagers;
using Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using System.Threading.Tasks;
using Websockets.Repositories;
namespace AspShogiSockets.Controllers
namespace Gameboard.ShogiUI.Sockets.Controllers
{
[Authorize]
[ApiController]
[Route("[controller]")]
public class GameController : ControllerBase
{
private readonly IGameboardRepository gameboardRepository;
private readonly IGameboardRepositoryManager manager;
private readonly IGameboardRepository repository;
public GameController(IGameboardRepository gameboardRepository)
public GameController(
IGameboardRepository repository,
IGameboardRepositoryManager manager)
{
this.gameboardRepository = gameboardRepository;
this.manager = manager;
this.repository = repository;
}
[Route("JoinCode")]
public async Task<IActionResult> PostGameInvitation([FromBody] PostGameInvitation request)
{
var userName = HttpContext.User.Claims.First(c => c.Type == "preferred_username").Value;
var code = (await gameboardRepository.PostJoinCode(request.SessionName, userName)).JoinCode;
var isPlayer1 = await manager.IsPlayer1(request.SessionName, userName);
if (isPlayer1)
{
var code = (await repository.PostJoinCode(request.SessionName, userName)).JoinCode;
return new CreatedResult("", new PostGameInvitationResponse(code));
}
else
{
return new UnauthorizedResult();
}
}
[AllowAnonymous]
[Route("GuestJoinCode")]
public async Task<IActionResult> PostGuestGameInvitation([FromBody] PostGuestGameInvitation request)
{
var isGuest = manager.IsGuest(request.GuestId);
var isPlayer1 = manager.IsPlayer1(request.SessionName, request.GuestId);
if (isGuest && await isPlayer1)
{
var code = (await repository.PostJoinCode(request.SessionName, request.GuestId)).JoinCode;
return new CreatedResult("", new PostGameInvitationResponse(code));
}
else
{
return new UnauthorizedResult();
}
}
}
}

View File

@@ -1,15 +1,13 @@
using AspShogiSockets.Repositories.RepositoryManagers;
using AspShogiSockets.ServiceModels.Api.Messages;
using Gameboard.ShogiUI.Sockets.Managers;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.Repositories.RepositoryManagers;
using Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Threading.Tasks;
using Websockets.Managers;
using Websockets.Repositories;
using Websockets.ServiceModels;
namespace Websockets.Controllers
namespace Gameboard.ShogiUI.Sockets.Controllers
{
[Authorize]
[Route("[controller]")]

View File

@@ -4,7 +4,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace AspShogiSockets.Extensions
namespace Gameboard.ShogiUI.Sockets.Extensions
{
public static class WebSocketExtensions
{

View File

@@ -4,6 +4,7 @@
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Controller</Controller_SelectedScaffolderCategoryPath>
<ActiveDebugProfile>AspShogiSockets</ActiveDebugProfile>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>

View File

@@ -1,14 +1,14 @@
using AspShogiSockets.Extensions;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class CreateGameHandler : IActionHandler
{

View File

@@ -1,8 +1,8 @@
using System.Net.WebSockets;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public interface IActionHandler
{

View File

@@ -1,14 +1,14 @@
using AspShogiSockets.Extensions;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class JoinByCodeHandler : IActionHandler
{

View File

@@ -1,13 +1,13 @@
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class JoinGameHandler : IActionHandler
{

View File

@@ -1,15 +1,15 @@
using AspShogiSockets.Extensions;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class ListGamesHandler : IActionHandler
{

View File

@@ -1,15 +1,15 @@
using AspShogiSockets.Extensions;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Managers.Utility;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Linq;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Managers.Utility;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class LoadGameHandler : IActionHandler
{

View File

@@ -1,15 +1,15 @@
using AspShogiSockets.Extensions;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.Shogi.Api.ServiceModels.Messages;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Managers.Utility;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Messages;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Managers.Utility;
using Websockets.Repositories;
using Websockets.ServiceModels.Messages;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers.ClientActionHandlers
namespace Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers
{
public class MoveHandler : IActionHandler
{

View File

@@ -1,5 +1,7 @@
using AspShogiSockets.Extensions;
using AspShogiSockets.Managers.Utility;
using Gameboard.ShogiUI.Sockets.Extensions;
using Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers;
using Gameboard.ShogiUI.Sockets.Managers.Utility;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
@@ -8,10 +10,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Websockets.Managers.ClientActionHandlers;
using Websockets.ServiceModels.Types;
namespace Websockets.Managers
namespace Gameboard.ShogiUI.Sockets.Managers
{
public interface ISocketCommunicationManager
{
@@ -68,6 +68,12 @@ namespace Websockets.Managers
{
logger.LogError(ex.Message);
}
catch(WebSocketException ex)
{
logger.LogInformation($"{nameof(WebSocketException)} in {nameof(SocketCommunicationManager)}.");
logger.LogInformation("Probably tried writing to a closed socket.");
logger.LogError(ex.Message);
}
}
UnsubscribeFromBroadcastAndGames(userName);
}

View File

@@ -3,7 +3,7 @@ using System;
using System.Net;
using System.Threading.Tasks;
namespace Websockets.Managers
namespace Gameboard.ShogiUI.Sockets.Managers
{
public interface ISocketConnectionManager
{

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Websockets.Managers
namespace Gameboard.ShogiUI.Sockets.Managers
{
public interface ISocketTokenManager
{

View File

@@ -1,6 +1,6 @@
using Websockets.ServiceModels.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
namespace Websockets.Managers.Utility
namespace Gameboard.ShogiUI.Sockets.Managers.Utility
{
public class JsonRequest
{

View File

@@ -1,8 +1,8 @@
using Microsoft.FSharp.Core;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
using Microsoft.FSharp.Core;
using GameboardTypes = Gameboard.Shogi.Api.ServiceModels.Types;
namespace Websockets.Managers.Utility
namespace Gameboard.ShogiUI.Sockets.Managers.Utility
{
public static class Mapper
{

View File

@@ -1,7 +1,7 @@
using Websockets.ServiceModels.Interfaces;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Interfaces;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace AspShogiSockets.Managers.Utility
namespace Gameboard.ShogiUI.Sockets.Managers.Utility
{
public class Request : IRequest
{

View File

@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace Websockets
namespace Gameboard.ShogiUI.Sockets
{
public class Program
{

View File

@@ -4,9 +4,9 @@ using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Websockets.Repositories.Utility;
using Gameboard.ShogiUI.Sockets.Repositories.Utility;
namespace Websockets.Repositories
namespace Gameboard.ShogiUI.Sockets.Repositories
{
public interface IGameboardRepository
{

View File

@@ -1,19 +1,21 @@
using Gameboard.Shogi.Api.ServiceModels.Messages;
using System;
using System.Threading.Tasks;
using Websockets.Repositories;
namespace AspShogiSockets.Repositories.RepositoryManagers
namespace Gameboard.ShogiUI.Sockets.Repositories.RepositoryManagers
{
public interface IGameboardRepositoryManager
{
Task<string> CreateGuestUser();
Task<bool> IsPlayer1(string sessionName, string playerName);
bool IsGuest(string playerName);
}
public class GameboardRepositoryManager : IGameboardRepositoryManager
{
private readonly IGameboardRepository repository;
private const int MaxTries = 3;
private const string GuestPrefix = "Guest-";
private readonly IGameboardRepository repository;
public GameboardRepositoryManager(IGameboardRepository repository)
{
@@ -39,5 +41,23 @@ namespace AspShogiSockets.Repositories.RepositoryManagers
}
throw new OperationCanceledException($"Failed to create guest user after {MaxTries} tries.");
}
public async Task<bool> IsPlayer1(string sessionName, string playerName)
{
var session = await repository.GetGame(sessionName);
return session?.Session.Player1 == playerName;
}
public async Task<string> CreateJoinCode(string sessionName, string playerName)
{
var getGameResponse = await repository.GetGame(sessionName);
if (playerName == getGameResponse?.Session.Player1)
{
return (await repository.PostJoinCode(sessionName, playerName)).JoinCode;
}
return null;
}
public bool IsGuest(string playerName) => playerName.StartsWith(GuestPrefix);
}
}

View File

@@ -6,7 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Websockets.Repositories.Utility
namespace Gameboard.ShogiUI.Sockets.Repositories.Utility
{
public interface IAuthenticatedHttpClient
{

View File

@@ -1,4 +1,4 @@
using AspShogiSockets.Repositories.RepositoryManagers;
using Gameboard.ShogiUI.Sockets.Repositories.RepositoryManagers;
using Gameboard.ShogiUI.Sockets.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
@@ -12,13 +12,13 @@ using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using Websockets.Managers;
using Websockets.Managers.ClientActionHandlers;
using Websockets.Repositories;
using Websockets.Repositories.Utility;
using Websockets.ServiceModels.Types;
using Gameboard.ShogiUI.Sockets.Managers;
using Gameboard.ShogiUI.Sockets.Managers.ClientActionHandlers;
using Gameboard.ShogiUI.Sockets.Repositories;
using Gameboard.ShogiUI.Sockets.Repositories.Utility;
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket.Types;
namespace Websockets
namespace Gameboard.ShogiUI.Sockets
{
public class Startup
{