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)); }
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)); }
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); }
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); }
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)); } }
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)); } }
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); }
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)); }
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)); } }
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)); } }
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)); } }
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; } }