Skip to content

Commit

Permalink
Bone held and release action options
Browse files Browse the repository at this point in the history
  • Loading branch information
LucHeart committed Nov 14, 2024
1 parent 389bda6 commit 0604d26
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 73 deletions.
18 changes: 1 addition & 17 deletions ShockOsc/Config/BehaviourConf.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
namespace OpenShock.ShockOsc.Config;

public sealed class BehaviourConf
public sealed class BehaviourConf : SharedBehaviourConfig
{
public bool RandomIntensity { get; set; }
public bool RandomDuration { get; set; }
public JsonRange<ushort> DurationRange { get; set; } = new JsonRange<ushort> { Min = 1000, Max = 5000 };
public JsonRange<byte> IntensityRange { get; set; } = new JsonRange<byte> { Min = 1, Max = 30 };
public byte FixedIntensity { get; set; } = 50;
public ushort FixedDuration { get; set; } = 2000;
public uint HoldTime { get; set; } = 250;
public uint CooldownTime { get; set; } = 5000;
public BoneHeldAction WhileBoneHeld { get; set; } = BoneHeldAction.Vibrate;
public bool SuppressPhysBoneReleaseAction { get; set; }
public bool DisableWhileAfk { get; set; } = true;
public bool ForceUnmute { get; set; }

public enum BoneHeldAction
{
Vibrate = 0,
Shock = 1,
None = 2
}
}
27 changes: 27 additions & 0 deletions ShockOsc/Config/BoneAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using OpenShock.SDK.CSharp.Models;

namespace OpenShock.ShockOsc.Config;

public enum BoneAction
{
None = 0,
Shock = 1,
Vibrate = 2,
Sound = 3
}

public static class BoneActionExtensions
{
public static readonly BoneAction[] BoneActions = Enum.GetValues(typeof(BoneAction)).Cast<BoneAction>().ToArray();

public static ControlType ToControlType(this BoneAction action)
{
return action switch
{
BoneAction.Shock => ControlType.Shock,
BoneAction.Vibrate => ControlType.Vibrate,
BoneAction.Sound => ControlType.Sound,
_ => ControlType.Vibrate
};
}
}
22 changes: 22 additions & 0 deletions ShockOsc/Config/ConfigUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using OpenShock.ShockOsc.Models;

namespace OpenShock.ShockOsc.Config;

public class ConfigUtils
{
private readonly ConfigManager _configManager;

public ConfigUtils(ConfigManager configManager)
{
_configManager = configManager;
}

public T GetGroupOrGlobal<T>(ProgramGroup group, Func<SharedBehaviourConfig, T> selector, Func<Group, bool> groupOverrideSelector)
{
if(group.ConfigGroup == null) return selector(_configManager.Config.Behaviour);

var groupOverride = groupOverrideSelector(group.ConfigGroup);
SharedBehaviourConfig config = groupOverride ? group.ConfigGroup : _configManager.Config.Behaviour;
return selector(config);
}
}
17 changes: 3 additions & 14 deletions ShockOsc/Config/Group.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
namespace OpenShock.ShockOsc.Config;

public sealed class Group
public sealed class Group : SharedBehaviourConfig
{
public required string Name { get; set; }
public IList<Guid> Shockers { get; set; } = new List<Guid>();

public bool OverrideIntensity { get; set; }

public bool RandomIntensity { get; set; }
public JsonRange<byte> IntensityRange { get; set; } = new JsonRange<byte> { Min = 1, Max = 30 };
public byte FixedIntensity { get; set; } = 50;

public bool OverrideDuration { get; set; }
public bool RandomDuration { get; set; }
public JsonRange<ushort> DurationRange { get; set; } = new JsonRange<ushort> { Min = 1000, Max = 5000 };
public ushort FixedDuration { get; set; } = 2000;

public bool OverrideCooldownTime { get; set; }
public uint CooldownTime { get; set; } = 5000;

public bool OverridePhysBoneReleaseAction { get; set; }
public bool SuppressPhysBoneReleaseAction { get; set; }
public bool OverrideBoneHeldAction { get; set; }
public bool OverrideBoneReleasedAction { get; set; }
}
17 changes: 17 additions & 0 deletions ShockOsc/Config/SharedBehaviourConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace OpenShock.ShockOsc.Config;

public class SharedBehaviourConfig
{
public bool RandomIntensity { get; set; }
public bool RandomDuration { get; set; }

public JsonRange<ushort> DurationRange { get; set; } = new JsonRange<ushort> { Min = 1000, Max = 5000 };
public JsonRange<byte> IntensityRange { get; set; } = new JsonRange<byte> { Min = 1, Max = 30 };
public byte FixedIntensity { get; set; } = 50;
public ushort FixedDuration { get; set; } = 2000;

public uint CooldownTime { get; set; } = 5000;

public BoneAction WhileBoneHeld { get; set; } = BoneAction.Vibrate;
public BoneAction WhenBoneReleased { get; set; } = BoneAction.Shock;
}
66 changes: 40 additions & 26 deletions ShockOsc/Services/ShockOsc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public sealed class ShockOsc
private readonly OscHandler _oscHandler;
private readonly LiveControlManager _liveControlManager;
private readonly ChatboxService _chatboxService;
private readonly ConfigUtils _configUtils;

private bool _oscServerActive;
private bool _isAfk;
Expand Down Expand Up @@ -64,7 +65,7 @@ public ShockOsc(ILogger<ShockOsc> logger,
OscQueryServer oscQueryServer,
ShockOscData dataLayer,
OscHandler oscHandler, LiveControlManager liveControlManager,
ChatboxService chatboxService)
ChatboxService chatboxService, ConfigUtils configUtils)
{
_logger = logger;
_oscClient = oscClient;
Expand All @@ -76,6 +77,7 @@ public ShockOsc(ILogger<ShockOsc> logger,
_oscHandler = oscHandler;
_liveControlManager = liveControlManager;
_chatboxService = chatboxService;
_configUtils = configUtils;

OnGroupsChanged += () =>
{
Expand Down Expand Up @@ -406,8 +408,7 @@ private async Task ReceiveLogic()
programGroup.TriggerMethod = TriggerMethod.PhysBoneRelease;
programGroup.LastActive = DateTime.UtcNow;
}
else if (_configManager.Config.Behaviour.WhileBoneHeld !=
BehaviourConf.BoneHeldAction.None)
else if (_configUtils.GetGroupOrGlobal(programGroup, config => config.WhileBoneHeld, group => group.OverrideBoneHeldAction) != BoneAction.None)
{
await _backendHubManager.CancelControl(programGroup);
}
Expand All @@ -416,9 +417,9 @@ private async Task ReceiveLogic()
if (!programGroup.IsGrabbed && isGrabbed)
{
// on physbone grab
ushort TheDuration = GetDuration(programGroup);
programGroup.PhysBoneGrabLimitTime = DateTime.UtcNow.AddMilliseconds(TheDuration);
_logger.LogDebug("Limiting hold duration of Group {Group} to {Duration}ms", programGroup.Name, TheDuration);
var theDuration = GetDuration(programGroup);
programGroup.PhysBoneGrabLimitTime = DateTime.UtcNow.AddMilliseconds(theDuration);
_logger.LogDebug("Limiting hold duration of Group {Group} to {Duration}ms", programGroup.Name, theDuration);
}
programGroup.IsGrabbed = isGrabbed;
return;
Expand Down Expand Up @@ -530,7 +531,6 @@ private async Task CheckProgramGroup(ProgramGroup programGroup, Guid pos, Behavi
{
_liveControlManager.ControlGroupFrameCheckLoop(programGroup, 0, ControlType.Stop);
programGroup.LastConcurrentIntensity = 0;
_logger.LogInformation("Stopping");
}

var cooldownTime = _configManager.Config.Behaviour.CooldownTime;
Expand All @@ -541,23 +541,27 @@ private async Task CheckProgramGroup(ProgramGroup programGroup, Guid pos, Behavi
programGroup.LastExecuted.AddMilliseconds(cooldownTime)
.AddMilliseconds(programGroup.LastDuration) > DateTime.UtcNow;



if (programGroup.TriggerMethod == TriggerMethod.None &&
_configManager.Config.Behaviour.WhileBoneHeld !=
BehaviourConf.BoneHeldAction.None &&
!isActiveOrOnCooldown &&
!_underscoreConfig.KillSwitch &&
programGroup.IsGrabbed &&
programGroup.PhysBoneGrabLimitTime > DateTime.UtcNow &&
programGroup.LastVibration < DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(100)))
programGroup.IsGrabbed)
{
var pullIntensityTranslated = GetPhysbonePullIntensity(programGroup, programGroup.LastStretchValue);
programGroup.LastVibration = DateTime.UtcNow;
var heldAction = _configUtils.GetGroupOrGlobal(programGroup, behaviourConfig => behaviourConfig.WhileBoneHeld,
group => group.OverrideBoneHeldAction);

if (heldAction != BoneAction.None && programGroup.PhysBoneGrabLimitTime > DateTime.UtcNow &&
programGroup.LastVibration < DateTime.UtcNow.Subtract(TimeSpan.FromMilliseconds(100)))
{
var pullIntensityTranslated = GetPhysbonePullIntensity(programGroup, programGroup.LastStretchValue);
programGroup.LastVibration = DateTime.UtcNow;

_logger.LogDebug("Vibrating/Shocking {Shocker} at {Intensity}", pos, pullIntensityTranslated);
_logger.LogDebug("Vibrating/Shocking {Shocker} at {Intensity}", pos, pullIntensityTranslated);

_liveControlManager.ControlGroupFrameCheckLoop(programGroup, pullIntensityTranslated, _configManager.Config.Behaviour.WhileBoneHeld == BehaviourConf.BoneHeldAction.Shock
? ControlType.Shock
: ControlType.Vibrate);
_liveControlManager.ControlGroupFrameCheckLoop(programGroup, pullIntensityTranslated,
heldAction.ToControlType());
}
}

if (programGroup.TriggerMethod == TriggerMethod.None)
Expand Down Expand Up @@ -589,25 +593,35 @@ private async Task CheckProgramGroup(ProgramGroup programGroup, Guid pos, Behavi
}

byte intensity;
var exclusive = false;

// Physbone was release
if (programGroup.TriggerMethod == TriggerMethod.PhysBoneRelease)
{
programGroup.TriggerMethod = TriggerMethod.None;
if (programGroup.ConfigGroup is { OverridePhysBoneReleaseAction: true } ? programGroup.ConfigGroup is { SuppressPhysBoneReleaseAction: true } : _configManager.Config.Behaviour.SuppressPhysBoneReleaseAction)
var releaseAction = _configUtils.GetGroupOrGlobal(programGroup,
behaviourConfig => behaviourConfig.WhenBoneReleased, group => group.OverrideBoneReleasedAction);

if (releaseAction == BoneAction.None)
{
programGroup.LastExecuted = DateTime.UtcNow;
programGroup.LastDuration = 0;
programGroup.LastStretchValue = 0;
return;
}

intensity = GetPhysbonePullIntensity(programGroup, programGroup.LastStretchValue);
programGroup.LastStretchValue = 0;

exclusive = true;

var heldAction = _configUtils.GetGroupOrGlobal(programGroup, behaviourConfig => behaviourConfig.WhileBoneHeld,
group => group.OverrideBoneHeldAction);

InstantAction(programGroup, GetDuration(programGroup), intensity, heldAction.ToControlType(), true);
return;
}
else intensity = GetIntensity(programGroup);

// Normal shock

intensity = GetIntensity(programGroup);

InstantAction(programGroup, GetDuration(programGroup), intensity, ControlType.Shock, exclusive);
InstantAction(programGroup, GetDuration(programGroup), intensity, ControlType.Shock, false);
}

private ushort GetScaledDuration(ProgramGroup programGroup, float scale)
Expand Down
2 changes: 2 additions & 0 deletions ShockOsc/ShockOscBootstrap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public static void AddShockOscServices(this IServiceCollection services)

services.AddSingleton<AuthService>();

services.AddSingleton<ConfigUtils>();

services.AddSingleton(provider =>
{
var config = provider.GetRequiredService<ConfigManager>();
Expand Down
33 changes: 20 additions & 13 deletions ShockOsc/Ui/Pages/Dash/Tabs/ConfigTab.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,37 @@
@using OpenShock.ShockOsc.Ui.Utils
@using OpenShock.ShockOsc.Utils
@implements IDisposable
@inject UnderscoreConfig underscoreConfig
@inject ConfigManager ConfigManager
@inject ShockOsc ShockOsc
@inject UnderscoreConfig UnderscoreConfig

@page "/dash/config"

<MudPaper Outlined="true" Class="rounded-lg mud-paper-padding">
<MudText>Global Shocker Options (_All Shocker)</MudText>
<MudText>Global Shocker Options (_All Group)</MudText>
<MudDivider/>
<MudPaper Style="display: inline-block; width: 200px; padding-top: 8px; padding-left: 5px">
<MudSelect Class="option-width" @bind-Value="ConfigManager.Config.Behaviour.WhileBoneHeld" Label="While PhysBone Held" @bind-Value:after="OnSettingsValueChangeAsync">
@foreach (BehaviourConf.BoneHeldAction boneHeldAction in Enum.GetValues(typeof(BehaviourConf.BoneHeldAction)))
<div style="display: flex; width: 600px; padding-top: 20px;">
<MudSelect Class="option-width" Dense="true" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.WhileBoneHeld" Label="While PhysBone Held" @bind-Value:after="OnSettingsValueChangeAsync">
@foreach (var boneHeldAction in BoneActionExtensions.BoneActions)
{
<MudSelectItem Value="@boneHeldAction">@boneHeldAction</MudSelectItem>
}
</MudSelect>
</MudPaper>
<MudCheckBox @bind-Value="ConfigManager.Config.Behaviour.SuppressPhysBoneReleaseAction" Class="checkbox-title" Label="Suppress PhysBone Release Action" @bind-Value:after="OnSettingsValueChangeAsync" />
<MudSelect Class="option-width" Dense="true" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.WhenBoneReleased" Label="When PhysBone Released" @bind-Value:after="OnSettingsValueChangeAsync">
@foreach (var boneReleasedAction in BoneActionExtensions.BoneActions)
{
<MudSelectItem Value="@boneReleasedAction">@boneReleasedAction</MudSelectItem>
}
</MudSelect>
</div>

<br/>
<br/>
<MudTextField Class="option-width" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.CooldownTime" Label="Cooldown Time" @bind-Value:after="OnSettingsValueChangeAsync"/>
<MudTextField Class="option-width" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.HoldTime" Label="Contact Hold Time" @bind-Value:after="OnSettingsValueChangeAsync"/>

<div style="display: flex; width: 600px; padding-top: 20px;">
<MudTextField Class="option-width" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.CooldownTime" Label="Cooldown Time (ms)" @bind-Value:after="OnSettingsValueChangeAsync"/>
<MudTextField Class="option-width" Variant="Variant.Filled" @bind-Value="ConfigManager.Config.Behaviour.HoldTime" Label="Contact Hold Time (ms)" @bind-Value:after="OnSettingsValueChangeAsync"/>
</div>


<br/>
<MudToggleGroup T="string" @bind-Value="RandomIntensityString" Style="width: 330px; margin: 30px 0 0 10px;" Delimiters="true" Rounded="true" CheckMark="false" FixedContent="false" @bind-Value:after="OnSettingsValueChangeAsync">
<MudToggleItem Value="@("Fixed Intensity")"/>
Expand Down Expand Up @@ -97,7 +104,7 @@
<MudPaper Outlined="true" Class="rounded-lg mud-paper-padding-margin">
<MudText>Game Options</MudText>
<MudDivider/>
<MudCheckBox Class="option-width option-checkbox-height" @bind-Value="underscoreConfig.KillSwitch" Label="Kill Switch" @bind-Value:after="OnSettingsValueChangeAsync"/>
<MudCheckBox Class="option-width option-checkbox-height" @bind-Value="UnderscoreConfig.KillSwitch" Label="Kill Switch" @bind-Value:after="OnSettingsValueChangeAsync"/>
<MudCheckBox Class="option-width option-checkbox-height" @bind-Value="ConfigManager.Config.Behaviour.DisableWhileAfk" Label="Disable While Afk" @bind-Value:after="OnSettingsValueChangeAsync"/>
<MudCheckBox Class="option-width option-checkbox-height" @bind-Value="ConfigManager.Config.Behaviour.ForceUnmute" Label="Force Unmute" @bind-Value:after="OnSettingsValueChangeAsync"/>
</MudPaper>
Expand All @@ -124,7 +131,7 @@
private Task OnSettingsValueChangeAsync()
{
ConfigManager.Save();
return underscoreConfig.SendUpdateForAll();
return UnderscoreConfig.SendUpdateForAll();
}

protected override void OnInitialized()
Expand Down
25 changes: 22 additions & 3 deletions ShockOsc/Ui/Pages/Dash/Tabs/GroupsTab.razor
Original file line number Diff line number Diff line change
Expand Up @@ -245,13 +245,32 @@
</MudPaper>

<MudPaper Outlined="true" Class="rounded-lg mud-paper-padding-margin">
<MudCheckBox Class="checkbox-title" @bind-Value="@CurrentGroup.OverridePhysBoneReleaseAction" Label="Override PhysBone Release Action" @bind-Value:after="OnGroupSettingsValueChange" />
<MudCheckBox Class="checkbox-title" @bind-Value="@CurrentGroup.OverrideBoneHeldAction" Label="Override PhysBone Held Action" @bind-Value:after="OnGroupSettingsValueChange" />
<MudDivider />
<MudCollapse Expanded="CurrentGroup.OverridePhysBoneReleaseAction">
<MudCollapse Expanded="CurrentGroup.OverrideBoneHeldAction">
<br/>

<MudCheckBox Class="checkbox-title" @bind-Value="@CurrentGroup.SuppressPhysBoneReleaseAction" Label="Suppress PhysBone Release Action" @bind-Value:after="OnGroupSettingsValueChange" />
<MudSelect Class="option-width" @bind-Value="CurrentGroup.OverrideBoneHeldAction" Label="When PhysBone Held" @bind-Value:after="OnGroupSettingsValueChange">

This comment has been minimized.

Copy link
@Docteh

Docteh Nov 14, 2024

Contributor

OverrideBoneHeldAction should be WhileBoneHeld

@foreach (var boneHeldAction in BoneActionExtensions.BoneActions)
{
<MudSelectItem Value="@boneHeldAction">@boneHeldAction</MudSelectItem>
}
</MudSelect>
</MudCollapse>
</MudPaper>

<MudPaper Outlined="true" Class="rounded-lg mud-paper-padding-margin">
<MudCheckBox Class="checkbox-title" @bind-Value="@CurrentGroup.OverrideBoneReleasedAction" Label="Override PhysBone Release Action" @bind-Value:after="OnGroupSettingsValueChange" />
<MudDivider />
<MudCollapse Expanded="CurrentGroup.OverrideBoneReleasedAction">
<br/>

<MudSelect Class="option-width" @bind-Value="CurrentGroup.WhenBoneReleased" Label="When PhysBone Released" @bind-Value:after="OnGroupSettingsValueChange">
@foreach (var boneReleasedAction in BoneActionExtensions.BoneActions)
{
<MudSelectItem Value="@boneReleasedAction">@boneReleasedAction</MudSelectItem>
}
</MudSelect>
</MudCollapse>
</MudPaper>

Expand Down

0 comments on commit 0604d26

Please sign in to comment.