From b8285263c70acfa2a7ddb972e3fb34c8da82fd20 Mon Sep 17 00:00:00 2001 From: T0biasCZe Date: Sun, 7 Apr 2024 17:34:32 +0200 Subject: [PATCH 1/2] fixed discord rpc init/deinit tried some more stuff to avoid memory leak --- Discord WMP/App.config | 3 + Discord WMP/Form1.Designer.cs | 3 + Discord WMP/Form1.cs | 139 ++++++++++++++--------------- Discord WMP/Settings1.Designer.cs | 14 ++- Discord WMP/Settings1.settings | 3 + Discord WMP/systemMediaControls.cs | 12 +-- 6 files changed, 96 insertions(+), 78 deletions(-) diff --git a/Discord WMP/App.config b/Discord WMP/App.config index 5d0a494..5cd5671 100644 --- a/Discord WMP/App.config +++ b/Discord WMP/App.config @@ -40,6 +40,9 @@ True + + False + diff --git a/Discord WMP/Form1.Designer.cs b/Discord WMP/Form1.Designer.cs index 3e985e9..69a0de8 100644 --- a/Discord WMP/Form1.Designer.cs +++ b/Discord WMP/Form1.Designer.cs @@ -201,6 +201,7 @@ private void InitializeComponent() { this.checkBox_dontautohide.TabIndex = 21; this.checkBox_dontautohide.Text = "dont hide"; this.checkBox_dontautohide.UseVisualStyleBackColor = true; + this.checkBox_dontautohide.CheckedChanged += new System.EventHandler(this.checkBox_changed); // // label2 // @@ -220,6 +221,7 @@ private void InitializeComponent() { this.linkLabel1.TabIndex = 23; this.linkLabel1.TabStop = true; this.linkLabel1.Text = "linkLabel_version"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); // // toolTip1 // @@ -252,6 +254,7 @@ private void InitializeComponent() { this.linkLabel2.TabIndex = 26; this.linkLabel2.TabStop = true; this.linkLabel2.Text = "linkLabel2"; + this.linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel_LinkClicked); // // Form1 // diff --git a/Discord WMP/Form1.cs b/Discord WMP/Form1.cs index 78ad1ae..cfd4882 100644 --- a/Discord WMP/Form1.cs +++ b/Discord WMP/Form1.cs @@ -195,6 +195,7 @@ private void settingsload() { checkBox_sendMediaInfo.Checked = send_media_info; use_rpc = Settings1.Default.show_discord; checkBox_userpc.Checked = use_rpc; + checkBox_dontautohide.Checked = Settings1.Default.dont_hide; Console.WriteLine("loaded settings"); loadingsettings = false; @@ -218,6 +219,7 @@ private void checkBox_changed(object sender, EventArgs e) { Settings1.Default.show_console = show_console; use_rpc = checkBox_userpc.Checked; Settings1.Default.show_discord = use_rpc; + Settings1.Default.dont_hide = checkBox_dontautohide.Checked; var handle = GetConsoleWindow(); if(show_console) ShowWindow(handle, SW_SHOW); @@ -248,6 +250,11 @@ private void button_settings_Click(object sender, EventArgs e) { this.Height = 428; } } + private void linkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { + string URL = ((LinkLabel)sender).Links[0].LinkData.ToString(); + Console.WriteLine(URL); + System.Diagnostics.Process.Start(URL); + } public struct playback_data { public string title; @@ -266,6 +273,7 @@ public struct playback_data { public string path; public string media_type; } + //gets current information from Windows Media Player public playback_data Data() { playback_data data = new playback_data(); data.artist = ""; data.album = ""; data.title = ""; data.lenght = ""; data.position = ""; data.lenght_sec = -1; data.position_sec = -1; data.play_state = WMPLib.WMPPlayState.wmppsStopped; data.guid = ""; data.path = ""; @@ -328,15 +336,27 @@ public playback_data Data() { abort:; return data; } - + //displays the current information from Windows Media Player private void debug(playback_data data) { label3.Text = "initialized " + initialized.ToString(); label4.Text = "send_data_lasttime " + send_data_lasttime.ToString(); label5.Text = "play_state " + data.play_state.ToString(); label6.Text = "mediatype " + data.media_type; label7.Text = "audiofilename " + data.audiofilename; - } + public static bool check_discord_running() { + //check if executable discord.exe, discordcanary.exe or discordptb.exe is running + Process[] pname = Process.GetProcessesByName("discord"); + Process[] pname2 = Process.GetProcessesByName("discordcanary"); + Process[] pname3 = Process.GetProcessesByName("discordptb"); + bool discordrunning = !(pname.Length == 0 && pname2.Length == 0 && pname3.Length == 0); + Console.BackgroundColor = ConsoleColor.Cyan; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Discord running: " + discordrunning); + Console.ResetColor(); + return discordrunning; + } + bool initialized = false; bool send_data_lasttime = false; Stopwatch pause_stopwatch = new Stopwatch(); @@ -346,12 +366,6 @@ private void update_Tick(object sender, EventArgs e) { if(data.lenght_sec == -1 || data.position_sec == -1) { playeddata = "Couldnt find WMP"; this.Refresh(); - if(use_rpc && initialized && send_data_lasttime) { - client.SetPresence(new RichPresence()); - send_data_lasttime = false; - Deinitialize(); - initialized = false; - } } bool stopped = data.play_state.In(WMPLib.WMPPlayState.wmppsStopped, WMPLib.WMPPlayState.wmppsMediaEnded, WMPLib.WMPPlayState.wmppsUndefined); if(data.play_state == WMPPlayState.wmppsPaused) { @@ -369,18 +383,31 @@ private void update_Tick(object sender, EventArgs e) { if(stopped) { playeddata = "Stopped"; this.Refresh(); - if(use_rpc && initialized && send_data_lasttime) { - client.SetPresence(new RichPresence()); - send_data_lasttime = false; - Deinitialize(); - initialized = false; - Console.WriteLine("stopped and deinitialized"); - } } if(send_media_info) { systemMediaControls.update(data, this); } if(use_rpc && !stopped) { + if(!check_discord_running()) { + if(initialized) { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("Discord not running but RPC inited, deiniting"); + Console.ResetColor(); + Deinitialize(); + initialized = false; + } + } + else { + if(!initialized) { + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("RPC Client not initialized, initing"); + Initialize(); + initialized = true; + Console.WriteLine("Initialized Discord RPC"); + Console.ResetColor(); + } + } + var mil = data.position_sec / data.lenght_sec; var time = data.position + "/" + data.lenght; var playbar = progressbar(mil, 10); @@ -393,47 +420,8 @@ private void update_Tick(object sender, EventArgs e) { playeddata += "\n" + albumart; this.Refresh(); - bool discord_not_running = false; - /*try { - } - catch { - Console.WriteLine("discord not running"); - discord_not_running = true; - }*/ - Console.WriteLine("e"); - label8.Text = "discord_not_running " + discord_not_running.ToString(); - if(discord_not_running) { - if(initialized) { - Deinitialize(); - initialized = false; - Console.WriteLine("discord not running, deinitialized"); - } - goto breakout; - } - if(!initialized) { - try { - if(client_id != null && client_id.Text.Length >= 3) { - Console.WriteLine("valid client id"); - bool result = Initialize(); - if(result) { - Console.WriteLine("initialized"); - initialized = true; - } - else { - Console.WriteLine("error initializing RPC."); - initialized = false; - goto breakout; - } - } - } - catch { - ConsoleColor old = Console.ForegroundColor; - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("error initializing RPC. Discord propably not running.\n If you do not want to use Discord RPC disable it in checkboxes below"); - Console.ForegroundColor = old; - goto breakout; - } - } + if(!initialized) return; + client.SetPresence(new RichPresence() { Details = data.title.Truncate(32), State = data.artist.Truncate(32), @@ -452,25 +440,38 @@ private void update_Tick(object sender, EventArgs e) { send_data_lasttime = true; Console.WriteLine("set data"); } - else if(!use_rpc && initialized) { + if(send_data_lasttime && initialized && stopped) { + client.ClearPresence(); + } + if(!use_rpc && initialized) { + client.ClearPresence(); Deinitialize(); initialized = false; } - breakout:; - } + } bool Initialize() { - /* - Create a Discord client - NOTE: If you are using Unity3D, you must use the full constructor and define - the pipe connection. - */ + Console.BackgroundColor = ConsoleColor.Cyan; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("Initialize() ran"); + Console.ResetColor(); if(client_id.Text.Length <= 8) { Console.WriteLine("invalid client id"); return false; } - client = new DiscordRpcClient(client_id.Text); + if(client != null) { + try { + client.Deinitialize(); + client.Dispose(); + } + catch { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Error while deinitializing client while initializing client"); + Console.ResetColor(); + } + } + client = new DiscordRpcClient(client_id.Text, -1); //Set the logger client.Logger = new ConsoleLogger() { Level = LogLevel.Warning }; @@ -481,7 +482,7 @@ the pipe connection. }; client.OnPresenceUpdate += (sender, e) => { - //Console.WriteLine("Received Update! {0}", e.Presence); + Console.WriteLine("Received Update! {0}", e.Presence); }; //Connect to the RPC @@ -490,12 +491,6 @@ the pipe connection. } void Deinitialize() { client.Deinitialize(); - client.OnPresenceUpdate -= (sender, e) => { - //Console.WriteLine("Received Update! {0}", e.Presence); - }; - client.OnReady -= (sender, e) => { - Console.WriteLine("Received Ready from user {0}", e.User.Username); - }; client.Dispose(); } private string progressbar(double value, int lenght) { diff --git a/Discord WMP/Settings1.Designer.cs b/Discord WMP/Settings1.Designer.cs index 0672950..645199f 100644 --- a/Discord WMP/Settings1.Designer.cs +++ b/Discord WMP/Settings1.Designer.cs @@ -12,7 +12,7 @@ namespace Discord_WMP { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")] public sealed partial class Settings1 : global::System.Configuration.ApplicationSettingsBase { private static Settings1 defaultInstance = ((Settings1)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings1()))); @@ -142,5 +142,17 @@ public bool first_setup { this["first_setup"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool dont_hide { + get { + return ((bool)(this["dont_hide"])); + } + set { + this["dont_hide"] = value; + } + } } } diff --git a/Discord WMP/Settings1.settings b/Discord WMP/Settings1.settings index 8dc87a3..1f21cba 100644 --- a/Discord WMP/Settings1.settings +++ b/Discord WMP/Settings1.settings @@ -32,5 +32,8 @@ True + + False + \ No newline at end of file diff --git a/Discord WMP/systemMediaControls.cs b/Discord WMP/systemMediaControls.cs index 27cb0f4..f3d94e5 100644 --- a/Discord WMP/systemMediaControls.cs +++ b/Discord WMP/systemMediaControls.cs @@ -174,12 +174,12 @@ static void StartServer() { listener.Start(); Console.WriteLine("Listening on " + prefix); } + static AsyncCallback callback = new AsyncCallback(ListenerCallback); static void ListenerCallback(IAsyncResult result) { //HttpListener listener = (HttpListener)result.AsyncState; // Call EndGetContext to complete the asynchronous operation. - HttpListenerContext context; try { - context = listener.EndGetContext(result); + HttpListenerContext context = listener.EndGetContext(result); if(!context.Request.IsLocal) { Console.WriteLine("request from not localhost"); context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; @@ -187,19 +187,21 @@ static void ListenerCallback(IAsyncResult result) { return; } ProcessRequest(context); + context.Response.Close(); } finally { // Start listening for next request - listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); + //listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); + listener.BeginGetContext(callback, listener); } } static void checkRequests() { if(listener.IsListening) { - listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); + //listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener); + listener.BeginGetContext(callback, listener); } } static void ProcessRequest(HttpListenerContext context) { - HttpListenerRequest request = context.Request; using(HttpListenerResponse response = context.Response) { if(File.Exists(thumbnail_path)) { response.ContentType = "image/jpeg"; From 2f75e0186396468fcd927aea94b751eadaa34b13 Mon Sep 17 00:00:00 2001 From: T0biasCZe Date: Sat, 28 Sep 2024 18:43:32 +0200 Subject: [PATCH 2/2] Some changes i dont remember --- Discord WMP/AlbumArtAdder.cs | 5 ++- Discord WMP/Form1.Designer.cs | 2 +- Discord WMP/Form1.cs | 49 ++++++++++++++++++++++++++++-- Discord WMP/albummanager.cs | 6 ++++ Discord WMP/systemMediaControls.cs | 33 ++++++++++++++++++++ 5 files changed, 90 insertions(+), 5 deletions(-) diff --git a/Discord WMP/AlbumArtAdder.cs b/Discord WMP/AlbumArtAdder.cs index 9781a53..9c849c0 100644 --- a/Discord WMP/AlbumArtAdder.cs +++ b/Discord WMP/AlbumArtAdder.cs @@ -151,6 +151,9 @@ private void showinlistbox() { else if(pér.type == pairtype.titlecontains) { listBox1.Items.Add(pér.filename + " ;;; " + pér.contains + " ;;; " + pér.doesntcontain + "\t" + pér.priority + "\t (words contained in title name)"); } + else if(pér.type == pairtype.audiofilenamecontains) { + listBox1.Items.Add(pér.filename + " ;;; " + pér.contains + " ;;; " + pér.doesntcontain + "\t" + pér.priority + "\t (words contained in audiofile name)"); + } else if(pér.type == pairtype.artistname) { listBox1.Items.Add(pér.filename + " ;;; " + pér.contains + " ;;; " + pér.doesntcontain + "\t" + pér.priority + "\t (artists name)"); } @@ -190,7 +193,7 @@ private void AlbumArtAdder_SizeChanged(object sender, EventArgs e) { } } //create int enum "pairtype" with names "albumstring", "albumcontains" and "titlecontains" - public enum pairtype : int {albumstring, albumcontains, titlecontains, audiofilename, artistname}; + public enum pairtype : int {albumstring, albumcontains, titlecontains, audiofilename, artistname, audiofilenamecontains}; public struct pair { public string filename { get; set; } public pairtype type { get; set; } diff --git a/Discord WMP/Form1.Designer.cs b/Discord WMP/Form1.Designer.cs index 69a0de8..e9e213d 100644 --- a/Discord WMP/Form1.Designer.cs +++ b/Discord WMP/Form1.Designer.cs @@ -261,7 +261,7 @@ private void InitializeComponent() { this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.White; - this.ClientSize = new System.Drawing.Size(856, 801); + this.ClientSize = new System.Drawing.Size(193, 123); this.Controls.Add(this.linkLabel2); this.Controls.Add(this.label8); this.Controls.Add(this.label7); diff --git a/Discord WMP/Form1.cs b/Discord WMP/Form1.cs index cfd4882..7eed428 100644 --- a/Discord WMP/Form1.cs +++ b/Discord WMP/Form1.cs @@ -41,7 +41,7 @@ public partial class Form1 : Form { private bool show_console; private bool use_rpc; public DiscordRpcClient client; - public static int random_port; + public static int random_port = 42565; public static bool albummanageropen = false; [DllImport("kernel32.dll")] @@ -66,6 +66,49 @@ private void SmoothingText_Paint(object sender, PaintEventArgs e) { } public Form1() { + //check if app is already running by sending http request to "localhost:42565/alive" + bool appAlreadyRunning = false; + try { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:42565/alive"); + request.Timeout = 2000; + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + if(response.StatusCode == HttpStatusCode.OK) { + appAlreadyRunning = true; + } + } + catch(WebException) { + + } + if(!appAlreadyRunning) { //app unresponsive or not running, so kill it + Process[] processes = Process.GetProcessesByName("Discord WMP"); + foreach(Process process in processes) { + if(process.Id == Process.GetCurrentProcess().Id) continue; + process.Kill(); + } + } + + if(appAlreadyRunning) { + if(Environment.GetCommandLineArgs().Contains("getdata")){ + //send http request to "localhost:42565/getdata" to get data + HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:42565/info"); + request.Timeout = 1000; + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + if(response.StatusCode == HttpStatusCode.OK) { + //get data from response + Stream dataStream = response.GetResponseStream(); + StreamReader reader = new StreamReader(dataStream); + string responseFromServer = reader.ReadToEnd(); + //send data to console + Console.WriteLine(responseFromServer); + //close response + response.Close(); + //close app + Environment.Exit(0); + } + } + else Environment.Exit(0); + } + if(Settings1.Default.first_setup) { loadingsettings = true; DialogResult dialog_userpc = MessageBox.Show("Do you want to put WMP play data into Discord Rich presence?\n(Recommended YES if you have Discord installed)", "Initial setup", MessageBoxButtons.YesNo); @@ -87,7 +130,7 @@ public Form1() { // Show console during boot ShowWindow(handle, SW_SHOW); - Random random = new Random(); + /*Random random = new Random(); bool isAvailable = false; while(isAvailable == false) { random_port = random.Next(49152, 65535); @@ -104,7 +147,7 @@ public Form1() { isAvailable = true; } } - } + }*/ Console.SetWindowSize(50, 15); InitializeComponent(); diff --git a/Discord WMP/albummanager.cs b/Discord WMP/albummanager.cs index 51b32b7..a7cb326 100644 --- a/Discord WMP/albummanager.cs +++ b/Discord WMP/albummanager.cs @@ -66,6 +66,12 @@ public static string getalbumart(string album, string title, string artist, stri return per.filename; } } + else if(per.type == pairtype.audiofilenamecontains) { + if(audiofilename.Contains(per.contains, StringComparison.OrdinalIgnoreCase)) { + if(per.doesntcontain.Length > 1) if(!audiofilename.Contains(per.doesntcontain, StringComparison.OrdinalIgnoreCase)) continue; + return per.filename; + } + } } } diff --git a/Discord WMP/systemMediaControls.cs b/Discord WMP/systemMediaControls.cs index f3d94e5..9b2ba47 100644 --- a/Discord WMP/systemMediaControls.cs +++ b/Discord WMP/systemMediaControls.cs @@ -202,6 +202,39 @@ static void checkRequests() { } } static void ProcessRequest(HttpListenerContext context) { + string url = context.Request.Url.AbsolutePath; + if(url == "/") { + ProcessRequestImage(context); + } + else if(url == "/alive") { + ProcessRequestAlive(context); + } + else if(url == "/info") { + ProcessRequestInfo(context); + } + else { + context.Response.StatusCode = (int)HttpStatusCode.NotFound; + } + } + static void ProcessRequestInfo(HttpListenerContext context) { + //return string with info about current song in format "Title\nArtist\nAlbum" + using(HttpListenerResponse response = context.Response) { + response.ContentType = "text/plain"; + string info = $"{data.title}\n{data.artist}\n{data.album}"; + byte[] buffer = Encoding.UTF8.GetBytes(info); + response.ContentLength64 = buffer.Length; + response.OutputStream.Write(buffer, 0, buffer.Length); + } + } + static void ProcessRequestAlive(HttpListenerContext context) { + using(HttpListenerResponse response = context.Response) { + response.ContentType = "text/plain"; + response.ContentLength64 = 5; + byte[] buffer = Encoding.UTF8.GetBytes("alive"); + response.OutputStream.Write(buffer, 0, buffer.Length); + } + } + static void ProcessRequestImage(HttpListenerContext context) { using(HttpListenerResponse response = context.Response) { if(File.Exists(thumbnail_path)) { response.ContentType = "image/jpeg";