Advertisement
Guest User

Untitled

a guest
Jun 1st, 2017
279
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.51 KB | None | 0 0
  1.  
  2. import java.awt.Point;
  3. import java.awt.event.MouseEvent;
  4.  
  5. import org.osbot.rs07.script.MethodProvider;
  6.  
  7. /*
  8. * @author BenLand100
  9. */
  10. public class MouseHandler {
  11.  
  12. /**
  13. * The default mouse speed. This is the delay in ms between actual mouse
  14. * moves. Lower is faster.
  15. */
  16. public static final int DEFAULT_MOUSE_SPEED = 10;
  17.  
  18. /**
  19. * The maximum distance (in pixels) to move the mouse after clicks in either
  20. * direction on both axes.
  21. */
  22. public static final int DEFAULT_MAX_MOVE_AFTER = 0;
  23.  
  24. /**
  25. * The amount of time (in ms) it takes per bit of difficulty (look up Fitts
  26. * Law) to move the mouse. This appears to partially control the speed of
  27. * mouse movement.
  28. */
  29. public static final int msPerBit = 105;
  30.  
  31. /**
  32. * The amount of time (in ms) it takes an average mouse user to realise the
  33. * mouse needs to be moved
  34. */
  35. public static final int reactionTime = 0;
  36.  
  37. private static final java.util.Random staticRandom = new java.util.Random();
  38.  
  39. protected MethodProvider s;
  40.  
  41. public MouseHandler(MethodProvider methodProvider) {
  42. this.s = methodProvider;
  43. }
  44.  
  45. /**
  46. * Applies a midpoint algorithm to the Vector of points to ensure pixel to
  47. * pixel movement
  48. *
  49. * @param points
  50. * The vector of points to be manipulated
  51. */
  52. private static void adaptiveMidpoints(final java.util.Vector<Point> points) {
  53. int i = 0;
  54. while (i < points.size() - 1) {
  55. final Point a = points.get(i++);
  56. final Point b = points.get(i);
  57. if ((Math.abs(a.x - b.x) > 1) || (Math.abs(a.y - b.y) > 1)) {
  58. if (Math.abs(a.x - b.x) != 0) {
  59. final double slope = (double) (a.y - b.y) / (double) (a.x - b.x);
  60. final double incpt = a.y - slope * a.x;
  61. for (int c = a.x < b.x ? a.x + 1 : b.x - 1; a.x < b.x ? c < b.x
  62. : c > a.x; c += a.x < b.x ? 1 : -1) {
  63. points.add(i++, new Point(c, (int) Math.round(incpt + slope * c)));
  64. }
  65. } else {
  66. for (int c = a.y < b.y ? a.y + 1 : b.y - 1; a.y < b.y ? c < b.y
  67. : c > a.y; c += a.y < b.y ? 1 : -1) {
  68. points.add(i++, new Point(a.x, c));
  69. }
  70. }
  71. }
  72. }
  73. }
  74.  
  75. /**
  76. * Omits points along the spline in order to move in steps rather then pixel
  77. * by pixel
  78. *
  79. * @param spline
  80. * The pixel by pixel spline
  81. * @param msForMove
  82. * The ammount of time taken to traverse the spline. should be a
  83. * value from {@link #fittsLaw}
  84. * @param msPerMove
  85. * The ammount of time per each move
  86. * @return The stepped spline
  87. */
  88. public Point[] applyDynamism(final Point[] spline, final int msForMove, final int msPerMove) {
  89. final int numPoints = spline.length;
  90. final double msPerPoint = (double) msForMove / (double) numPoints;
  91. final double undistStep = msPerMove / msPerPoint;
  92. final int steps = (int) Math.floor(numPoints / undistStep);
  93. final Point[] result = new Point[steps];
  94. final double[] gaussValues = MouseHandler.gaussTable(result.length);
  95. double currentPercent = 0;
  96. for (int i = 0; i < steps; i++) {
  97. currentPercent += gaussValues[i];
  98. final int nextIndex = (int) Math.floor(numPoints * currentPercent);
  99. if (nextIndex < numPoints) {
  100. result[i] = spline[nextIndex];
  101. } else {
  102. result[i] = spline[numPoints - 1];
  103. }
  104. }
  105. if (currentPercent < 1D) {
  106. result[steps - 1] = spline[numPoints - 1];
  107. }
  108. return result;
  109. }
  110.  
  111. /**
  112. * Binomial Coefficient.
  113. *
  114. * @param n
  115. * The superset element count.
  116. * @param k
  117. * The subset size.
  118. * @return <code>n</code> choose <code>k</code>.
  119. */
  120. private static double nCk(final int n, final int k) {
  121. return MouseHandler.fact(n) / (MouseHandler.fact(k) * MouseHandler.fact(n - k));
  122. }
  123.  
  124. /**
  125. * Factorial ("n!").
  126. *
  127. * @param n
  128. * The integer.
  129. * @return The factorial.
  130. */
  131. private static double fact(final int n) {
  132. double result = 1;
  133. for (int i = 1; i <= n; i++) {
  134. result *= i;
  135. }
  136. return result;
  137. }
  138.  
  139. /**
  140. * Calculates the ammount of time a movement should Mousetake based on
  141. * Fitts' Law TIP: Do not add/subtract random values from this result,
  142. * rather varry the targetSize value or do not move the same distance each
  143. * time ;)
  144. *
  145. * @param targetDist
  146. * The distance from the current position to the center of the
  147. * target
  148. * @param targetSize
  149. * The maximum distence from the center of the target within
  150. * which the end point could be
  151. * @return the ammount of time (in ms) the movement should take
  152. */
  153. public long fittsLaw(final double targetDist, final double targetSize) {
  154. return (long) (MouseHandler.reactionTime
  155. + MouseHandler.msPerBit * Math.log10(targetDist / targetSize + 1) / Math.log10(2));
  156. }
  157.  
  158. /**
  159. * Satisfies Integral[gaussian(t),t,0,1] == 1D Therefore can distribute a
  160. * value as a bell curve over the intervel 0 to 1
  161. *
  162. * @param t
  163. * = A value, 0 to 1, representing a percent along the curve
  164. * @return The value of the gaussian curve at this position
  165. */
  166. private static double gaussian(double t) {
  167. t = 10D * t - 5D;
  168. return 1D / (Math.sqrt(5D) * Math.sqrt(2D * Math.PI)) * Math.exp(-t * t / 20D);
  169. }
  170.  
  171. /**
  172. * Returns an array of gaussian values that add up to 1 for the number of
  173. * steps Solves the problem of having using an intergral to distribute
  174. * values
  175. *
  176. * @param steps
  177. * Number of steps in the distribution
  178. * @return An array of values that contains the percents of the distribution
  179. */
  180. private static double[] gaussTable(final int steps) {
  181. final double[] table = new double[steps];
  182. final double step = 1D / steps;
  183. double sum = 0;
  184. for (int i = 0; i < steps; i++) {
  185. sum += MouseHandler.gaussian(i * step);
  186. }
  187. for (int i = 0; i < steps; i++) {
  188. table[i] = MouseHandler.gaussian(i * step) / sum;
  189. }
  190. return table;
  191. }
  192.  
  193. /**
  194. * Creates random control points for a spline. Written by Benland100
  195. *
  196. * @param sx
  197. * Begining X position
  198. * @param sy
  199. * Begining Y position
  200. * @param ex
  201. * Begining X position
  202. * @param ey
  203. * Begining Y position
  204. * @param ctrlSpacing
  205. * Distance between control origins
  206. * @param ctrlVariance
  207. * Max X or Y variance of each control point from its origin
  208. * @return An array of Points that represents the control points of the
  209. * spline
  210. */
  211. public Point[] generateControls(final int sx, final int sy, final int ex, final int ey, int ctrlSpacing,
  212. int ctrlVariance) {
  213. final double dist = Math.sqrt((sx - ex) * (sx - ex) + (sy - ey) * (sy - ey));
  214. final double angle = Math.atan2(ey - sy, ex - sx);
  215. int ctrlPoints = (int) Math.floor(dist / ctrlSpacing);
  216. ctrlPoints = ctrlPoints * ctrlSpacing == dist ? ctrlPoints - 1 : ctrlPoints;
  217. if (ctrlPoints <= 1) {
  218. ctrlPoints = 2;
  219. ctrlSpacing = (int) dist / 3;
  220. ctrlVariance = (int) dist / 2;
  221. }
  222. final Point[] result = new Point[ctrlPoints + 2];
  223. result[0] = new Point(sx, sy);
  224. for (int i = 1; i < ctrlPoints + 1; i++) {
  225. final double radius = ctrlSpacing * i;
  226. final Point cur = new Point((int) (sx + radius * Math.cos(angle)), (int) (sy + radius * Math.sin(angle)));
  227. double percent = 1D - (double) (i - 1) / (double) ctrlPoints;
  228. percent = percent > 0.5 ? percent - 0.5 : percent;
  229. percent += 0.25;
  230. final int curVariance = (int) (ctrlVariance * percent);
  231. /**
  232. * Hopefully {@link java.util.Random} is thread safe. (it is in Sun
  233. * JVM 1.5+)
  234. */
  235. cur.x = (int) (cur.x + curVariance * 2 * MouseHandler.staticRandom.nextDouble() - curVariance);
  236. cur.y = (int) (cur.y + curVariance * 2 * MouseHandler.staticRandom.nextDouble() - curVariance);
  237. result[i] = cur;
  238. }
  239. result[ctrlPoints + 1] = new Point(ex, ey);
  240. return result;
  241. }
  242.  
  243. /**
  244. * Generates a spline that moves no more then one pixel at a time TIP: For
  245. * most movements, this spline is not good, use <code>applyDynamism</code>
  246. *
  247. * @param controls
  248. * An array of control points
  249. * @return An array of Points that represents the spline
  250. */
  251. public Point[] generateSpline(final Point[] controls) {
  252. final double degree = controls.length - 1;
  253. final java.util.Vector<Point> spline = new java.util.Vector<Point>();
  254. boolean lastFlag = false;
  255. for (double theta = 0; theta <= 1; theta += 0.01) {
  256. double x = 0;
  257. double y = 0;
  258. for (double index = 0; index <= degree; index++) {
  259. final double probPoly = MouseHandler.nCk((int) degree, (int) index) * Math.pow(theta, index)
  260. * Math.pow(1D - theta, degree - index);
  261. x += probPoly * controls[(int) index].x;
  262. y += probPoly * controls[(int) index].y;
  263. }
  264. final Point temp = new Point((int) x, (int) y);
  265. try {
  266. if (!temp.equals(spline.lastElement())) {
  267. spline.add(temp);
  268. }
  269. } catch (final Exception e) {
  270. spline.add(temp);
  271. }
  272. lastFlag = theta != 1.0;
  273. }
  274. if (lastFlag) {
  275. spline.add(new Point(controls[(int) degree].x, controls[(int) degree].y));
  276. }
  277. MouseHandler.adaptiveMidpoints(spline);
  278. return spline.toArray(new Point[spline.size()]);
  279. }
  280.  
  281. private final java.util.Random random = new java.util.Random();
  282.  
  283. /**
  284. * Moves the mouse from a position to another position with randomness
  285. * applied.
  286. *
  287. * @param speed
  288. * the speed to move the mouse. Anything under
  289. * {@link #DEFAULT_MOUSE_SPEED} is faster than normal.
  290. * @param x1
  291. * from x
  292. * @param y1
  293. * from y
  294. * @param x2
  295. * to x
  296. * @param y2
  297. * to y
  298. * @param randX
  299. * randomness in the x direction
  300. * @param randY
  301. * randomness in the y direction
  302. */
  303. public void moveMouse(final int speed, final int x1, final int y1, final int x2, final int y2, int randX,
  304. int randY) {
  305. if ((x2 == -1) && (y2 == -1))
  306. // MouseHandler.log
  307. // .warning("Non-fatal error. Please post log on forums. ("
  308. // + x2 + "," + y2 + ")");
  309. {
  310. return;
  311. }
  312. if (randX <= 0) {
  313. randX = 1;
  314. }
  315. if (randY <= 0) {
  316. randY = 1;
  317. }
  318. try {
  319. if ((x2 == x1) && (y2 == y1)) {
  320. return;
  321. }
  322. final Point[] controls = generateControls(x1, y1, x2 + random.nextInt(randX), y2 + random.nextInt(randY),
  323. 50, 120);
  324. final Point[] spline = generateSpline(controls);
  325. final long timeToMove = fittsLaw(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), 10);
  326. final Point[] path = applyDynamism(spline, (int) timeToMove, DEFAULT_MOUSE_SPEED);
  327. for (final Point aPath : path) {
  328. hopMouse(aPath.x, aPath.y);
  329. try {
  330. Thread.sleep(Math.max(0, speed - 2 + random.nextInt(4)));
  331. } catch (final InterruptedException e) {
  332. throw new RuntimeException(e);
  333. }
  334. }
  335. } catch (final Exception e) {
  336. // MouseHandler.log.info("Error moving mouse: " + e);
  337. // MouseHandler.log.info("Source: " + x1 + "," + y1);
  338. // MouseHandler.log.info("Dest: " + x2 + "," + y2);
  339. // MouseHandler.log.info("Randx/Randy: " + randX + "/" + randY);
  340. // e.printStackTrace();
  341. }
  342. }
  343.  
  344. public void moveMouse(int speed, int x, int y) {
  345. moveMouse(speed, s.mouse.getPosition().x, s.mouse.getPosition().y, x, y, 0, 0);
  346. }
  347.  
  348. public void moveMouse(int x, int y) {
  349. moveMouse(DEFAULT_MOUSE_SPEED, s.mouse.getPosition().x, s.mouse.getPosition().y, x, y, 0, 0);
  350. }
  351.  
  352. public void hopMouse(int x, int y) {
  353. moveMouseInstantly(x, y);
  354. }
  355.  
  356. final void moveMouseInstantly(final int x, final int y) {
  357. s.bot.getMouseEventHandler().generateBotMouseEvent(MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, x, y,
  358. 0, false, MouseEvent.NOBUTTON, true);
  359. }
  360.  
  361. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement