This commit is contained in:
Christian Kauer 2023-12-28 16:32:47 +01:00
parent 7bbace5cb2
commit 527975e977
8 changed files with 125 additions and 26 deletions

View File

@ -1,5 +1,6 @@
using GameData.Repository;
using GameModel.Settings;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -20,12 +21,13 @@ namespace GameData
}
private readonly HttpClient client;
private readonly ILogger<ApiClient> _logger;
private readonly AppSettings _appSettings;
private readonly string Api;
public ApiClient(AppSettings appSettings)
public ApiClient(AppSettings appSettings, ILogger<ApiClient> logger)
{
_logger = logger;
_appSettings = appSettings;
client = new HttpClient
@ -121,12 +123,12 @@ namespace GameData
else
{
var errorResult = await response.Content.ReadAsStringAsync();
//_logger.LogError("error downloading from service '{service}' with code '{statuscode}' - Result: '{result}', TargetFile: '{payload}'", serviceUrl, response.StatusCode, errorResult, targetFile);
_logger.LogError("error downloading from service '{service}' with code '{statuscode}' - Result: '{result}', TargetFile: '{payload}'", serviceUrl, response.StatusCode, errorResult, targetFile);
}
}
catch (Exception ex)
{
//_logger.LogError(ex, "error at DownloadFile");
_logger.LogError(ex, "error at DownloadFile");
}
return res;
@ -157,12 +159,12 @@ namespace GameData
else
{
var errorResult = await response.Content.ReadAsStringAsync();
//_logger.LogError("error posting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
_logger.LogError("error posting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
}
}
catch (Exception ex)
{
//_logger.LogError(ex, "error at post");
_logger.LogError(ex, "error at post");
if (!suppressExceptions)
{
throw ex;
@ -197,12 +199,12 @@ namespace GameData
else
{
var errorResult = await response.Content.ReadAsStringAsync();
//_logger.LogError("error deleting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
_logger.LogError("error deleting to service '{service}' with code '{statuscode}' - Result: '{result}', Payload: '{payload}'", serviceUrl, response.StatusCode, errorResult, JsonConvert.SerializeObject(payload));
}
}
catch (Exception ex)
{
//_logger.LogError(ex, "error at Delete");
_logger.LogError(ex, "error at Delete");
if (!suppressExceptions)
{
throw ex;
@ -212,13 +214,13 @@ namespace GameData
return res;
}
public T[] Get<T>(string serviceUrl, bool suppressExceptions = true)
public T[] Get<T>(string serviceUrl, bool suppressExceptions = false)
{
Wrapper<T> res = default;
try
{
//_logger.LogDebug($"calling service url {serviceUrl}");
_logger.LogDebug($"calling service url {serviceUrl}");
var response = client.Send(GetHttpRequestMessage(HttpMethod.Get, serviceUrl));
if (response.IsSuccessStatusCode)
@ -238,7 +240,6 @@ namespace GameData
using (var jsonTextReader = new JsonTextReader(streamReader))
{
var serializer = new JsonSerializer();
//serializer.
res = serializer.Deserialize<Wrapper<T>>(jsonTextReader);
}
}
@ -248,12 +249,12 @@ namespace GameData
else
{
var errorResult = response.Content.ReadAsStringAsync();
//_logger.LogError("error getting from service '{service}' with code '{statuscode}' - Result: '{result}'", serviceUrl, response.StatusCode, errorResult);
_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");
_logger.LogError(ex, "error at Get");
if (!suppressExceptions)
{
throw ex;

View File

@ -0,0 +1,21 @@
using GameHandler.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameHandler.Extensions;
namespace GameHandler.UnitTests.Extensions
{
[TestFixture]
internal class GameServiceExtensionTests
{
[Test]
public void GetGameHandler_ThrowsExceptionWhenGamenameIsNotValid()
{
var gs = new GameService();
Assert.That(() => gs.GetGameHandler("unknown"), Throws.TypeOf<InvaildGameNameException>());
}
}
}

View File

@ -23,20 +23,44 @@ namespace GameHandler
_expenseRepository = expenseRepository;
}
//private ExpenseModel _expenseModel = new ExpenseModel(Array.Empty<MemberExpense>());
public ExpenseModel HandleGameExenseEventArgs(GameExenseEventArgs gameExenseEventArgs, ExpenseModel expenseModelToAppend)
{
if (!gameExenseEventArgs.PlayerIds.Any(_ => _ == gameExenseEventArgs.PlayerId))
{
throw new InvalidPinThrowException($"Player {gameExenseEventArgs.PlayerId} not found");
}
List<MemberExpense> memberExpenses = PrepareResult(ref expenseModelToAppend);
var destExpenses = _expenseRepository.GetAll().Where(_ => _.ExpenseTriggers.Any(et => gameExenseEventArgs.Triggers.Any(et2 => et2 == et)));
var inversePlayers = gameExenseEventArgs.PlayerIds.Where(_ => _ != gameExenseEventArgs.PlayerId);
foreach (var expense in destExpenses)
{
if (expense.IsInverse)
{
foreach (var player in inversePlayers)
{
memberExpenses.Add(MemberExpense.Create(player, expense));
}
}
else
{
memberExpenses.Add(MemberExpense.Create(gameExenseEventArgs.PlayerId, expense));
}
}
return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() };
}
public ExpenseModel CheckThrow(BoardState currentState, PinThrow pinThrow, int[] PlayerIds, ExpenseModel expenseModelToAppend = null)
{
if (!PlayerIds.Any(_ => _ == pinThrow.PlayerId))
{
throw new InvalidPinThrowException($"Player {pinThrow.PlayerId} not found");
throw new InvalidPinThrowException($"Player {pinThrow.PlayerId} not found");
}
if (expenseModelToAppend == null)
{
expenseModelToAppend = new ExpenseModel(Array.Empty<MemberExpense>());
}
var memberExpenses = new List<MemberExpense>(expenseModelToAppend.MemberExpenses);
List<MemberExpense> memberExpenses = PrepareResult(ref expenseModelToAppend);
var triggers = pinThrow.GetExpenseTriggers(currentState);
var destExpenses = _expenseRepository.GetAll().Where(_ => _.ExpenseTriggers.Any(et => triggers.Any(et2 => et2 == et)));
@ -56,8 +80,18 @@ namespace GameHandler
memberExpenses.Add(MemberExpense.Create(pinThrow.PlayerId, expense));
}
}
return expenseModelToAppend with { MemberExpenses = memberExpenses.ToArray() };
}
private static List<MemberExpense> PrepareResult(ref ExpenseModel expenseModelToAppend)
{
if (expenseModelToAppend == null)
{
expenseModelToAppend = new ExpenseModel(Array.Empty<MemberExpense>());
}
var memberExpenses = new List<MemberExpense>(expenseModelToAppend.MemberExpenses);
return memberExpenses;
}
}
}

View File

@ -0,0 +1,24 @@
using GameModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GameHandler
{
public class GameExenseEventArgs : EventArgs
{
public int[] PlayerIds { get; set; }
public int PlayerId { get; set; }
public ExpenseTrigger[] Triggers { get; set; }
public GameExenseEventArgs(int playerId, ExpenseTrigger[] triggers, int[] playerIds)
{
PlayerId = playerId;
Triggers = triggers;
PlayerIds = playerIds;
}
}
}

View File

@ -11,7 +11,6 @@ using System.Threading.Tasks;
namespace GameHandler.DeathGame
{
public delegate void CoffinCompleted(Coffin coffin);
public delegate void FirstThrowFailed(Coffin coffin);
public class DeathGameHandler : IGameHandler
{
@ -22,7 +21,7 @@ namespace GameHandler.DeathGame
public const string GAMENAME_DEATHBOX = "Totenkiste";
public event CoffinCompleted CoffinCompleted;
public event FirstThrowFailed FirstThrowFailed;
public event EventHandler GameExpenseOccured;
private static Random random = new Random();
@ -80,7 +79,7 @@ namespace GameHandler.DeathGame
return CalcNextModel(gameModel as DeathGameModel, pinThrow.PinCount, isTrowIntoAllPins, boardCleared);
}
public DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, bool boardCleared)
private DeathGameModel CalcNextModel(DeathGameModel gm, int pinCount, bool isTrowIntoAllPins, bool boardCleared)
{
var current = gm.Coffins.First();
var next = gm.Coffins.Skip(1).First();
@ -93,7 +92,7 @@ namespace GameHandler.DeathGame
incX = true;
if (pinCount < 3)
{
FirstThrowFailed?.Invoke(current);
OnFirstThrowFailed(gm, current);
incLine = true;
}
}
@ -192,6 +191,11 @@ namespace GameHandler.DeathGame
return result;
}
private void OnFirstThrowFailed(DeathGameModel gm, Coffin current)
{
OnGameExpenseOccured(new GameExenseEventArgs(current.PlayerId, new[] { ExpenseTrigger.FirstThrowFail }, gm.PlayerIds));
}
public static string GameName()
{
return GAMENAME_DEATHBOX;
@ -209,6 +213,9 @@ namespace GameHandler.DeathGame
public int ThrowsPerRount() => IGameHandler.INFINIT_THROWS;
protected virtual void OnGameExpenseOccured(GameExenseEventArgs e)
{
GameExpenseOccured?.Invoke(this, e);
}
}
}

View File

@ -13,6 +13,9 @@ namespace GameHandler.GameHandler
public class FreeGameHandler : IGameHandler
{
public const string GAMENAME_FREETRAINING = "Freies Spiel";
public event EventHandler GameExpenseOccured;
public static string GameName()
{
return GAMENAME_FREETRAINING;

View File

@ -66,6 +66,7 @@ namespace GameHandler
_scope = _rootContainer?.BeginLifetimeScope();
_gh = this.GetGameHandler(gameName);
_gh.GameExpenseOccured += _gh_GameExpenseOccured;
var gm = _gh.InitGameModel(playerIds, gameSettings);
_th = new ThrowHandler();
@ -78,6 +79,12 @@ namespace GameHandler
}
private void _gh_GameExpenseOccured(object? sender, EventArgs e)
{
var expenseModel = _eh.HandleGameExenseEventArgs(e as GameExenseEventArgs, _lastState.ExpenseModel);
_lastState = _lastState with { ExpenseModel = expenseModel };
}
public GameState HandleThrow(PinThrow pinThrow)
{
if (!_isStarted)

View File

@ -23,6 +23,8 @@ namespace GameModel.Contract
int GetCurrentPlayerId(IGameModel gameModel);
IGameModel Update(PinThrow pinThrow, IGameModel gameModel, BoardState boardStateBeforeUpdate);
event EventHandler GameExpenseOccured;
}
}