コード例 #1
0
        public async Task PieceMovedAsync(string playerName, string from, string to, ChessGameState gameState)
        {
            await gameHubContext.Clients.User(gameState.GameInfo.White.Name == playerName?gameState.GameInfo.Black.Name : gameState.GameInfo.White.Name)
            .SendAsync("OnPieceMoved", from, to, gameState);

            await gameHubContext.Clients.Group(ChessFabrickUtils.GameGroupName(gameState.GameInfo.GameId)).SendAsync("OnBoardChanged", gameState);
        }
コード例 #2
0
        public async Task <ChessGameState> SpectateGame(string gameId)
        {
            ServiceEventSource.Current.ServiceMessage(serviceContext, $"SpectateGame({gameId}): {Context.User.Identity.Name}");
            try
            {
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var board       = await chessClient.ActiveGameStateAsync(gameId);

                await Groups.AddToGroupAsync(Context.ConnectionId, ChessFabrickUtils.GameGroupName(gameId));

                return(board);
            }
            catch (Exception ex)
            {
                throw new HubException(ex.Message);
            }
        }
コード例 #3
0
        public async Task <IActionResult> GetPlayer(string playerName)
        {
            ServiceEventSource.Current.ServiceMessage(context, $"GetPlayer({playerName})");

            var playersClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(playerServiceUri, ChessFabrickUtils.NamePartitionKey(playerName));
            var player        = await playersClient.PlayerInfoAsync(playerName);

            return(Ok(player));
        }
コード例 #4
0
        public async Task <IActionResult> PostNewPlayer([FromBody] AuthenticationModel model)
        {
            ServiceEventSource.Current.ServiceMessage(context, $"PostNewPlayer({model.Name}, {model.Password})");

            if (string.IsNullOrEmpty(model.Name) || model.Name.Length > 30)
            {
                return(BadRequest("Username must not be empty or longer than 30 characters."));
            }
            if (!Regex.IsMatch(model.Name, "^[a-zA-Z0-9_]+$"))
            {
                return(BadRequest("Username can contain only letters, numbers and underscore."));
            }
            //if (!Regex.IsMatch(model.Password, "([a-zA-Z0-9_]+)"))
            //{
            //    return BadRequest("Username can contain only letters, numbers and underscore.");
            //}

            var playersClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(playerServiceUri, ChessFabrickUtils.NamePartitionKey(model.Name));
            var player        = await playersClient.NewPlayerAsync(model.Name);

            var user = await userService.Authenticate(model.Name, model.Password);

            return(Ok(user));
        }
コード例 #5
0
        public async Task PerformMove()
        {
            ActorEventSource.Current.ActorMessage(this, $"PerformMove({gameId})");
            await Task.Delay(rand.Next(800, 1600));

            var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
            var game        = await chessClient.ActiveGameStateAsync(gameId);

            while (true)
            {
                try
                {
                    var board = new Board();
                    board.PerformMoves(game.GameInfo.MoveHistory);
                    var move = GetRandomMove(board);
                    await chessClient.MovePieceAsync(gameId, ChessFabrickUtils.BOT_NAME, move.Item1, move.Item2);

                    return;
                }
                catch (Exception ex)
                {
                    ActorEventSource.Current.ActorMessage(this, $"PerformMoveException({gameId}): \n{ex}");
                }
            }
        }
コード例 #6
0
        public async Task <IActionResult> GetGameState(string gameId)
        {
            ServiceEventSource.Current.ServiceMessage(context, $"GetGameState({gameId})");
            var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));

            try
            {
                var board = await chessClient.ActiveGameStateAsync(gameId);

                return(Ok(board));
            }
            catch (Exception ex)
            {
                try
                {
                    var board = await chessClient.NewGameStateAsync(gameId);

                    return(Ok(board));
                }
                catch (Exception ex1)
                {
                    try
                    {
                        var board = await chessClient.CompletedGameStateAsync(gameId);

                        return(Ok(board));
                    }
                    catch (Exception ex2)
                    {
                        return(StatusCode(500, ex2.Message));
                    }
                }
            }
        }
コード例 #7
0
        public async Task <IActionResult> GetPlayerGames()
        {
            ServiceEventSource.Current.ServiceMessage(context, $"GetPlayerGames()");
            try
            {
                var playerClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(playerServiceUri, ChessFabrickUtils.NamePartitionKey(User.Identity.Name));
                var games        = await playerClient.PlayerGamesAsync(User.Identity.Name);

                return(Ok(games));
            }
            catch (Exception ex)
            {
                ServiceEventSource.Current.ServiceMessage(context, ex.ToString());;
                return(StatusCode(500, ex.Message));
            }
        }
コード例 #8
0
        public async Task <IActionResult> PostBotGame()
        {
            ServiceEventSource.Current.ServiceMessage(context, $"PostBotGame(): {User.Identity.Name}");
            try
            {
                var gameId      = $"{ChessFabrickUtils.BOT_NAME}-{Guid.NewGuid()}";
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var newGame     = await chessClient.NewGameAsync(gameId, ChessFabrickUtils.BOT_NAME, PieceColor.White);

                var startedGame = await chessClient.AddBot(gameId);

                return(Ok(startedGame));
            }
            catch (Exception ex)
            {
                return(StatusCode(500, ex.Message));
            }
        }
コード例 #9
0
        public async Task <ChessGameState> MovePiece(string gameId, string from, string to)
        {
            try
            {
                ServiceEventSource.Current.ServiceMessage(serviceContext, $"MovePiece({gameId}, {from}, {to}): {Context.User.Identity.Name}");
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var board       = await chessClient.MovePieceAsync(gameId, Context.User.Identity.Name, from, to);

                return(board);
            }
            catch (Exception ex)
            {
                throw new HubException(ex.Message);
            }
        }
コード例 #10
0
        public async Task <IActionResult> PostNewGame([FromBody] NewGameModel model)
        {
            ServiceEventSource.Current.ServiceMessage(context, $"PostNewGame({model.PlayerColor}): {User.Identity.Name}");
            try
            {
                var gameId      = $"{User.Identity.Name}-{Guid.NewGuid()}";
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var game        = await chessClient.NewGameAsync(gameId, User.Identity.Name, model.PlayerColor);

                return(Ok(game));
            } catch (Exception ex)
            {
                return(StatusCode(500, ex.Message));
            }
        }
コード例 #11
0
 public async Task PlayerJoined(string playerName, ChessGameInfo game)
 {
     await gameHubContext.Clients.Group(ChessFabrickUtils.GameGroupName(game.GameId)).SendAsync("OnPlayerJoined", game, playerName);
 }
コード例 #12
0
        public async Task <List <string> > GetPieceMoves(string gameId, string field)
        {
            ServiceEventSource.Current.ServiceMessage(serviceContext, $"GetPieceMoves({gameId}, {field}): {Context.User.Identity.Name}");
            try
            {
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var moves       = await chessClient.ListPieceMovesAsync(gameId, field);

                return(moves);
            } catch (Exception ex)
            {
                throw new HubException(ex.Message);
            }
        }
コード例 #13
0
 public async Task UnspectateGame(string gameId)
 {
     ServiceEventSource.Current.ServiceMessage(serviceContext, $"UnspectateGame({gameId}): {Context.User.Identity.Name}");
     await Groups.RemoveFromGroupAsync(Context.ConnectionId, ChessFabrickUtils.GameGroupName(gameId));
 }
コード例 #14
0
        public async Task <ChessGameState> JoinGame(string gameId)
        {
            ServiceEventSource.Current.ServiceMessage(serviceContext, $"JoinGame({gameId}): {Context.User.Identity.Name}");
            try
            {
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var board       = await chessClient.ActiveGameStateAsync(gameId);

                if (board.GameInfo.White.Name != Context.User.Identity.Name && board.GameInfo.Black.Name != Context.User.Identity.Name)
                {
                    throw new ArgumentException("Player not in the game.");
                }
                Clients.User(board.GameInfo.White.Name == Context.User.Identity.Name ? board.GameInfo.Black.Name : board.GameInfo.White.Name)
                .SendAsync("OnPlayerJoined", board);
                return(board);
            }
            catch (Exception ex)
            {
                throw new HubException(ex.Message);
            }
        }
コード例 #15
0
        public async Task <ChessGameInfo> NewGameAsync(string gameId, string playerName, PieceColor playerColor)
        {
            var playersClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(playerServiceUri, ChessFabrickUtils.NamePartitionKey(playerName));
            var player        = playerName == ChessFabrickUtils.BOT_NAME ? new ChessPlayer(ChessFabrickUtils.BOT_NAME) : await playersClient.PlayerInfoAsync(playerName);

            var dictGames = await GetNewGameDict();

            ChessGameInfo game;

            using (var tx = StateManager.CreateTransaction())
            {
                game = playerColor == PieceColor.White ?
                       new ChessGameInfo(gameId, player, null) :
                       new ChessGameInfo(gameId, null, player);
                await dictGames.AddAsync(tx, gameId, game);

                await playersClient.AddPlayerGameAsync(playerName, gameId);

                await tx.CommitAsync();
            }

            var chessSignalRClient = proxyFactory.CreateServiceProxy <IChessFabrickSignalRService>(chessSignalRUri /*, ChessFabrickUtils.GuidPartitionKey(gameId)*/);

            chessSignalRClient.GameCreated(game);

            return(game);
        }
コード例 #16
0
        public async Task <IActionResult> PostAddBot(string gameId)
        {
            ServiceEventSource.Current.ServiceMessage(context, $"PostAddBot({gameId}): {User.Identity.Name}");
            try
            {
                var chessClient = proxyFactory.CreateServiceProxy <IChessFabrickStatefulService>(chessStatefulUri, ChessFabrickUtils.GuidPartitionKey(gameId));
                var game        = await chessClient.AddBot(gameId);

                return(Ok(game));
            }
            catch (Exception ex)
            {
                return(StatusCode(500, ex.Message));
            }
        }
コード例 #17
0
        public async Task <ChessGameInfo> JoinGameAsync(string gameId, string playerName)
        {
            var playersClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(playerServiceUri, ChessFabrickUtils.NamePartitionKey(playerName));
            var player        = await playersClient.PlayerInfoAsync(playerName);

            var dictNewGames = await GetNewGameDict();

            var dictActiveGames = await GetActiveGameDict();

            ChessGameInfo activeGame;

            using (var tx = StateManager.CreateTransaction())
            {
                var game = await dictNewGames.TryGetValueAsync(tx, gameId);

                if (!game.HasValue)
                {
                    throw new ArgumentException("Game does not exist.");
                }
                if ((game.Value.White ?? game.Value.Black).Name == playerName)
                {
                    throw new ArgumentException("Can't play against yourself");
                }
                activeGame = game.Value.White == null ?
                             new ChessGameInfo(game.Value.GameId, player, game.Value.Black) :
                             new ChessGameInfo(game.Value.GameId, game.Value.White, player);
                await dictNewGames.TryRemoveAsync(tx, gameId);

                await dictActiveGames.AddAsync(tx, gameId, activeGame);

                await playersClient.AddPlayerGameAsync(playerName, gameId);

                await tx.CommitAsync();
            }

            var chessSignalRClient = proxyFactory.CreateServiceProxy <IChessFabrickSignalRService>(chessSignalRUri /*, ChessFabrickUtils.GuidPartitionKey(gameId)*/);

            chessSignalRClient.PlayerJoined(playerName, activeGame);

            return(activeGame);
        }
コード例 #18
0
        public async Task <UserModel> Authenticate(string userName, string password)
        {
            var userClient = proxyFactory.CreateServiceProxy <IChessFabrickPlayersStatefulService>(userServiceUri, ChessFabrickUtils.NamePartitionKey(userName));
            var player     = await userClient.PlayerInfoAsync(userName);

            if (player == null)
            {
                throw new ArgumentException("Authentication failed.");
            }

            var tokenHandler    = new JwtSecurityTokenHandler();
            var key             = Encoding.ASCII.GetBytes(appSettings.Secret);
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, player.Name)
                }),
                Expires            = DateTime.UtcNow.AddDays(7),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);

            var user = new UserModel {
                Player = player, Token = tokenHandler.WriteToken(token)
            };

            return(user);
        }