From 2756c589ae40833e81134c135a3008cdcf355028 Mon Sep 17 00:00:00 2001 From: Christian Kauer Date: Fri, 29 Dec 2023 22:04:27 +0100 Subject: [PATCH] dev --- GameData/ApiClient.cs | 50 ++++++++++++++++++++++++++ GameData/Dummy/DummyGameRepository.cs | 5 +++ GameData/Repository/GameRepository.cs | 5 +++ GameHandler/GameService.cs | 15 ++++++++ GameHandler/GameStateHandler.cs | 10 ++++++ GameModel/Contracts/IGameRepository.cs | 1 + GameModel/Game.cs | 6 ++-- GameModel/GameStatus.cs | 15 ++++++++ KoogleCli/Program.cs | 35 ++++++++++++------ 9 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 GameModel/GameStatus.cs diff --git a/GameData/ApiClient.cs b/GameData/ApiClient.cs index 2a1553a..3460ba5 100644 --- a/GameData/ApiClient.cs +++ b/GameData/ApiClient.cs @@ -282,6 +282,56 @@ namespace GameData return res.Data; } + public async Task GetSingle(string serviceUrl, bool suppressExceptions = false) + { + WrapperSingle res = default; + + try + { + _logger.LogDebug($"calling service url {serviceUrl}"); + var response = await client.SendAsync(GetHttpRequestMessage(HttpMethod.Get, serviceUrl)); + + if (response.IsSuccessStatusCode) + { + using (var responseStream = response.Content.ReadAsStream()) + { + using (var streamReader = new StreamReader(responseStream)) + { + string content; + if (typeof(T).Equals(typeof(string))) + { + content = streamReader.ReadToEnd(); + res = (WrapperSingle)Convert.ChangeType(content, typeof(T)); + } + else + { + using (var jsonTextReader = new JsonTextReader(streamReader)) + { + var serializer = new JsonSerializer(); + res = serializer.Deserialize>(jsonTextReader); + } + } + } + } + } + else + { + var errorResult = await response.Content.ReadAsStringAsync(); + _logger.LogError("error getting from service '{service}' with code '{statuscode}' - Result: '{result}'", serviceUrl, response.StatusCode, errorResult); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "error at Get"); + if (!suppressExceptions) + { + throw ex; + } + } + + return res.Data; + } + internal async Task Put(object payload, string serviceUrl, bool suppressExceptions = false) { T res = default; diff --git a/GameData/Dummy/DummyGameRepository.cs b/GameData/Dummy/DummyGameRepository.cs index ffa0903..237a31e 100644 --- a/GameData/Dummy/DummyGameRepository.cs +++ b/GameData/Dummy/DummyGameRepository.cs @@ -32,5 +32,10 @@ namespace GameData.Dummy { throw new NotImplementedException(); } + + public Task LoadGame(Guid gameId) + { + throw new NotImplementedException(); + } } } diff --git a/GameData/Repository/GameRepository.cs b/GameData/Repository/GameRepository.cs index ff352f5..88d1b65 100644 --- a/GameData/Repository/GameRepository.cs +++ b/GameData/Repository/GameRepository.cs @@ -58,5 +58,10 @@ namespace GameData.Repository { return await _client.Post(game, UrlGame); } + + public async Task LoadGame(Guid gameId) + { + return await _client.GetSingle(UrlGame + "/" + gameId); + } } } diff --git a/GameHandler/GameService.cs b/GameHandler/GameService.cs index f74d686..273535c 100644 --- a/GameHandler/GameService.cs +++ b/GameHandler/GameService.cs @@ -153,6 +153,21 @@ namespace GameHandler return ThrowCommandParser.Parse(stringData, _gh.FreePlayerSelection(), 0); } + public async Task Load(Guid gameId) + { + Game game = null; + using (var scope = _rootContainer?.BeginLifetimeScope()) + { + var gs = new GameStateHandler(_scope.Resolve(), _scope.Resolve()); + game = await gs.LoadGame(gameId); + } + + _game = game; + InitGameServiceBehaviour(game.GameName); + var res = await _gameStateHandler.LoadState(game.Id); + return res; + } + public bool FreePlayerSelection => _gh.FreePlayerSelection(); } } diff --git a/GameHandler/GameStateHandler.cs b/GameHandler/GameStateHandler.cs index ded2997..5ed237e 100644 --- a/GameHandler/GameStateHandler.cs +++ b/GameHandler/GameStateHandler.cs @@ -118,5 +118,15 @@ namespace GameHandler { return await _gameRepository.Create(null); } + + internal Task LoadState(Guid gameId) + { + throw new NotImplementedException(); + } + + internal async Task LoadGame(Guid gameId) + { + return await _gameRepository.LoadGame(gameId); + } } } diff --git a/GameModel/Contracts/IGameRepository.cs b/GameModel/Contracts/IGameRepository.cs index 421e81b..666b84d 100644 --- a/GameModel/Contracts/IGameRepository.cs +++ b/GameModel/Contracts/IGameRepository.cs @@ -10,6 +10,7 @@ namespace GameModel.Contracts { Task Create(Game game); GameState Load(Guid gameId); + Task LoadGame(Guid gameId); Task Save(GameState gameState); Task Update(Game game); } diff --git a/GameModel/Game.cs b/GameModel/Game.cs index d51acec..08eacc4 100644 --- a/GameModel/Game.cs +++ b/GameModel/Game.cs @@ -6,11 +6,11 @@ using System.Threading.Tasks; namespace GameModel { - public record Game(Guid Id) + public record Game(Guid Id, GameStatus GameStatus, string GameName) { - public static Game Create() + public static Game Create(string gameName) { - return new Game(Guid.NewGuid()); + return new Game(Guid.NewGuid(), GameStatus.Running, gameName); } } } diff --git a/GameModel/GameStatus.cs b/GameModel/GameStatus.cs new file mode 100644 index 0000000..5f5243e --- /dev/null +++ b/GameModel/GameStatus.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GameModel +{ + public enum GameStatus + { + Running, + Finnished, + Aborted + } +} diff --git a/KoogleCli/Program.cs b/KoogleCli/Program.cs index ef7abe4..dbd126e 100644 --- a/KoogleCli/Program.cs +++ b/KoogleCli/Program.cs @@ -74,6 +74,7 @@ async Task ShowMainMenu() .AddChoices(new[] { new Option("Neues Spiel",NewGameAction), new Option("Stammdaten", MasterDataAction), + new Option("Fortsetzen", ContinueGame), new Option("Beenden", null) })); option.Action?.Invoke(); @@ -85,6 +86,11 @@ async Task ShowMainMenu() } while (true); } +void ContinueGame() +{ + StartGameAction("", new Guid("597956fe-6d83-424f-865f-5856b63f82c9")); +} + void MasterDataAction() { Console.WriteLine("todo"); @@ -98,7 +104,7 @@ void NewGameAction() //do //{ var games = new GameService(null).GetGameHandler().Keys.Order().ToList(); - games.Add("Abbreche"); + games.Add("Abbrechen"); option = AnsiConsole.Prompt( new SelectionPrompt() @@ -119,21 +125,30 @@ void NewGameAction() } else { - StartGameAction(option); + StartGameAction(option, Guid.Empty); } } -void StartGameAction(string gameName) +void StartGameAction(string gameName, Guid gameId) { _gs = new GameService(container); - var starttask = _gs.Start(new[] { 1, 2, 3, 4 }, GetGameSettings(gameName), gameName); - var bs = starttask.Result; - - Show(bs); + GameState gameState = null; + + if (gameId.Equals(Guid.Empty)) + { + var starttask = _gs.Start(new[] { 1, 2, 3, 4 }, GetGameSettings(gameName), gameName); + gameState = starttask.Result; + } else + { + var starttask = _gs.Load(gameId); + gameState = starttask.Result; + } + + Show(gameState); do { - var proptText = _gs.FreePlayerSelection ? $"Spieler,Wurf [yellow]{bs.ThrowState.ThrowCount + 1}[/]:" : $"Wurf [yellow]{bs.ThrowState.ThrowCount + 1}[/]"; + var proptText = _gs.FreePlayerSelection ? $"Spieler,Wurf [yellow]{gameState.ThrowState.ThrowCount + 1}[/]:" : $"Wurf [yellow]{gameState.ThrowState.ThrowCount + 1}[/]"; var stringData = AnsiConsole.Prompt( new TextPrompt(proptText) @@ -160,8 +175,8 @@ void StartGameAction(string gameName) } var task = _gs.HandleThrow(PinThrow.Create(throwData.Pindata, throwData.Bell, throwData.Sink, throwData.PlayerId)); - bs = task.Result; - Show(bs); + gameState = task.Result; + Show(gameState); } while (true);