DigDig.IO Gold Bot

A simple bot that farms gold in digdig.io

  1. // ==UserScript==
  2. // @name DigDig.IO Gold Bot
  3. // @namespace https://tampermonkey.net/
  4. // @version 0.0.8
  5. // @description A simple bot that farms gold in digdig.io
  6. // @author Zertalious (Zert)
  7. // @match *://digdig.io/*
  8. // @icon https://www.google.com/s2/favicons?domain=digdig.io
  9. // @grant none
  10. // @run-at document-end
  11. // ==/UserScript==
  12.  
  13. let goldCount = 0;
  14. let timeRan = 0;
  15.  
  16. let lastTime = 0;
  17.  
  18. const chunkSize = 64;
  19. const goldPositions = [];
  20.  
  21. let isDead = false;
  22. let isRunning = false;
  23.  
  24. let health = 0;
  25.  
  26. let border = null;
  27.  
  28. const chunks = [];
  29.  
  30. let serverIndex = 0;
  31. const servers = [];
  32.  
  33. const modes = [ 'ffa', 'teams', 'maze' ];
  34.  
  35. let angle = Math.random() * Math.PI * 2;
  36.  
  37. init();
  38.  
  39. async function init() {
  40.  
  41. for ( let i = 0; i < modes.length; i ++ ) {
  42.  
  43. const response = await fetch( 'https://api.n.m28.io/endpoint/digdig-' + modes[ i ] + '/findEach' );
  44.  
  45. const json = await response.json();
  46.  
  47. for ( let key in json.servers ) {
  48.  
  49. servers.push( json.servers[ key ].id );
  50.  
  51. }
  52.  
  53. }
  54.  
  55. isRunning = true;
  56.  
  57. window.addEventListener( 'keyup', function ( event ) {
  58.  
  59. if ( String.fromCharCode( event.keyCode ) === 'B' ) {
  60.  
  61. isRunning = ! isRunning;
  62.  
  63. setTimeout( function () {
  64.  
  65. setAttack( isRunning );
  66.  
  67. }, 0 );
  68.  
  69. }
  70.  
  71. } );
  72.  
  73. }
  74.  
  75. window.requestAnimationFrame = new Proxy( window.requestAnimationFrame, {
  76. apply( target, thisArgs, args ) {
  77.  
  78. if ( isRunning === true ) {
  79.  
  80. args[ 0 ] = new Proxy( args[ 0 ], {
  81. apply( target, thisArgs, args ) {
  82.  
  83. isDead = false;
  84.  
  85. healthX.length = 0;
  86. health = 0;
  87.  
  88. border = null;
  89.  
  90. goldPositions.length = 0;
  91.  
  92. Reflect.apply( ...arguments );
  93.  
  94. const now = Date.now();
  95.  
  96. if ( isRunning && lastTime > 0 ) {
  97.  
  98. timeRan += now - lastTime;
  99.  
  100. }
  101.  
  102. lastTime = now;
  103.  
  104. if ( isDead === true || health <= 0 ) {
  105.  
  106. pressEnter();
  107.  
  108. return;
  109.  
  110. }
  111.  
  112. setAttack( true );
  113.  
  114. if ( goldPositions.length > 0 ) {
  115.  
  116. let target;
  117.  
  118. if ( border !== null ) {
  119.  
  120. const [ bx, by, br ] = border;
  121.  
  122. for ( let i = 0; i < goldPositions.length; i ++ ) {
  123.  
  124. const [ x, y ] = goldPositions[ i ];
  125.  
  126. if ( Math.hypot( x - bx, y - by ) < br ) {
  127.  
  128. mouseMove( x, y );
  129. return;
  130.  
  131. }
  132.  
  133. }
  134.  
  135. } else {
  136.  
  137. mouseMove(
  138. goldPositions[ 0 ][ 0 ],
  139. goldPositions[ 0 ][ 1 ]
  140. );
  141.  
  142. return;
  143.  
  144. }
  145.  
  146. }
  147.  
  148. mouseMove(
  149. ( Math.cos( angle ) * 0.5 + 0.5 ) * window.innerWidth,
  150. ( Math.sin( angle ) * 0.5 + 0.5 ) * window.innerHeight
  151. );
  152.  
  153. if ( health <= 0.05 ) {
  154.  
  155. angle = Math.random() * Math.PI * 2;
  156.  
  157. serverIndex = ( serverIndex + 1 ) % servers.length;
  158.  
  159. cp6.forceServerID( servers[ serverIndex ] );
  160.  
  161. while ( chunks.length > 0 ) {
  162.  
  163. chunks.shift().golds.length = 0;
  164.  
  165. }
  166.  
  167. }
  168.  
  169. }
  170. } );
  171.  
  172. }
  173.  
  174. return Reflect.apply( ...arguments );
  175.  
  176. }
  177. } );
  178.  
  179. const Context = CanvasRenderingContext2D.prototype;
  180.  
  181. Context.arc = new Proxy( Context.arc, {
  182. apply( target, ctx, [ x, y, r ] ) {
  183.  
  184. Reflect.apply( ...arguments );
  185.  
  186. if ( isRunning && ctx.fillStyle === '#222222' && x !== 0 && y !== 0 ) {
  187.  
  188. border = [ x, y, r ];
  189.  
  190. ctx.save();
  191.  
  192. ctx.translate( window.innerWidth / 2, 10 );
  193.  
  194. ctx.font = 'bolder 30px Ubuntu';
  195.  
  196. ctx.textAlign = 'center';
  197. ctx.textBaseline = 'top';
  198.  
  199. const a = goldCount + ' gold found';
  200.  
  201. ctx.lineWidth = 2;
  202. ctx.strokeStyle = '#000';
  203.  
  204. ctx.strokeText( a, 0, 0 );
  205.  
  206. ctx.fillStyle = '#fff';
  207. ctx.fillText( a, 0, 0 );
  208.  
  209. const seconds = timeRan / 1000;
  210. const mins = Math.floor( seconds / 60 );
  211.  
  212. const b ='in ' + ( mins > 0 ? mins + 'm ' : '' ) + ( seconds % 60 ).toFixed( 1 ) + 's';
  213.  
  214. ctx.font = 'bolder 18px Ubuntu';
  215.  
  216. ctx.strokeText( b, 0, 32 );
  217. ctx.fillText( b, 0, 32 );
  218.  
  219. ctx.restore();
  220.  
  221. }
  222.  
  223. }
  224. } );
  225.  
  226. Context.drawImage = new Proxy( Context.drawImage, {
  227. apply( target, thisArgs, [ { golds } ] ) {
  228.  
  229. if ( golds !== undefined ) {
  230.  
  231. const { a, d, e, f } = thisArgs.getTransform();
  232.  
  233. for ( let i = 0; i < golds.length; i ++ ) {
  234.  
  235. const [ m, n, ] = golds[ i ];
  236.  
  237. goldPositions.push( [
  238. m / chunkSize * a + e,
  239. n / chunkSize * d + f
  240. ] );
  241.  
  242. if ( ! golds[ i ].counted ) {
  243.  
  244. goldCount ++;
  245.  
  246. golds[ i ].counted = true;
  247.  
  248. }
  249.  
  250. }
  251.  
  252. }
  253.  
  254. return Reflect.apply( ...arguments );
  255.  
  256. }
  257. } );
  258.  
  259. const healthX = [];
  260.  
  261. const params = {
  262. apply( target, thisArgs, [ x ] ) {
  263.  
  264. healthX[ target.name === 'moveTo' ? 0 : 1 ] = x;
  265.  
  266. return Reflect.apply( ...arguments );
  267.  
  268. }
  269. };
  270.  
  271. Context.moveTo = new Proxy( Context.moveTo, params );
  272. Context.lineTo = new Proxy( Context.lineTo, params );
  273.  
  274. Context.stroke = new Proxy( Context.stroke, {
  275. apply( target, thisArgs, args ) {
  276.  
  277. if ( thisArgs.strokeStyle === '#75dd34' ) {
  278.  
  279. health = ( healthX[ 0 ] - healthX[ 1 ] ) / ( 2 * healthX[ 0 ] );
  280.  
  281. }
  282.  
  283. return Reflect.apply( ...arguments );
  284.  
  285. }
  286. } );
  287.  
  288. const OffscreenContext = typeof OffscreenCanvasRenderingContext2D !== 'undefined' ?
  289. OffscreenCanvasRenderingContext2D.prototype : Context;
  290.  
  291. OffscreenContext.drawImage = new Proxy( OffscreenContext.drawImage, {
  292. apply( target, thisArgs, [ { golds } ] ) {
  293.  
  294. if ( golds !== undefined ) {
  295.  
  296. console.log( 'here!' );
  297.  
  298. thisArgs.canvas.golds = golds;
  299.  
  300. }
  301.  
  302. return Reflect.apply( ...arguments );
  303.  
  304. }
  305. } );
  306.  
  307. OffscreenContext.fillRect = new Proxy( OffscreenContext.fillRect, {
  308. apply( target, thisArgs, args ) {
  309.  
  310. if ( thisArgs.fillStyle === '#000000' ) {
  311.  
  312. isDead = true;
  313.  
  314. }
  315.  
  316. return Reflect.apply( ...arguments );
  317.  
  318. }
  319. } );
  320.  
  321. OffscreenContext.putImageData = new Proxy( OffscreenContext.putImageData, {
  322. apply( target, thisArgs, [ { data } ] ) {
  323.  
  324. console.log( thisArgs.canvas );
  325.  
  326. if ( thisArgs.canvas.width === chunkSize && thisArgs.canvas.height === chunkSize ) {
  327.  
  328. thisArgs.canvas.golds = [];
  329.  
  330. for ( let i = 0; i < data.length; i += 4 ) {
  331.  
  332. if ( isGoldColor( data[ i ], data[ i + 1 ], data[ i + 2 ] ) ) {
  333.  
  334. const index = i / 4;
  335.  
  336. thisArgs.canvas.golds.push( [
  337. index % chunkSize,
  338. Math.floor( index / chunkSize )
  339. ] );
  340.  
  341. }
  342.  
  343. }
  344.  
  345. chunks.push( thisArgs.canvas );
  346.  
  347. }
  348.  
  349. return Reflect.apply( ...arguments );
  350.  
  351. }
  352. } );
  353.  
  354. OffscreenContext.fillRect = new Proxy( OffscreenContext.fillRect, {
  355. apply( target, thisArgs, [ x, y, width, height ] ) {
  356.  
  357. if ( thisArgs.canvas.width === chunkSize && thisArgs.canvas.height === chunkSize ) {
  358.  
  359. if ( thisArgs.canvas.golds === undefined ) {
  360.  
  361. thisArgs.canvas.golds = [];
  362.  
  363. }
  364.  
  365. if ( isGoldColor( thisArgs.fillStyle ) ) {
  366.  
  367. thisArgs.canvas.golds.push( [ x, y ] );
  368.  
  369. }
  370.  
  371. }
  372.  
  373. return Reflect.apply( ...arguments );
  374.  
  375. }
  376. } );
  377.  
  378. OffscreenContext.clearRect = new Proxy( OffscreenContext.clearRect, {
  379. apply( target, thisArgs, [ x, y, width, height ] ) {
  380.  
  381. if ( thisArgs.canvas.golds !== undefined ) {
  382.  
  383. if ( width === chunkSize && height === chunkSize ) {
  384.  
  385. thisArgs.canvas.golds.length = 0;
  386.  
  387. } else {
  388.  
  389. for ( let i = 0; i < thisArgs.canvas.golds.length; i ++ ) {
  390.  
  391. const [ m, n ] = thisArgs.canvas.golds[ i ];
  392.  
  393. if ( m === x && n === y ) {
  394.  
  395. thisArgs.canvas.golds.splice( i, 1 );
  396. break;
  397.  
  398. }
  399.  
  400. }
  401.  
  402. }
  403. }
  404.  
  405. return Reflect.apply( ...arguments );
  406.  
  407. }
  408. } );
  409.  
  410. function isGoldColor( r, g, b ) {
  411.  
  412. if ( arguments.length === 1 ) {
  413.  
  414. g = parseInt( r.substring( 3, 5 ), 16 );
  415. b = parseInt( r.substring( 5, 7 ), 16 );
  416. r = parseInt( r.substring( 1, 3 ), 16 );
  417.  
  418. }
  419.  
  420. return Math.hypot( 0xa5 - r, 0x9e - g, 0x15 - b ) < 25;
  421.  
  422. }
  423.  
  424. function pressEnter() {
  425.  
  426. keyEvent( 'keydown', 13 );
  427. keyEvent( 'keyup', 13 );
  428.  
  429. }
  430.  
  431. function setAttack( bool ) {
  432.  
  433. keyEvent( bool !== false ? 'keydown' : 'keyup', 32 );
  434.  
  435. }
  436.  
  437. function setHeal( bool ) {
  438.  
  439. keyEvent( bool !== false ? 'keydown' : 'keyup', 16 );
  440.  
  441. }
  442.  
  443. function keyEvent( type, keyCode ) {
  444.  
  445. window.dispatchEvent( new KeyboardEvent( type, { keyCode } ) );
  446.  
  447. }
  448.  
  449. function mouseMove( clientX, clientY ) {
  450.  
  451. window.Module.canvas.dispatchEvent(
  452. new MouseEvent( 'mousemove', {
  453. clientX,
  454. clientY
  455. } )
  456. );
  457.  
  458. }