async Task <GameData> IGameRepository.UpdateGameAsync(int id, GameUpdateData update, CancellationToken cancellationToken) { var existingGame = await _context.Game.SingleOrDefaultAsync(x => x.GamePk == id, cancellationToken : cancellationToken); if (existingGame == null) { throw new CardHeroDataException($"Game { id } does not exist."); } if (update.CurrentUserId.IsSet) { existingGame.CurrentUserFk = update.CurrentUserId.Value; } if (update.EndTime.IsSet) { existingGame.EndTime = update.EndTime.Value; } if (update.WinnerUserId.IsSet) { existingGame.WinnerUserFk = update.WinnerUserId.Value; } await _context.SaveChangesAsync(cancellationToken : cancellationToken); return(await GetGameByIdInternalAsync(id, cancellationToken : cancellationToken)); }
async Task IGamePlayService.MakeMoveAsync(MoveModel move, CancellationToken cancellationToken) { var game = await ValidateMoveInternalAsync(move, cancellationToken : cancellationToken); var turns = await _turnRepository.GetTurnsByGameIdAsync(game.Id, cancellationToken : cancellationToken); var currentTurn = turns .Where(x => !x.EndTime.HasValue) .OrderByDescending(x => x.StartTime) .FirstOrDefault(); var turnUpdate = new TurnUpdateData { EndTime = DateTime.UtcNow, }; await _turnRepository.UpdateTurnAsync(currentTurn.Id, turnUpdate, cancellationToken : cancellationToken); var currentMove = new MoveData { GameDeckCardCollectionId = move.GameDeckCardCollectionId, Column = move.Column, Row = move.Row, TurnId = currentTurn.Id, }; await _moveRepository.AddMoveAsync(currentMove, cancellationToken : cancellationToken); var nextUserId = game.UserIds .SkipWhile(x => x != move.UserId) .Skip(1) .FirstOrDefault(); if (nextUserId == default) { nextUserId = game.UserIds.First(); } var newTurn = new TurnData { CurrentUserId = nextUserId, GameId = game.Id, StartTime = DateTime.UtcNow, }; await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken); var gameUpdate = new GameUpdateData { CurrentUserId = nextUserId, }; await _gameRepository.UpdateGameAsync(game.Id, gameUpdate, cancellationToken : cancellationToken); }
async Task IHandleWinnerHandler.HandleAsync(int gameId, IEnumerable <int> userIds, CancellationToken cancellationToken) { var moves = await _moveService.GetMovesAsync(gameId, cancellationToken : cancellationToken); var cardIds = moves.Select(x => x.CardId).ToArray(); var result = await _cardService.GetCardsAsync( new Abstractions.CardSearchFilter { Ids = cardIds, }, cancellationToken : cancellationToken); var cards = result.Results; var newMoves = await _moveUserService.PopulateMoveUsersAsync(moves, cards, userIds, cancellationToken : cancellationToken); var groupedMoves = newMoves .GroupBy(x => x.UserId) .Select(x => new { UserId = x.Key, Count = x.Count() - (x.Key == userIds.First() ? 1 : 0), }) .OrderByDescending(x => x.Count) .ToArray() ; var highestValue = groupedMoves[0].Count; var gameUpdate = new GameUpdateData { EndTime = DateTime.UtcNow, }; if (groupedMoves.Skip(1).Any(x => x.Count == highestValue)) { // draw } else if (groupedMoves.Skip(1).Any(x => x.Count > highestValue)) { // winner is someone else gameUpdate.WinnerUserId = groupedMoves.Skip(1).First(x => x.Count > highestValue).UserId; } else { gameUpdate.WinnerUserId = groupedMoves[0].UserId; } await _gameRepository.UpdateGameAsync(gameId, gameUpdate, cancellationToken : cancellationToken); }
private async Task PrepareGameForPlayAsync(int id, int[] userIds, CancellationToken cancellationToken) { var randomUserIds = userIds.OrderBy(x => RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue)).ToArray(); var currentUserId = randomUserIds[0]; var updateGame = new GameUpdateData { CurrentUserId = currentUserId, }; await _gameRepository.UpdateGameAsync(id, updateGame, cancellationToken : cancellationToken); await _gameRepository.UpdateGameUsersOrderAsync(id, randomUserIds, cancellationToken : cancellationToken); var newTurn = new TurnData { CurrentUserId = currentUserId, GameId = id, }; await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken); }
void UpdateClientGameState(GameUpdateData gameUpdateData) { LastReceivedServerTick = gameUpdateData.Frame; foreach (PlayerSpawnData data in gameUpdateData.SpawnDataData) { if (data.Id != ConnectionManager.Instance.PlayerId) { SpawnPlayer(data); } } foreach (PlayerDespawnData data in gameUpdateData.DespawnDataData) { if (players.ContainsKey(data.Id)) { Destroy(players[data.Id].gameObject); players.Remove(data.Id); } } foreach (PlayerStateData data in gameUpdateData.UpdateData) { ClientPlayer p; if (players.TryGetValue(data.Id, out p)) { p.OnServerDataUpdate(data); } } foreach (PlayerHealthUpdateData data in gameUpdateData.HealthData) { ClientPlayer p; if (players.TryGetValue(data.PlayerId, out p)) { p.SetHealth(data.Value); } } }
void PerformGameUpdate(GameUpdateData updateData) { LastRecievedServerTick = updateData.Frame; foreach (PlayerSpawnData data in updateData.SpawnData) { if (data.Id != GlobalManager.Instance.PlayerId) { SpawnPlayer(data); } } foreach (PlayerDespawnData data in updateData.DespawnData) { if (players.ContainsKey(data.Id)) { Destroy(players[data.Id].gameObject); players.Remove(data.Id); } } foreach (PlayerUpdateData data in updateData.UpdateData) { ClientPlayer p; if (players.TryGetValue(data.Id, out p)) { p.OnServerDataUpdate(data); } } foreach (PLayerHealthUpdateData data in updateData.HealthData) { ClientPlayer p; if (players.TryGetValue(data.PlayerId, out p)) { p.SetHealth(data.Value); } } }
private void OnGameUpdate(GameUpdateData updateData) => buffer.Add(updateData);
private async Task AddUserToGameInternalAsync(int id, int userId, int deckId, CancellationToken cancellationToken = default) { var game = await _gameRepository.GetGameByIdAsync(id); if (game == null) { throw new InvalidGameException($"Game { id } does not exist."); } var gameUsers = await _gameRepository.GetGameUsersAsync(id, cancellationToken : cancellationToken); if (gameUsers.Any(x => x.Id == userId)) { throw new InvalidPlayerException($"User { userId } is already in game { id }."); } var gul = gameUsers.Length; if (gul >= game.MaxPlayers) { throw new InvalidPlayerException($"Game { id } is already filled."); } var deck = await _deckRepository.GetDeckByIdAsync(deckId, userId, cancellationToken : cancellationToken); if (deck == null) { throw new InvalidDeckException($"Deck { deckId } does not exist."); } if (deck.UserId != userId) { throw new InvalidDeckException($"Deck { deckId } does not belong to user { userId }."); } var dc = deck.Cards.Select(x => x.CardId).ToArray(); var dcc = dc.Length; if (dcc < deck.MaxCards) { throw new InvalidDeckException($"Deck { deckId } needs { deck.MaxCards } cards. Currently only has { dcc }."); } await _gameDeckRepository.AddGameDeckAsync(id, userId, deck.Name, deck.Description, dc, cancellationToken : cancellationToken); if (gul + 1 == game.MaxPlayers) { var allUsers = gameUsers.Select(x => x.Id).Concat(new int[] { userId }).ToArray(); var currentUserIdx = new Random().Next(0, allUsers.Length); var currentUserId = allUsers[currentUserIdx]; var updateGame = new GameUpdateData { CurrentUserId = currentUserId, }; await _gameRepository.UpdateGameAsync(id, updateGame, cancellationToken : cancellationToken); var newTurn = new TurnData { CurrentUserId = currentUserId, GameId = game.Id, }; await _turnRepository.AddTurnAsync(newTurn, cancellationToken : cancellationToken); } }
void OnGameUpdate(GameUpdateData gameUpdateData) { gameUpdateDataBuffer.Add(gameUpdateData); }
private void FixedUpdate() { if (!IsRunning) { return; } ServerTick++; foreach (var p in serverPlayers) { p.PlayerPreUpdate(); } // player states updaten for (int i = 0; i < serverPlayers.Count; i++) { var p = serverPlayers[i]; playerStates[i] = p.PlayerUpdate(); } // bullet states updaten for (int i = 0; i < serverBullets.Count; i++) { var b = serverBullets[i]; bulletStates[b.Id] = b.BulletUpdate(); } // updates an alle clients schicken var playerStateUpdates = playerStates.ToArray(); var despawnDataUpdates = playerDespawns.ToArray(); var bulletStateUpdates = new BulletStateData[bulletStates.Count]; bulletStates.Values.CopyTo(bulletStateUpdates, 0); var bulletDespawnUpdates = bulletDespawns.ToArray(); foreach (var p in serverPlayers) { var updateData = new GameUpdateData( p.InputTick, playerStateUpdates, despawnDataUpdates, bulletStateUpdates, bulletDespawnUpdates ); //Debug.Log($"sending update: {updateData.Frame}"); using (var msg = Message.Create((ushort)MessageTag.GameUpdate, updateData)) { p.Client.SendMessage(msg, SendMode.Reliable); } } // bullets für den nächsten frame initialisieren while (requestedBullets.Count > 0) { var bullet = requestedBullets.Dequeue(); SpawnBullet(bullet); } playerDespawns.Clear(); bulletDespawns.Clear(); }
void OnGameUpdate(GameUpdateData updateData) { gameUpdateBuffer.Add(updateData); }