From 4d7202c45d57a6666b557dcd5016b311d5ac63fe Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Mon, 13 Jun 2022 18:09:39 -0500 Subject: [PATCH 1/3] Relative path for portable building. --- release_files/release_config.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/release_files/release_config.xml b/release_files/release_config.xml index 3e637282..1a27b019 100644 --- a/release_files/release_config.xml +++ b/release_files/release_config.xml @@ -2,8 +2,8 @@ false gui - C:\repo\github\MercuryTrade\release_files\MercuryTrade.jar - C:\repo\github\MercuryTrade\release_files\MercuryTrade.exe + .\release_files\MercuryTrade.jar + .\release_files\MercuryTrade.exe MercuryTrade needs java to work. Please install java first . @@ -13,7 +13,7 @@ false false - C:\repo\github\MercuryTrade\release_files\app-icon.ico + .\release_files\app-icon.ico MercuryTrade MercuryTrade From 557ac092b58281c6ca119eaffcaa358c6225782c Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Mon, 13 Jun 2022 18:13:17 -0500 Subject: [PATCH 2/3] Rudimentary support for multiple processes * Settable PID field in general settings * Check and optionally use PID in ChatHelper --- .../com/mercury/platform/core/ChatHelper.java | 10 +++++++++- .../descriptor/ApplicationDescriptor.java | 1 + .../page/GeneralSettingsPagePanel.java | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java b/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java index 13bde8f4..1d32f460 100644 --- a/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java +++ b/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java @@ -12,6 +12,7 @@ import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinUser; +import com.sun.jna.ptr.IntByReference; import org.apache.commons.lang3.SystemUtils; import javax.swing.*; @@ -202,11 +203,18 @@ private void findInStashTab(String toBeFound) { final int SWP_SHOWWINDOW = 0x0040; private void gameToFront() { + int pid = Configuration.get().applicationConfiguration().get().getGamePid(); + IntByReference winpid = new IntByReference(); + if (SystemUtils.IS_OS_WINDOWS) { WindowUtils.getAllWindows(false).forEach(window -> { char[] className = new char[512]; User32.INSTANCE.GetClassName(window.getHWND(), className, 512); - if (Native.toString(className).equals("POEWindowClass")) { + User32.INSTANCE.GetWindowThreadProcessId(window.getHWND(), winpid); + + boolean pidMatch = (pid == 0) || (pid == winpid.getValue()); + + if (Native.toString(className).equals("POEWindowClass") && pidMatch) { User32.INSTANCE.ShowWindow(window.getHWND(), 5); boolean isAtFront = User32.INSTANCE.SetForegroundWindow(window.getHWND()); diff --git a/app-core/src/main/java/com/mercury/platform/shared/config/descriptor/ApplicationDescriptor.java b/app-core/src/main/java/com/mercury/platform/shared/config/descriptor/ApplicationDescriptor.java index c2511bf0..22dc043b 100644 --- a/app-core/src/main/java/com/mercury/platform/shared/config/descriptor/ApplicationDescriptor.java +++ b/app-core/src/main/java/com/mercury/platform/shared/config/descriptor/ApplicationDescriptor.java @@ -12,6 +12,7 @@ public class ApplicationDescriptor implements Serializable { private int maxOpacity; private int fadeTime; private String gamePath; + private int gamePid; private String pushbulletAccessToken; private boolean showOnStartUp; private boolean itemsGridEnable; diff --git a/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java b/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java index 2445bc64..b13560b8 100644 --- a/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java +++ b/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java @@ -105,6 +105,23 @@ public void keyTyped(KeyEvent e) { JButton changeButton = this.componentsFactory.getBorderedButton("Change"); poeFolderPanel.add(changeButton, BorderLayout.LINE_END); + JTextField poePidField = this.componentsFactory.getTextField(""); + poePidField.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(AppThemeColor.BORDER, 1), + BorderFactory.createLineBorder(AppThemeColor.TRANSPARENT, 2) + )); + poePidField.addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + int pid = applicationSnapshot.getGamePid(); + + try { pid = Integer.parseInt(poePidField.getText() + e.getKeyChar()); } + catch(Exception ex) {} + + applicationSnapshot.setGamePid(pid); + } + }); + JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); changeButton.addActionListener(e -> { @@ -153,6 +170,8 @@ public void keyTyped(KeyEvent e) { root.add(this.componentsFactory.wrapToSlide(notifierStatusPicker, AppThemeColor.ADR_BG, 0, 0, 0, 2)); root.add(this.componentsFactory.getTextLabel("Path of Exile folder: ", FontStyle.REGULAR, 16)); root.add(this.componentsFactory.wrapToSlide(poeFolderPanel, AppThemeColor.ADR_BG, 0, 0, 2, 2)); + root.add(this.componentsFactory.getTextLabel("Single game PID: ", FontStyle.REGULAR, 16)); + root.add(this.componentsFactory.wrapToSlide(poePidField, AppThemeColor.ADR_BG, 0, 0, 2, 2)); root.add(this.componentsFactory.getTextLabel("Pushbullet AccessToken ", FontStyle.REGULAR, 16)); root.add(this.componentsFactory.wrapToSlide(pushbulletPanel, AppThemeColor.ADR_BG, 0, 0, 0, 2)); From 69465cbdd2a94c77cac7cb69f0586717c18eea39 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Sat, 25 Jun 2022 22:57:05 -0500 Subject: [PATCH 3/3] Better support for multiple processes and options * Dropdown with PIDs populated "live" * Options for "old behavior" and "no switching" * Starts to add a few utility functions to ChatHelper which should probably be extended later when message PIDs are parsed out --- .../com/mercury/platform/core/ChatHelper.java | 44 +++++++++++--- .../page/GeneralSettingsPagePanel.java | 59 +++++++++++++------ 2 files changed, 79 insertions(+), 24 deletions(-) diff --git a/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java b/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java index 1d32f460..0e4c4685 100644 --- a/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java +++ b/app-core/src/main/java/com/mercury/platform/core/ChatHelper.java @@ -24,6 +24,9 @@ import java.awt.event.KeyEvent; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + public class ChatHelper implements AsSubscriber { private Robot robot; @@ -202,19 +205,45 @@ private void findInStashTab(String toBeFound) { final int SWP_NOMOVE = 0x0002; final int SWP_SHOWWINDOW = 0x0040; + static public ArrayList getPoeWindows() { + ArrayList windows = new ArrayList(); + WindowUtils.getAllWindows(false).forEach(window -> { + char[] className = new char[512]; + User32.INSTANCE.GetClassName(window.getHWND(), className, 512); + + if (Native.toString(className).equals("POEWindowClass")) { + windows.add(window); + } + }); + + return windows; + } + + static public int getWindowPid(DesktopWindow window) { + IntByReference winpid = new IntByReference(); + User32.INSTANCE.GetWindowThreadProcessId(window.getHWND(), winpid); + + return winpid.getValue(); + } + + static public ArrayList getPoeWindowPids() { + ArrayList windows = getPoeWindows(); + ArrayList pids = new ArrayList(); + + windows.forEach(window -> { pids.add(getWindowPid(window)); }); + return pids; + } + private void gameToFront() { int pid = Configuration.get().applicationConfiguration().get().getGamePid(); - IntByReference winpid = new IntByReference(); if (SystemUtils.IS_OS_WINDOWS) { - WindowUtils.getAllWindows(false).forEach(window -> { - char[] className = new char[512]; - User32.INSTANCE.GetClassName(window.getHWND(), className, 512); - User32.INSTANCE.GetWindowThreadProcessId(window.getHWND(), winpid); + getPoeWindows().forEach(window -> { + int winpid = getWindowPid(window); - boolean pidMatch = (pid == 0) || (pid == winpid.getValue()); + boolean pidMatch = (pid == 0) || (pid == winpid); - if (Native.toString(className).equals("POEWindowClass") && pidMatch) { + if (pidMatch) { User32.INSTANCE.ShowWindow(window.getHWND(), 5); boolean isAtFront = User32.INSTANCE.SetForegroundWindow(window.getHWND()); @@ -232,6 +261,7 @@ private void gameToFront() { User32.INSTANCE.SetFocus(window.getHWND()); } }); + // User32.INSTANCE.EnumWindows((hWnd, arg1) -> { // char[] className = new char[512]; // User32.INSTANCE.GetClassName(hWnd, className, 512); diff --git a/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java b/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java index b13560b8..5ea022ce 100644 --- a/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java +++ b/app-ui/src/main/java/com/mercury/platform/ui/components/panel/settings/page/GeneralSettingsPagePanel.java @@ -1,6 +1,7 @@ package com.mercury.platform.ui.components.panel.settings.page; +import com.mercury.platform.core.ChatHelper; import com.mercury.platform.core.misc.WhisperNotifierStatus; import com.mercury.platform.shared.CloneHelper; import com.mercury.platform.shared.PushBulletManager; @@ -12,13 +13,15 @@ import com.mercury.platform.ui.components.fields.font.FontStyle; import com.mercury.platform.ui.manager.HideSettingsManager; import com.mercury.platform.ui.misc.AppThemeColor; +import org.checkerframework.checker.units.qual.A; import javax.swing.*; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import java.awt.*; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; +import java.awt.event.*; +import java.util.ArrayList; +import java.util.Arrays; public class GeneralSettingsPagePanel extends SettingsPagePanel { private PlainConfigurationService applicationConfig; @@ -29,6 +32,19 @@ public class GeneralSettingsPagePanel extends SettingsPagePanel { private JSlider minSlider; private JSlider maxSlider; + private String[] PidStrings; + private ArrayList Pids; + + private void updatePoePids() { + ArrayList PidOptions = new ArrayList(Arrays.asList( + "Always Switch (old behavior)", + "Never switch")); + Pids = ChatHelper.getPoeWindowPids(); + Pids.forEach(pid -> { PidOptions.add(String.format("PID: %d", pid.intValue())); }); + PidStrings = new String[PidOptions.size()]; + PidStrings = PidOptions.toArray(PidStrings); + } + @Override public void onViewInit() { super.onViewInit(); @@ -105,20 +121,29 @@ public void keyTyped(KeyEvent e) { JButton changeButton = this.componentsFactory.getBorderedButton("Change"); poeFolderPanel.add(changeButton, BorderLayout.LINE_END); - JTextField poePidField = this.componentsFactory.getTextField(""); - poePidField.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createLineBorder(AppThemeColor.BORDER, 1), - BorderFactory.createLineBorder(AppThemeColor.TRANSPARENT, 2) - )); - poePidField.addKeyListener(new KeyAdapter() { + updatePoePids(); + JComboBox poePidPicker = this.componentsFactory.getComboBox(PidStrings); + poePidPicker.setSelectedItem(this.applicationSnapshot.getNotifierStatus().asPretty()); + poePidPicker.addPopupMenuListener(new PopupMenuListener() { @Override - public void keyTyped(KeyEvent e) { - int pid = applicationSnapshot.getGamePid(); + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + updatePoePids(); + poePidPicker.setModel(new DefaultComboBoxModel(PidStrings)); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + @Override + public void popupMenuCanceled(PopupMenuEvent e) {} + }); - try { pid = Integer.parseInt(poePidField.getText() + e.getKeyChar()); } - catch(Exception ex) {} + poePidPicker.addActionListener(action -> { + int sel = poePidPicker.getSelectedIndex(); - applicationSnapshot.setGamePid(pid); + switch (sel) { + case 0: applicationSnapshot.setGamePid(0); break; + case 1: applicationSnapshot.setGamePid(-1); break; + default: applicationSnapshot.setGamePid(Pids.get(sel - 2)); } }); @@ -170,8 +195,8 @@ public void keyTyped(KeyEvent e) { root.add(this.componentsFactory.wrapToSlide(notifierStatusPicker, AppThemeColor.ADR_BG, 0, 0, 0, 2)); root.add(this.componentsFactory.getTextLabel("Path of Exile folder: ", FontStyle.REGULAR, 16)); root.add(this.componentsFactory.wrapToSlide(poeFolderPanel, AppThemeColor.ADR_BG, 0, 0, 2, 2)); - root.add(this.componentsFactory.getTextLabel("Single game PID: ", FontStyle.REGULAR, 16)); - root.add(this.componentsFactory.wrapToSlide(poePidField, AppThemeColor.ADR_BG, 0, 0, 2, 2)); + root.add(this.componentsFactory.getTextLabel("Multi-client switching: ", FontStyle.REGULAR, 16)); + root.add(this.componentsFactory.wrapToSlide(poePidPicker, AppThemeColor.ADR_BG, 0, 0, 2, 2)); root.add(this.componentsFactory.getTextLabel("Pushbullet AccessToken ", FontStyle.REGULAR, 16)); root.add(this.componentsFactory.wrapToSlide(pushbulletPanel, AppThemeColor.ADR_BG, 0, 0, 0, 2));