Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions ShockOsc/Services/OscHandler.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
using OpenShock.Desktop.ModuleBase.Config;
using OpenShock.Desktop.ModuleBase.Models;
using OpenShock.ShockOSC.Config;
using OpenShock.ShockOSC.OscChangeTracker;
using OpenShock.ShockOSC.Utils;
Expand All @@ -13,6 +15,8 @@ public sealed class OscHandler
private readonly ChangeTrackedOscParam<float> _paramAnyCooldownPercentage;
private readonly ChangeTrackedOscParam<float> _paramAnyIntensity;

private readonly ConcurrentDictionary<Guid, LastControlLogEntry> _lastControlLogs = new();

private readonly ILogger<OscHandler> _logger;
private readonly OscClient _oscClient;
private readonly IModuleConfig<ShockOscConfig> _moduleConfig;
Expand Down Expand Up @@ -71,10 +75,11 @@ await _oscClient.SendGameMessage("/input/Voice", false)
public async Task SendParams()
{
// TODO: maybe force resend on avatar change
var anyActive = false;

await UpdateAnyActive();

var anyCooldown = false;
var anyCooldownPercentage = 0f;
var anyIntensity = 0f;

foreach (var shocker in _shockOscData.ProgramGroups.Values)
{
Expand All @@ -99,16 +104,46 @@ public async Task SendParams()
await shocker.ParamCooldown.SetValue(onCoolDown);
await shocker.ParamCooldownPercentage.SetValue(cooldownPercentage);
await shocker.ParamIntensity.SetValue(intensity);

if (isActive) anyActive = true;

if (onCoolDown) anyCooldown = true;
anyCooldownPercentage = MathF.Max(anyCooldownPercentage, cooldownPercentage);
anyIntensity = MathF.Max(anyIntensity, intensity);
}

await _paramAnyActive.SetValue(anyActive);

await _paramAnyCooldown.SetValue(anyCooldown);
await _paramAnyCooldownPercentage.SetValue(anyCooldownPercentage);
await _paramAnyIntensity.SetValue(anyIntensity);
}

private async Task UpdateAnyActive()
{
var now = DateTimeOffset.UtcNow;
var anyActive = false;
var maxIntensity = 0f;

foreach (var logEntry in _lastControlLogs.Values)
{
if(logEntry.ControlLog.Type != ControlType.Shock) continue;
var activeUntil = logEntry.Timestamp.AddMilliseconds(logEntry.ControlLog.Duration);

if (activeUntil < now) continue;

anyActive = true;
var intensity = MathUtils.Saturate(logEntry.ControlLog.Intensity / 100f);
maxIntensity = MathF.Max(maxIntensity, intensity);
}

await _paramAnyActive.SetValue(anyActive);
await _paramAnyIntensity.SetValue(maxIntensity);
}

public void SetLastControlCommand(LastControlLogEntry controlLogs)
{
_lastControlLogs[controlLogs.ControlLog.Shocker.Id] = controlLogs;
}

public class LastControlLogEntry
{
public required DateTimeOffset Timestamp { get; set; }
public required ControlLog ControlLog { get; set; }
}

}
53 changes: 33 additions & 20 deletions ShockOsc/ShockOSCModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
using OpenShock.ShockOSC.Services;
using OpenShock.ShockOSC.Ui.Pages.Dash.Tabs;
using OscQueryLibrary;

// ReSharper disable InconsistentNaming

[assembly:DesktopModule(typeof(ShockOSCModule), "openshock.shockosc", "ShockOSC")]
[assembly: DesktopModule(typeof(ShockOSCModule), "openshock.shockosc", "ShockOSC")]

namespace OpenShock.ShockOSC;

public sealed class ShockOSCModule : DesktopModuleBase, IAsyncDisposable
Expand Down Expand Up @@ -50,16 +52,14 @@ public sealed class ShockOSCModule : DesktopModuleBase, IAsyncDisposable

public override async Task Setup()
{

var config = await ModuleInstanceManager.GetModuleConfig<ShockOscConfig>();
ModuleServiceProvider = BuildServices(config);

}

private IServiceProvider BuildServices(IModuleConfig<ShockOscConfig> config)
{
var loggerFactory = ModuleInstanceManager.AppServiceProvider.GetRequiredService<ILoggerFactory>();

var services = new ServiceCollection();

services.AddSingleton(loggerFactory);
Expand All @@ -71,45 +71,58 @@ private IServiceProvider BuildServices(IModuleConfig<ShockOscConfig> config)
services.AddSingleton<OscClient>();
services.AddSingleton<OscHandler>();
services.AddSingleton<ChatboxService>();

services.AddSingleton(_ =>
{
var listenAddress = config.Config.Osc.QuestSupport ? IPAddress.Any : IPAddress.Loopback;
return new OscQueryServer("ShockOSC", listenAddress);
});

services.AddSingleton<ShockOsc>();
services.AddSingleton<UnderscoreConfig>();


return services.BuildServiceProvider();
}
}

public override async Task Start()
{
var config = ModuleServiceProvider.GetRequiredService<IModuleConfig<ShockOscConfig>>();

await ModuleServiceProvider.GetRequiredService<ShockOsc>().Start();

if (config.Config.Osc.OscQuery) ModuleServiceProvider.GetRequiredService<OscQueryServer>().Start();

var chatboxService = ModuleServiceProvider.GetRequiredService<ChatboxService>();
var oscHandler = ModuleServiceProvider.GetRequiredService<OscHandler>();

_onRemoteControlSubscription = await ModuleInstanceManager.OpenShock.Control.OnRemoteControlledShocker.SubscribeAsync(async args =>
{
foreach (var controlLog in args.Logs)
_onRemoteControlSubscription =
await ModuleInstanceManager.OpenShock.Control.OnRemoteControlledShocker.SubscribeAsync(async args =>
{
await chatboxService.SendRemoteControlMessage(controlLog.Shocker.Name, args.Sender.Name,
args.Sender.CustomName, controlLog.Intensity, controlLog.Duration, controlLog.Type);
}
});
// Dont do anything if there are no logs
if (args.Logs.Count <= 0) return;

foreach (var controlLog in args.Logs)
{
await chatboxService.SendRemoteControlMessage(controlLog.Shocker.Name, args.Sender.Name,
args.Sender.CustomName, controlLog.Intensity, controlLog.Duration, controlLog.Type);

var now = DateTimeOffset.UtcNow;

oscHandler.SetLastControlCommand(new OscHandler.LastControlLogEntry()
{
ControlLog = controlLog,
Timestamp = now,
});
}
});
}

private bool _disposed;

public async ValueTask DisposeAsync()
{
if(_disposed) return;
if (_disposed) return;
_disposed = true;

if (_onRemoteControlSubscription != null) await _onRemoteControlSubscription.DisposeAsync();
Expand Down
6 changes: 3 additions & 3 deletions ShockOsc/ShockOsc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
<PackageReference Include="MudBlazor" Version="8.11.0" />
<PackageReference Include="EmbedIO" Version="3.5.2"/>
<PackageReference Include="LucHeart.CoreOSC" Version="1.5.0" />
<PackageReference Include="LucHeart.CoreOSC" Version="1.6.0" />
<PackageReference Include="MeaMod.DNS" Version="1.0.71" />
<PackageReference Include="OpenShock.Desktop.ModuleBase" Version="1.1.0" />
<PackageReference Include="OscQueryLibrary" Version="1.2.0" />
<PackageReference Include="SmartFormat.NET" Version="3.6.0" />
<PackageReference Include="System.Reactive" Version="6.0.1" />
<PackageReference Include="SmartFormat.NET" Version="3.6.1" />
<PackageReference Include="System.Reactive" Version="6.1.0" />
</ItemGroup>


Expand Down