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