public GameProcessor(Game game, GameVariant gameVariant, Dictionary <string, GameRole> playerDictionary, IMapper mapper) { _Game = game; _GameVariant = gameVariant; _PlayerDictionary = playerDictionary; _Mapper = mapper; }
public void StartNewGame( int boardSize, int whiteCountSize, int blackCountSize, GameVariant gameVariant, IEngine whiteEngine, IEngine blackEngine, int moveAnimationTime) { CurrentPlayer = PieceColor.White; MoveAnimationTime = moveAnimationTime; Game = new Game( whiteEngine, blackEngine, boardSize, whiteCountSize, blackCountSize, gameVariant); WhiteIsHumnan = Game.WhitePlayerEngine is HumanEngine; BlackIsHuman = Game.BlackPlayerEngine is HumanEngine; skipSize = 700 / Game.Board.Size; DrawCurrentBoard(); Game.WhitePlayerEngine.Reset(); Game.BlackPlayerEngine.Reset(); }
public async Task <GameVariant> GetGameVariantAsync(string gameVariantId) { var createResponse = await CosmosClient.CreateDatabaseIfNotExistsAsync(_DatabaseName, _DatabaseThroughput); var database = createResponse.Database; var containerProperties = new ContainerProperties(_GameVariantContainerName, _GameVariantContainerPartitionKeyPath); var containerResponse = await database.CreateContainerIfNotExistsAsync( containerProperties, _GameVariantContainerThroughput); var container = containerResponse.Container; var query = new QueryDefinition($"SELECT * FROM {_GameVariantContainerName} c WHERE c.gv_id = @gv_id") .WithParameter("@gv_id", gameVariantId); var queryIterator = container.GetItemQueryIterator <GameVariant>(query, requestOptions: new QueryRequestOptions() { MaxConcurrency = 1 }); GameVariant gameVariant = null; while (queryIterator.HasMoreResults) { var response = await queryIterator.ReadNextAsync(); gameVariant = response.FirstOrDefault(); } return(gameVariant); }
public IActionResult SureBitti() { var gameVariant = new GameVariant(); gameVariant.GameScoreCount = 0; gameVariant.GameQuestionCount = 0; gameVariant.GameIsCompleted = false; gameVariant.GameIsOver = false; gameVariant.GameVariantID = 1; _unitOfWorkGameVariant.RepositoryGameVariant.Update(gameVariant); int request = HttpContext.Response.StatusCode; if (request == 200) { TempData["Message"] = "Süreniz bitti !!!"; TempData["JS"] = "showSuccess();"; _unitOfWorkGameVariant.Complete(); return(RedirectToAction("GameArena")); } else { TempData["Message"] = "Bir sorun oluştu,tekrar deneyiniz"; TempData["JS"] = "showError();"; return(RedirectToAction("GameArena")); } }
public async void StartNewGame( int boardSize, int whiteCountSize, int blackCountSize, GameVariant gameVariant, IEngine whiteEngine, IEngine blackEngine, int moveAnimationTime) { try { BoardViewModelObject.StartNewGame( boardSize, whiteCountSize, blackCountSize, gameVariant, whiteEngine, blackEngine, moveAnimationTime); HistoryViewModelObject.History.Clear(); HistoryShowed = false; } catch (ArgumentException e) { await this.ShowMessageAsync("Błąd", $"{e.Message}"); } }
public async Task <Game> CreateNewGameAsync(GameVariant gameVariant, string organizationId, string gameMasterUserId) { var createResponse = await CosmosClient.CreateDatabaseIfNotExistsAsync(_DatabaseName, _DatabaseThroughput); var database = createResponse.Database; var containerProperties = new ContainerProperties(_GamesContainerName, _GamesContainerPartitionKeyPath); var containerResponse = await database.CreateContainerIfNotExistsAsync( containerProperties, _GamesContainerThroughput); var container = containerResponse.Container; var game = new Game { GameMasterId = gameMasterUserId, OrganizationId = organizationId, GameVariantId = gameVariant.GameVariantId, InitialValues = gameVariant.InitialProjectValues, AccessCode = CreateAccessCode(), State = GameStatusEnum.WaitingForPlayers }; var createItemResponse = await container.CreateItemAsync(game, new PartitionKey(game.GameId)); if (createItemResponse.StatusCode == HttpStatusCode.Created || createItemResponse.StatusCode == HttpStatusCode.OK) { return(game); } return(null); }
public static async Task <Score> GetScore(GameVariant gameVariant) { var scores = await MobileService.GetTable <Score>() .Where(x => x.PlayerId == Player.Id && x.GameVariantId == gameVariant.Id) .ToEnumerableAsync(); return(scores.FirstOrDefault()); }
public void Setup() { _gameVariant = JsonConvert.DeserializeObject<GameVariant>(File.ReadAllText(Config.UserGeneratedContentGameVariantJsonPath)); var mock = new Mock<IHaloSession>(); mock.Setup(m => m.Get<GameVariant>(It.IsAny<string>())) .ReturnsAsync(_gameVariant); _mockSession = mock.Object; }
public MetadataViewModel(GameVariant variant) { _variant = variant; _metadata = _variant.Metadata; _dateModifiedTimer = new Timer((object state) => { (state as MetadataViewModel).DateModified = DateTime.Now; }, this, 0, 1000); }
public TeamsSettingsViewModel(GameVariant variant) { _variant = variant; _teams = new ObservableCollection <TeamViewModel>(); for (int i = 0; i < 8; i++) { _teams.Add(new TeamViewModel(_variant.TeamSettings.GetTeam(i), i)); } }
public Game(IEngine whiteEngine, IEngine blackEngine, int boardSize, List <Piece> pieces, GameVariant variant) { WhitePlayerEngine = whiteEngine; BlackPlayerEngine = blackEngine; Board = new CheckersBoard(boardSize, pieces); History = new List <HistoryBoard>(); Variant = variant; StartDate = DateTime.Now; GameMoves = new List <Move>(); }
public int GetHeuristicScore(GameVariant variant, bool isDraw) { int score = 0; if (isDraw) { return(0); } for (int ind = 1; ind != Board.BoardArray.Length; ind++) { //-2 - czarna dama //-1 - czarny pion // 0 - brak piona // 1 - biały pion // 2 - biała dama //za każdy pionek odpowiedniego koloru dodajemy lub odejmujemy 2 punkty //w przypadku królowych dostajemy lub tracimy 6 punktów if (Board.BoardArray[ind] == 2) { score += 6; } if (Board.BoardArray[ind] == 1) { score += 2; } if (Board.BoardArray[ind] == -2) { score -= 6; } if (Board.BoardArray[ind] == -1) { score -= 2; } //czarne pionki w pierwszym rzędzie są dodatkowo punktowane dla czarnych if (Board.BoardArray[ind] < 0 && Piece.ToRow(ind, Board.Size) == Board.Size - 1) { score -= 1; } //białe pionki ostatnim rzędzie planszy są dodatkowo punktowane dla białych if (Board.BoardArray[ind] > 0 && Piece.ToRow(ind, Board.Size) == 0) { score += 1; } } //w przypadku antywarcabów odwracamy znak wyniku (dążymy do najgorszej pozycji) if (variant == GameVariant.Anticheckers) { score = -score; } return(score); }
public void Setup() { _gameVariant = JsonConvert.DeserializeObject <GameVariant>(File.ReadAllText(Halo5Config.UserGeneratedContentGameVariantJsonPath)); var mock = new Mock <IHaloSession>(); mock.Setup(m => m.Get <GameVariant>(It.IsAny <string>())) .ReturnsAsync(_gameVariant); _mockSession = mock.Object; }
/// <summary> /// Initializes a new instance of the <see cref="GameVariantViewModel"/> class based on the /// specified <paramref name="variant"/>. /// </summary> /// <param name="variant">The gametype data.</param> public GameVariantViewModel(GameVariant variant) { _variant = variant; Metadata = new MetadataViewModel(_variant); General = new GeneralSettingsViewModel(_variant); Respawn = new RespawnSettingsViewModel(_variant); Social = new SocialSettingsViewModel(_variant); MapOverrides = new MapOverridesViewModel(_variant); Loadouts = new LoadoutSettingsViewModel(_variant); Ordnance = new OrdnanceSettingsViewModel(_variant); Teams = new TeamsSettingsViewModel(_variant); }
public Move MakeMove(CheckersBoard currentBoard, GameVariant variant, List <Move> gameMoves) { Random random = new Random(); List <Move> allPossibleMoves = currentBoard.GetAllPossibleMoves(Color); int count = allPossibleMoves.Count; if (count == 0) { throw new NotAvailableMoveException(Color); } int elemIndex = MakeMoveGpu((char)currentBoard.Size, Color == PieceColor.White ? 0 : 1, currentBoard.GetBoardArray(), GetPossibleMovesArray(allPossibleMoves), MctsIterationCount, GridSize, BlockSize, variant == GameVariant.Checkers ? 0 : 1); return(allPossibleMoves[elemIndex]); }
public Move MakeMove(CheckersBoard currentBoard, GameVariant variant, List <Move> gameMoves) { List <Move> allPossibleMoves = currentBoard.GetAllPossibleMoves(Color); int count = allPossibleMoves.Count; if (count == 0) { throw new NotAvailableMoveException(Color); } int elemIndex = randomGenerator.Next(count); return(allPossibleMoves[elemIndex]); }
public static Type SingleOption(GameVariant game, MapVariant map, List <string> commands = null) { return(new Type() { GameVariant = game, Commands = commands ?? new List <string>(), SpecificMaps = new List <MapVariant>() { map, map } }); }
public async Task OnGetAsync(string matchId) { MatchId = matchId; var haloApiService = new HaloAPIService("bdd5cbaf0ca34682a8f6b50742747e6f", "https://www.haloapi.com"); PlayerStats = await haloApiService.GetArenaPostGameCarnageReport(Guid.Parse(matchId)); GameTypeName = await haloApiService.GetGameVariant(PlayerStats.GameVariantResourceId.ResourceId.ToString()); Impulses = await haloApiService.GetImpulses(); MedalAwards = await haloApiService.GetMedals(); Maps = await haloApiService.GetMaps(); }
/// <summary> /// Makes this option into a single-option voting file. Requires special handling of the server to make sure it doesn't crash from having too few voting options. /// </summary> /// <param name="game">The game that will be used. Is not validated here.</param> /// <param name="map">The map that will be used. Is not validated here.</param> /// <param name="writeImmediately">True by default. If true, writes/updates the vote file to disk immediately after updating.</param> public void MakeSingleOptionVotingFile(GameVariant game, MapVariant map, bool writeImmediately = true) { Maps = new List <MapVariant>() { map, map }; //Games = new List<GameVariant>() { game }; Types = new List <Type>() { Type.SingleOption(game, map), Type.SingleOption(game, map) }; if (writeImmediately) { WriteToDisk(); } }
public Move MakeMove(CheckersBoard currentBoard, GameVariant variant, List <Move> gameMoves) { List <Move> allPossibleMoves = currentBoard.GetAllPossibleMoves(Color); int count = allPossibleMoves.Count; if (count == 0) { throw new NotAvailableMoveException(Color); } if (count == 1) { return(allPossibleMoves.First()); } else { AlphaBetaTree tree = new AlphaBetaTree(AlphaBetaTreeDepth, Color, currentBoard); int elemIndex = tree.ChooseBestMove(variant, gameMoves); return(allPossibleMoves[elemIndex]); } }
public Move MakeMove(CheckersBoard currentBoard, GameVariant variant, List <Move> gameMoves) { List <Move> allPossibleMoves = currentBoard.GetAllPossibleMoves(Color); int count = allPossibleMoves.Count; if (count == 0) { throw new NotAvailableMoveException(Color); } if (count == 1) { return(allPossibleMoves.First()); } else { MctsTree tree = new MctsTree(NumberOfIterations, UctParameter, randomGenerator, currentBoard, Color); int elemIndex = tree.ChooseBestMove(variant, gameMoves); return(allPossibleMoves[elemIndex]); } }
public int ChooseBestMove(GameVariant variant, List <Move> gameMoves) { var lastMoves = gameMoves.Skip(Math.Max(0, gameMoves.Count - 2 * 25)).Reverse().ToList(); int numberOfLastKingMovesWithoutBeat = 0; foreach (var move in lastMoves) { if (move.OldPiece.IsKing && (move.BeatedPieces == null || move.BeatedPieces.Count == 0)) { numberOfLastKingMovesWithoutBeat++; } else { break; } } GetScore(variant, Root, int.MinValue, int.MaxValue, 0, numberOfLastKingMovesWithoutBeat); int index = Root.Children.FindIndex(n => n.CurrentScore == Root.CurrentScore); return(index); }
public static async void PublishScore(GameVariant gameVariant, string score) { var scores = await MobileService.GetTable <Score>() .Where(x => x.PlayerId == Player.Id && x.GameVariantId == gameVariant.Id) .ToEnumerableAsync(); var scoreEntry = scores.FirstOrDefault(); if (scoreEntry == null) { scoreEntry = new Score { PlayerId = Player.Id, GameVariantId = gameVariant.Id, Value = score, DateCreated = DateTime.Now }; await MobileService.GetTable <Score>().InsertAsync(scoreEntry); } else { scoreEntry.Value = score; await MobileService.GetTable <Score>().UpdateAsync(scoreEntry); } }
public override int GetHashCode() { unchecked { var hashCode = GameBaseVariantId.GetHashCode(); hashCode = (hashCode * 397) ^ (GameVariant?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ HopperId.GetHashCode(); hashCode = (hashCode * 397) ^ (Id?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ IsTeamGame.GetHashCode(); hashCode = (hashCode * 397) ^ (Links?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ MapId.GetHashCode(); hashCode = (hashCode * 397) ^ (MapVariant?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ (MatchCompletedDate?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ MatchDuration.GetHashCode(); hashCode = (hashCode * 397) ^ (Players?.GetHashCode() ?? 0); hashCode = (hashCode * 397) ^ SeasonId.GetHashCode(); hashCode = (hashCode * 397) ^ MatchCompletedDateFidelity; hashCode = (hashCode * 397) ^ (Teams?.GetHashCode() ?? 0); return(hashCode); } }
static void Main(string[] args) { Console.WriteLine("Nitrogen Variant Builder"); var variants = (from type in typeof(Program).Assembly.GetTypes() where Attribute.IsDefined(type, typeof(OutputPathAttribute)) select type); foreach (var variant in variants) { var gt = Activator.CreateInstance(variant); Console.WriteLine("Creating {0}...", gt.GetType().Name); var output = gt.GetType().GetCustomAttribute <OutputPathAttribute>(); if (output == null) { continue; } var gameVariant = new GameVariant(); if (gt is IMegaloVariant) { var megalo = gameVariant.EngineData as MegaloData; (gt as IMegaloVariant).Create(gameVariant, megalo); // megalo.Category = 25; // megalo.CategoryName.Set("Community"); } else { (gt as IGameVariant).Create(gameVariant); } gameVariant.Metadata.Category = 25; using (var fs = File.Create(output.OutputPath)) ContentFactory.CreateGameVariant(fs, gameVariant); } }
public Move MakeMove(CheckersBoard currentBoard, GameVariant variant, List <Move> gameMoves) { List <Move> allPossibleMoves = currentBoard.GetAllPossibleMoves(Color); int count = allPossibleMoves.Count; if (count == 0) { throw new NotAvailableMoveException(Color); } StringBuilder stringBuilder = new StringBuilder(); foreach (var move in allPossibleMoves) { stringBuilder.Append($"{GetPossibility(move)}, "); } stringBuilder.Remove(stringBuilder.Length - 2, 2); int beatedPawns = allPossibleMoves[0].BeatedPieces?.Count ?? 1; if (HumanMove.Count == 1 + beatedPawns) { var possibleMoves = allPossibleMoves.Where(m => m.OldPiece.Position == HumanMove[0].Position && m.NewPiece.Position == HumanMove.Last().Position).ToList(); HumanMove.Remove(HumanMove.First()); HumanMove.Remove(HumanMove.Last()); for (int i = 0; i < HumanMove.Count; i++) { possibleMoves = possibleMoves.Where(p => p.BeatedPieces[i + 1].BeatPieceColumn == HumanMove[i].Column && p.BeatedPieces[i + 1].BeatPieceRow == HumanMove[i].Row).ToList(); } var humanMove = possibleMoves.SingleOrDefault(); if (humanMove == null) { throw new WrongMoveException(allPossibleMoves[0].BeatedPieces == null ? 0 : beatedPawns, stringBuilder.ToString()); } return(humanMove); } else { throw new WrongMoveException(allPossibleMoves[0].BeatedPieces == null ? 0 : beatedPawns, stringBuilder.ToString()); } }
public SettingsWindow( MainWindow window, int boardSize, int whiteCountSize, int blackCountSize, GameVariant gameVariant, IEngine whiteEngine, IEngine blackEngine, int moveAnimationTime) { this.Left = 0; this.Top = 0; Window = window; InitializeComponent(); viewModel = new SettingsViewModel( boardSize, whiteCountSize, blackCountSize, whiteEngine, blackEngine, gameVariant, moveAnimationTime); this.DataContext = this; base.DataContext = viewModel; this.Colors = typeof(Colors) .GetProperties() .Where(prop => typeof(Color).IsAssignableFrom(prop.PropertyType)) .Select(prop => new KeyValuePair <String, Color>(prop.Name, (Color)prop.GetValue(null))) .ToList(); var theme = ThemeManager.DetectAppStyle(Application.Current); ThemeManager.ChangeAppStyle(this, theme.Item2, theme.Item1); }
public async Task <string> CreateGameVariantAsync(GameVariant gameVariant) { var createResponse = await CosmosClient.CreateDatabaseIfNotExistsAsync(_DatabaseName, _DatabaseThroughput); var database = createResponse.Database; var containerProperties = new ContainerProperties(_GameVariantContainerName, _GameVariantContainerPartitionKeyPath); var containerResponse = await database.CreateContainerIfNotExistsAsync( containerProperties, _GameVariantContainerThroughput); var container = containerResponse.Container; var createItemResponse = await container.CreateItemAsync(gameVariant, new PartitionKey(gameVariant.GameVariantId)); if (createItemResponse.StatusCode == HttpStatusCode.Created || createItemResponse.StatusCode == HttpStatusCode.OK) { return(gameVariant.GameVariantId); } return(null); }
public MapOverridesViewModel(GameVariant variant) { _variant = variant; _map = _variant.MapOverrides; _baseTraits = new TraitsViewModel(_map.BasePlayerTraits); }
public ActionResult GameType(ViewModels.UploadViewModel model) { Response.TrySkipIisCustomErrors = true; if (ModelState.IsValid) { var currentUser = UserManager.FindById(User.Identity.GetUserId<int>()); Models.GameTypeVariant variant = new Models.GameTypeVariant(); variant.Title = model.Title.Replace("\0", ""); variant.ShortDescription = model.Description; variant.Description = model.Content; variant.CreatedOn = DateTime.UtcNow; variant.AuthorId = User.Identity.GetUserId<int>(); variant.File = new Models.File() { FileSize = model.File.ContentLength, FileName = Guid.NewGuid().ToString() + ".gtv", UploadedOn = variant.CreatedOn, MD5 = model.File.InputStream.ToMD5() }; var validateGame = GameTypeService.ValidateHash(variant.File.MD5); if(validateGame != null) { Response.StatusCode = 400; return Content(string.Format( "<b>Keep it Clean!</b> The game variant has already been uploaded: <a target=\"_blank\" href=\"{0}\">{1}</a>.", Url.Action("Details", "GameType", new { slug = validateGame.Slug }), validateGame.Title)); } /* Read the map type from the uploaded file. * This is also a validation message to make sure * that the file uploaded is an actual map. */ var detectType = VariantDetector.Detect(model.File.InputStream); if (detectType == VariantType.Invalid) { // The given map doesn't exist. model.File.InputStream.Close(); Response.StatusCode = 400; return Content("<b>Keep it Clean!</b> The file uploaded is invalid. Please make sure it's a valid game variant."); } else if (detectType == VariantType.ForgeVariant) { // The given map doesn't exist. model.File.InputStream.Close(); Response.StatusCode = 400; return Content("<strong>PARDON OUR DUST!</strong> Can't upload forge variant as game variant."); } string path = System.IO.Path.Combine(Server.MapPath("~/Content/Files/GameType/"), variant.File.FileName); using (var stream = new System.IO.MemoryStream()) { model.File.InputStream.Seek(0, System.IO.SeekOrigin.Begin); model.File.InputStream.CopyTo(stream); GameVariant variantItem = new GameVariant(stream); var type = GameTypeService.GetByInternalId(variantItem.TypeId); if (type != null) { variant.GameTypeId = type.Id; variantItem.VariantName = model.Title; //variantItem.VariantAuthor = currentUser.UploaderName; variantItem.VariantDescription = variant.ShortDescription; variantItem.Save(); // Save the file. using (var fileStream = System.IO.File.Create(path)) { stream.Seek(0, System.IO.SeekOrigin.Begin); stream.CopyTo(fileStream); } } else { Response.StatusCode = 400; return Content("<strong>PARDON OUR DUST!</strong> We currently do not support the uploaded gametype."); } } GameTypeService.AddVariant(variant); GameTypeService.Save(); return Content(Url.Action("Details", "GameType", new { slug = variant.Slug })); } Response.StatusCode = 400; return View("~/Views/Shared/_ModelState.cshtml"); }
public MatchInfo(GameVariant game, MapVariant map) { GameVariant = game; MapVariant = map; }
public void Update(ServerState newState, Connection connection) { lock (ServerStateLock) { if (Status != newState.Status) { connection.RecordMatchResults(this); } if (connection.ServerHookEnabled && Teams != newState.Teams) { Scoreboard.RegenerateScoreboardImage = true; } Name = newState.Name; Port = newState.Port; HostPlayer = newState.HostPlayer; SprintEnabled = newState.SprintEnabled; SprintUnlimitedEnabled = newState.SprintUnlimitedEnabled; DualWielding = newState.DualWielding; AssassinationEnabled = newState.AssassinationEnabled; VotingEnabled = newState.VotingEnabled; Teams = newState.Teams; Map = newState.Map; MapFile = newState.MapFile; Variant = newState.Variant; VariantType = newState.VariantType; NumPlayers = newState.NumPlayers; MaxPlayers = newState.MaxPlayers; TeamScores = newState.TeamScores; Passworded = newState.Passworded; Xnkid = newState.Xnkid; Xnaddr = newState.Xnaddr; IsDedicated = newState.IsDedicated; GameVersion = newState.GameVersion; EldewritoVersion = newState.EldewritoVersion; PreviousStatus = Status; Status = newState.Status; inLobby = Status == "InLobby"; isLoading = Status == "Loading"; GameVariantType = GameVariant.GetBaseGameID(VariantType); } //string date = System.DateTime.Now.ToString("[MM-dd-yyyy HH:mm:ss] "); string date = $"[{DateTimeUTC()}] "; // Detect Match Start and End if (Status != PreviousStatus) { // Game Started if (Status == Connection.StatusStringInGame) { connection.InvokeMatchBeganOrEnded(new Connection.MatchBeginEndArgs(true, connection)); //connection.OnMatchBeginOrEnd(this, new Connection.MatchBeginEndArgs(true, connection)); connection.PrintToConsole("Game Started: " + newState.Variant + " ON " + newState.Map); } // Game Ended else if (Status == Connection.StatusStringInLobby && PreviousStatus == Connection.StatusStringInGame) { connection.InvokeMatchBeganOrEnded(new Connection.MatchBeginEndArgs(false, connection)); //connection.OnMatchBeginOrEnd(this, new Connection.MatchBeginEndArgs(false, connection)); connection.PrintToConsole("Game Ended"); PlayerStatsRecord match; foreach (PlayerInfo player in Players) { match = App.PlayerStatsRecords.Value.Find(x => x.Uid == player.Uid); if (match != null) { match.Kills += player.Kills; match.Deaths += player.Deaths; } else { match = new PlayerStatsRecord(player); if (match.IsValid) { App.PlayerStatsRecords.Value.Add(match); } } } App.PlayerStatsRecords.Save(); } } // For each player in the new server state's player list foreach (PlayerInfo player in newState.Players) { if (player.Name.Length == 0) { continue; } if (!Teams) { player.Team = -1; } else if (Status == Connection.StatusStringInLobby) { player.Team = -1; } else if (Status == Connection.StatusStringLoading) { player.Team = -1; } // If the player list does not contain this player, this player has just joined the game PlayerInfo match = Players.Find(x => x.Uid == player.Uid); if (match == null) { connection.PrintToPlayerLog(player.Name + " - " + player.ServiceTag + " : " + player.Uid + " has Joined."); connection.OnPlayerJoined(new Connection.PlayerJoinLeaveEventArgs(player, true, newState.Players.Count, date, connection)); lock (ServerStateLock) { // add new player to the player list Players.Add(player); } } } // For each player in the player list foreach (PlayerInfo player in Players) { // If the new server state's player list does not contain this player, this player has just left the game //NOTE added '&& x.Name == player.Name', so if any bugs crop up check here PlayerInfo match = newState.Players.Find(x => x.Uid == player.Uid && x.Name == player.Name); if (match == null) { connection.PrintToPlayerLog(player.Name + " - " + player.ServiceTag + " : " + player.Uid + " has Left."); connection.OnPlayerLeft(new Connection.PlayerJoinLeaveEventArgs(player, false, newState.Players.Count, date, connection)); // Mark player for removal from players list RemovePlayers.Add(player); } else { if (player.Team != match.Team && player.Team != -1 && match.Team != -1) { // Player has switched teams connection.OnPlayerTeamChanged(this, new Connection.PlayerTeamChangeEventArgs(match, player, connection)); } lock (ServerStateLock) { // Update the player's stats player.Update(match); } } } lock (ServerStateLock) { // Remove players that left from the player list foreach (PlayerInfo removePlayer in RemovePlayers) { Players.Remove(removePlayer); } RemovePlayers.Clear(); // Sort by team and then by score List <IGrouping <int, PlayerInfo> > teams = Players.GroupBy(x => x.Team).OrderBy(x => x.Key).ToList(); Players.Clear(); foreach (IGrouping <int, PlayerInfo> team in teams) { Players.AddRange(team.OrderByDescending(x => x.Score)); } OrderedTeamScores.Clear(); OrderedTeams.Clear(); RankedPlayers.Clear(); // Sort team scores for scoreboard display if (Teams) { OrderedTeamScores = TeamScores.Select( (x, i) => (Players.Any(p => p.Team == i)) ? new Tuple <int, int>(i, x) : new Tuple <int, int>(-1, x) ) // Mark all empty teams with -1 .Where(x => x.Item1 > -1) // Grab all non-empty teams .OrderByDescending(x => x.Item2).ToList(); // Order teams by score (descending) connection.PopulatedTeams = OrderedTeamScores?.Count ?? 1; for (int i = 0; i < OrderedTeamScores.Count; i++) { OrderedTeams.Add( new Tuple <Tuple <int, int>, List <PlayerInfo> >( OrderedTeamScores[i], Players.Where(x => x.Team == OrderedTeamScores[i].Item1).ToList() ) ); } } } }