/// <summary>
        /// Proxy function that processes the selected color and sends it to the Game host
        /// </summary>
        /// <param name="color"></param>
        /// <param name="effects"></param>
        public async Task SendColorToHost(string color, SpecialCardActions effects)
        {
            ServerGameSession session = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (session != null)
            {
                PlayerObject player = session.game.Players.FirstOrDefault(n => n.connid == Context.ConnectionId);
                if (player != null)
                {
                    switch (color)
                    {
                    case "green":
                    case "yellow":
                    case "red":
                    case "blue":
                        await session.UpdateColorInHost(player, color, effects);

                        break;

                    case "error":
                    default:
                        await session.UpdateColorInHost(player, null, null);

                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Proxy function that sends the pressed card to the Game host
        /// </summary>
        /// <param name="cardName"></param>
        public async Task PostCard(string cardName)
        {
            ServerGameSession sGame = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (sGame != null)
            {
                UnoGame game = sGame.game;

                //get the player object
                PlayerObject player = game.Players.FirstOrDefault(n => n.connid == Context.ConnectionId);
                if (player != null)
                {
                    //get the card object
                    CardObject card = player.cards.FirstOrDefault(n => n.name == cardName);
                    if (card != null)
                    {
                        //send the game to the host, and let the host process it
                        await sGame.PlayCard(player.id, card);
                    }
                    else
                    {
                        //todo: maybe not end the session, but there is some cheating going on
                        await Clients.Caller.endSession("The card you played was not in your posession.");
                    }
                }
                else
                {
                    await Clients.Caller.endSession("You are not a member of this game");
                }
            }
            else
            {
                await Clients.Caller.endSession("You are not a member of a game");
            }
        }
        /// <summary>
        /// Proxy function that is called after a user picks a color, the function checks if it needs to send cards from the draw four card.
        /// </summary>
        /// <param name="game">game object</param>
        /// <param name="effects">the effects object</param>
        /// <returns></returns>
        public async Task HandleSpecialAfterColorPick(UnoGame game, SpecialCardActions effects)
        {
            ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (effects.sendColorWheel)
            {
                if (effects.cardDrawAmount != 0)
                {
                    //send the NEXT client the amount of cards.
                    game.CurrentPlayer = GetNextPlayerId(game, null);
                    string targetPlayer = new string(game.CurrentPlayer.ToCharArray());
                    game.CurrentPlayer = GetNextPlayerId(game, null);
                    await PushGame(game);

                    Clients.Caller.drawCardFromSpecial(targetPlayer, effects.cardDrawAmount);
                }
                else
                {
                    game.CurrentPlayer = GetNextPlayerId(game, null);
                }

                await PushGame(game);

                //set the current playing name:
                await MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId).UpdateCurrentPlayingName(game.Players.FirstOrDefault(n => n.id == game.CurrentPlayer));
            }
        }
Example #4
0
        /// <summary>
        /// Checks if the password belongs to a game and if the game is still available
        /// </summary>
        /// <param name="password"></param>
        /// <returns>Returns the status message, if the game exists, a redirect will happen through a seperate client call.</returns>
        public string CreateClientSessionFromPassword(string password)
        {
            ServerGameSession session = MvcApplication.Manager.FindSessionByPassword(password);

            if (session == null)
            {
                return("Game does not exists, try again please.");
            }

            if (!session.game.HasAvailablePlayerSpots())
            {
                return("This game is full, you can create a new one or check if you have the correct code.");
            }

            if (session.GameStarted)
            {
                return("Game has already started, ask the game owner to wait longer next time.");
            }

            lock (PlayerSelectionLock) //this is going to cause issues with more active games, players will have to wait a bit longer before they get a selectable game assigned
            {
                PlayerObject p = session.game.Players.FirstOrDefault(n => n.connid == "" && !n.UserPicked);
                p.UserPicked = true;
                string clientId = p.id;                 //todo prevent racecondition / deadlock if 2 players join at the same time by using a request queue of some sort.
                Clients.Caller.redirectToClientGame(clientId);
            }

            return("Game has been found, you will be redirected shortly...");
        }
        /// <summary>
        /// Proxy function that stops the game and sends the clients back to the lobby
        /// </summary>
        /// <returns></returns>
        public async Task EndGame()
        {
            ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);
            await sGame?.EndGameForClients();

            MvcApplication.Manager.EndGame(sGame);

            await GlobalHost.ConnectionManager.GetHubContext <SessionHub>().Clients.All.setSessions(MvcApplication.Manager.GetGameSessions());
        }
        /// <summary>
        /// Proxy function that reports uno to the Game host
        /// </summary>
        /// <returns></returns>
        public async Task ReportUno()
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (game != null)
            {
                PlayerObject player = game.game.Players.FirstOrDefault(n => n.connid == Context.ConnectionId);
                player.reportedUno = true;
                await game.UpdateHost();
            }
        }
        /// <summary>
        /// Proxy function that requests a card from the Draw Pile at the Game host
        /// </summary>
        public async Task DrawCardFromDeck()
        {
            string            connId  = Context.ConnectionId;
            ServerGameSession session = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (session != null)
            {
                UnoGame      game   = session.game;
                PlayerObject player = game.Players.FirstOrDefault(n => n.connid == connId);
                await session.DrawCard(player.id);
            }
        }
        /// <summary>
        /// Proxy function that causes a game update on every connected screen
        /// </summary>
        /// <returns></returns>
        public async Task Update()
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (game != null)
            {
                await game.UpdateAll();
            }
            else
            {
                await Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
Example #9
0
        // GET: Host
        public ActionResult Index(string id)
        {
            ServerGameSession game = MvcApplication.Manager.FindSession(id);

            if (game != null)
            {
                return(View(game));
            }
            else
            {
                return(View("Error"));
            }
        }
Example #10
0
        /// <summary>
        /// Proxy function that allows the host to send a message to all connected clients (this is only implemented in the console atm)
        /// </summary>
        /// <param name="message">the message to relay</param>
        public async Task RelayMessage(string message)
        {
            ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (sGame != null)
            {
                await sGame.MessageClients(message);
            }
            else
            {
                Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
Example #11
0
        /// <summary>
        /// Proxy function that processes the game after someone won.
        /// </summary>
        /// <param name="PlayerId">id of the player that won</param>
        /// <returns></returns>
        public async Task ProcessGameWon(string PlayerId)
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (game != null)
            {
                await game.GameWon(PlayerId);
            }
            else
            {
                Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
Example #12
0
        /// <summary>
        /// Proxy function that is called when an Action card is used in the game, the function decides what the game should do.
        /// </summary>
        /// <param name="game">current game object</param>
        /// <param name="effects">effects object</param>
        /// <returns></returns>
        public async Task HandleSpecialCard(UnoGame game, SpecialCardActions effects)
        {
            ServerGameSession sGame         = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);
            string            currentPlayer = game.CurrentPlayer;

            if (effects.sendColorWheel)
            {
                //send the colorwheel update to the current client.
                //after receiving the color wheel update advance the turn
                await sGame.ShowColorWheelInClient(effects);
            }
            else if (effects.cardDrawAmount != 0)
            {
                //send the NEXT client the amount of cards.
                game.CurrentPlayer = GetNextPlayerId(game, null);
                string targetPlayer = new string(game.CurrentPlayer.ToCharArray());
                game.CurrentPlayer = GetNextPlayerId(game, null);
                await PushGame(game);

                await Clients.Caller.drawCardFromSpecial(targetPlayer, effects.cardDrawAmount);
            }
            else if (effects.skipNextPerson)
            {
                //the skip is handled in code
                game.CurrentPlayer = GetNextPlayerId(game, effects);
            }
            else if (effects.reverseOrder)
            {
                game.DirectionClockwise = !game.DirectionClockwise;
                if (game.Players.Count > 2)
                {
                    game.CurrentPlayer = GetNextPlayerId(game, null);
                }
            }
            int drawCards = CheckUno(game, currentPlayer);

            await PushGame(game);

            //set the current playing name:
            PlayerObject pObject = game.Players.FirstOrDefault(n => n.id == game.CurrentPlayer);
            await MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId).UpdateCurrentPlayingName(pObject);

            if (drawCards > 0)
            {
                await Clients.Caller.drawCardFromSpecial(currentPlayer, drawCards);
            }
            else if (drawCards == -69)
            {
                await Clients.Caller.gameWon(currentPlayer);
            }
        }
Example #13
0
        /// <summary>
        /// Proxy function that creates the game object server side.
        /// </summary>
        /// <param name="gameId"></param>
        /// <returns>Return the games password to display to the viewers.</returns>
        public async Task <string> InitGame(string gameId)
        {
            ServerGameSession game = MvcApplication.Manager.FindSession(gameId);

            if (game != null)
            {
                if (string.IsNullOrEmpty(game.GameConnectionId) && !game.GameStarted)
                {
                    game.GameConnectionId = Context.ConnectionId;
                    await Clients.Caller.setGameMode("AWAITING_PLAYERS");

                    if (game.game.Players.Count == 0)
                    {
                        game.game.CreateNewPlayerObjects();
                    }
                    else
                    {
                        if (game.game.HasConnectedPlayers())
                        {
                            await Clients.Caller.setGameMode("AWAITING_PLAYERS_REFRESHED");

                            await game.UpdateHost();
                        }
                    }
                }
                else if (string.IsNullOrEmpty(game.GameConnectionId) && game.GameStarted)
                {
                    game.GameConnectionId = Context.ConnectionId;
                    await Clients.Caller.setGameMode("RESUMING_GAME");

                    await game.UpdateHost();

                    PlayerObject pObject = game.game.Players.FirstOrDefault(n => n.id == game.game.CurrentPlayer);
                    await game.UpdateCurrentPlayingName(pObject);

                    await Clients.Caller.displayMessage($"Game is resuming");
                }
                else
                {
                    Clients.Caller.endSession("game is already being hosted somewhere else.");
                    return(null);
                }

                return(game.GamePassword);
            }
            else
            {
                Clients.Caller.endSession("unkown game id was passed to the server.");
            }
            return(null);
        }
Example #14
0
        /// <summary>
        /// Proxy funtion that causes an update on all connected screens.
        /// </summary>
        /// <returns></returns>
        public async Task Update()
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (game != null)
            {
                await game.UpdateAll();

                PlayerObject pObject = game.game.Players.FirstOrDefault(n => n.id == game.game.CurrentPlayer);
                await game.UpdateCurrentPlayingName(pObject);
            }
            else
            {
                Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
Example #15
0
        public override Task OnDisconnected(bool stopCalled)
        {
            //find game by connection id -> dbe1b95e-ea84-40f9-a570-455ca8edf6e2
            ServerGameSession game = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (game != null)
            {
                game.GameConnectionId = null;

                if (game.HasGameEnded || !game.game.HasConnectedPlayers())
                {
                    MvcApplication.Manager.EndGame(game);
                }
            }

            return(base.OnDisconnected(stopCalled));
        }
        // GET: Client
        public ActionResult Index(string id)
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByClientId(id);

            if (game != null)
            {
                ClientGameSession session = new ClientGameSession();
                session.ClientId = id;
                session.GameId   = game.GameId;
                session.GameName = game.GameName;
                return(View(session));
            }
            else
            {
                return(View("Error"));
            }
        }
        public override Task OnDisconnected(bool stopCalled)
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByClientConnectionId(Context.ConnectionId);

            if (game != null)
            {
                lock (PlayerSelectionLock)
                {
                    game.game.Players.First(n => n.connid == Context.ConnectionId).connid = "";
                }

                //check if this is the last client disconnecting, and if there is no more host, remove the game
                if (game.game.Players.Where(n => n.connid != "").Count() == game.game.Players.Count && game.GameConnectionId == "")
                {
                    MvcApplication.Manager.EndGame(game);
                }
            }

            return(base.OnDisconnected(stopCalled));
        }
Example #18
0
        /// <summary>
        /// Proxy function that starts the game
        /// </summary>
        /// <returns></returns>
        public async Task StartGame()
        {
            ServerGameSession game = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (game != null)
            {
                game.GameStarted = true;

                //remove the empty player objects: no need for new players to connect after the game has started
                game.game.Players.RemoveAll(n => n.connid == "");
                await Clients.Caller.startGame(game.game.Players);

                await Clients.Caller.displayMessage($"Game has started");

                await game.UpdateCurrentPlayingName(game.game.Players[0]);
            }
            else
            {
                await Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
        /// <summary>
        /// Proxy function that connects this client with a Game host
        /// </summary>
        /// <param name="hostId">id of the host</param>
        /// <param name="clientId">id of the current client (not connection id)</param>
        /// <param name="playername">the name provided by the client.</param>
        /// <returns></returns>
        public async Task SubscribeToHost(string hostId, string clientId, string playername)
        {
            string connId = Context.ConnectionId;
            //find the session in memory
            ServerGameSession game = MvcApplication.Manager.FindSession(hostId);

            if (game != null)
            {
                //check if game is at max players
                if (game.game.Players.Where(n => n.connid != "").Count() < game.MaxClients)
                {
                    if (game.game.Players.First(n => n.id == clientId).connid != "")
                    {
                        //game slot is in use
                        await Clients.Caller.endSession("This place has already been taken by another player.");
                    }
                    else
                    {
                        lock (PlayerSelectionLock)
                        {
                            PlayerObject p = game.game.Players.First(n => n.id == clientId);
                            p.connid = connId;
                            p.name   = playername;
                        }
                        await game.UpdateAll();
                    }
                }
                else
                {
                    await Clients.Caller.endSession("This game is already at its max players.");
                }
            }
            else
            {
                await Clients.Caller.endSession("This game does not exist");
            }
        }
Example #20
0
        /// <summary>
        /// Proxy and local function that syncs the JS and C# backend with eachother.
        /// </summary>
        /// <param name="game"></param>
        /// <returns></returns>
        public async Task PushGame(UnoGame game)
        {
            ServerGameSession sGame = MvcApplication.Manager.FindSessionByConnectionId(Context.ConnectionId);

            if (sGame != null)
            {
                if (sGame.game.FullDeck.Count == 0 || sGame.game.CurrentPlayer == null)
                {
                    //new game, select first player from list.
                    sGame.game = game;
                    sGame.game.CurrentPlayer = sGame.game.Players[0].id;
                }
                else
                {
                    sGame.game = game;
                }

                await sGame.UpdateAll();
            }
            else
            {
                await Clients.Caller.endSession("unkown game id was passed to the server.");
            }
        }
Example #21
0
 public void EndGame(ServerGameSession session)
 {
     Sessions.Remove(session);
 }