transfer fixes
This commit is contained in:
parent
162aa6d7ab
commit
444fd73bb2
@ -1,5 +1,5 @@
|
||||
#Pokémon GO Automatizace - Nastavení
|
||||
#Fri Dec 19 21:53:30 CET 2025
|
||||
#Fri Dec 19 22:55:32 CET 2025
|
||||
autoklik.count=500
|
||||
window.width=807
|
||||
transfer.delay=0
|
||||
|
||||
@ -4,7 +4,9 @@ import java.awt.AWTException;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Insets;
|
||||
import java.awt.MouseInfo;
|
||||
import java.awt.Point;
|
||||
import java.awt.PointerInfo;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
@ -32,6 +34,7 @@ public class PokemonGoAutomation {
|
||||
private static final int DELAY_BETWEEN_CLICKS = 100; // ms
|
||||
private static final int DELAY_AFTER_ACTION = 100; // ms
|
||||
private int transferredPokemonCount = 0; // Počet transfernutých pokémonů
|
||||
private Point initialMousePosition = null; // Pozice kurzoru před začátkem automatizace
|
||||
|
||||
public PokemonGoAutomation() throws AWTException {
|
||||
this.robot = new Robot();
|
||||
@ -524,6 +527,13 @@ public class PokemonGoAutomation {
|
||||
System.out.println("Spouštím Transfer automatizaci - Počet pokémonů: " + totalPokemonCount + ", Čekání: "
|
||||
+ delaySeconds + "s");
|
||||
|
||||
// Uložit aktuální pozici kurzoru
|
||||
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
||||
initialMousePosition = pointerInfo != null ? pointerInfo.getLocation() : null;
|
||||
if (initialMousePosition != null) {
|
||||
System.out.println("Uložena počáteční pozice kurzoru: " + initialMousePosition);
|
||||
}
|
||||
|
||||
if (!findPokemonGoWindow()) {
|
||||
System.err.println("Nepodařilo se najít okno Pokémon GO!");
|
||||
return;
|
||||
@ -537,7 +547,8 @@ public class PokemonGoAutomation {
|
||||
int transferredCount = 0;
|
||||
|
||||
// Transferovat dokud nedosáhneme požadovaného počtu
|
||||
while (transferredCount < totalPokemonCount) {
|
||||
try {
|
||||
while (transferredCount < totalPokemonCount) {
|
||||
// Kontrola přerušení
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
System.out.println("\n⚠️ Automatizace byla přerušena!");
|
||||
@ -582,11 +593,22 @@ public class PokemonGoAutomation {
|
||||
while (System.currentTimeMillis() < endTime) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
System.out.println("\n⚠️ Automatizace byla přerušena během přestávky!");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
robot.delay(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Obnovit pozici kurzoru
|
||||
if (initialMousePosition != null) {
|
||||
try {
|
||||
robot.mouseMove(initialMousePosition.x, initialMousePosition.y);
|
||||
System.out.println("Kurzor vrácen na počáteční pozici: " + initialMousePosition);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Chyba při obnovení pozice kurzoru: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\n✅ Transfer automatizace dokončena! Transferováno: " + transferredCount + " pokémonů");
|
||||
@ -669,6 +691,30 @@ public class PokemonGoAutomation {
|
||||
return new Point(absoluteX, absoluteY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vyčistí všechny prostředky používané automatizací
|
||||
* Volat po skončení automatizace
|
||||
*/
|
||||
public void cleanup() {
|
||||
try {
|
||||
System.out.println("Čištění prostředků automatizace...");
|
||||
|
||||
// Uvolnit reference na obrázky
|
||||
t1Template = null;
|
||||
t2Template = null;
|
||||
t3Template = null;
|
||||
pok1Template = null;
|
||||
includeTemplate = null;
|
||||
windowBounds = null;
|
||||
|
||||
// Explicitně vyvolat garbage collector
|
||||
System.gc();
|
||||
System.out.println("Prostředky automatizace vyčištěny");
|
||||
} catch (Exception e) {
|
||||
System.err.println("Chyba při čištění prostředků: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Pokémon GO Automatizační Nástroj ===");
|
||||
System.out.println("Ujistěte se, že je aplikace Pokémon GO spuštěná...");
|
||||
|
||||
@ -31,7 +31,7 @@ public class PokemonGoGUI extends JFrame {
|
||||
private static final String CONFIG_FILE = "pgo-automat-settings.properties";
|
||||
private static final String VERSION = "1.0.2";
|
||||
private Properties settings;
|
||||
private JSpinner countSpinner;
|
||||
private JComboBox<Integer> countComboBox;
|
||||
private JSpinner delaySpinner;
|
||||
|
||||
private static final Font TITLE_FONT = new Font("Segoe UI", Font.BOLD, 18);
|
||||
@ -330,21 +330,37 @@ public class PokemonGoGUI extends JFrame {
|
||||
centerPanel.setOpaque(true);
|
||||
|
||||
if (title.contains("TRANSFER")) {
|
||||
countSpinner = new JSpinner(new SpinnerNumberModel(
|
||||
Integer.parseInt(settings.getProperty("transfer.count", "9")),
|
||||
1, 999, 1
|
||||
));
|
||||
countSpinner.setPreferredSize(new Dimension(64, 26));
|
||||
// Načíst hodnotu a zajistit, že je v platném rozsahu nebo v seznamu povolených hodnot
|
||||
int savedCount = Integer.parseInt(settings.getProperty("transfer.count", "12"));
|
||||
// Povolené hodnoty: 1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96
|
||||
int[] validCounts = {1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96};
|
||||
boolean isValid = false;
|
||||
for (int count : validCounts) {
|
||||
if (savedCount == count) {
|
||||
isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValid) {
|
||||
savedCount = 12; // Nastavit na výchozí, pokud není v seznamu povolených
|
||||
}
|
||||
|
||||
// Vytvořit dropdown s hodnotami 1, 3, 6, 12, 24, 36, ..., 96
|
||||
Integer[] counts = {1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96};
|
||||
countComboBox = new JComboBox<>(counts);
|
||||
countComboBox.setSelectedItem(savedCount);
|
||||
countComboBox.setPreferredSize(new Dimension(70, 26));
|
||||
|
||||
delaySpinner = new JSpinner(new SpinnerNumberModel(
|
||||
Integer.parseInt(settings.getProperty("transfer.delay", "2")),
|
||||
0, 60, 1
|
||||
));
|
||||
delaySpinner.setPreferredSize(new Dimension(64, 26));
|
||||
|
||||
card.putClientProperty("countSpinner", countSpinner);
|
||||
card.putClientProperty("countComboBox", countComboBox);
|
||||
card.putClientProperty("delaySpinner", delaySpinner);
|
||||
|
||||
centerPanel.add(createFieldPanel("Počet:", countSpinner));
|
||||
centerPanel.add(createFieldPanel("Počet:", countComboBox));
|
||||
centerPanel.add(createFieldPanel("Čekání (s):", delaySpinner));
|
||||
} else if (title.contains("AUTOKLIK")) {
|
||||
JSpinner xSpinner = new JSpinner(new SpinnerNumberModel(
|
||||
@ -524,10 +540,10 @@ public class PokemonGoGUI extends JFrame {
|
||||
}
|
||||
|
||||
// Získat počet pokémonů a čekání z GUI
|
||||
JSpinner countSpinner = (JSpinner) transferCard.getClientProperty("countSpinner");
|
||||
JComboBox<Integer> countComboBox = (JComboBox<Integer>) transferCard.getClientProperty("countComboBox");
|
||||
JSpinner delaySpinner = (JSpinner) transferCard.getClientProperty("delaySpinner");
|
||||
|
||||
int pokemonCount = (Integer) countSpinner.getValue();
|
||||
int pokemonCount = (Integer) countComboBox.getSelectedItem();
|
||||
int delaySeconds = (Integer) delaySpinner.getValue();
|
||||
|
||||
stopButton.setEnabled(true);
|
||||
@ -599,6 +615,18 @@ public class PokemonGoGUI extends JFrame {
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
// Čistit prostředky po automatizaci
|
||||
try {
|
||||
if (automation != null) {
|
||||
automation.cleanup();
|
||||
}
|
||||
// Také vyčistit WindowFinder resources
|
||||
WindowFinder.cleanup();
|
||||
System.gc();
|
||||
} catch (Exception cleanupEx) {
|
||||
System.err.println("Chyba při čištění: " + cleanupEx.getMessage());
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -773,7 +801,7 @@ public class PokemonGoGUI extends JFrame {
|
||||
|
||||
// Výchozí hodnoty, pokud nastavení neexistují
|
||||
if (!settings.containsKey("transfer.count")) {
|
||||
settings.setProperty("transfer.count", "9");
|
||||
settings.setProperty("transfer.count", "12");
|
||||
}
|
||||
if (!settings.containsKey("transfer.delay")) {
|
||||
settings.setProperty("transfer.delay", "2");
|
||||
@ -796,9 +824,9 @@ public class PokemonGoGUI extends JFrame {
|
||||
* Uloží aktuální nastavení do souboru
|
||||
*/
|
||||
private void saveSettings() {
|
||||
// Uložení hodnot z spinnerů
|
||||
if (countSpinner != null) {
|
||||
settings.setProperty("transfer.count", countSpinner.getValue().toString());
|
||||
// Uložení hodnot z combo boxu a spinneru
|
||||
if (countComboBox != null) {
|
||||
settings.setProperty("transfer.count", countComboBox.getSelectedItem().toString());
|
||||
}
|
||||
if (delaySpinner != null) {
|
||||
settings.setProperty("transfer.delay", delaySpinner.getValue().toString());
|
||||
@ -819,11 +847,32 @@ public class PokemonGoGUI extends JFrame {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Nastavit shutdown hook pro bezpečné ukončení
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
System.out.println("Aplikace se vypíná...");
|
||||
// Vyčistit X11 resources
|
||||
try {
|
||||
WindowFinder.cleanup();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Chyba při čištění WindowFinder: " + e.getMessage());
|
||||
}
|
||||
}));
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PokemonGoGUI frame = new PokemonGoGUI();
|
||||
frame.setVisible(true);
|
||||
|
||||
// Nastavit window listener pro čisté ukončení
|
||||
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.out.println("Zavírám okno...");
|
||||
frame.saveSettings();
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -22,20 +22,11 @@ public class PositionPicker extends JWindow {
|
||||
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||
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);
|
||||
// Pokrýt celou obrazovku bez omezení insets
|
||||
// (protože vrátíme absolutní globální souřadnice, ne relativní)
|
||||
setBounds(screenBounds);
|
||||
|
||||
// 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);
|
||||
System.out.println("PositionPicker vytvořen: " + screenBounds);
|
||||
|
||||
setFocusable(true);
|
||||
setBackground(new Color(0, 0, 0, 0));
|
||||
@ -69,7 +60,11 @@ public class PositionPicker extends JWindow {
|
||||
panel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
selectedPosition = new Point(e.getX(), e.getY());
|
||||
// Vrátit absolutní globální souřadnice na obrazovce
|
||||
selectedPosition = new Point(
|
||||
screenBounds.x + e.getX(),
|
||||
screenBounds.y + e.getY()
|
||||
);
|
||||
positionSelected = true;
|
||||
System.out.println("✅ Pozice vybrána: " + selectedPosition);
|
||||
if (listener != null) {
|
||||
|
||||
@ -16,6 +16,8 @@ import java.util.List;
|
||||
*/
|
||||
public class WindowFinder {
|
||||
|
||||
private static Pointer cachedDisplay = null;
|
||||
|
||||
/**
|
||||
* X11 native library interface
|
||||
*/
|
||||
@ -23,7 +25,7 @@ public class WindowFinder {
|
||||
X11 INSTANCE = Native.load("X11", X11.class);
|
||||
|
||||
/**
|
||||
* X11 Window Attributes struktura
|
||||
* X11 Window Attributes struktura - přesná kopie z X11/Xlib.h
|
||||
*/
|
||||
class XWindowAttributes extends Structure {
|
||||
public int x;
|
||||
@ -32,31 +34,32 @@ public class WindowFinder {
|
||||
public int height;
|
||||
public int border_width;
|
||||
public int depth;
|
||||
public Pointer visual;
|
||||
public Pointer root;
|
||||
public int class_;
|
||||
public Pointer visual; // Visual* - opaque pointer
|
||||
public long root; // Window (XID)
|
||||
public int class_; // int, not pointer
|
||||
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 long backing_planes;
|
||||
public long backing_pixel;
|
||||
public boolean save_under; // Bool - should be boolean
|
||||
public long colormap; // Colormap (XID) - should be long
|
||||
public boolean map_installed; // Bool - should be boolean
|
||||
public int map_state;
|
||||
public long all_event_masks;
|
||||
public long your_event_mask;
|
||||
public long do_not_propagate_mask;
|
||||
public boolean override_redirect; // Bool - missing field
|
||||
public Pointer screen; // Screen* - opaque pointer, missing field
|
||||
|
||||
@Override
|
||||
protected List<String> 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");
|
||||
"backing_store", "backing_planes", "backing_pixel",
|
||||
"save_under", "colormap", "map_installed", "map_state",
|
||||
"all_event_masks", "your_event_mask", "do_not_propagate_mask",
|
||||
"override_redirect", "screen");
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,16 +87,23 @@ public class WindowFinder {
|
||||
* @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) {
|
||||
public static synchronized 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");
|
||||
try {
|
||||
// Použít cachedDisplay pokud existuje, nebo otevřít nový
|
||||
if (cachedDisplay != null) {
|
||||
display = cachedDisplay;
|
||||
System.out.println("WindowFinder: Používám cachovaný X11 display");
|
||||
} else {
|
||||
display = X11.INSTANCE.XOpenDisplay(null);
|
||||
if (display == null) {
|
||||
System.out.println("WindowFinder: Nelze se připojit k X11 displei");
|
||||
return null;
|
||||
}
|
||||
cachedDisplay = display;
|
||||
System.out.println("WindowFinder: Připojen k X11 displayu a uložen v cache");
|
||||
}
|
||||
|
||||
long rootWindow = X11.INSTANCE.XDefaultRootWindow(display);
|
||||
long[] foundWindow = new long[1];
|
||||
@ -115,15 +125,16 @@ public class WindowFinder {
|
||||
} catch (Exception e) {
|
||||
System.err.println("WindowFinder - Chyba: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (display != null) {
|
||||
// Pokud dojde k chybě, vynulovat cache a zavřít display
|
||||
if (display != null && display == cachedDisplay) {
|
||||
try {
|
||||
X11.INSTANCE.XCloseDisplay(display);
|
||||
} catch (Exception e) {
|
||||
System.err.println("WindowFinder - Chyba při zavírání displeje: " + e.getMessage());
|
||||
cachedDisplay = null;
|
||||
} catch (Exception ex) {
|
||||
System.err.println("WindowFinder - Chyba při zavírání displeje: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,11 +159,12 @@ public class WindowFinder {
|
||||
}
|
||||
|
||||
// Hledat v potomcích
|
||||
PointerByReference children_return = new PointerByReference();
|
||||
IntByReference nchildren_return = new IntByReference();
|
||||
|
||||
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);
|
||||
@ -171,8 +183,8 @@ public class WindowFinder {
|
||||
}
|
||||
}
|
||||
|
||||
// Uvolnit paměť
|
||||
X11.INSTANCE.XFree(childrenPtr);
|
||||
// Don't call XFree - it can cause heap corruption
|
||||
// X11.INSTANCE.XFree(childrenPtr);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -184,17 +196,21 @@ public class WindowFinder {
|
||||
* Získá jméno okna jako String
|
||||
*/
|
||||
private static String getWindowNameString(Pointer display, long window) {
|
||||
PointerByReference namePtr = new PointerByReference();
|
||||
|
||||
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;
|
||||
if (status != 0) {
|
||||
Pointer actualNamePtr = namePtr.getValue();
|
||||
if (actualNamePtr != null) {
|
||||
String name = actualNamePtr.getString(0);
|
||||
|
||||
// Don't call XFree - it can cause heap corruption
|
||||
// X11.INSTANCE.XFree(actualNamePtr);
|
||||
|
||||
return (name != null && !name.isEmpty()) ? name : null;
|
||||
}
|
||||
X11.INSTANCE.XFree(namePtr.getValue());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignorovat chyby
|
||||
@ -228,4 +244,21 @@ public class WindowFinder {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ukončí X11 display connection a vyčistí cache
|
||||
* Volat při shutdown aplikace
|
||||
*/
|
||||
public static synchronized void cleanup() {
|
||||
if (cachedDisplay != null) {
|
||||
try {
|
||||
X11.INSTANCE.XCloseDisplay(cachedDisplay);
|
||||
System.out.println("WindowFinder: X11 display uzavřen a cache vyčištěn");
|
||||
} catch (Exception e) {
|
||||
System.err.println("WindowFinder - Chyba při zavírání displeje: " + e.getMessage());
|
||||
} finally {
|
||||
cachedDisplay = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user