Skip to content

Commit 3fd9601

Browse files
committed
make _Any react to all remote commands
1 parent 76d6228 commit 3fd9601

2 files changed

Lines changed: 76 additions & 28 deletions

File tree

ShockOsc/Services/OscHandler.cs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
using System.Collections.Concurrent;
12
using Microsoft.Extensions.Logging;
23
using OpenShock.Desktop.ModuleBase.Config;
4+
using OpenShock.Desktop.ModuleBase.Models;
35
using OpenShock.ShockOSC.Config;
46
using OpenShock.ShockOSC.OscChangeTracker;
57
using OpenShock.ShockOSC.Utils;
@@ -13,6 +15,8 @@ public sealed class OscHandler
1315
private readonly ChangeTrackedOscParam<float> _paramAnyCooldownPercentage;
1416
private readonly ChangeTrackedOscParam<float> _paramAnyIntensity;
1517

18+
private readonly ConcurrentDictionary<Guid, LastControlLogEntry> _lastControlLogs = new();
19+
1620
private readonly ILogger<OscHandler> _logger;
1721
private readonly OscClient _oscClient;
1822
private readonly IModuleConfig<ShockOscConfig> _moduleConfig;
@@ -71,10 +75,11 @@ await _oscClient.SendGameMessage("/input/Voice", false)
7175
public async Task SendParams()
7276
{
7377
// TODO: maybe force resend on avatar change
74-
var anyActive = false;
78+
79+
await UpdateAnyActive();
80+
7581
var anyCooldown = false;
7682
var anyCooldownPercentage = 0f;
77-
var anyIntensity = 0f;
7883

7984
foreach (var shocker in _shockOscData.ProgramGroups.Values)
8085
{
@@ -99,16 +104,46 @@ public async Task SendParams()
99104
await shocker.ParamCooldown.SetValue(onCoolDown);
100105
await shocker.ParamCooldownPercentage.SetValue(cooldownPercentage);
101106
await shocker.ParamIntensity.SetValue(intensity);
102-
103-
if (isActive) anyActive = true;
107+
104108
if (onCoolDown) anyCooldown = true;
105109
anyCooldownPercentage = MathF.Max(anyCooldownPercentage, cooldownPercentage);
106-
anyIntensity = MathF.Max(anyIntensity, intensity);
107110
}
108-
109-
await _paramAnyActive.SetValue(anyActive);
111+
110112
await _paramAnyCooldown.SetValue(anyCooldown);
111113
await _paramAnyCooldownPercentage.SetValue(anyCooldownPercentage);
112-
await _paramAnyIntensity.SetValue(anyIntensity);
113114
}
115+
116+
private async Task UpdateAnyActive()
117+
{
118+
var now = DateTimeOffset.UtcNow;
119+
var anyActive = false;
120+
var maxIntensity = 0f;
121+
122+
foreach (var logEntry in _lastControlLogs.Values)
123+
{
124+
if(logEntry.ControlLog.Type != ControlType.Shock) continue;
125+
var activeUntil = logEntry.Timestamp.AddMilliseconds(logEntry.ControlLog.Duration);
126+
127+
if (activeUntil < now) continue;
128+
129+
anyActive = true;
130+
var intensity = MathUtils.Saturate(logEntry.ControlLog.Intensity / 100f);
131+
maxIntensity = MathF.Max(maxIntensity, intensity);
132+
}
133+
134+
await _paramAnyActive.SetValue(anyActive);
135+
await _paramAnyIntensity.SetValue(maxIntensity);
136+
}
137+
138+
public void SetLastControlCommand(LastControlLogEntry controlLogs)
139+
{
140+
_lastControlLogs[controlLogs.ControlLog.Shocker.Id] = controlLogs;
141+
}
142+
143+
public class LastControlLogEntry
144+
{
145+
public required DateTimeOffset Timestamp { get; set; }
146+
public required ControlLog ControlLog { get; set; }
147+
}
148+
114149
}

ShockOsc/ShockOSCModule.cs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
using OpenShock.ShockOSC.Services;
1111
using OpenShock.ShockOSC.Ui.Pages.Dash.Tabs;
1212
using OscQueryLibrary;
13+
1314
// ReSharper disable InconsistentNaming
1415

15-
[assembly:DesktopModule(typeof(ShockOSCModule), "openshock.shockosc", "ShockOSC")]
16+
[assembly: DesktopModule(typeof(ShockOSCModule), "openshock.shockosc", "ShockOSC")]
17+
1618
namespace OpenShock.ShockOSC;
1719

1820
public sealed class ShockOSCModule : DesktopModuleBase, IAsyncDisposable
@@ -50,16 +52,14 @@ public sealed class ShockOSCModule : DesktopModuleBase, IAsyncDisposable
5052

5153
public override async Task Setup()
5254
{
53-
5455
var config = await ModuleInstanceManager.GetModuleConfig<ShockOscConfig>();
5556
ModuleServiceProvider = BuildServices(config);
56-
5757
}
5858

5959
private IServiceProvider BuildServices(IModuleConfig<ShockOscConfig> config)
6060
{
6161
var loggerFactory = ModuleInstanceManager.AppServiceProvider.GetRequiredService<ILoggerFactory>();
62-
62+
6363
var services = new ServiceCollection();
6464

6565
services.AddSingleton(loggerFactory);
@@ -71,45 +71,58 @@ private IServiceProvider BuildServices(IModuleConfig<ShockOscConfig> config)
7171
services.AddSingleton<OscClient>();
7272
services.AddSingleton<OscHandler>();
7373
services.AddSingleton<ChatboxService>();
74-
74+
7575
services.AddSingleton(_ =>
7676
{
7777
var listenAddress = config.Config.Osc.QuestSupport ? IPAddress.Any : IPAddress.Loopback;
7878
return new OscQueryServer("ShockOSC", listenAddress);
7979
});
80-
80+
8181
services.AddSingleton<ShockOsc>();
8282
services.AddSingleton<UnderscoreConfig>();
83-
84-
83+
84+
8585
return services.BuildServiceProvider();
86-
}
86+
}
8787

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

9292
await ModuleServiceProvider.GetRequiredService<ShockOsc>().Start();
93-
93+
9494
if (config.Config.Osc.OscQuery) ModuleServiceProvider.GetRequiredService<OscQueryServer>().Start();
95-
95+
9696
var chatboxService = ModuleServiceProvider.GetRequiredService<ChatboxService>();
97+
var oscHandler = ModuleServiceProvider.GetRequiredService<OscHandler>();
9798

98-
_onRemoteControlSubscription = await ModuleInstanceManager.OpenShock.Control.OnRemoteControlledShocker.SubscribeAsync(async args =>
99-
{
100-
foreach (var controlLog in args.Logs)
99+
_onRemoteControlSubscription =
100+
await ModuleInstanceManager.OpenShock.Control.OnRemoteControlledShocker.SubscribeAsync(async args =>
101101
{
102-
await chatboxService.SendRemoteControlMessage(controlLog.Shocker.Name, args.Sender.Name,
103-
args.Sender.CustomName, controlLog.Intensity, controlLog.Duration, controlLog.Type);
104-
}
105-
});
102+
// Dont do anything if there are no logs
103+
if (args.Logs.Count <= 0) return;
104+
105+
foreach (var controlLog in args.Logs)
106+
{
107+
await chatboxService.SendRemoteControlMessage(controlLog.Shocker.Name, args.Sender.Name,
108+
args.Sender.CustomName, controlLog.Intensity, controlLog.Duration, controlLog.Type);
109+
110+
var now = DateTimeOffset.UtcNow;
111+
112+
oscHandler.SetLastControlCommand(new OscHandler.LastControlLogEntry()
113+
{
114+
ControlLog = controlLog,
115+
Timestamp = now,
116+
});
117+
}
118+
});
106119
}
107-
120+
108121
private bool _disposed;
109122

110123
public async ValueTask DisposeAsync()
111124
{
112-
if(_disposed) return;
125+
if (_disposed) return;
113126
_disposed = true;
114127

115128
if (_onRemoteControlSubscription != null) await _onRemoteControlSubscription.DisposeAsync();

0 commit comments

Comments
 (0)