diff --git a/GameData/Repository/ExpenseRepository.cs b/GameData/Repository/ExpenseRepository.cs index 2d37b9f..87df232 100644 --- a/GameData/Repository/ExpenseRepository.cs +++ b/GameData/Repository/ExpenseRepository.cs @@ -41,7 +41,7 @@ namespace GameData.Repository public async Task Delete(IEnumerable items) { dynamic keys = new JObject(); - keys.keys = items.Select(_ => _.Id).ToArray(); + keys.keys = new JArray(items.Select(_ => _.Id)); await _client.Delete(keys, UrlPlayerExpense); } diff --git a/GameData/Repository/GameRepository.cs b/GameData/Repository/GameRepository.cs index 2761771..d089381 100644 --- a/GameData/Repository/GameRepository.cs +++ b/GameData/Repository/GameRepository.cs @@ -97,10 +97,19 @@ namespace GameData.Repository public async Task Delete(IEnumerable gameStates) { - dynamic keys = new JObject(); - keys.keys = gameStates.Select(_ => _.Id).ToArray(); + try + { + var arr = gameStates.Select(_ => _.Id.ToString()).ToArray(); + dynamic keys = new JObject(); + keys.keys = new JArray(arr); - await _client.Delete(keys, UrlGameState); + await _client.Delete(keys, UrlGameState); + } + catch (Exception e) + { + _log.LogError(e, "error on Delete"); + throw; + } } } } diff --git a/GameHandler/ExpenseHandler.cs b/GameHandler/ExpenseHandler.cs index 1c4a254..b11de3d 100644 --- a/GameHandler/ExpenseHandler.cs +++ b/GameHandler/ExpenseHandler.cs @@ -33,12 +33,15 @@ namespace GameHandler List memberExpenses = PrepareResult(ref expenseModelToAppend); var triggers = gameExenseEventArgs.Triggers; - await AssignExpenses(gameExenseEventArgs.PlayerId, gameExenseEventArgs.PlayerIds, memberExpenses, triggers); + await AssignExpenses(gameExenseEventArgs.PlayerId, gameExenseEventArgs.PlayerIds, memberExpenses, triggers, + gameExenseEventArgs.GameStateId); return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() }; } - private async Task AssignExpenses(int playerId, int[] playerIds, List memberExpenses, ExpenseTrigger[] triggers) + private async Task AssignExpenses(int playerId, int[] playerIds, + List memberExpenses, ExpenseTrigger[] triggers, + Guid gameStateId) { var list = await _expenseRepository.GetAll(); var destExpenses = list @@ -51,17 +54,19 @@ namespace GameHandler { foreach (var player in inversePlayers) { - memberExpenses.Add(PlayerExpense.Create(player, expense)); + memberExpenses.Add(PlayerExpense.Create(player, expense, gameStateId)); } } else { - memberExpenses.Add(PlayerExpense.Create(playerId, expense)); + memberExpenses.Add(PlayerExpense.Create(playerId, expense, gameStateId)); } } } - public async Task CheckThrow(BoardState currentState, PinThrow pinThrow, int[] PlayerIds, ExpenseModel expenseModelToAppend = null) + public async Task CheckThrow(BoardState currentState, PinThrow pinThrow, int[] PlayerIds, + Guid gameStateId, + ExpenseModel expenseModelToAppend = null) { if (!PlayerIds.Any(_ => _ == pinThrow.PlayerId)) { @@ -71,7 +76,7 @@ namespace GameHandler List memberExpenses = PrepareResult(ref expenseModelToAppend); var triggers = pinThrow.GetExpenseTriggers(currentState); - await AssignExpenses(pinThrow.PlayerId, PlayerIds, memberExpenses, triggers); + await AssignExpenses(pinThrow.PlayerId, PlayerIds, memberExpenses, triggers, gameStateId); return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() }; } diff --git a/GameHandler/GameExenseEventArgs.cs b/GameHandler/GameExenseEventArgs.cs index 5e98c91..027b112 100644 --- a/GameHandler/GameExenseEventArgs.cs +++ b/GameHandler/GameExenseEventArgs.cs @@ -11,14 +11,15 @@ namespace GameHandler { public int[] PlayerIds { get; set; } public int PlayerId { get; set; } - + public Guid GameStateId { get; set; } public ExpenseTrigger[] Triggers { get; set; } - public GameExenseEventArgs(int playerId, ExpenseTrigger[] triggers, int[] playerIds) + public GameExenseEventArgs(int playerId, ExpenseTrigger[] triggers, int[] playerIds, Guid gameStateId) { PlayerId = playerId; Triggers = triggers; PlayerIds = playerIds; + GameStateId = gameStateId; } } } diff --git a/GameHandler/GameHandler/DeathGameHandler.cs b/GameHandler/GameHandler/DeathGameHandler.cs index 8c20695..8d73829 100644 --- a/GameHandler/GameHandler/DeathGameHandler.cs +++ b/GameHandler/GameHandler/DeathGameHandler.cs @@ -72,15 +72,18 @@ namespace GameHandler.DeathGame return new DeathGameModel(1, coffins.OrderBy(_ => random.Next()).ToList().ToArray(), deathGameSettings, playerIds); } - public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, ThrowState throwStateAfterUpdate) + public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, + ThrowState throwStateAfterUpdate, Guid gameStateId) { var isTrowIntoAllPins = boardStateBeforeUpdate.PinPicture.UpCount == 9; var boardCleared = pinThrow.IsCleared; var firstThrowInRound = throwStateAfterUpdate.ThrowCount == 1; - return CalcNextModel(gameModel as DeathGameModel, pinThrow.PinCount, isTrowIntoAllPins, boardCleared, firstThrowInRound); + return CalcNextModel(gameModel as DeathGameModel, pinThrow.PinCount, + isTrowIntoAllPins, boardCleared, firstThrowInRound, gameStateId); } - public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, bool boardCleared, bool firstThrowInRound) + public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, + bool boardCleared, bool firstThrowInRound, Guid gameStateId) { var current = gm.Coffins.First(); var next = gm.Coffins.Skip(1).First(); @@ -93,7 +96,7 @@ namespace GameHandler.DeathGame incX = true; if ((pinCount < 3) && firstThrowInRound) { - OnFirstThrowFailed(gm, current); + OnFirstThrowFailed(gm, current, gameStateId); incLine = true; } } @@ -192,9 +195,9 @@ namespace GameHandler.DeathGame return result; } - private void OnFirstThrowFailed(DeathGameModel gm, Coffin current) + private void OnFirstThrowFailed(DeathGameModel gm, Coffin current, Guid gameStateId) { - OnGameExpenseOccured(new GameExenseEventArgs(current.PlayerId, new[] { ExpenseTrigger.FirstThrowFail }, gm.PlayerIds)); + OnGameExpenseOccured(new GameExenseEventArgs(current.PlayerId, new[] { ExpenseTrigger.FirstThrowFail }, gm.PlayerIds, gameStateId)); } public static string GameName() diff --git a/GameHandler/GameHandler/FreeGameHandler.cs b/GameHandler/GameHandler/FreeGameHandler.cs index 12744fc..ec44f10 100644 --- a/GameHandler/GameHandler/FreeGameHandler.cs +++ b/GameHandler/GameHandler/FreeGameHandler.cs @@ -33,7 +33,8 @@ namespace GameHandler.GameHandler return new FreeGameModel(playerIds, playerIds.First(), throws); } - public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, ThrowState throwStateAfterUpdate) + public IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, + ThrowState throwStateAfterUpdate, Guid gameStateId) { if (gameModel == null) { diff --git a/GameHandler/GameService.cs b/GameHandler/GameService.cs index b81bfbb..85885ce 100644 --- a/GameHandler/GameService.cs +++ b/GameHandler/GameService.cs @@ -68,8 +68,10 @@ namespace GameHandler InitGameServiceBehaviour(gameName); var state = await InitGameState(playerIds, gameSettings, gameName); + await _gameStateHandler.Add(state); await _gameStateHandler.Add(ExpenseModel.Create()); + await _gameStateHandler.Save(); return state; } @@ -78,8 +80,11 @@ namespace GameHandler { var gm = _gh.InitGameModel(playerIds, gameSettings); var throwState = ThrowState.Create(_gh.ThrowMode(), _gh.ThrowsPerRount()); - _game = await _gameStateHandler.CreateNewGame(gameName); - return GameState.Create(_game.Id, gameName, throwState, _gh.GetCurrentPlayerId(gm), gm); + _game = await _gameStateHandler.CreateNewGame(gameName); + + var state = GameState.Create(_game.Id, gameName, throwState, _gh.GetCurrentPlayerId(gm), gm); + + return state; } private void InitGameServiceBehaviour(string gameName) @@ -107,20 +112,23 @@ namespace GameHandler } var lastGameState = _gameStateHandler.GameState; + var nextGameStateId = Guid.NewGuid(); var boardStateBeforeUpdate = lastGameState.ThrowState.BoardState; pinThrow = AutoCompletePlayerId(pinThrow); var throwStateAfterUpdate = _th.Update(lastGameState.ThrowState, pinThrow); - var gameModel = _gh.Update(pinThrow, lastGameState.GameModel, boardStateBeforeUpdate, throwStateAfterUpdate); - var expenseModel = await _eh.CheckThrow(throwStateAfterUpdate.BoardState, pinThrow, gameModel.PlayerIds, _gameStateHandler.ExpenseModel); + var gameModel = _gh.Update(pinThrow, lastGameState.GameModel, boardStateBeforeUpdate, throwStateAfterUpdate, nextGameStateId); + var expenseModel = await _eh.CheckThrow(throwStateAfterUpdate.BoardState, pinThrow, gameModel.PlayerIds, nextGameStateId, + _gameStateHandler.ExpenseModel); - var newGameState = lastGameState with { ThrowState = throwStateAfterUpdate, GameModel = gameModel, NextPlayerId = _gh.GetCurrentPlayerId(gameModel) }; + var newGameState = lastGameState with { Id = nextGameStateId, ThrowState = throwStateAfterUpdate, GameModel = gameModel, NextPlayerId = _gh.GetCurrentPlayerId(gameModel) }; - await _gameStateHandler.Add(expenseModel); await _gameStateHandler.Add(newGameState); - + await _gameStateHandler.Add(expenseModel); + await _gameStateHandler.Save(); + // todo: bei undo wird gamestate nicht korrekt gelöscht return newGameState; } diff --git a/GameHandler/GameStateHandler.cs b/GameHandler/GameStateHandler.cs index fc295a6..2afa64d 100644 --- a/GameHandler/GameStateHandler.cs +++ b/GameHandler/GameStateHandler.cs @@ -82,18 +82,29 @@ namespace GameHandler { expenseModels.Add(new GameStateHandlerItem(_gameStateId, expenseModel)); } - - - foreach(var memberExpense in expenseModel.MemberExpenses.Where(_ => !memberExpenses.Any(me => me.Data.Id.Equals(_.Id)))) - { - var item = new GameStateHandlerItem(_gameStateId, memberExpense with { GamestateId = _gameStateId }); - memberExpenses.Add(item); - await Save(item); - } - - await DeleteRedoableStates(); } + public async Task Save() + { + await DeleteRedoableStates(); // first delete undone items - otherwise ID is not unique in DB + + var gameState = gameStates.FirstOrDefault(_ => _.GameStateId == _gameStateId); + await Save(gameState); + + var expenseModelItem = expenseModels.FirstOrDefault(_ => _.GameStateId == _gameStateId); + if (expenseModelItem != null) + { + var expenseModel = expenseModelItem.Data; + foreach (var memberExpense in expenseModel.MemberExpenses.Where(_ => _.GamestateId == _gameStateId)) + { + var item = new GameStateHandlerItem(memberExpense.GamestateId, memberExpense); + memberExpenses.Add(item); + await Save(item); + } + } + } + + private async Task DeleteRedoableStates() { if (redoableGameStates.Count > 0) @@ -104,26 +115,27 @@ namespace GameHandler if (redoableMeberExpenses.Count > 0) { - await _expenseRepository.Delete(redoableMeberExpenses.Select(_ => _.Data)); + // wird über fremdschlüssel gelöscht + //await _expenseRepository.Delete(redoableMeberExpenses.Select(_ => _.Data)); redoableMeberExpenses.Clear(); } - } - private async Task Save(GameStateHandlerItem item) - { - await _expenseRepository.Save(item.Data); + redoableExpenseModels.Clear(); } internal async Task Add(GameState newState) { if (!newState.Equals(GameState)) { - _gameStateId = Guid.NewGuid(); - var item = new GameStateHandlerItem(_gameStateId, newState with { Id = _gameStateId, Counter = gameStates.Count + 1 }); + _gameStateId = newState.Id; + var item = new GameStateHandlerItem(_gameStateId, newState with { Counter = gameStates.Count + 1 }); gameStates.Add(item); - await Save(item); } } + private async Task Save(GameStateHandlerItem item) + { + await _expenseRepository.Save(item.Data); + } private async Task Save(GameStateHandlerItem item) { diff --git a/GameModel/Contracts/IGameHandler.cs b/GameModel/Contracts/IGameHandler.cs index 47fe1b0..8e27074 100644 --- a/GameModel/Contracts/IGameHandler.cs +++ b/GameModel/Contracts/IGameHandler.cs @@ -23,7 +23,7 @@ namespace GameModel.Contract int GetCurrentPlayerId(IGameModel gameModel); IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate, - ThrowState throwStateAfterUpdate); + ThrowState throwStateAfterUpdate, Guid gameStateId); event EventHandler GameExpenseOccured; } diff --git a/GameModel/PlayerExpense.cs b/GameModel/PlayerExpense.cs index 3e9c624..af90f88 100644 --- a/GameModel/PlayerExpense.cs +++ b/GameModel/PlayerExpense.cs @@ -14,5 +14,11 @@ namespace GameModel return new PlayerExpense(Guid.NewGuid(), playerId, expense.Id, expense.ExpenseType, DateTime.Now, expense.Price, expense.Name, Guid.Empty); } + + public static PlayerExpense Create(int playerId, Expense expense, Guid gameStateId) + { + return new PlayerExpense(Guid.NewGuid(), playerId, expense.Id, expense.ExpenseType, + DateTime.Now, expense.Price, expense.Name, gameStateId); + } } }