Exemple #1
0
        public Guid CreateGame(Guid player, Guid room)
        {
            using (var context = new MilleBornesEntities())
            {
                var playerEntity = context.User
                    .Where(us => us.LoggedInUser != null)
                    .SingleOrDefault(us => us.LoggedInUser.Token == player);
                if (playerEntity == null)
                {
                    throw new FaultException("Le joueur n'est pas valide ou est hors-ligne.");
                }

                var roomEntity = context.Room
                    .SingleOrDefault(rm => rm.Token == room);
                if (roomEntity == null)
                {
                    throw new FaultException("La salle n'est pas trouvée.");
                }

                if (roomEntity.MasterUserId != playerEntity.UserId)
                {
                    throw new FaultException("Seul le maître de la salle peut démarrer la partie.");
                }

                var newGame = new Game()
                {
                    Token = Guid.NewGuid(),
                    StartDate = DateTime.UtcNow,
                    IsTakingDisconnectDecision = false
                };

                FillPlayerConfig(context, roomEntity, newGame);

                roomEntity.Game = newGame;
                roomEntity.Started = true;
                context.Game.Add(newGame);
                try
                {
                    context.SaveChanges();
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateException dbue)
                {
                    throw;
                }

                InitializeGame(newGame);
                try
                {
                    context.SaveChanges();
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateException dbue)
                {
                    throw;
                }

                return newGame.Token;
            }
        }
        /// <summary>
        /// Crée la room avec le master associé.
        /// </summary>
        /// <param name="name">Nom de la salle</param>
        /// <param name="roomMaster">Guid du créateur.</param>
        /// <returns>Le guid de la room. </returns>
        public Guid? CreateRoom(string name, Guid roomMaster)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    // Fetch le master id. 
                    int mId = context.LoggedInUser.First(p => p.Token == roomMaster).UserId;
                    // Vérifie si déjà master d'une room ou membre d'une room.
                    bool alreadyInRoom = context.Room
                        .Where(p => p.MasterUserId == mId)
                        .Count() > 0;

                    if (alreadyInRoom)
                        return null;

                    alreadyInRoom = context.PlayerRoomState
                        .Where(p => p.UserId == mId)
                        .Count() > 0;

                    if (alreadyInRoom)
                        return null;

                    Guid roomGuid = Guid.NewGuid();
                    Room r = new Room();
                    r.Name = name;
                    r.Started = false;
                    r.Token = roomGuid;
                    r.MasterUserId = mId;
                    r.GameInProgressId = null;

                    // Crée le playerroomstate du roommaster
                    PlayerRoomState prs = new PlayerRoomState();
                    prs.Room = r;
                    prs.UserId = mId;
                    prs.IsReady = false;
                    prs.Order = 0;
                    prs.Team = 0;
                    prs.LastHeartbeat = DateTime.UtcNow;

                    context.Room.Add(r);
                    context.PlayerRoomState.Add(prs);
                    context.SaveChanges();

                    return roomGuid;
                }
            }
            catch
            {
                return null;
            }
        }
Exemple #3
0
        /// <summary>
        /// Crée l'utilisateur en fonction des informations fournies.
        /// </summary>
        /// <param name="info"></param>
        /// <returns>True si créé avec succès. False autrement.</returns>
        public bool CreateUser(Models.CreateUserInfo info)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    // Vérification basiques.
                    if (info.Email.Trim() == "" || !info.Email.Contains("@"))
                        return false;

                    if (info.Username.Trim().Length < 2 || info.Password.Length < 3)
                        return false;

                    User user = new User();
                    user.Name = info.Username.Trim();
                    user.PasswordHash = GetSHA1HashString(info.Password);
                    user.EmailAddress = info.Email.Trim();

                    // Si l'utilisateur est déjà présent, soit email soit name.
                    if (context.User.Where(p => p.Name == user.Name
                        || user.EmailAddress == p.EmailAddress).Count() > 0)
                    {
                        return false;
                    }


                    context.User.Add(user);
                    context.SaveChanges();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }
Exemple #4
0
        /// <summary>
        /// Vérifie la connexion de l'utilisateur.
        /// </summary>
        /// <param name="username">Nom d'utilisateur</param>
        /// <param name="password">Mot de passe</param>
        /// <returns>Retourne le Guid de l'utilisateur.</returns>
        /// <remarks>Si cet appel retourne null, c'est que l'utilisateur n'a pas réussi à se logger.</remarks>
        public Guid? Login(string username, string password)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    string hashedPassword = GetSHA1HashString(password);
                    var lstUsers = new List<User>();

                    lstUsers = new List<User>(context.User
                        .Where(p => p.Name == username.Trim()
                        && p.PasswordHash.ToLower() == hashedPassword.ToLower()));

                    if (lstUsers.Count() < 1)
                        return null;

                    User user = lstUsers.First();

                    LoggedInUser loggedInfo = new LoggedInUser();
                    loggedInfo.LoginDate = DateTime.UtcNow;
                    Guid guid = Guid.NewGuid();

                    loggedInfo.Token = guid;
                    loggedInfo.UserId = user.UserId;
                    DateTime hb = DateTime.UtcNow;
                    loggedInfo.LastHeartbeat = hb.AddMilliseconds(DELAY_MS_HEARTBEAT * 10);

                    LoggedInUser old = context.LoggedInUser.Find(loggedInfo.UserId);

                    if (old == null)
                    {
                        context.LoggedInUser.Add(loggedInfo);
                    }
                    else
                    {
                        old.Token = loggedInfo.Token;
                        old.LoginDate = DateTime.UtcNow;
                        old.LastHeartbeat = DateTime.UtcNow;
                    }

                    context.SaveChanges();
                    return guid;
                }
            }
            catch
            {
                return null;
            }
        }
Exemple #5
0
        /// <summary>
        /// Envoie un mess
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <param name="message"></param>
        /// <returns>True si envoyé avec succès.</returns>
        public bool SendGlobalMessage(Guid player, string message)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    int userId = context.LoggedInUser.Where(p => p.Token == player)
                        .ToList().First().UserId;

                    Message msg = new Message();
                    msg.Content = message;
                    msg.Date = DateTime.UtcNow;
                    msg.UserId = userId;
                    msg.Type = MessageType.GLOBAL;

                    context.Message.Add(msg);
                    context.SaveChanges();
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Exemple #6
0
        /// <summary>
        /// Détermine si la connexion est toujours vivante.
        /// </summary>
        /// <param name="userToken"></param>
        /// <returns>True si c'est le cas, false autrement.</returns>
        /// <remarks>Tolérance d'un skip de heartbeat. 
        /// Valeur par défaut 1 heartbeat == 2000ms</remarks>
        public bool Heartbeat(Guid userToken)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    var lstLoggedUsers = context.LoggedInUser.Where(p => p.Token == userToken);
                    LoggedInUser liu = lstLoggedUsers.First();

                    // Différence de temps.
                    TimeSpan dt = DateTime.UtcNow - liu.LastHeartbeat;

                    liu.LastHeartbeat = DateTime.UtcNow;
                    context.SaveChanges();

                    return (dt.TotalMilliseconds <= DELAY_MS_HEARTBEAT * 10);
                }
            }
            catch
            {
                return false;
            }
        }
Exemple #7
0
        public bool SendGameMessage(Guid playerToken, Guid gameToken, string message)
        {
            using (var context = new MilleBornesEntities())
            {
                var player = GetPlayerFromToken(context, playerToken);

                if (player == null)
                {
                    throw new FaultException("Le joueur n'est pas trouvé.");
                }

                var game = context.Game
                    .SingleOrDefault(gm => gm.Token == gameToken);

                if (game == null)
                {
                    throw new FaultException("La partie n'est pas trouvée.");
                }

                if (!GetPlayersInGame(game).Any(pg => pg.UserId == player.UserId))
                {
                    throw new FaultException("Le joueur n'est pas dans la partie.");
                }

                game.Message.Add(new Message() 
                {
                    UserId = player.UserId,
                    Type = MessageType.GAME,
                    Date = DateTime.UtcNow,
                    Content = message
                });

                try
                {
                    context.SaveChanges();
                    return true;
                }
                catch (System.Data.Entity.Infrastructure.DbUpdateException dbue)
                {
                    return false;
                }
            }
        }
Exemple #8
0
        public bool DoHeartbeat(Guid playerToken, Guid gameToken)
        {
            using (var context = new MilleBornesEntities())
            {
                var player = GetPlayerFromToken(context, playerToken);

                if (player == null)
                {
                    throw new FaultException("Le joueur n'est pas trouvé.");
                }

                var game = context.Game
                    .SingleOrDefault(gm => gm.Token == gameToken);

                if (game == null)
                {
                    throw new FaultException("La partie n'est pas trouvée.");
                }

                var playerGame = game.PlayerGame
                    .SingleOrDefault(pg => pg.UserId == player.UserId);
                if (playerGame == null)
                {
                    throw new FaultException("Le joueur n'est pas dans la partie.");
                }

                if (!playerGame.HasJoined)
                {
                    throw new FaultException("Le joueur n'a pas rejoint la partie.");
                }

                bool validPlayerHeartbeat = ValidatePlayerHeartbeat(playerGame);
                if (validPlayerHeartbeat)
                {
                    playerGame.LastHeartbeat = DateTime.UtcNow;
                    context.SaveChanges();
                }

                if (!CheckAllPlayersHeartbeat(game))
                {
                    context.SaveChanges();
                }

                return validPlayerHeartbeat;
            }
        }
        /// <summary>
        /// Définit le nom de la salle.
        /// </summary>
        /// <param name="room"></param>
        /// <param name="newName"></param>
        /// <returns></returns>
        public bool SetRoomName(Guid room, string newName)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    context.Room.First(p => p.Token == room).Name = newName;
                    context.SaveChanges();

                    return true;
                }
            }
            catch
            {
            }

            return false;
        }
Exemple #10
0
        /// <summary>
        /// Défini l'équipe laquelle le joueur join.
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <param name="team"></param>
        /// <returns></returns>
        public bool SetTeam(Guid player, Guid room, int team)
        {
            if (team > 2)
                return false;

            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    var user = context.LoggedInUser
                        .First(p => p.Token == player);

                    PlayerRoomState prs = context.PlayerRoomState.First(p => p.UserId == user.UserId);
                    prs.Team = team;

                    context.SaveChanges();

                    SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"),
                        room,
                        "**Le joueur " + user.User.Name + " a rejoint l'équipe #" + (team + 1).ToString() + ". **");

                    return true;
                }
            }
            catch
            {
            }

            return false;
        }
Exemple #11
0
        /// <summary>
        /// Défini le master de la salle.
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <param name="newMaster"></param>
        /// <returns></returns>
        public bool SetMaster(Guid player, Guid room, string newMaster)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    // Trouve l'id du master.
                    int masterId = context.Room.First(p => p.Token == room).MasterUserId;

                    // Trouve l'id du joueur qui fait la requête.
                    int playerId = context.LoggedInUser.First(p => p.Token == player).UserId;

                    // Si le player n'est pas le master.
                    if (masterId != playerId)
                        return false;

                    // Ok. Le joueur est le master.
                    // Trouve le nouveau master id :
                    int newMasterId = context.User.First(p => p.Name == newMaster).UserId;

                    // Swap.
                    context.Room.First(p => p.Token == room).MasterUserId = newMasterId;

                    context.SaveChanges();

                    SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), room, "**Le maître de la salle est désormais " + newMaster + "**");
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Exemple #12
0
        /// <summary>
        /// Change le nom de la salle.
        /// </summary>
        /// <remarks>Le joueur doit être master.</remarks>
        /// <param name="player">Guid du joueur qui requiert.</param>
        /// <param name="room">Guid de la salle.</param>
        /// <param name="newName">Nouveau nom de la salle.</param>
        /// <returns>True si réussi, false autrement.</returns>
        public bool SetName(Guid player, Guid room, string newName)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    var lstRooms = context.Room.Where(p => p.Token == room);

                    if (lstRooms.Count() < 1)
                        return false;

                    var lstUsers = context.LoggedInUser.Where(p => p.Token == player);

                    if (lstUsers.Count() < 1)
                        return false;

                    if (lstUsers.First().UserId != lstRooms.First().MasterUserId)
                        return false;

                    Room r = context.Room.Find(lstRooms.First().RoomId);

                    r.Name = newName;
                    context.SaveChanges();

                    SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), room, "**Le nom de la salle est désormais " + r.Name + " **");
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Exemple #13
0
        /// <summary>
        /// Parse la commande demandée par l'utilisateur dans le message.
        /// </summary>
        /// <param name="input"></param>
        /// <returns>True si succès, false autrement</returns>
        /// o /teams                    => affiche les équipes.
        /// o /status                   => affiche le status des gens (prêt, pas prêt, j'y vais! :^)
        /// o /validate                 => Valide la composition et les équipes et retourne ce qui ne va pas!
        /// o /kick [name]; [reason]    => Kick le joueur "name" avec la raison "reason".
        private bool GetCommandOuput(Guid player, Guid room, string input)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    User caller = context.LoggedInUser.First(p => p.Token == player).User;

                    var lstPlayers = context.PlayerRoomState
                            .Where(p => p.Room.Token == room)
                            .OrderBy(o => o.Team);

                    string output = "";

                    if (input.StartsWith("/teams"))
                    {
                        output = "**" + caller.Name + " a demandé à afficher les équipes.**\r\n";

                        foreach (PlayerRoomState prs in lstPlayers)
                            output += "   - [" + prs.Team.ToString() + "] " + prs.User.Name + "\r\n";
                    }
                    else if (input.StartsWith("/status"))
                    {
                        output = "**" + caller.Name + " a demandé à afficher les status:**\r\n";

                        foreach (PlayerRoomState prs in lstPlayers)
                            output += "   - [" + (prs.IsReady ? "Prêt" : "Pas prêt") + "] " + prs.User.Name + "\r\n";
                    }
                    else if (input.StartsWith("/validate"))
                    {
                        // Les équipes sont-elles balancées?
                        // Les joueurs sont-ils prêts?
                        if (lstPlayers.Where(p => p.IsReady == false).Count() > 0)
                            output += "  - Certains joueurs ne sont pas prêts. (/status)\r\n";

                        byte t1 = 0;
                        byte t2 = 0;
                        byte t3 = 0;

                        foreach (var user in lstPlayers)
                        {
                            if (user.Team == 0)
                                t1++;
                            else if (user.Team == 1)
                                t2++;
                            else
                                t3++;
                        }

                        // On regarde si il y a moins de 2 équipes
                        if (t1 == 0 && (
                            (t2 == 0 || t3 == 0) ||
                            (t1 == 0 || t3 == 0)
                            ))
                        {
                            output += "  - Il y a moins de 2 équipes! (/teams)\r\n";
                        }

                        // Si 2 équipe, et la troisième vide.
                        if ((t1 != t2 && t3 == 0) ||
                            (t2 != t3 && t1 == 0) ||
                            (t3 != t1 && t2 == 0))
                        {
                            output += "  - Équipes non équilibrées! (/teams)\r\n";
                        }

                        // Si aucune erreur
                        if (output == "")
                        {
                            output += "**Validation (/validate): Tous les éléments sont prêt pour commencer une belle partie!**";
                        }
                        else
                        {
                            output = "**Validation (/validate) échouée.**\r\nRaison:\r\n" + output;
                        }
                    }
                    else if (input.StartsWith("/kick ") && input.Length > "/kick ".Length + 1 && input.Contains(";"))
                    {
                        // Si le caller est le master.
                        if (context.Room.First(p => p.Token == room).MasterUserId == caller.UserId)
                        {
                            string kName = input.Substring("/kick ".Length, input.IndexOf(';') - "/kick ".Length);
                            string reason = input.Substring(input.IndexOf(';') + 1);

                            Guid pId = context.LoggedInUser.First(p => p.User.Name == kName).Token;
                            LeaveRoom(pId, room);

                            output = "**Le joueur " + kName + " a été kické de la salle.**\r\nRaison: " + reason;
                        }
                        else
                        {
                            output = "**Avertissement. Seul le maître peut kicker un joueur.**";
                        }
                    }
                    else
                    {
                        return false;
                    }

                    if (output.Length == 0)
                        return true;

                    Room r = context.Room.First(p => p.Token == room);
                    Message msg = new Message();
                    msg.Content = output;
                    msg.Date = DateTime.UtcNow;
                    msg.Type = MessageType.ROOM; // 1== room.
                    msg.UserId = 5; // sys
                    msg.Room.Add(r);

                    context.Message.Add(msg);
                    context.SaveChanges();

                    return true;
                }
            }
            catch
            {
            }

            return false;
        }
Exemple #14
0
        /// <summary>
        /// Set un joueur "prêt".
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <param name="ready"></param>
        /// <returns>True si succès, false autrement</returns>
        public bool SetReady(Guid player, bool ready)
        {
            try
            {
                using (MilleBornesEntities tities = new MilleBornesEntities())
                {
                    LoggedInUser liu = tities.LoggedInUser.First(p => p.Token == player);
                    PlayerRoomState prsUser = tities.PlayerRoomState.First(p => p.UserId == liu.UserId);
                    prsUser.IsReady = ready;

                    tities.SaveChanges();

                    if (ready)
                        SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), prsUser.Room.Token, "**" + prsUser.User.Name + " est prêt! ☺**");
                    else
                        SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), prsUser.Room.Token, "**" + prsUser.User.Name + " n'est pas prêt! ☹**");
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Exemple #15
0
        public Guid JoinGame(Guid player, Guid room)
        {
            using (var context = new MilleBornesEntities())
            {
                var playerEntity = context.User
                    .Where(us => us.LoggedInUser != null)
                    .SingleOrDefault(us => us.LoggedInUser.Token == player);
                if (playerEntity == null)
                {
                    throw new FaultException("Le joueur n'est pas valide ou est hors-ligne.");
                }

                var roomEntity = context.Room
                    .SingleOrDefault(rm => rm.Token == room);
                if (roomEntity == null)
                {
                    throw new FaultException("La salle n'est pas trouvée.");
                }

                var game = roomEntity.Game;
                if (game == null)
                {
                    throw new FaultException("Celle salle n'est pas associée à une partie en cours.");
                }

                var playerGame = game.PlayerGame
                    .SingleOrDefault(pg => pg.UserId == playerEntity.UserId);
                if (playerGame == null)
                {
                    throw new FaultException("Le joueur n'est pas dans cette partie.");
                }

                if (playerGame.HasJoined)
                {
                    throw new FaultException("Le joueur a déja rejoint la partie.");
                }

                playerGame.HasJoined = true;
                playerGame.LastHeartbeat = DateTime.UtcNow;
                context.SaveChanges();

                return game.Token;
            }
        }
Exemple #16
0
        /// <summary>
        /// Permet de joindre une room!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <returns>True si succès, false autrement.</returns>
        public bool JoinRoom(Guid player, Guid room)
        {
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    LoggedInUser liu = context.LoggedInUser.First(p => p.Token == player);

                    // On vérifie si le user est dans la room... 
                    // vérifie si déjà dans une room
                    bool alreadyInRoom = context.PlayerRoomState
                        .Where(p => p.UserId == liu.UserId)
                        .Count() > 0;

                    Room r = context.Room.First(p => p.Token == room);

                    // Si il est dans une autre room.
                    if (alreadyInRoom)
                    {
                        if (r.MasterUserId == liu.UserId || r.PlayerRoomState.First(p => p.UserId == liu.UserId).Room.Token == room)
                        {
                            SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), room, "**Le joueur " + liu.User.Name + " revenu dans la partie ☺**");
                            return true;
                        }

                        return false;
                    }

                    PlayerRoomState prsUser = new PlayerRoomState();
                    prsUser.UserId = liu.UserId;
                    prsUser.RoomId = r.RoomId;
                    prsUser.IsReady = false;
                    prsUser.Order = 0;
                    prsUser.Team = 0;
                    prsUser.LastHeartbeat = DateTime.UtcNow;

                    context.PlayerRoomState.Add(prsUser);
                    context.SaveChanges();
                    SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), room, "**Le joueur " + liu.User.Name + " a join la partie ☺**");
                }

                return true;
            }
            catch
            {
                return false;
            }
        }
Exemple #17
0
        /// <summary>
        /// Obtient les nouveaux messages de name
        /// </summary>
        /// <param name="name">Utilisateur</param>
        /// <returns>Liste des nouveaux messages.</returns>
        public List<UserMessage> GetNewMessageFrom(Guid player, string name)
        {
            List<UserMessage> lstMessages = new List<UserMessage>();
            
            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    // Récupère les ids...
                    LoggedInUser receiver = context.LoggedInUser.First(p => p.Token == player);
                    User sender = context.User.First(p => p.Name.Trim() == name.Trim());

                    IQueryable<PrivateMessage> lstNewMessages = context.PrivateMessage.Where(p => p.ReceiverUserId == receiver.UserId
                                                                && p.SenderUserId == sender.UserId
                                                                && p.Read == false);

                    foreach (PrivateMessage pm in lstNewMessages)
                    {
                        UserMessage um = new UserMessage();
                        um.Content = pm.Message;
                        um.Date = pm.SentTime;
                        um.Username = name;

                        lstMessages.Add(um);
                        pm.Read = true;
                    }

                    context.SaveChanges();
                }
            }
            catch
            {
            }

            return lstMessages;
        }
Exemple #18
0
        public PlayCardResult PlayCard(Guid gameToken, Guid playerToken, Guid cardToken, int targetTeamIndex)
        {
            using (var context = new MilleBornesEntities())
            {
                var player = GetPlayerFromToken(context, playerToken);

                if (player == null)
                {
                    throw new FaultException("Le joueur n'est pas trouvé.");
                }

                var game = context.Game
                    .SingleOrDefault(gm => gm.Token == gameToken);

                if (game == null)
                {
                    throw new FaultException("La partie n'est pas trouvée.");
                }

                if (!GetPlayersInGame(game).All(pg => pg.HasJoined))
                {
                    return PlayCardResult.NOT_ALL_PLAYERS_PRESENT;
                }

                if (game.IsTakingDisconnectDecision)
                {
                    throw new FaultException("La partie est en attente de décison de déconnection d'un joueur.");
                }

                var playerGame = GetPlayersInGame(game)
                    .SingleOrDefault(pg => pg.UserId == player.UserId);
                if (playerGame == null)
                {
                    throw new FaultException("Le joueur n'est pas dans la partie.");
                }

                if (!playerGame.HasJoined)
                {
                    throw new FaultException("Le joueur n'a pas rejoint la partie.");
                }

                if (!ValidatePlayerHeartbeat(playerGame))
                {
                    throw new FaultException("Le heartbeat du joueur à expiré.");
                }

                if (game.EndReason != null)
                {
                    throw new FaultException("La partie est terminée.");
                }

                var currentPlayerId = GetCurrentPlayerUserId(game);
                if (currentPlayerId != player.UserId)
                {
                    LogPlayCardError(
                        "ce n'est pas le tour du joueur {0}({1})",
                        playerToken.ToString("B"),
                        player.Name
                    );

                    return PlayCardResult.WRONG_TURN;
                }

                var card = game.GameEvent
                    .Where(ge => ge.Type == GameEventType.DRAW_CARD)
                    .Cast<DrawCardEvent>()
                    .Where(dc => dc.Token == cardToken)
                    .SingleOrDefault();

                if (card == null)
                {
                    LogPlayCardError(
                        "le jeton de carte {0} est introuvable pour la partie {1}",
                        cardToken.ToString("B"),
                        gameToken.ToString("B")
                    );

                    return PlayCardResult.WRONG_TOKEN;
                }

                if (card.PlayerId != player.UserId)
                {
                    LogPlayCardError(
                        "le jeton de carte {0} est introuvable pour le joueur {1}",
                        cardToken.ToString("B"),
                        playerToken.ToString("B")
                    );

                    return PlayCardResult.WRONG_TOKEN_PLAYER;
                }

                if (card.PlayCardEvent.Count != 0)
                {
                    LogPlayCardError(
                        "le joueur {0} à joué la carte {1} déja jouée",
                        playerToken.ToString("B"),
                        cardToken.ToString("B")
                    );
                    return PlayCardResult.ALREADY_PLAYED;
                }

                if (!CanPlayCard(game, card, playerGame.Team, targetTeamIndex))
                {
                    LogPlayCardError(
                        "le joueur {0} à tenté de jouer la carte {1} sur l'équipe {2} dans un état invalide.",
                        playerToken.ToString("B"),
                        cardToken.ToString("B"),
                        targetTeamIndex
                    );
                    return PlayCardResult.CANNOT_PLAY;
                }

                PlayCardInGame(game, card, targetTeamIndex);
                context.SaveChanges();
                if (CheckGameEnd(game))
                {
                    context.SaveChanges();

                    LogMessage(
                        "Le joueur {0} joue la carte {1} sur l'équipe {2}",
                        playerToken.ToString("B"),
                        cardToken.ToString("B"),
                        targetTeamIndex
                    );
                    LogMessage(
                        "La partie {0} est terminée par la raison {1}",
                        game.Token,
                        game.EndReason
                    );

                    return PlayCardResult.SUCCESS;
                }

                DrawNewCardToPlayer(game, player);

                var newPlayer = player;
                var playedCardDef = CardDefinitions.Cards
                    .Single(cd => cd.CardId == card.CardIndex);
                if (playedCardDef.CardType != CardType.EFFECT_INVINCIBLE)
                {
                    newPlayer = GoToNextPlayer(game);
                }

                context.SaveChanges();
                LogMessage(
                    "Le joueur {0} joue la carte {1} sur l'équipe {2}, le nouveau joueur est {3}",
                    playerToken.ToString("B"),
                    cardToken.ToString("B"),
                    targetTeamIndex,
                    newPlayer.LoggedInUser.Token.ToString("B")
                );
                return PlayCardResult.SUCCESS;
            }
        }
Exemple #19
0
        /// <summary>
        /// Envoie un nouveau message.
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="message"></param>
        /// <returns>True si succès.</returns>
        public bool SendPrivateMessage(Guid from, string to, string message)
        {
            bool ok = false;

            try
            {
                using (MilleBornesEntities context = new MilleBornesEntities())
                {
                    LoggedInUser user = context.LoggedInUser.First(p => p.Token == from);
                    int receiverId = context.User.First(p => p.Name.Trim() == to.Trim()).UserId;

                    PrivateMessage pm = new PrivateMessage();
                    pm.Message = message.Trim();
                    pm.Read = false;
                    pm.ReceiverUserId = receiverId;
                    pm.SenderUserId = user.UserId;
                    pm.SentTime = DateTime.UtcNow;

                    context.PrivateMessage.Add(pm);
                    context.SaveChanges();

                    ok = true;
                }
            }
            catch 
            {
            }

            return ok;
        }
Exemple #20
0
        public void TakePlayerDisconnectionDecision(Guid playerToken, Guid gameToken, bool continueGame)
        {
            using (var context = new MilleBornesEntities())
            {
                var playerEntity = context.User
                    .Where(us => us.LoggedInUser != null)
                    .SingleOrDefault(us => us.LoggedInUser.Token == playerToken);
                if (playerEntity == null)
                {
                    throw new FaultException("Le joueur n'est pas valide ou est hors-ligne.");
                }

                var game = context.Game
                    .SingleOrDefault(rm => rm.Token == gameToken);
                if (game == null)
                {
                    throw new FaultException("La partie n'est pas trouvée.");
                }

                if (game.Room == null)
                {
                    throw new FaultException("La partie n'est pas associée à une salle.");
                }

                if (game.Room.Count > 1)
                {
                    throw new FaultException("La partie est associée à plusieurs salles.");
                }

                if (game.Room.First().MasterUserId != playerEntity.UserId)
                {
                    throw new FaultException("Seul le maître de la salle peut prendre la décision.");
                }

                if (!game.IsTakingDisconnectDecision)
                {
                    throw new FaultException("La partie n'est pas en attente d'une décision.");
                }

                if (continueGame)
                {
                    var disconnectedPlayers = GetPlayersInGame(game)
                        .Where(pg => !ValidatePlayerHeartbeat(pg));

                    foreach (var player in disconnectedPlayers)
                    {
                        player.Order = -player.Order;
                    }

                    game.IsTakingDisconnectDecision = false;
                }
                else
                {
                    EndGame(game, GameEndReason.PLAYER_DISCONNECTION);
                    game.IsTakingDisconnectDecision = false;
                }

                context.SaveChanges();
            }
        }
Exemple #21
0
        /// <summary>
        /// Quitte la salle présentement dedans.
        /// </summary>
        /// <param name="player"></param>
        /// <param name="room"></param>
        /// <returns>True si succès, false autrement</returns>
        public bool LeaveRoom(Guid player, Guid room)
        {
            try
            {
                using (MilleBornesEntities tities = new MilleBornesEntities())
                {
                    LoggedInUser u = tities.LoggedInUser.First(p => p.Token == player);

                    Room r = tities.Room.First(p => p.Token == room);

                    // Si c'est le master, on DÉTRUIT LA ROOOOOOOOOOOOOOOOOOOOOOOOOM
                    // Et tout les player state.
                    // Et tous les messages.
                    if (r.MasterUserId == u.UserId)
                    {
                        var lstPrs = tities.PlayerRoomState.Where(p => p.RoomId == r.RoomId).ToList();
                        tities.Message.RemoveRange(r.Message);
                        tities.PlayerRoomState.RemoveRange(lstPrs);
                        tities.Room.Remove(r);
                    }
                    else
                    {
                        // Sinon on quitte la salle, simplement.
                        PlayerRoomState prsUser = tities.PlayerRoomState.First(p => p.UserId == u.UserId);
                        tities.PlayerRoomState.Remove(prsUser);
                    }

                    tities.SaveChanges();

                    SendRoomMessage(Guid.ParseExact("00000000-0000-0000-0000-000000000000", "D"), room, "**Le joueur " + u.User.Name + " a quitté la partie ☹**");
                }

                return true;
            }
            catch
            {
                return false;
            }
        }