Implement Audio Service

Change Max Currency Jackpot Win To 200
This commit is contained in:
Alan Moon 2025-12-10 15:26:44 -08:00
parent 91c733c3ee
commit 1097dfe353
13 changed files with 125 additions and 15 deletions

View File

@ -1,4 +1,5 @@
using System; using qtcnet_client.Services;
using System;
using System.ComponentModel; using System.ComponentModel;
using System.Windows.Forms; using System.Windows.Forms;
@ -17,8 +18,10 @@ namespace qtcnet_client.Forms
private readonly Random _rndInt = new(); private readonly Random _rndInt = new();
private bool _allowClose = true; private bool _allowClose = true;
public JackpotSpinForm() private readonly AudioService _audioService;
public JackpotSpinForm(AudioService audioService)
{ {
_audioService = audioService;
InitializeComponent(); InitializeComponent();
FormClosing += JackpotSpinForm_FormClosing; FormClosing += JackpotSpinForm_FormClosing;
@ -55,6 +58,7 @@ namespace qtcnet_client.Forms
// Start spinning numbers // Start spinning numbers
_animationTimer.Start(); _animationTimer.Start();
_audioService.PlaySoundEffect("sndTokenSpinLoop");
// Schedule stop // Schedule stop
_stopTimer.Interval = (int)AnimationLengthMilliseconds; _stopTimer.Interval = (int)AnimationLengthMilliseconds;
@ -77,6 +81,9 @@ namespace qtcnet_client.Forms
// Show final result // Show final result
lblSpinAnim.Text = $"{CurrencyWon} Q's Won"; lblSpinAnim.Text = $"{CurrencyWon} Q's Won";
// play done sound
_audioService.PlaySoundEffect("sndTokenWin");
_allowClose = true; _allowClose = true;
} }
} }

View File

@ -42,6 +42,7 @@ namespace qtcnet_client
private readonly ClientConfig _config; private readonly ClientConfig _config;
private readonly ImageFactory _imgFactory; private readonly ImageFactory _imgFactory;
private readonly UpdateService _updateService; private readonly UpdateService _updateService;
private readonly AudioService _audioService;
public MainForm(IApiService apiService, public MainForm(IApiService apiService,
IGatewayService gatewayService, IGatewayService gatewayService,
@ -49,7 +50,8 @@ namespace qtcnet_client
CredentialService credentialService, CredentialService credentialService,
ClientConfig config, ClientConfig config,
ImageFactory imageFactory, ImageFactory imageFactory,
UpdateService updateService) UpdateService updateService,
AudioService audioService)
{ {
_apiService = apiService; _apiService = apiService;
_gatewayService = gatewayService; _gatewayService = gatewayService;
@ -58,6 +60,7 @@ namespace qtcnet_client
_config = config; _config = config;
_imgFactory = imageFactory; _imgFactory = imageFactory;
_updateService = updateService; _updateService = updateService;
_audioService = audioService;
// sub to currentuser updates // sub to currentuser updates
_apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate; _apiService.OnCurrentUserUpdate += _apiService_OnCurrentUserUpdate;
@ -402,13 +405,7 @@ namespace qtcnet_client
CurrentProfileControl?.Username = _apiService.CurrentUser?.Username ?? "Username"; CurrentProfileControl?.Username = _apiService.CurrentUser?.Username ?? "Username";
CurrentProfileControl?.CurrencyCount = _apiService.CurrentUser?.CurrencyAmount ?? 0; CurrentProfileControl?.CurrencyCount = _apiService.CurrentUser?.CurrencyAmount ?? 0;
var _pfpRes = await _apiService.GetUserProfilePic(_apiService.CurrentUser!.Id); CurrentProfileControl?.ProfileImage = await _imgFactory.GetAndCreateProfileImage(_apiService.CurrentUser!.Id, _apiService.CurrentUser!.Status, _apiService.CurrentUser!.ActiveProfileCosmetic);
if (_pfpRes.Success && _pfpRes.Data != null)
{
using var ms = new MemoryStream(_pfpRes.Data);
Image img = Image.FromStream(ms);
CurrentProfileControl?.ProfileImage = img;
}
CurrentProfileControl?.RefreshInfo(); CurrentProfileControl?.RefreshInfo();
} }
@ -637,14 +634,14 @@ namespace qtcnet_client
// check for daily spin eligibility // check for daily spin eligibility
var now = DateTime.UtcNow; var now = DateTime.UtcNow;
var lastSpin = _apiService.CurrentUser.LastCurrencySpin; var lastSpin = DateTime.MinValue;
if(lastSpin.Date < now.Date) if(lastSpin.Date < now.Date)
{ {
Random rnd = new(); Random rnd = new();
JackpotSpinForm _jackpotSpin = new() JackpotSpinForm _jackpotSpin = new(_audioService)
{ {
CurrencyWon = rnd.Next(0, 500) CurrencyWon = rnd.Next(0, 200)
}; };
var _dialogRes = _jackpotSpin.ShowDialog(); var _dialogRes = _jackpotSpin.ShowDialog();
if(_dialogRes == DialogResult.OK) if(_dialogRes == DialogResult.OK)
@ -802,6 +799,12 @@ namespace qtcnet_client
if(_args.User.Id != "0") if(_args.User.Id != "0")
await _chatRoom.LoadProfileImage(_msg, _args.User); await _chatRoom.LoadProfileImage(_msg, _args.User);
// play sound
if (_args.User.Id != _apiService.CurrentUser?.Id)
_audioService.PlaySoundEffect("sndMessage");
else
_audioService.PlaySoundEffect("sndSendClick");
} }
} }
} }

View File

@ -41,6 +41,7 @@ namespace qtcnet_client
service.AddSingleton<CredentialService>(); service.AddSingleton<CredentialService>();
service.AddSingleton<ImageFactory>(); service.AddSingleton<ImageFactory>();
service.AddSingleton<UpdateService>(); service.AddSingleton<UpdateService>();
service.AddSingleton<AudioService>();
service.AddSingleton(provider => GetOrCreateClientConfig()); service.AddSingleton(provider => GetOrCreateClientConfig());
service.AddSingleton<IApiService>(provider => new ApiService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/api", provider.GetService<LoggingService>()!, provider.GetService<CredentialService>()!)); service.AddSingleton<IApiService>(provider => new ApiService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/api", provider.GetService<LoggingService>()!, provider.GetService<CredentialService>()!));
service.AddSingleton<IGatewayService>(provider => new GatewayService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/chat", provider.GetService<IApiService>()!, provider.GetService<LoggingService>()!)); service.AddSingleton<IGatewayService>(provider => new GatewayService(provider.GetService<ClientConfig>()!.ServerBaseUri + "/chat", provider.GetService<IApiService>()!, provider.GetService<LoggingService>()!));

View File

@ -0,0 +1,71 @@
using NAudio.Wave;
namespace qtcnet_client.Services
{
public class AudioService : IDisposable
{
public WaveOutEvent? OutputDevice { get; set; }
public AudioFileReader? AudioFileReader { get; set; }
public event EventHandler<SoundEndedEventArgs>? OnSoundEnded;
public void PlaySoundEffect(string soundName)
{
if (!File.Exists($"./Sounds/{soundName}.wav")) return;
OutputDevice = new WaveOutEvent();
AudioFileReader = new AudioFileReader($"./Sounds/{soundName}.wav");
OutputDevice.Init(AudioFileReader);
OutputDevice.Play();
return;
}
public void PlaySoundEffectWithEventString(string soundName, string eventString)
{
if (!File.Exists($"./Sounds/{soundName}.wav")) return;
OutputDevice = new WaveOutEvent();
AudioFileReader = new AudioFileReader($"./Sounds/{soundName}.wav");
OutputDevice.Init(AudioFileReader);
OutputDevice.Play();
OutputDevice.PlaybackStopped += (sender, args) => OnSoundEnded?.Invoke(null, new SoundEndedEventArgs { EventString = eventString });
}
public void PlaySoundLooped(string soundName, int loopCount)
{
if (!File.Exists($"./Sounds/{soundName}.wav")) return;
OutputDevice = new WaveOutEvent();
AudioFileReader = new AudioFileReader($"./Sounds/{soundName}.wav");
OutputDevice.Init(AudioFileReader);
OutputDevice.Play();
int i = 0;
OutputDevice.PlaybackStopped += (sender, args) =>
{
i++;
if (i == loopCount) { OutputDevice.PlaybackStopped += null; return; }
AudioFileReader.Seek(0, SeekOrigin.Begin);
OutputDevice.Play();
};
}
public void Dispose()
{
GC.SuppressFinalize(this);
OutputDevice?.Dispose();
OutputDevice = null;
AudioFileReader?.Dispose();
AudioFileReader = null;
}
}
public class SoundEndedEventArgs : EventArgs
{
public string EventString { get; set; } = "UNKNOWN";
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -18,8 +18,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Krypton.Toolkit" Version="100.25.11.328" /> <PackageReference Include="Krypton.Toolkit" Version="100.25.11.328" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.1" />
<PackageReference Include="NAudio" Version="2.2.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -41,4 +42,31 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Update="Sounds\sndContactRequest.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndDirectMsg.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndMessage.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndSendClick.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndTokenJackpot.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndTokenSpinLoop.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndTokenWin.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Sounds\sndTTTMoveMade.wav">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>