fixed terminate
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
parent
0998ba3762
commit
b3cf1825d9
@ -7,40 +7,43 @@ import java.util.Set;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Globální hotkey listener pro detekci CTRL+ALT+Z kombinace
|
* Globální hotkey listener pro detekci CTRL+ALT+Q.
|
||||||
* Funguje i když není okno fokusované
|
* Na Linuxu funguje i bez fokusu přes nativní polling X11.
|
||||||
*/
|
*/
|
||||||
public class GlobalHotkey extends JLabel {
|
public class GlobalHotkey extends JLabel {
|
||||||
private static GlobalHotkey instance;
|
private static GlobalHotkey instance;
|
||||||
private GlobalKeyListener globalKeyListener;
|
private static final long HOTKEY_COOLDOWN_MS = 700;
|
||||||
|
|
||||||
|
private final GlobalKeyListener globalKeyListener;
|
||||||
|
private final Runnable onHotkey;
|
||||||
|
private volatile boolean running = true;
|
||||||
|
private volatile long lastHotkeyTrigger = 0L;
|
||||||
|
private Thread pollingThread;
|
||||||
|
|
||||||
public GlobalHotkey(Runnable onHotkey) {
|
public GlobalHotkey(Runnable onHotkey) {
|
||||||
this.globalKeyListener = new GlobalKeyListener(onHotkey);
|
this.onHotkey = onHotkey;
|
||||||
|
this.globalKeyListener = new GlobalKeyListener();
|
||||||
|
|
||||||
// Registrace globálního key listeneru pro případy, kdy má aplikace fokus
|
// Registrace globálního key listeneru pro případy, kdy má aplikace fokus
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
.addKeyEventDispatcher(globalKeyListener);
|
.addKeyEventDispatcher(globalKeyListener);
|
||||||
|
|
||||||
// Spustit nativní polling pro globální STOP hotkey na Linuxu (funguje i bez fokusu)
|
// Nativní polling globální hotkey na Linuxu (funguje i bez fokusu)
|
||||||
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
if (isLinux()) {
|
||||||
Thread pollingThread = new Thread(() -> {
|
pollingThread = new Thread(() -> {
|
||||||
while (true) {
|
while (running && !Thread.currentThread().isInterrupted()) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(150);
|
Thread.sleep(150);
|
||||||
// Kontrola CTRL+ALT+X globálně
|
// XK_Control_L/R: 0xFFE3/4, XK_Alt_L/R: 0xFFE9/A, XK_q: 0x71, XK_Q: 0x51
|
||||||
// XK_Control_L/R: 0xFFE3/4, XK_Alt_L/R: 0xFFE9/A, XK_x: 0x78, XK_X: 0x58
|
|
||||||
boolean ctrl = WindowFinder.isKeyPressedGlobally(0xFFE3) || WindowFinder.isKeyPressedGlobally(0xFFE4);
|
boolean ctrl = WindowFinder.isKeyPressedGlobally(0xFFE3) || WindowFinder.isKeyPressedGlobally(0xFFE4);
|
||||||
boolean alt = WindowFinder.isKeyPressedGlobally(0xFFE9) || WindowFinder.isKeyPressedGlobally(0xFFEA);
|
boolean alt = WindowFinder.isKeyPressedGlobally(0xFFE9) || WindowFinder.isKeyPressedGlobally(0xFFEA);
|
||||||
boolean xPressed = WindowFinder.isKeyPressedGlobally(0x78) || WindowFinder.isKeyPressedGlobally(0x58);
|
boolean qPressed = WindowFinder.isKeyPressedGlobally(0x71) || WindowFinder.isKeyPressedGlobally(0x51);
|
||||||
|
|
||||||
if (ctrl && alt && xPressed) {
|
if (ctrl && alt && qPressed) {
|
||||||
if (onHotkey != null) {
|
triggerHotkey("Globální NATIVNÍ hotkey detekován: CTRL+ALT+Q");
|
||||||
System.out.println("🔌 Globální NATIVNÍ hotkey detekován: CTRL+ALT+X");
|
|
||||||
onHotkey.run();
|
|
||||||
Thread.sleep(1000); // Prevence vícenásobného spuštění
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
break;
|
break;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Ignorovat chyby v pollingu
|
// Ignorovat chyby v pollingu
|
||||||
@ -62,7 +65,7 @@ public class GlobalHotkey extends JLabel {
|
|||||||
public boolean isKeyPressed(int keyCode) {
|
public boolean isKeyPressed(int keyCode) {
|
||||||
// Na Linuxu pro šipky používáme výhradně nativní globální detekci.
|
// Na Linuxu pro šipky používáme výhradně nativní globální detekci.
|
||||||
// Standardní KeyEventDispatcher se může "zaseknout", pokud okno ztratí fokus během stisku.
|
// Standardní KeyEventDispatcher se může "zaseknout", pokud okno ztratí fokus během stisku.
|
||||||
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
if (isLinux()) {
|
||||||
if (keyCode == KeyEvent.VK_DOWN) {
|
if (keyCode == KeyEvent.VK_DOWN) {
|
||||||
try {
|
try {
|
||||||
return WindowFinder.isKeyPressedGlobally(0xFF54); // XK_Down
|
return WindowFinder.isKeyPressedGlobally(0xFF54); // XK_Down
|
||||||
@ -76,17 +79,40 @@ public class GlobalHotkey extends JLabel {
|
|||||||
return globalKeyListener.isKeyPressed(keyCode);
|
return globalKeyListener.isKeyPressed(keyCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
running = false;
|
||||||
|
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||||
|
.removeKeyEventDispatcher(globalKeyListener);
|
||||||
|
|
||||||
|
if (pollingThread != null) {
|
||||||
|
pollingThread.interrupt();
|
||||||
|
pollingThread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLinux() {
|
||||||
|
return System.getProperty("os.name").toLowerCase().contains("linux");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void triggerHotkey(String logMessage) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
if (now - lastHotkeyTrigger < HOTKEY_COOLDOWN_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lastHotkeyTrigger = now;
|
||||||
|
|
||||||
|
if (onHotkey != null) {
|
||||||
|
System.out.println("🔌 " + logMessage);
|
||||||
|
onHotkey.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interní třída pro globální naslouchání na klávesnici
|
* Interní třída pro globální naslouchání na klávesnici
|
||||||
*/
|
*/
|
||||||
private static class GlobalKeyListener implements java.awt.KeyEventDispatcher {
|
private class GlobalKeyListener implements java.awt.KeyEventDispatcher {
|
||||||
private Runnable callback;
|
|
||||||
private Set<Integer> pressedKeys = new HashSet<>();
|
private Set<Integer> pressedKeys = new HashSet<>();
|
||||||
|
|
||||||
public GlobalKeyListener(Runnable callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isKeyPressed(int keyCode) {
|
public boolean isKeyPressed(int keyCode) {
|
||||||
return pressedKeys.contains(keyCode);
|
return pressedKeys.contains(keyCode);
|
||||||
}
|
}
|
||||||
@ -96,13 +122,10 @@ public class GlobalHotkey extends JLabel {
|
|||||||
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||||
pressedKeys.add(e.getKeyCode());
|
pressedKeys.add(e.getKeyCode());
|
||||||
|
|
||||||
// Detekce CTRL+ALT+X
|
// Detekce CTRL+ALT+Q
|
||||||
if (e.getKeyCode() == KeyEvent.VK_X &&
|
if (e.getKeyCode() == KeyEvent.VK_Q &&
|
||||||
e.isControlDown() && e.isAltDown()) {
|
e.isControlDown() && e.isAltDown()) {
|
||||||
System.out.println("🔌 Globální hotkey detekován: CTRL+ALT+X");
|
triggerHotkey("Globální hotkey detekován: CTRL+ALT+Q");
|
||||||
if (callback != null) {
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
return true; // Konzumovat event
|
return true; // Konzumovat event
|
||||||
}
|
}
|
||||||
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
|
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||||
|
|||||||
@ -1,15 +1,11 @@
|
|||||||
package com.pokemongo;
|
package com.pokemongo;
|
||||||
|
|
||||||
import java.awt.AWTException;
|
import java.awt.AWTException;
|
||||||
import java.awt.GraphicsDevice;
|
|
||||||
import java.awt.GraphicsEnvironment;
|
|
||||||
import java.awt.Insets;
|
|
||||||
import java.awt.MouseInfo;
|
import java.awt.MouseInfo;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.PointerInfo;
|
import java.awt.PointerInfo;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Robot;
|
import java.awt.Robot;
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.event.InputEvent;
|
import java.awt.event.InputEvent;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -35,6 +31,7 @@ public class PokemonGoAutomation {
|
|||||||
private static final int DELAY_AFTER_ACTION = 100; // ms
|
private static final int DELAY_AFTER_ACTION = 100; // ms
|
||||||
private int transferredPokemonCount = 0; // Počet transfernutých pokémonů
|
private int transferredPokemonCount = 0; // Počet transfernutých pokémonů
|
||||||
private Point initialMousePosition = null; // Pozice kurzoru před začátkem automatizace
|
private Point initialMousePosition = null; // Pozice kurzoru před začátkem automatizace
|
||||||
|
private volatile boolean stopRequested = false;
|
||||||
|
|
||||||
public PokemonGoAutomation() throws AWTException {
|
public PokemonGoAutomation() throws AWTException {
|
||||||
this.robot = new Robot();
|
this.robot = new Robot();
|
||||||
@ -57,6 +54,14 @@ public class PokemonGoAutomation {
|
|||||||
transferredPokemonCount = 0;
|
transferredPokemonCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void requestStop() {
|
||||||
|
stopRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldStop() {
|
||||||
|
return stopRequested || Thread.currentThread().isInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pořídí screenshot oblasti okna
|
* Pořídí screenshot oblasti okna
|
||||||
*/
|
*/
|
||||||
@ -120,6 +125,10 @@ public class PokemonGoAutomation {
|
|||||||
if (template == null)
|
if (template == null)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
int tWidth = template.getWidth();
|
int tWidth = template.getWidth();
|
||||||
int tHeight = template.getHeight();
|
int tHeight = template.getHeight();
|
||||||
|
|
||||||
@ -136,6 +145,9 @@ public class PokemonGoAutomation {
|
|||||||
int requiredMatch = (int) (totalPixels * 0.75); // 75% shody
|
int requiredMatch = (int) (totalPixels * 0.75); // 75% shody
|
||||||
|
|
||||||
for (int y = 0; y < tHeight; y++) {
|
for (int y = 0; y < tHeight; y++) {
|
||||||
|
if (shouldStop()) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
for (int x = 0; x < tWidth; x++) {
|
for (int x = 0; x < tWidth; x++) {
|
||||||
int templateRGB = template.getRGB(x, y);
|
int templateRGB = template.getRGB(x, y);
|
||||||
int screenRGB = screenshot.getRGB(startX + x, startY + y);
|
int screenRGB = screenshot.getRGB(startX + x, startY + y);
|
||||||
@ -175,6 +187,10 @@ public class PokemonGoAutomation {
|
|||||||
private Point findConfirmTransferButtonPosition(BufferedImage template, int tolerance) {
|
private Point findConfirmTransferButtonPosition(BufferedImage template, int tolerance) {
|
||||||
System.out.println("Hledám potvrzovací TRANSFER tlačítko pomocí template matchingu...");
|
System.out.println("Hledám potvrzovací TRANSFER tlačítko pomocí template matchingu...");
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
BufferedImage screenshot = captureScreen(windowBounds);
|
BufferedImage screenshot = captureScreen(windowBounds);
|
||||||
|
|
||||||
int tWidth = template.getWidth();
|
int tWidth = template.getWidth();
|
||||||
@ -190,6 +206,9 @@ public class PokemonGoAutomation {
|
|||||||
|
|
||||||
// Skenovat Y-ové pozice s větším krokem - 15px místo 5px pro zrychlení
|
// Skenovat Y-ové pozice s větším krokem - 15px místo 5px pro zrychlení
|
||||||
for (int y = searchStartY; y <= searchEndY - tHeight; y += 15) {
|
for (int y = searchStartY; y <= searchEndY - tHeight; y += 15) {
|
||||||
|
if (shouldStop()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// Skenovat také X pozice pro nalezení středu shody
|
// Skenovat také X pozice pro nalezení středu shody
|
||||||
for (int x = 0; x <= windowBounds.width - tWidth; x += 30) {
|
for (int x = 0; x <= windowBounds.width - tWidth; x += 30) {
|
||||||
double score = templateMatch(screenshot, x, y, template, tolerance);
|
double score = templateMatch(screenshot, x, y, template, tolerance);
|
||||||
@ -218,6 +237,10 @@ public class PokemonGoAutomation {
|
|||||||
private Point findIncludeButtonPosition(int tolerance) {
|
private Point findIncludeButtonPosition(int tolerance) {
|
||||||
System.out.println("Hledám tlačítko INCLUDE pomocí template matchingu (include.png)...");
|
System.out.println("Hledám tlačítko INCLUDE pomocí template matchingu (include.png)...");
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
BufferedImage screenshot = captureScreen(windowBounds);
|
BufferedImage screenshot = captureScreen(windowBounds);
|
||||||
|
|
||||||
int tWidth = includeTemplate.getWidth();
|
int tWidth = includeTemplate.getWidth();
|
||||||
@ -233,6 +256,9 @@ public class PokemonGoAutomation {
|
|||||||
|
|
||||||
// Skenovat Y-ové pozice s větším krokem - 15px místo 5px pro zrychlení
|
// Skenovat Y-ové pozice s větším krokem - 15px místo 5px pro zrychlení
|
||||||
for (int y = searchStartY; y <= searchEndY - tHeight; y += 15) {
|
for (int y = searchStartY; y <= searchEndY - tHeight; y += 15) {
|
||||||
|
if (shouldStop()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// Skenovat také X pozice pro nalezení středu shody
|
// Skenovat také X pozice pro nalezení středu shody
|
||||||
for (int x = 0; x <= windowBounds.width - tWidth; x += 30) {
|
for (int x = 0; x <= windowBounds.width - tWidth; x += 30) {
|
||||||
double score = templateMatch(screenshot, x, y, includeTemplate, tolerance);
|
double score = templateMatch(screenshot, x, y, includeTemplate, tolerance);
|
||||||
@ -309,6 +335,10 @@ public class PokemonGoAutomation {
|
|||||||
* Stiskne tlačítko Transfer na spodní části obrazovky
|
* Stiskne tlačítko Transfer na spodní části obrazovky
|
||||||
*/
|
*/
|
||||||
public void clickTransferButton() {
|
public void clickTransferButton() {
|
||||||
|
if (shouldStop()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Použít detekci tlačítka
|
// Použít detekci tlačítka
|
||||||
// Point buttonPos = findTransferButtonPosition();
|
// Point buttonPos = findTransferButtonPosition();
|
||||||
Point buttonPos = getAbsolutePoint(300, 1156);
|
Point buttonPos = getAbsolutePoint(300, 1156);
|
||||||
@ -334,6 +364,10 @@ public class PokemonGoAutomation {
|
|||||||
public void clickConfirmTransferButton(BufferedImage template, int tolerance) {
|
public void clickConfirmTransferButton(BufferedImage template, int tolerance) {
|
||||||
System.out.println("Potvrzuji transfer - hledám confirmation button...");
|
System.out.println("Potvrzuji transfer - hledám confirmation button...");
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
robot.delay(100); // Počkat na zobrazení dialogu
|
robot.delay(100); // Počkat na zobrazení dialogu
|
||||||
|
|
||||||
// Najít zelené TRANSFER tlačítko v potvrzovacím dialogu
|
// Najít zelené TRANSFER tlačítko v potvrzovacím dialogu
|
||||||
@ -356,6 +390,10 @@ public class PokemonGoAutomation {
|
|||||||
public boolean clickIncludeButton(int tolerance) {
|
public boolean clickIncludeButton(int tolerance) {
|
||||||
System.out.println("Potvrzuji transfer - hledám include.png (confirmation button)...");
|
System.out.println("Potvrzuji transfer - hledám include.png (confirmation button)...");
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
robot.delay(100); // Počkat na zobrazení dialogu
|
robot.delay(100); // Počkat na zobrazení dialogu
|
||||||
|
|
||||||
// Najít zelené INCLUDE tlačítko v potvrzovacím dialogu
|
// Najít zelené INCLUDE tlačítko v potvrzovacím dialogu
|
||||||
@ -409,7 +447,7 @@ public class PokemonGoAutomation {
|
|||||||
try {
|
try {
|
||||||
while (transferredCount < totalPokemonCount) {
|
while (transferredCount < totalPokemonCount) {
|
||||||
// Kontrola přerušení
|
// Kontrola přerušení
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (shouldStop()) {
|
||||||
System.out.println("\n⚠️ Automatizace byla přerušena!");
|
System.out.println("\n⚠️ Automatizace byla přerušena!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -423,9 +461,19 @@ public class PokemonGoAutomation {
|
|||||||
// Vybrat pokémony a získat skutečný počet vybraných
|
// Vybrat pokémony a získat skutečný počet vybraných
|
||||||
int actualTransferredCount = selectAllPokemonCount(pokemonThisRound);
|
int actualTransferredCount = selectAllPokemonCount(pokemonThisRound);
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
System.out.println("\n⚠️ Automatizace byla přerušena během označování!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Čekám na TRANSFER...");
|
System.out.println("Čekám na TRANSFER...");
|
||||||
clickTransferButton();
|
clickTransferButton();
|
||||||
|
|
||||||
|
if (shouldStop()) {
|
||||||
|
System.out.println("\n⚠️ Automatizace byla přerušena po kliknutí na TRANSFER!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("Čekám na INCLUDE dialog...");
|
System.out.println("Čekám na INCLUDE dialog...");
|
||||||
robot.delay(100);
|
robot.delay(100);
|
||||||
if (clickIncludeButton(110)) {
|
if (clickIncludeButton(110)) {
|
||||||
@ -450,7 +498,7 @@ public class PokemonGoAutomation {
|
|||||||
// Čekat s kontrolou přerušení
|
// Čekat s kontrolou přerušení
|
||||||
long endTime = System.currentTimeMillis() + (delaySeconds * 1000L);
|
long endTime = System.currentTimeMillis() + (delaySeconds * 1000L);
|
||||||
while (System.currentTimeMillis() < endTime) {
|
while (System.currentTimeMillis() < endTime) {
|
||||||
if (Thread.currentThread().isInterrupted()) {
|
if (shouldStop()) {
|
||||||
System.out.println("\n⚠️ Automatizace byla přerušena během přestávky!");
|
System.out.println("\n⚠️ Automatizace byla přerušena během přestávky!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -487,6 +535,11 @@ public class PokemonGoAutomation {
|
|||||||
System.out.println("Budu označovat " + maxPokemon + " pokémonů...");
|
System.out.println("Budu označovat " + maxPokemon + " pokémonů...");
|
||||||
|
|
||||||
for (int i = 0; i < maxPokemon; i++) {
|
for (int i = 0; i < maxPokemon; i++) {
|
||||||
|
if (shouldStop()) {
|
||||||
|
System.out.println("Označování přerušeno.");
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
Point pos = positions.get(i);
|
Point pos = positions.get(i);
|
||||||
System.out.println("Klikám na Pokémona " + (i + 1) + "/" + maxPokemon + " na pozici: " + pos);
|
System.out.println("Klikám na Pokémona " + (i + 1) + "/" + maxPokemon + " na pozici: " + pos);
|
||||||
|
|
||||||
|
|||||||
@ -96,7 +96,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
versionLabel.setFont(SMALL_FONT);
|
versionLabel.setFont(SMALL_FONT);
|
||||||
versionLabel.setForeground(new Color(120, 120, 120));
|
versionLabel.setForeground(new Color(120, 120, 120));
|
||||||
|
|
||||||
stopButton = new JButton("⏹ ZASTAVIT (CTRL+ALT+X)");
|
stopButton = new JButton("⏹ ZASTAVIT (CTRL+ALT+Q)");
|
||||||
stopButton.setPreferredSize(new Dimension(150, 30));
|
stopButton.setPreferredSize(new Dimension(150, 30));
|
||||||
styleButton(stopButton, PRIMARY_RED, Color.WHITE, SMALL_FONT);
|
styleButton(stopButton, PRIMARY_RED, Color.WHITE, SMALL_FONT);
|
||||||
stopButton.setEnabled(false);
|
stopButton.setEnabled(false);
|
||||||
@ -261,8 +261,8 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
|
|
||||||
add(mainPanel);
|
add(mainPanel);
|
||||||
|
|
||||||
// Klávesová zkratka: Ctrl+Alt+Z pro zastavení
|
// Klávesová zkratka: Ctrl+Alt+Q pro zastavení
|
||||||
KeyStroke hotkey = KeyStroke.getKeyStroke(KeyEvent.VK_X, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK);
|
KeyStroke hotkey = KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_DOWN_MASK | KeyEvent.ALT_DOWN_MASK);
|
||||||
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(hotkey, "stopAutomationAction");
|
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(hotkey, "stopAutomationAction");
|
||||||
getRootPane().getActionMap().put("stopAutomationAction", new AbstractAction() {
|
getRootPane().getActionMap().put("stopAutomationAction", new AbstractAction() {
|
||||||
@Override
|
@Override
|
||||||
@ -273,7 +273,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Globální hotkey pro ESC (bonus, když okno není fokusované)
|
// Globální hotkey (funguje i když okno není fokusované)
|
||||||
globalHotkey = new GlobalHotkey(new Runnable() {
|
globalHotkey = new GlobalHotkey(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -290,7 +290,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
logArea.append("=== Pokémon GO Automatizace ===\n\n");
|
logArea.append("=== Pokémon GO Automatizace ===\n\n");
|
||||||
logArea.append("Vyberte jednu z automatizací a klikněte na tlačítko START.\n");
|
logArea.append("Vyberte jednu z automatizací a klikněte na tlačítko START.\n");
|
||||||
logArea.append("Ujistěte se, že je aplikace Pokémon GO spuštěná.\n");
|
logArea.append("Ujistěte se, že je aplikace Pokémon GO spuštěná.\n");
|
||||||
logArea.append("Pro zastavení stiskněte Ctrl+Alt+X nebo klikněte ZASTAVIT.\n\n");
|
logArea.append("Pro zastavení stiskněte Ctrl+Alt+Q nebo klikněte ZASTAVIT.\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -482,6 +482,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Získat počet pokémonů a čekání z GUI
|
// Získat počet pokémonů a čekání z GUI
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
JComboBox<Integer> countComboBox = (JComboBox<Integer>) transferCard.getClientProperty("countComboBox");
|
JComboBox<Integer> countComboBox = (JComboBox<Integer>) transferCard.getClientProperty("countComboBox");
|
||||||
JSpinner delaySpinner = (JSpinner) transferCard.getClientProperty("delaySpinner");
|
JSpinner delaySpinner = (JSpinner) transferCard.getClientProperty("delaySpinner");
|
||||||
|
|
||||||
@ -742,10 +743,17 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
* Zastaví automatizaci
|
* Zastaví automatizaci
|
||||||
*/
|
*/
|
||||||
private void stopAutomation() {
|
private void stopAutomation() {
|
||||||
|
if (!isRunning && !autoClickRunning) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
shouldStop = true;
|
shouldStop = true;
|
||||||
autoClickRunning = false;
|
autoClickRunning = false;
|
||||||
isRunning = false;
|
isRunning = false;
|
||||||
stopButton.setEnabled(false);
|
|
||||||
|
if (automation != null) {
|
||||||
|
automation.requestStop();
|
||||||
|
}
|
||||||
|
|
||||||
if (automationThread != null && automationThread.isAlive()) {
|
if (automationThread != null && automationThread.isAlive()) {
|
||||||
automationThread.interrupt();
|
automationThread.interrupt();
|
||||||
@ -760,6 +768,7 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
stopButton.setEnabled(false);
|
||||||
logArea.append("\n⚠️ Automatizace byla přerušena uživatelem\n");
|
logArea.append("\n⚠️ Automatizace byla přerušena uživatelem\n");
|
||||||
statusLabel.setText("Přerušeno");
|
statusLabel.setText("Přerušeno");
|
||||||
statusLabel.setForeground(new Color(244, 67, 54));
|
statusLabel.setForeground(new Color(244, 67, 54));
|
||||||
@ -852,6 +861,9 @@ public class PokemonGoGUI extends JFrame {
|
|||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent e) {
|
public void windowClosing(WindowEvent e) {
|
||||||
System.out.println("Zavírám okno...");
|
System.out.println("Zavírám okno...");
|
||||||
|
if (frame.globalHotkey != null) {
|
||||||
|
frame.globalHotkey.cleanup();
|
||||||
|
}
|
||||||
frame.saveSettings();
|
frame.saveSettings();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user