From 162aa6d7ab3d978b46b3d606f9211e1d6a1ed3e6 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Fri, 19 Dec 2025 21:54:56 +0100 Subject: [PATCH] removed xdotool --- pgo-automat-settings.properties | 8 +- .../com/pokemongo/PokemonGoAutomation.java | 87 +++---- .../java/com/pokemongo/PositionPicker.java | 14 +- src/main/java/com/pokemongo/WindowFinder.java | 231 ++++++++++++++++++ 4 files changed, 280 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/pokemongo/WindowFinder.java diff --git a/pgo-automat-settings.properties b/pgo-automat-settings.properties index 911a184..451f7cc 100644 --- a/pgo-automat-settings.properties +++ b/pgo-automat-settings.properties @@ -1,12 +1,12 @@ #Pokémon GO Automatizace - Nastavení -#Sun Dec 14 20:04:32 CET 2025 +#Fri Dec 19 21:53:30 CET 2025 autoklik.count=500 window.width=807 transfer.delay=0 window.height=743 autoklik.x=2380 autoklik.y=1124 -transfer.count=48 -window.x=866 +transfer.count=3 +window.x=1127 autoklik.interval=100 -window.y=237 +window.y=697 diff --git a/src/main/java/com/pokemongo/PokemonGoAutomation.java b/src/main/java/com/pokemongo/PokemonGoAutomation.java index d1b5dba..6983551 100644 --- a/src/main/java/com/pokemongo/PokemonGoAutomation.java +++ b/src/main/java/com/pokemongo/PokemonGoAutomation.java @@ -3,9 +3,11 @@ package com.pokemongo; import java.awt.AWTException; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.InputEvent; import java.awt.image.BufferedImage; import java.io.IOException; @@ -38,6 +40,23 @@ public class PokemonGoAutomation { loadButtonTemplates(); } + /** + * ZjistĂ­ insets displeje (offset zp ĹŻsobenĂ˝ OS - panel, taskbar, apod.) + * DĹŻleĹľitĂ© pro Ubuntu s GNOME panelem na hornĂ­ stranÄ› + */ + private Insets getScreenInsets() { + try { + GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); + System.out.println("ZjištÄ›ny OS insets: top=" + insets.top + ", left=" + insets.left + + ", bottom=" + insets.bottom + ", right=" + insets.right); + return insets; + } catch (Exception e) { + System.out.println("Chyba pĹ™i zjištÄ›nĂ­ insets: " + e.getMessage()); + return new Insets(0, 0, 0, 0); + } + } + /** * VrátĂ­ poÄŤet dosud transfernutĂ˝ch pokĂ©monĹŻ */ @@ -382,65 +401,21 @@ public class PokemonGoAutomation { */ public boolean findPokemonGoWindow() { try { - // Pro Linux - hledánĂ­ okna pomocĂ­ xdotool - // Nejdříve najĂ­t ID okna, pak zĂ­skat jeho geometrii - Process searchProcess = Runtime.getRuntime().exec( - new String[] { "bash", "-c", "xdotool search --name \"Lenovo|L78032\" | head -1" }); - - java.io.BufferedReader searchReader = new java.io.BufferedReader( - new java.io.InputStreamReader(searchProcess.getInputStream())); - - String windowId = searchReader.readLine(); - searchProcess.waitFor(); - - if (windowId != null && !windowId.trim().isEmpty()) { - System.out.println("Nalezeno okno s ID: " + windowId); - - // ZĂ­skat geometrii okna - Process geomProcess = Runtime.getRuntime().exec( - new String[] { "bash", "-c", "xdotool getwindowgeometry " + windowId.trim() }); - - java.io.BufferedReader geomReader = new java.io.BufferedReader( - new java.io.InputStreamReader(geomProcess.getInputStream())); - - String line; - int x = 0, y = 0, width = 0, height = 0; - - while ((line = geomReader.readLine()) != null) { - System.out.println("xdotool vĂ˝stup: " + line); - if (line.contains("Position:")) { - String[] parts = line.split("Position: ")[1].split(","); - x = Integer.parseInt(parts[0].trim()); - y = Integer.parseInt(parts[1].trim().split(" ")[0]); - } else if (line.contains("Geometry:")) { - String[] parts = line.split("Geometry: ")[1].split("x"); - width = Integer.parseInt(parts[0].trim()); - height = Integer.parseInt(parts[1].trim()); - } - } - - geomProcess.waitFor(); - - if (width > 0 && height > 0) { - windowBounds = new Rectangle(x, y, width, height); - System.out.println("Nalezeno okno: " + windowBounds); - return true; - } + Rectangle bounds = WindowFinder.findWindowByName("Lenovo"); + + if (bounds != null && bounds.width > 0 && bounds.height > 0) { + windowBounds = bounds; + System.out.println("Nalezeno okno: " + windowBounds); + return true; } - // Fallback - pouĹľitĂ­ celĂ© obrazovky - System.out.println("Okno nenalezeno, pouĹľiji celou obrazovku"); - GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - windowBounds = gd.getDefaultConfiguration().getBounds(); - return true; + System.out.println("Okno PokĂ©mon GO nebylo nalezeno."); + return false; } catch (Exception e) { System.err.println("Chyba pĹ™i hledánĂ­ okna: " + e.getMessage()); e.printStackTrace(); - // PouĹľitĂ­ celĂ© obrazovky jako záloĹľnĂ­ varianta - GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - windowBounds = gd.getDefaultConfiguration().getBounds(); - return true; + return false; } } @@ -687,8 +662,10 @@ public class PokemonGoAutomation { * @return AbsolutnĂ­ pozice na obrazovce */ private Point getAbsolutePoint(int relativeX, int relativeY) { - int absoluteX = windowBounds.x + relativeX; - int absoluteY = windowBounds.y + relativeY; + int xCorrection = 20; + int yCorrection = 100; + int absoluteX = windowBounds.x + relativeX + xCorrection; + int absoluteY = windowBounds.y + relativeY + yCorrection; return new Point(absoluteX, absoluteY); } diff --git a/src/main/java/com/pokemongo/PositionPicker.java b/src/main/java/com/pokemongo/PositionPicker.java index c92cb3c..38c72a2 100644 --- a/src/main/java/com/pokemongo/PositionPicker.java +++ b/src/main/java/com/pokemongo/PositionPicker.java @@ -20,7 +20,19 @@ public class PositionPicker extends JWindow { public PositionPicker(PositionPickerListener listener) { this.listener = listener; GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - Rectangle bounds = gd.getDefaultConfiguration().getBounds(); + Rectangle screenBounds = gd.getDefaultConfiguration().getBounds(); + + // Zjistit insets - offset zp ĹŻsobenĂ˝ OS panelem/dashboardem + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); + System.out.println("PositionPicker insets: top=" + insets.top + ", left=" + insets.left); + + // Aplikovat insets na bounds + Rectangle bounds = new Rectangle( + screenBounds.x + insets.left, + screenBounds.y + insets.top, + screenBounds.width - insets.left - insets.right, + screenBounds.height - insets.top - insets.bottom + ); setBounds(bounds); System.out.println("PositionPicker vytvoĹ™en: " + bounds); diff --git a/src/main/java/com/pokemongo/WindowFinder.java b/src/main/java/com/pokemongo/WindowFinder.java new file mode 100644 index 0000000..d496b21 --- /dev/null +++ b/src/main/java/com/pokemongo/WindowFinder.java @@ -0,0 +1,231 @@ +package com.pokemongo; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; +import java.awt.Rectangle; +import java.util.Arrays; +import java.util.List; + +/** + * Pomocná třída pro hledánĂ­ oken v Linux/X11 prostĹ™edĂ­. + * Používá X11 API pĹ™es JNA bindings. + */ +public class WindowFinder { + + /** + * X11 native library interface + */ + public interface X11 extends Library { + X11 INSTANCE = Native.load("X11", X11.class); + + /** + * X11 Window Attributes struktura + */ + class XWindowAttributes extends Structure { + public int x; + public int y; + public int width; + public int height; + public int border_width; + public int depth; + public Pointer visual; + public Pointer root; + public int class_; + public int bit_gravity; + public int win_gravity; + public int backing_pixel; + public int backing_planes; + public int backing_store; + public long backing_pixel_unused; + public int save_under; + public Pointer colormap; + public int map_installed; + public int map_state; + public long all_event_masks; + public long your_event_mask; + public long do_not_propagate_mask; + + @Override + protected List getFieldOrder() { + return Arrays.asList("x", "y", "width", "height", "border_width", "depth", + "visual", "root", "class_", "bit_gravity", "win_gravity", + "backing_pixel", "backing_planes", "backing_store", + "backing_pixel_unused", "save_under", "colormap", + "map_installed", "map_state", "all_event_masks", + "your_event_mask", "do_not_propagate_mask"); + } + } + + // X11 funkce + // Display je Pointer (nije Structure) + Pointer XOpenDisplay(String displayName); + int XCloseDisplay(Pointer display); + long XDefaultRootWindow(Pointer display); + + int XGetWindowAttributes(Pointer display, long window, XWindowAttributes attrs); + + long XInternAtom(Pointer display, String atomName, boolean onlyIfExists); + + int XQueryTree(Pointer display, long window, + PointerByReference root_return, PointerByReference parent_return, + PointerByReference children_return, IntByReference nchildren_return); + + int XFetchName(Pointer display, long window, PointerByReference window_name_return); + + Pointer XFree(Pointer ptr); + } + + /** + * Najde okno podle jeho názvu a vrátĂ­ jeho bounds + * @param searchPattern Pattern pro hledánĂ­ (substring názvu okna) + * @return Rectangle s pozicĂ­ a velikostĂ­ okna, nebo null pokud nenalezeno + */ + public static Rectangle findWindowByName(String searchPattern) { + Pointer display = null; + try { + display = X11.INSTANCE.XOpenDisplay(null); + if (display == null) { + System.out.println("WindowFinder: Nelze se pĹ™ipojit k X11 displei"); + return null; + } + + System.out.println("WindowFinder: PĹ™ipojen k X11 displayu"); + + long rootWindow = X11.INSTANCE.XDefaultRootWindow(display); + long[] foundWindow = new long[1]; + foundWindow[0] = 0; + + searchWindowRecursive(display, rootWindow, searchPattern, foundWindow); + + if (foundWindow[0] != 0) { + Rectangle bounds = getWindowBounds(display, foundWindow[0]); + if (bounds != null) { + System.out.println("WindowFinder: Okno nalezeno: " + bounds); + return bounds; + } + } + + System.out.println("WindowFinder: Okno s názvem '" + searchPattern + "' nenalezeno"); + return null; + + } catch (Exception e) { + System.err.println("WindowFinder - Chyba: " + e.getMessage()); + e.printStackTrace(); + return null; + } finally { + if (display != null) { + try { + X11.INSTANCE.XCloseDisplay(display); + } catch (Exception e) { + System.err.println("WindowFinder - Chyba pĹ™i zavĂ­ránĂ­ displeje: " + e.getMessage()); + } + } + } + } + + /** + * RekurzivnÄ› hledá okno v stromÄ› oken + */ + private static void searchWindowRecursive(Pointer display, long window, + String searchPattern, long[] result) { + if (result[0] != 0) { + return; // Okno jiĹľ nalezeno + } + + try { + String windowName = getWindowNameString(display, window); + if (windowName != null && windowName.contains(searchPattern)) { + result[0] = window; + System.out.println("WindowFinder: Nalezeno okno: '" + windowName + "' (XID: " + window + ")"); + return; + } + } catch (Exception e) { + // Ignorovat chyby pĹ™i ÄŤtenĂ­ jmĂ©na okna + } + + // Hledat v potomcĂ­ch + try { + PointerByReference root_return = new PointerByReference(); + PointerByReference parent_return = new PointerByReference(); + PointerByReference children_return = new PointerByReference(); + IntByReference nchildren_return = new IntByReference(); + + int status = X11.INSTANCE.XQueryTree(display, window, root_return, parent_return, + children_return, nchildren_return); + + if (status != 0 && nchildren_return.getValue() > 0) { + Pointer childrenPtr = children_return.getValue(); + int numChildren = nchildren_return.getValue(); + + if (childrenPtr != null) { + // ÄŚtenĂ­ window IDs z pole + for (int i = 0; i < numChildren && result[0] == 0; i++) { + long childWindow = childrenPtr.getLong((long) i * 8); // 64-bit window IDs + + if (childWindow != 0) { + searchWindowRecursive(display, childWindow, searchPattern, result); + } + } + + // Uvolnit paměť + X11.INSTANCE.XFree(childrenPtr); + } + } + } catch (Exception e) { + // Ignorovat chyby pĹ™i hledánĂ­ v potomcĂ­ch + } + } + + /** + * ZĂ­ská jmĂ©no okna jako String + */ + private static String getWindowNameString(Pointer display, long window) { + try { + PointerByReference namePtr = new PointerByReference(); + int status = X11.INSTANCE.XFetchName(display, window, namePtr); + + if (status != 0 && namePtr.getValue() != null) { + String name = namePtr.getValue().getString(0); + if (name != null && !name.isEmpty()) { + X11.INSTANCE.XFree(namePtr.getValue()); + return name; + } + X11.INSTANCE.XFree(namePtr.getValue()); + } + } catch (Exception e) { + // Ignorovat chyby + } + + return null; + } + + /** + * ZĂ­ská bounds okna (pozici a velikost) + */ + private static Rectangle getWindowBounds(Pointer display, long window) { + try { + X11.XWindowAttributes attrs = new X11.XWindowAttributes(); + int status = X11.INSTANCE.XGetWindowAttributes(display, window, attrs); + + if (status == 0) { + System.err.println("WindowFinder - Chyba pĹ™i zĂ­skávánĂ­ window attributes"); + return null; + } + + System.out.println("WindowFinder: Window bounds - x:" + attrs.x + " y:" + attrs.y + + " w:" + attrs.width + " h:" + attrs.height); + + return new Rectangle(attrs.x, attrs.y, attrs.width, attrs.height); + + } catch (Exception e) { + System.err.println("WindowFinder - Chyba pĹ™i zĂ­skávánĂ­ bounds: " + e.getMessage()); + e.printStackTrace(); + } + + return null; + } +} \ No newline at end of file