diff --git a/KoogleApp/Components/Controls/GameSetupHost.razor b/KoogleApp/Components/Controls/GameSetupHost.razor new file mode 100644 index 0000000..18a7dbd --- /dev/null +++ b/KoogleApp/Components/Controls/GameSetupHost.razor @@ -0,0 +1,5 @@ +

GameSetupHost

+ +@code { + +} diff --git a/KoogleApp/Components/Controls/NumberPanel.razor b/KoogleApp/Components/Controls/NumberPanel.razor index b78c5ee..0cedfcd 100644 --- a/KoogleApp/Components/Controls/NumberPanel.razor +++ b/KoogleApp/Components/Controls/NumberPanel.razor @@ -25,7 +25,7 @@ - @(GetThrowModeName(ThrowPanelState.Value.ThrowMode)) + @(ThrowPanelSelectors.GetThrowModeName(ThrowPanelState.Value)) Wurf @ThrowPanelState.Value.ThrowCounterPerRound von @ThrowPanelState.Value.ThrowsPerRound @@ -154,17 +154,6 @@ Dispatcher.Dispatch(new UpdatePinStateByNumberAction(number)); } - private string GetThrowModeName(ThrowMode value) - { - switch (value) - { - case ThrowMode.Decrease: - return "Abräumen"; - case ThrowMode.Reposition: - return "in die Vollen"; - default: - throw new ArgumentOutOfRangeException(nameof(value), value, null); - } - } + } diff --git a/KoogleApp/Components/Controls/ThrowCountSelect.razor b/KoogleApp/Components/Controls/ThrowCountSelect.razor new file mode 100644 index 0000000..e55b33a --- /dev/null +++ b/KoogleApp/Components/Controls/ThrowCountSelect.razor @@ -0,0 +1,51 @@ +@using KoogleApp.Store.Game.ThrowPanel + +@typeparam TState +@inject IState State + + + +@code { + private int _count; + private int Count + { + get => _count; + set + { + if (_count == value) + { + return; + } + _count = value; + OnValueChanged?.Invoke(_count); + } + } + + [Parameter, EditorRequired] + public Func ValueSelector + { + get; + set; + } = null!; + + + [Parameter, EditorRequired] + public Action OnValueChanged + { + get; + set; + } = null!; + + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + _count = ValueSelector.Invoke(State.Value); + StateHasChanged(); + } + } + +} diff --git a/KoogleApp/Components/Controls/ThrowModeSelect.razor b/KoogleApp/Components/Controls/ThrowModeSelect.razor new file mode 100644 index 0000000..26a3dec --- /dev/null +++ b/KoogleApp/Components/Controls/ThrowModeSelect.razor @@ -0,0 +1,63 @@ +@using KoogleApp.Store.Game.ThrowPanel + +@typeparam TState +@inject IState State + + + + @foreach (var item in _items) + { + @item.Name + } + + +@code { + private ThrowModeClass _throwModeClass; + + private ThrowModeClass ThrowModeClass + { + get => _throwModeClass; + set + { + if (_throwModeClass == value) + { + return; + } + _throwModeClass = value; + OnValueChanged?.Invoke(value.ThrowMode); + } + } + + [Parameter, EditorRequired] + public Func ValueSelector + { + get; + set; + } = null!; + + + [Parameter, EditorRequired] + public Action OnValueChanged + { + get; + set; + } = null!; + + + private readonly List _items = []; + + protected override void OnAfterRender(bool firstRender) + { + if (firstRender) + { + _items.Add(new ThrowModeClass(ThrowMode.Reposition, "in die Vollen")); + _items.Add(new ThrowModeClass(ThrowMode.Decrease, "Abräumen")); + + _throwModeClass = _items.FirstOrDefault(_ => _.ThrowMode == ValueSelector.Invoke(State.Value)); + StateHasChanged(); + } + } +} diff --git a/KoogleApp/Components/Dialogs/StartGameDialog.razor b/KoogleApp/Components/Dialogs/StartGameDialog.razor index cd37b66..bc5b274 100644 --- a/KoogleApp/Components/Dialogs/StartGameDialog.razor +++ b/KoogleApp/Components/Dialogs/StartGameDialog.razor @@ -1,22 +1,38 @@ -@using KoogleApp.Model +@using KoogleApp.Games +@using KoogleApp.Model +@using KoogleApp.Services +@using KoogleApp.Store.Game.Setup @using KoogleApp.Store.Game.ThrowPanel +@inject GameTypeService GameTypeService +@inject IState SetupState - + - - Save as favorite? + Neues Spiel starten? - - @foreach (var item in _items) + @foreach (var item in _gameTypes) { - @item.Item1 + @item.Name } + + + @if (_selectedSetupComponentType is not null) + { + +

Spieleinstellungen auswählen:

+
+ + + } +
+
Abbrechen @@ -25,25 +41,27 @@
@code { - private List> _items = new List>(); - + protected override void OnAfterRender(bool firstRender) { if (firstRender) { - _items.Add(new Tuple("in die Vollen", ThrowMode.Reposition)); - _items.Add(new Tuple("Abräumen", ThrowMode.Decrease)); + _gameTypes.AddRange(GameTypeService.GetGameTypes()); - _valueThrowMode = _items[0]; StateHasChanged(); } } + Type? _selectedSetupComponentType => _selectedGameType?.SetupComponentType; + + IKnownGame? _selectedGameType = null; + + private readonly List _gameTypes = []; [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } - private Tuple _valueThrowMode; + public ThrowMode ThrowMode { get; set; } [Parameter] public string Description { get; set; } = ""; @@ -55,7 +73,7 @@ // if (!string.IsNullOrEmpty(Description)) { // Snackbar.Add("Favorite added", Severity.Success); - MudDialog.Close(DialogResult.Ok(new StartParams(_valueThrowMode.Item2, 3))); + MudDialog.Close(DialogResult.Ok(new StartParams(SetupState.Value.ThrowMode, SetupState.Value.ThrowsPerRound))); } } } diff --git a/KoogleApp/Games/IKnownGame.cs b/KoogleApp/Games/IKnownGame.cs new file mode 100644 index 0000000..a57376e --- /dev/null +++ b/KoogleApp/Games/IKnownGame.cs @@ -0,0 +1,9 @@ +namespace KoogleApp.Games +{ + public interface IKnownGame + { + public string Name { get; } + + public Type SetupComponentType { get; } + } +} diff --git a/KoogleApp/Games/Training/Game.cs b/KoogleApp/Games/Training/Game.cs new file mode 100644 index 0000000..51a018f --- /dev/null +++ b/KoogleApp/Games/Training/Game.cs @@ -0,0 +1,9 @@ +namespace KoogleApp.Games.Training +{ + public class Game : IKnownGame + { + public string Name => "Training"; + + public Type SetupComponentType => typeof(Setup); + } +} diff --git a/KoogleApp/Games/Training/Setup.razor b/KoogleApp/Games/Training/Setup.razor new file mode 100644 index 0000000..654c12f --- /dev/null +++ b/KoogleApp/Games/Training/Setup.razor @@ -0,0 +1,22 @@ +@using Fluxor +@using KoogleApp.Store.Game.Setup +@using KoogleApp.Components.Controls +@using MudBlazor + +@inject IDispatcher Dispatcher +@inject IState SetupState + + + + + + + + +@code { + +} diff --git a/KoogleApp/Model/EventMessages/NumberPanelMessage.cs b/KoogleApp/Model/EventMessages/NumberPanelMessage.cs index d432af0..c58bb81 100644 --- a/KoogleApp/Model/EventMessages/NumberPanelMessage.cs +++ b/KoogleApp/Model/EventMessages/NumberPanelMessage.cs @@ -1,15 +1,15 @@ -using KoogleApp.Model.Framework; +//using KoogleApp.Model.Framework; -namespace KoogleApp.Model.EventMessages -{ - public class NumberPanelMessage: ScopedEventBase - { - public int Number { get; private set; } +//namespace KoogleApp.Model.EventMessages +//{ +// public class NumberPanelMessage: ScopedEventBase +// { +// public int Number { get; private set; } - public NumberPanelMessage(int number) - { - Scope = EventScope.Global; - Number = number; - } - } -} +// public NumberPanelMessage(int number) +// { +// Scope = EventScope.Global; +// Number = number; +// } +// } +//} diff --git a/KoogleApp/Model/EventMessages/PinToggleMessage.cs b/KoogleApp/Model/EventMessages/PinToggleMessage.cs index ac552dd..92b93b6 100644 --- a/KoogleApp/Model/EventMessages/PinToggleMessage.cs +++ b/KoogleApp/Model/EventMessages/PinToggleMessage.cs @@ -1,12 +1,12 @@ -using KoogleApp.Model.Framework; +//using KoogleApp.Model.Framework; -namespace KoogleApp.Model.EventMessages -{ - public class PinToggleMessage : ScopedEventBase - { - public PinToggleMessage() - { - Scope = EventScope.Global; - } - } -} +//namespace KoogleApp.Model.EventMessages +//{ +// public class PinToggleMessage : ScopedEventBase +// { +// public PinToggleMessage() +// { +// Scope = EventScope.Global; +// } +// } +//} diff --git a/KoogleApp/Model/EventMessages/PinValueChangedMessage.cs b/KoogleApp/Model/EventMessages/PinValueChangedMessage.cs index 2963b58..e07a416 100644 --- a/KoogleApp/Model/EventMessages/PinValueChangedMessage.cs +++ b/KoogleApp/Model/EventMessages/PinValueChangedMessage.cs @@ -1,18 +1,18 @@ -using KoogleApp.Components.Controls; -using KoogleApp.Model.Framework; +//using KoogleApp.Components.Controls; +//using KoogleApp.Model.Framework; -namespace KoogleApp.Model.EventMessages -{ - public class PinValueChangedMessage : ScopedEventBase - { - public int PinNumber { get; private set; } +//namespace KoogleApp.Model.EventMessages +//{ +// public class PinValueChangedMessage : ScopedEventBase +// { +// public int PinNumber { get; private set; } - public bool Value { get; private set; } - public PinValueChangedMessage(int pinNumber, bool value) - { - Scope = EventScope.Global; - Value = value; - PinNumber = pinNumber; - } - } -} +// public bool Value { get; private set; } +// public PinValueChangedMessage(int pinNumber, bool value) +// { +// Scope = EventScope.Global; +// Value = value; +// PinNumber = pinNumber; +// } +// } +//} diff --git a/KoogleApp/Services/GameStatusDataService.cs b/KoogleApp/Services/GameStatusDataService.cs index a4ca090..6e6ad2d 100644 --- a/KoogleApp/Services/GameStatusDataService.cs +++ b/KoogleApp/Services/GameStatusDataService.cs @@ -93,6 +93,10 @@ namespace KoogleApp.Services public void UpdateData(GameStatus content, string username) { + if (_currentData == null) + { + return; + } if (_currentData.Status == null) { throw new InvalidOperationException("Service not initialized. Call Initialize() first."); diff --git a/KoogleApp/Services/GameTypeService.cs b/KoogleApp/Services/GameTypeService.cs new file mode 100644 index 0000000..05a8f8f --- /dev/null +++ b/KoogleApp/Services/GameTypeService.cs @@ -0,0 +1,25 @@ +using KoogleApp.Games; +using System.Reflection; + +namespace KoogleApp.Services +{ + public class GameTypeService + { + public IList GetGameTypes() + { + var res = new List(); + + var assembly = Assembly.GetAssembly(typeof(IKnownGame)); + var allJobTypes = assembly + .GetTypes() + .Where(t => t.IsClass && !t.IsAbstract && + //t.Namespace.StartsWith("KoogleApp.Games") && + typeof(IKnownGame).IsAssignableFrom(t)); + + var allJobInstances = allJobTypes.Select(_ => (IKnownGame)Activator.CreateInstance(_)!); + res.AddRange(allJobInstances); + + return res; + } + } +} diff --git a/KoogleApp/Services/ServiceExtension.cs b/KoogleApp/Services/ServiceExtension.cs index 50b45d5..3d4197e 100644 --- a/KoogleApp/Services/ServiceExtension.cs +++ b/KoogleApp/Services/ServiceExtension.cs @@ -42,6 +42,8 @@ namespace KoogleApp.Services services.AddScoped(); services.AddScoped(); + services.AddSingleton(); + return services; } } diff --git a/KoogleApp/Store/Game/Setup/Actions.cs b/KoogleApp/Store/Game/Setup/Actions.cs new file mode 100644 index 0000000..7e2fa5c --- /dev/null +++ b/KoogleApp/Store/Game/Setup/Actions.cs @@ -0,0 +1,8 @@ +using KoogleApp.Store.Game.ThrowPanel; + +namespace KoogleApp.Store.Game.Setup +{ + public record SetThrowModeAction(ThrowMode ThrowMode); + + public record SetThrowsPerRoundAction(int ThrowsPerRound); +} diff --git a/KoogleApp/Store/Game/Setup/Reducer.cs b/KoogleApp/Store/Game/Setup/Reducer.cs new file mode 100644 index 0000000..acf3b2e --- /dev/null +++ b/KoogleApp/Store/Game/Setup/Reducer.cs @@ -0,0 +1,25 @@ +using Fluxor; + +namespace KoogleApp.Store.Game.Setup +{ + public static class SetupStateReducer + { + [ReducerMethod] + public static SetupState OnSetThrowModeAction(SetupState state, SetThrowModeAction action) + { + return state with + { + ThrowMode = action.ThrowMode + }; + } + + [ReducerMethod] + public static SetupState OnSetThrowsPerRoundAction(SetupState state, SetThrowsPerRoundAction action) + { + return state with + { + ThrowsPerRound = action.ThrowsPerRound + }; + } + } +} diff --git a/KoogleApp/Store/Game/Setup/State.cs b/KoogleApp/Store/Game/Setup/State.cs new file mode 100644 index 0000000..f47e0f4 --- /dev/null +++ b/KoogleApp/Store/Game/Setup/State.cs @@ -0,0 +1,12 @@ +using Fluxor; +using KoogleApp.Store.Game.ThrowPanel; + +namespace KoogleApp.Store.Game.Setup +{ + [FeatureState] + public record SetupState(ThrowMode ThrowMode, int ThrowsPerRound) + { + public SetupState() : this(ThrowMode: ThrowMode.Reposition, ThrowsPerRound:3) + { } + } +} diff --git a/KoogleApp/Store/Game/ThrowPanel/Actions.cs b/KoogleApp/Store/Game/ThrowPanel/Actions.cs index a62cb35..79c1a30 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Actions.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Actions.cs @@ -2,7 +2,7 @@ namespace KoogleApp.Store.Game.ThrowPanel { - public record TogglePinValueAction(bool IsOn, int PinNumber); + public record TogglePinValueAction(bool IsHit, int PinNumber); public record StartStopAction(ThrowPanelState State, StartParams? StartParams); diff --git a/KoogleApp/Store/Game/ThrowPanel/Reducers.cs b/KoogleApp/Store/Game/ThrowPanel/Reducers.cs index 609d36a..5d74921 100644 --- a/KoogleApp/Store/Game/ThrowPanel/Reducers.cs +++ b/KoogleApp/Store/Game/ThrowPanel/Reducers.cs @@ -18,55 +18,55 @@ namespace KoogleApp.Store.Game.ThrowPanel case 1: return state with { - Pin1State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin1State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 2: return state with { - Pin2State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin2State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 3: return state with { - Pin3State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin3State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 4: return state with { - Pin4State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin4State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 5: return state with { - Pin5State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin5State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 6: return state with { - Pin6State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin6State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 7: return state with { - Pin7State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin7State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 8: return state with { - Pin8State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin8State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; case 9: return state with { - Pin9State = action.IsOn ? PinStatus.Fallen : PinStatus.Standing, + Pin9State = action.IsHit ? PinStatus.Fallen : PinStatus.Standing, ThrowPanelStateStatus = ThrowPanelStateStatus.BeforeThrow }; } diff --git a/KoogleApp/Store/Game/ThrowPanel/Selectors.cs b/KoogleApp/Store/Game/ThrowPanel/Selectors.cs new file mode 100644 index 0000000..68c59ef --- /dev/null +++ b/KoogleApp/Store/Game/ThrowPanel/Selectors.cs @@ -0,0 +1,18 @@ +namespace KoogleApp.Store.Game.ThrowPanel +{ + public static class ThrowPanelSelectors + { + public static string GetThrowModeName(ThrowPanelState state) + { + switch (state.ThrowMode) + { + case ThrowMode.Decrease: + return "Abräumen"; + case ThrowMode.Reposition: + return "in die Vollen"; + default: + throw new ArgumentOutOfRangeException(nameof(state.ThrowMode), state.ThrowMode, null); + } + } + } +} diff --git a/KoogleApp/Store/Game/ThrowPanel/State.cs b/KoogleApp/Store/Game/ThrowPanel/State.cs index b8fe38a..f6aa3e5 100644 --- a/KoogleApp/Store/Game/ThrowPanel/State.cs +++ b/KoogleApp/Store/Game/ThrowPanel/State.cs @@ -5,6 +5,8 @@ using Microsoft.IdentityModel.Tokens; namespace KoogleApp.Store.Game.ThrowPanel { + public record ThrowModeClass(ThrowMode ThrowMode, string Name); + public enum ThrowMode { Reposition, // in die Vollen diff --git a/KoogleApp/ThrowPanelState.json b/KoogleApp/ThrowPanelState.json new file mode 100644 index 0000000..d03461c --- /dev/null +++ b/KoogleApp/ThrowPanelState.json @@ -0,0 +1,18 @@ +{ + "IsStated": false, + "BellValue": false, + "Pin1State": 0, + "Pin2State": 0, + "Pin3State": 0, + "Pin4State": 0, + "Pin5State": 0, + "Pin6State": 0, + "Pin7State": 0, + "Pin8State": 0, + "Pin9State": 0, + "ThrowsPerRound": 3, + "ThrowCounterPerRound": 1, + "ThrowMode": 0, + "ThrowPanelStateStatus": 4, + "ThrowCounter": 0 +} \ No newline at end of file diff --git a/KoogleApp/appdata.json b/KoogleApp/appdata.json deleted file mode 100644 index 83eb0fe..0000000 --- a/KoogleApp/appdata.json +++ /dev/null @@ -1,330 +0,0 @@ -{ - "CurrentData": { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 1, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 6 - } - }, - "Version": 13, - "LastModified": "2025-11-11T21:28:53.8441622+01:00", - "LastModifiedBy": "test1@test.de" - }, - "UndoHistory": [ - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 1, - "Pin5State": 2, - "Pin6State": 0, - "Pin7State": 2, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 3, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 5 - } - }, - "Version": 12, - "LastModified": "2025-11-11T21:28:53.8383228+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 2, - "Pin6State": 0, - "Pin7State": 2, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 3, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 5 - } - }, - "Version": 11, - "LastModified": "2025-11-11T21:28:51.9038117+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 1, - "Pin6State": 0, - "Pin7State": 1, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 2, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 4 - } - }, - "Version": 10, - "LastModified": "2025-11-11T21:28:51.8982999+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 2, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 4 - } - }, - "Version": 9, - "LastModified": "2025-11-11T21:28:46.3878041+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 1, - "Pin2State": 1, - "Pin3State": 1, - "Pin4State": 1, - "Pin5State": 1, - "Pin6State": 1, - "Pin7State": 1, - "Pin8State": 1, - "Pin9State": 1, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 1, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 3 - } - }, - "Version": 8, - "LastModified": "2025-11-11T21:28:46.3824896+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 1, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 3 - } - }, - "Version": 7, - "LastModified": "2025-11-11T21:28:43.6630774+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 1, - "Pin2State": 2, - "Pin3State": 1, - "Pin4State": 2, - "Pin5State": 1, - "Pin6State": 1, - "Pin7State": 2, - "Pin8State": 1, - "Pin9State": 2, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 3, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 2 - } - }, - "Version": 6, - "LastModified": "2025-11-11T21:28:43.659034+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 2, - "Pin3State": 0, - "Pin4State": 2, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 2, - "Pin8State": 0, - "Pin9State": 2, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 3, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 2 - } - }, - "Version": 5, - "LastModified": "2025-11-11T21:28:41.8730592+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 1, - "Pin3State": 0, - "Pin4State": 1, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 1, - "Pin8State": 0, - "Pin9State": 2, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 2, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 1 - } - }, - "Version": 4, - "LastModified": "2025-11-11T21:28:41.8621437+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 2, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 2, - "ThrowMode": 1, - "ThrowPanelStateStatus": 3, - "ThrowCounter": 1 - } - }, - "Version": 3, - "LastModified": "2025-11-11T21:28:37.9622236+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 1, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 1, - "ThrowMode": 1, - "ThrowPanelStateStatus": 2, - "ThrowCounter": 0 - } - }, - "Version": 2, - "LastModified": "2025-11-11T21:28:37.9354506+01:00", - "LastModifiedBy": "test1@test.de" - }, - { - "Status": { - "ThrowPanelState": { - "IsStated": true, - "BellValue": false, - "Pin1State": 0, - "Pin2State": 0, - "Pin3State": 0, - "Pin4State": 0, - "Pin5State": 0, - "Pin6State": 0, - "Pin7State": 0, - "Pin8State": 0, - "Pin9State": 0, - "ThrowsPerRound": 3, - "ThrowCounterPerRound": 1, - "ThrowMode": 1, - "ThrowPanelStateStatus": 1, - "ThrowCounter": 0 - } - }, - "Version": 1, - "LastModified": "2025-11-11T21:28:35.0126704+01:00", - "LastModifiedBy": "test1@test.de" - } - ], - "RedoHistory": [] -} \ No newline at end of file