Beispiel #1
0
        public Task SendPrivateMessage(string toName, CatanMessage message)
        {
            message.ActionType = ActionType.Redo;
            var toId = PlayerToConnectionDictionary[toName];

            // Console.WriteLine($"[ToId: {toId}] for [toName={toName}]");
            //return Clients.User(toId).ToOneClient(message);
            return(Clients.All.ToOneClient(message));
        }
Beispiel #2
0
        public async Task <IActionResult> Monitor(Guid id, string gameName, string playerName, bool requestAutoJoin, bool delete)
        {
            Game game = Games.GetGame(id);

            if (game == default)
            {
                var err = new CatanResult(CatanError.NoGameWithThatName)
                {
                    Description = $"Game '{id}' does not exist", Request = this.Request.Path
                };
                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(NotFound(errMessage));
            }
            bool success = game.NameToPlayerDictionary.TryGetValue(playerName, out Player player);

            if (!success)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"Player '{playerName}' is not a member of Game with id = '{id}'.",
                };

                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(NotFound(errMessage));
            }

            var messages = await player.WaitForLogEntries();

            if (messages == null || messages.Count == 0)
            {
                var err = new CatanResult(CatanError.Unexpected)
                {
                    Request = this.Request.Path, Description = $"Why did {playerName} release with no log entries?"
                };
                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(errMessage));
            }

            return(Ok(messages));
        }
Beispiel #3
0
        public IActionResult DeleteGame(Guid id, string by)
        {
            try
            {
                bool success = Games.DeleteGame(id, out Game game);
                if (!success)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $" Game '{id}' does not exist",
                    };

                    return(NotFound(err));
                }
                //CatanServiceMessage msg = new CatanServiceMessage() { GameInfo = game.GameInfo, PlayerName = by };

                //CatanMessage message = new CatanMessage()
                //{
                //    ActionType = ActionType.Normal,
                //    Data = (object)msg,
                //    DataTypeName = typeof(GameInfo).FullName,
                //    From = by,
                //    Sequence = game.GetNextSequenceNumber(),
                //    MessageType = MessageType.DeleteGame
                //};
                //game.PostLog(message);
                //game.ReleaseLogs();

                return(GetGames());
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };

                CatanMessage message = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(message));
            }
        }
 public bool PostLog(CatanMessage message, bool addToPlayerLog = true)
 {
     message.Sequence = Interlocked.Increment(ref GlobalSequnceNumber);
     GameLog.Enqueue(message);
     if (addToPlayerLog)
     {
         foreach (var player in NameToPlayerDictionary.Values)
         {
             player.PlayerLog.Enqueue(message);
         }
     }
     return(true);
 }
Beispiel #5
0
 public async Task SendError(CatanMessage message, string error)
 {
     var errorMessage = new CatanMessage()
     {
         Data         = error,
         DataTypeName = typeof(String).FullName,
         From         = message.From,
         GameInfo     = message.GameInfo,
         ActionType   = ActionType.Normal,
         MessageId    = message.MessageId
     };
     await Clients.Group(message.GameInfo.Id.ToString()).ToAllClients(errorMessage);
 }
Beispiel #6
0
        public IActionResult CreateGame([FromBody] GameInfo gameInfo)
        {
            try
            {
                Game game = Games.GetGame(gameInfo.Id);
                if (game != default)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $" Game '{gameInfo.Id}' with description '{gameInfo.Name}' created by '{gameInfo.Creator}' already exists.  You can join it or delete it",
                    };
                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }
                Games.AddGame(gameInfo.Id, new Game()
                {
                    GameInfo = gameInfo
                });

                return(GetGames());
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };

                CatanMessage message = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(message));
            }
        }
Beispiel #7
0
        public IActionResult BroadcastMessage([FromBody] CatanMessage message, Guid gameId)
        {
            try
            {
                Game game = Games.GetGame(gameId);

                if (game == null)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Game '{gameId}' does not exists",
                    };

                    CatanMessage errMessage = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(NotFound(errMessage));
                }
                message.MessageType = MessageType.BroadcastMessage;
                game.PostLog(message);
                game.ReleaseLogs();
                return(Ok(message));
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };
                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(errMessage));
            }
        }
Beispiel #8
0
        public Task BroadcastMessage(Guid gameId, CatanMessage message)
        {
            //
            //  need to unmarshal to store the message and set the sequence number
            //

            Game game = GameController.Games.GetGame(gameId);

            if (game != null)
            {
                message.MessageType = MessageType.BroadcastMessage;
                // record in game log, but not player log and set the sequence number
                // note: this means there is no interop between a REST client and a SignalR client.
                game.PostLog(message, false);


                return(Clients.Group(gameId.ToString()).ToAllClients(message));
            }

            return(Task.CompletedTask);
        }
Beispiel #9
0
        public IActionResult GetGameLogRecords(Guid id, string playerName)
        {
            Game game = Games.GetGame(id);

            if (game == default)
            {
                var err = new CatanResult(CatanError.NoGameWithThatName)
                {
                    Description = $"Game '{id}' does not exist", Request = this.Request.Path
                };
                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(NotFound(errMessage));
            }
            bool success = game.NameToPlayerDictionary.TryGetValue(playerName, out Player player);

            if (!success)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"Player '{playerName}' is not a member of Game with id = '{id}'.",
                };

                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(NotFound(errMessage));
            }

            return(Ok(game.GameLog));
        }
Beispiel #10
0
        public IActionResult SendPrivateMessage([FromBody] CatanMessage message, Guid gameId, string to)
        {
            try
            {
                Game game = Games.GetGame(gameId);

                if (game == null)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Game '{gameId}' does not exists",
                    };

                    CatanMessage errMessage = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(NotFound(errMessage));
                }

                //
                //  should already be in here since you shoudl have called Monitor()
                bool success = game.NameToPlayerDictionary.TryGetValue(to, out Player player);

                if (!success)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Player '{to}' not found for game  '{gameId}'. Did you call Monitor() before Join()?",
                    };

                    return(BadRequest(err));
                }
                message.MessageType = MessageType.PrivateMessage;
                player.PlayerLog.Enqueue(message);
                player.ReleaseLog();
                return(Ok(message));
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };
                CatanMessage errMessage = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(errMessage));
            }
        }
Beispiel #11
0
        public IActionResult Leave([FromBody] GameInfo gameInfo, string playerName)
        {
            try
            {
                Game game = Games.GetGame(gameInfo.Id);

                if (game == null)

                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $" Game '{gameInfo.Name}' with id={gameInfo.Id} does not exist.  Call Monitor() before calling Join()",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                if (game.Started)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Player '{playerName}' can't be removed from '{gameInfo.Name}' because it has already been started.",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                if (game.GameInfo.Creator == playerName)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"The Creator can't leave their own game.",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                //
                //  should already be in here since you shoudl have called Monitor()
                bool success = game.NameToPlayerDictionary.TryRemove(playerName, out Player player);

                if (!success)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Player '{playerName}' can't be removed from '{gameInfo.Name}'.",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                //CatanMessage leaving = new CatanMessage()
                //{
                //    MessageType = MessageType.LeaveGame,
                //    From = playerName,
                //    Sequence = game.GetNextSequenceNumber(),
                //    To = "*"
                //};
                //game.PostLog(leaving);
                //game.ReleaseLogs();
                return(Ok(game.NameToPlayerDictionary.Keys)); // the client is going to want to know the creator
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };

                CatanMessage message = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(message));
            }
        }
Beispiel #12
0
        public IActionResult JoinGame([FromBody] GameInfo gameInfo, string playerName)
        {
            try
            {
                Game game = Games.GetGame(gameInfo.Id);

                if (game == null)

                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $" Game '{gameInfo.Name}' with id={gameInfo.Id} does not exist.  Call Monitor() before calling Join()",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                //
                //  should already be in here since you shoudl have called Monitor()
                bool success = game.NameToPlayerDictionary.TryAdd(playerName, new Player(game.GameLog));

                if (!success)
                {
                    var err = new CatanResult(CatanError.BadParameter)
                    {
                        CantanRequest = new CatanRequest()
                        {
                            Url = this.Request.Path
                        },
                        Description = $"Player '{playerName}' can't be added to  '{gameInfo.Name}'.",
                    };

                    CatanMessage message = new CatanMessage()
                    {
                        Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                    };
                    return(BadRequest(message));
                }

                return(Ok(game.GameInfo)); // the client is going to want to know the creator
            }
            catch (Exception e)
            {
                var err = new CatanResult(CatanError.BadParameter)
                {
                    CantanRequest = new CatanRequest()
                    {
                        Url = this.Request.Path
                    },
                    Description = $"{this.Request.Path} threw an exception. {e}",
                };

                CatanMessage message = new CatanMessage()
                {
                    Data = err, Sequence = 0, DataTypeName = typeof(CatanResult).FullName
                };
                return(BadRequest(message));
            }
        }
Beispiel #13
0
        public async Task PostMessage(CatanMessage message)
        {
            if (message == null)
            {
                return;
            }
            if (message.GameInfo == null)
            {
                return;
            }
            if (message.GameInfo.Id == null)
            {
                return;
            }

            Game game = Games.GetGame(message.GameInfo.Id);

            if (game != null)
            {
                game.PostLog(message, false);
            }

            string gameId = message.GameInfo.Id.ToString();

            message.MessageDirection = MessageDirection.ServerToClient;

            switch (message.MessageType)
            {
            case MessageType.BroadcastMessage:
                message.MessageType = MessageType.BroadcastMessage;
                await Clients.Group(gameId).ToAllClients(message);

                break;

            case MessageType.PrivateMessage:
                await Clients.Group(gameId).ToAllClients(message);      // no private message for now

                break;

            case MessageType.CreateGame:

                //
                //  do nothing if game is already created
                if (game == default)
                {
                    game = new Game()
                    {
                        GameInfo = message.GameInfo
                    };
                    Games.AddGame(message.GameInfo.Id, game);
                    await Groups.AddToGroupAsync(Context.ConnectionId, gameId);

                    game.PostLog(message);
                }
                else
                {
                    //
                    //  this will set the creator correctly
                    message.GameInfo = game.GameInfo;
                }

                //
                //  tell *all* the clients that a game was created
                await Clients.All.CreateGame(message);

                break;

            case MessageType.DeleteGame:
                Games.DeleteGame(message.GameInfo.Id, out Game _);
                //
                //  tell *all* the clients that a game was deleted
                await Clients.All.DeleteGame(message);

                break;

            case MessageType.RejoinGame:
                //
                //  this will only fail if the player is already there, but we don't care about that
                game.NameToPlayerDictionary.TryAdd(message.From, new Player(game.GameLog));

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

                //
                //  the difference between Join and Rejoin is that on Rejoin only the caller is told
                //  the client will (presumably) make the rejoin seamless to the user
                await Clients.Caller.RejoinGame(message);

                break;

            case MessageType.JoinGame:

                //
                //  this will only fail if the player is already there, but we don't care about that
                game.NameToPlayerDictionary.TryAdd(message.From, new Player(game.GameLog));

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

                //
                //  notify everybody else in the group that somebody has joined the game
                await Clients.Group(gameId).JoinGame(message);

                break;

            case MessageType.LeaveGame:
                game.NameToPlayerDictionary.TryRemove(message.From, out Player _);
                _ = Groups.RemoveFromGroupAsync(Context.ConnectionId, gameId);
                await Clients.Group(gameId).LeaveGame(message);

                break;

            case MessageType.Ack:
                await Clients.Group(gameId).OnAck(message);

                break;

            default:
                break;
            }
        }