diff --git a/DeltaTune/DeltaTune.cs b/DeltaTune/DeltaTune.cs index bed849e..c10c21c 100644 --- a/DeltaTune/DeltaTune.cs +++ b/DeltaTune/DeltaTune.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using DeltaTune.Discord; using DeltaTune.Display; using DeltaTune.Media; using DeltaTune.Settings; @@ -21,6 +22,7 @@ public class DeltaTune : Game private ISettingsMenu settingsMenu; private ISettingsService settingsService; private ISettingsFile settingsFile; + private IDiscordService discordService; private SpriteBatch spriteBatch; private BitmapFont musicTitleFont; @@ -46,7 +48,7 @@ protected override void Initialize() { settingsService = new SettingsService(); settingsFile = new SettingsFile(settingsService, Path.Combine(relativePathRoot, "Settings.json")); - settingsMenu = new SettingsMenu(settingsService); + settingsMenu = new SettingsMenu(settingsService, () => this.discordService); mediaInfoService = new SystemMediaInfoService(new MediaFilter()); @@ -74,8 +76,11 @@ protected override void BeginRun() windowService = new WindowService(this, graphicsDeviceManagerInstance, settingsMenu, settingsService, musicTitleFont.LineHeight); windowService.InitializeWindow(); + discordService = new DiscordService(settingsService); + discordService.UpdateState(); + Vector2 WindowSizeProvider() => new Vector2(graphicsDeviceManagerInstance.GraphicsDevice.Viewport.Width, graphicsDeviceManagerInstance.GraphicsDevice.Viewport.Height); - displayService = new DisplayService(mediaInfoService, settingsService, new MediaFormatter(settingsService), musicTitleFont, WindowSizeProvider); + displayService = new DisplayService(mediaInfoService, settingsService, new MediaFormatter(settingsService), musicTitleFont, WindowSizeProvider, discordService); displayService.BeginRun(); base.BeginRun(); diff --git a/DeltaTune/DeltaTune.csproj b/DeltaTune/DeltaTune.csproj index c685234..53e8740 100644 --- a/DeltaTune/DeltaTune.csproj +++ b/DeltaTune/DeltaTune.csproj @@ -16,6 +16,7 @@ false + diff --git a/DeltaTune/Discord/DiscordService.cs b/DeltaTune/Discord/DiscordService.cs new file mode 100644 index 0000000..34c90ad --- /dev/null +++ b/DeltaTune/Discord/DiscordService.cs @@ -0,0 +1,51 @@ +using System; +using DeltaTune.Media; +using DeltaTune.Settings; +using DiscordRPC; + +namespace DeltaTune.Discord +{ + public class DiscordService : IDiscordService, IDisposable + { + private static readonly MediaInfo Default = new MediaInfo("", "", PlaybackStatus.Stopped); + private readonly ISettingsService settingsService; + private readonly DiscordRpcClient discord; + + private MediaInfo lastMediaInfo = Default; + + public DiscordService(ISettingsService settingsService) + { + this.settingsService = settingsService; + this.discord = new DiscordRpcClient("1446140892850290911"); + this.discord.Initialize(); + } + + public void UpdateState() + { + if (!settingsService.EnableDiscordRichPresence.Value) + { + discord.ClearPresence(); + } + else if (!lastMediaInfo.Equals(Default)) + { + UpdateDisplay(lastMediaInfo); + } + } + + public void UpdateDisplay(MediaInfo mediaInfo) + { + lastMediaInfo = mediaInfo; + if (!settingsService.EnableDiscordRichPresence.Value) + { + return; + } + discord.SetPresence(new RichPresence { State = mediaInfo.Artist, Details = mediaInfo.Title, Timestamps = Timestamps.Now, Assets = new Assets { LargeImageKey = "deltatune" }, Type = ActivityType.Listening, StatusDisplay = StatusDisplayType.Name }); + } + + public void Dispose() + { + discord.ClearPresence(); + discord.Dispose(); + } + } +} \ No newline at end of file diff --git a/DeltaTune/Discord/IDiscordService.cs b/DeltaTune/Discord/IDiscordService.cs new file mode 100644 index 0000000..8854192 --- /dev/null +++ b/DeltaTune/Discord/IDiscordService.cs @@ -0,0 +1,10 @@ +using DeltaTune.Media; + +namespace DeltaTune.Discord +{ + public interface IDiscordService + { + void UpdateState(); + void UpdateDisplay(MediaInfo mediaInfo); + } +} \ No newline at end of file diff --git a/DeltaTune/Display/DisplayService.cs b/DeltaTune/Display/DisplayService.cs index 56114b4..2abf826 100644 --- a/DeltaTune/Display/DisplayService.cs +++ b/DeltaTune/Display/DisplayService.cs @@ -1,4 +1,5 @@ using System; +using DeltaTune.Discord; using DeltaTune.Media; using DeltaTune.Settings; using Microsoft.Xna.Framework; @@ -16,6 +17,7 @@ public class DisplayService : IDisplayService private readonly IMediaFormatter mediaFormatter; private readonly Func windowSizeProvider; private readonly BitmapFont musicTitleFont; + private readonly IDiscordService discordService; private MediaInfo currentMediaInfo; private IMusicTitleDisplay primaryDisplay; @@ -23,13 +25,14 @@ public class DisplayService : IDisplayService private double lastMediaInfoUpdateTime; - public DisplayService(IMediaInfoService mediaInfoService, ISettingsService settingsService, IMediaFormatter mediaFormatter, BitmapFont musicTitleFont, Func windowSizeProvider) + public DisplayService(IMediaInfoService mediaInfoService, ISettingsService settingsService, IMediaFormatter mediaFormatter, BitmapFont musicTitleFont, Func windowSizeProvider, IDiscordService discordService) { this.mediaInfoService = mediaInfoService; this.settingsService = settingsService; this.musicTitleFont = musicTitleFont; this.windowSizeProvider = windowSizeProvider; this.mediaFormatter = mediaFormatter; + this.discordService = discordService; } public void BeginRun() @@ -53,6 +56,11 @@ public void Update(GameTime gameTime) bool shouldUpdateDisplayState = settingsService.ShowPlaybackStatus.Value ? titleChanged || artistChanged || statusChanged : titleChanged || artistChanged; + if (titleChanged || artistChanged) + { + discordService.UpdateDisplay(currentMediaInfo); + } + // Even if playback status shouldn't be shown, show the song title again when resuming playback if (!shouldUpdateDisplayState && !settingsService.ShowPlaybackStatus.Value && statusChanged && currentMediaInfo.Status == PlaybackStatus.Playing) diff --git a/DeltaTune/Settings/ISettingsService.cs b/DeltaTune/Settings/ISettingsService.cs index 0ae817c..0c5027d 100644 --- a/DeltaTune/Settings/ISettingsService.cs +++ b/DeltaTune/Settings/ISettingsService.cs @@ -13,5 +13,6 @@ public interface ISettingsService ReactiveProperty ShowPlaybackStatus { get; } ReactiveProperty HideAutomatically { get; } ReactiveProperty ScreenCaptureCompatibilityMode { get; } + ReactiveProperty EnableDiscordRichPresence { get; } } } \ No newline at end of file diff --git a/DeltaTune/Settings/SettingsFile.cs b/DeltaTune/Settings/SettingsFile.cs index e9bd521..259a32a 100644 --- a/DeltaTune/Settings/SettingsFile.cs +++ b/DeltaTune/Settings/SettingsFile.cs @@ -29,6 +29,7 @@ public SettingsFile(ISettingsService settingsService, string filePath) settingsService.ShowPlaybackStatus.Subscribe(state => saveEvent.OnNext(Unit.Default)).AddTo(ref valueChangeDisposableBuilder); settingsService.HideAutomatically.Subscribe(state => saveEvent.OnNext(Unit.Default)).AddTo(ref valueChangeDisposableBuilder); settingsService.ScreenCaptureCompatibilityMode.Subscribe(state => saveEvent.OnNext(Unit.Default)).AddTo(ref valueChangeDisposableBuilder); + settingsService.EnableDiscordRichPresence.Subscribe(state => saveEvent.OnNext(Unit.Default)).AddTo(ref valueChangeDisposableBuilder); valueChangeSubscription = valueChangeDisposableBuilder.Build(); saveSubscription = saveEvent.DebounceFrame(1).Subscribe(_ => Save()); diff --git a/DeltaTune/Settings/SettingsFileModel.cs b/DeltaTune/Settings/SettingsFileModel.cs index 2eec51c..873c2fa 100644 --- a/DeltaTune/Settings/SettingsFileModel.cs +++ b/DeltaTune/Settings/SettingsFileModel.cs @@ -11,6 +11,7 @@ public class SettingsFileModel public bool ShowPlaybackStatus { get; set; } = false; public float? HideAutomatically { get; set; } = 2.5f; public bool ScreenCaptureCompatibilityMode { get; set; } = false; + public bool EnableDiscordRichPresence { get; set; } = true; public void FromSettings(ISettingsService settingsService) { @@ -21,6 +22,7 @@ public void FromSettings(ISettingsService settingsService) ShowPlaybackStatus = settingsService.ShowPlaybackStatus.Value; HideAutomatically = settingsService.HideAutomatically.Value; ScreenCaptureCompatibilityMode = settingsService.ScreenCaptureCompatibilityMode.Value; + EnableDiscordRichPresence = settingsService.EnableDiscordRichPresence.Value; } public void ToSettings(ISettingsService settingsService) @@ -32,6 +34,7 @@ public void ToSettings(ISettingsService settingsService) settingsService.ShowPlaybackStatus.Value = ShowPlaybackStatus; settingsService.HideAutomatically.Value = HideAutomatically; settingsService.ScreenCaptureCompatibilityMode.Value = ScreenCaptureCompatibilityMode; + settingsService.EnableDiscordRichPresence.Value = EnableDiscordRichPresence; } } } \ No newline at end of file diff --git a/DeltaTune/Settings/SettingsMenu.cs b/DeltaTune/Settings/SettingsMenu.cs index b17bca0..f5f213a 100644 --- a/DeltaTune/Settings/SettingsMenu.cs +++ b/DeltaTune/Settings/SettingsMenu.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using System.Globalization; using System.Windows.Forms; +using DeltaTune.Discord; using DeltaTune.Window; using SharpDX; @@ -11,11 +13,13 @@ public class SettingsMenu : ISettingsMenu private static readonly float[] hideAutomaticallyDelayOptions = new[] { 1f, 2.5f, 5f, 7.5f, 10f }; private readonly ISettingsService settingsService; + private readonly Func discord; private ContextMenuStrip settingsMenuStrip; - public SettingsMenu(ISettingsService settingsService) + public SettingsMenu(ISettingsService settingsService, Func discord) { this.settingsService = settingsService; + this.discord = discord; } public ContextMenuStrip GetSettingsMenu() @@ -173,6 +177,15 @@ private ToolStripMenuItem GetBehaviorMenuItem() showPlaybackStatusItem.Checked = settingsService.ShowPlaybackStatus.Value; showPlaybackStatusItem.Click += (sender, args) => settingsService.ShowPlaybackStatus.Value = !settingsService.ShowPlaybackStatus.Value; behaviorItem.DropDownItems.Add(showPlaybackStatusItem); + + ToolStripMenuItem enableDiscordItem = new ToolStripMenuItem(); + enableDiscordItem.Text = "Enable Discord Rich Presence"; + enableDiscordItem.Checked = settingsService.EnableDiscordRichPresence.Value; + enableDiscordItem.Click += (sender, args) => { + settingsService.EnableDiscordRichPresence.Value = !settingsService.EnableDiscordRichPresence.Value; + discord.Invoke()?.UpdateState(); + }; + behaviorItem.DropDownItems.Add(enableDiscordItem); ToolStripMenuItem screenCaptureCompatItem = new ToolStripMenuItem(); screenCaptureCompatItem.Text = "Streamer Mode"; diff --git a/DeltaTune/Settings/SettingsService.cs b/DeltaTune/Settings/SettingsService.cs index 622b2ae..3ff5d51 100644 --- a/DeltaTune/Settings/SettingsService.cs +++ b/DeltaTune/Settings/SettingsService.cs @@ -13,5 +13,6 @@ public class SettingsService : ISettingsService public ReactiveProperty ShowPlaybackStatus { get; } = new ReactiveProperty(false); public ReactiveProperty HideAutomatically { get; } = new ReactiveProperty(2.5f); public ReactiveProperty ScreenCaptureCompatibilityMode { get; } = new ReactiveProperty(false); + public ReactiveProperty EnableDiscordRichPresence { get; } = new ReactiveProperty(true); } } \ No newline at end of file