static class MouseMover { Pt cur, last; Robot robot; java.util.Timer timer; int interferenceMinDistance = 100; int mouseCheckInterval = 50; int blockTimeAfterInterference = 5000; // ms bool endAfterInterference = true; volatile bool interference; long blockUntil; synchronized bool enabled() { ret timer != null; } synchronized void enable() ctex { if (robot == null) robot = new Robot; if (timer == null) { interference = false; cur = new Pt(mouseLocation()); timer = new java.util.Timer("MouseMover"); timer.scheduleAtFixedRate(new TimerTask { public void run() { checkMouse(); } }, mouseCheckInterval, mouseCheckInterval); print("Mouse automation started"); } } bool farAway(Pt a, Pt b) { ret pointDistance(a, b) >= interferenceMinDistance; } synchronized void checkMouse() { if (!enabled()) ret; Pt p = new Pt(mouseLocation()); if (farAway(p, cur) && neq(p, last)) { interference = true; if (endAfterInterference) { print("Mouse interference detected, stopping automation"); disable(); } else { bool blockedAlready = blocked(); blockUntil = now()+blockTimeAfterInterference; if (!blockedAlready) print("Mouse automation blocked for at least " + blockTimeAfterInterference + " ms"); cur = new Pt(mouseLocation()); } } } synchronized void disable() { if (timer != null) { timer.cancel(); timer = null; if (!interference) print("Mouse automation ended without interference"); } } synchronized void moveMouseImmediate(Pt p) { checkMouse(); if (!enabled() || blocked()) ret; p = normalizePointToScreen(p); if (neq(cur, p)) { if (neq(new Pt(mouseLocation()), last)) last = cur; cur = p; robot.mouseMove(p.x, p.y); } } synchronized bool hasInterference() { ret interference; } synchronized bool blocked() { if (!enabled() || blockUntil == 0) false; if (now() < blockUntil) true; blockUntil = 0; cur = new Pt(mouseLocation()); print("Mouse automation resumes"); false; } }