Visionary. Value focused.

How you do anything is how you do everything.

Write automated script with Tampermonkey and Webpack

Recently I was pulled into an old web-based game called Ghost Trapper. The gist of it is, after a period of time, I can click on a button to trap a ghost, then a count down appears and I have to wait for the count down to stop until I can hunt ghosts again.

Then it hit me, why don’t I automate the process so that I don’t have to spend so much time to play anymore.

Here’s a screenshot of the game.

Ghost trapper screen image

Note the top left count down. Once it reaches 0, I can click that button again and continue hunting ghosts.

I look around for a solution for automating the process. There are quite a few options:

  • Python’s scrapy
  • Phantom.js or Casper.js
  • Puppeteer
  • Tampermonkey (Google Chrome only)

I have some experience in Scrapy, Phantom.js; so I was thinking, why not utilize what I have already known?

… Or I can jump into new things and learn how to do it.

 

I decided to go with the second option, and I chose Tampermonkey to do the work.

 

So I quickly wrote a small script to check if the button is active, and if so, click on it.

setTimeout(() => {
  if (!$('#huntBtn').hasClass('disabled')) {
    $('#huntBtn').trigger('click');
  }
}, 3000);

Simple, isn’t it?!

The problem is, I would like to have the script runs on multiple machines, and I want to synchonize the code in all machines, so if I update the code I’ll just need to do it once.

I ended up with the following structure:

  • A github project to host the code
  • Tampermonkey’s ability to refer to external javascript resources.

My Tampermonkey script

// ==UserScript==
// @name         ghost-trapper
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Ghost Trapper auto
// @author       lightbringer
// @noframes
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require      file:///Z:/nodejs/ghost-trapper/ghost-trapper.js
// @match        http://www.ghost-trappers.com/fb/*
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

My ghost-trapper.js

class GhostTrapper {
  constructor() {
    // do stuff
  }
  
  hunt() {
    if (!$('#huntBtn').hasClass('disabled')) { 
      $('#huntBtn').trigger('click'); 
    }
  }
  
  run() {
    setTimeout(this.hunt, 3000);
  }
}

var gt = new GhostTrapper();
gt.run();

 

Looking good, however, the script requires 2 files, one from jquery CDN. one from my local machine. And the speed is not very nice (took me a noticeable time before the hunt click happened).

I thought, why can’t I combine them into 1 file? I have experience in Webpack, so let’s try it out.

 

First I installed necessary packages

npm i --save jquery
npm i --save-dev webpack webpack-cli babel-core babel-loader babel-preset-env

Then I created webpack config file

// webpack.config.js
const path = require('path');
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'ghost-trapper.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
};

Then I create a main file for webpack to point to.

// src/main.js 
import $ from 'jquery'; 
import GhostTrapper from './GhostTrapper'; 
const gt = new GhostTrapper(); 
gt.run();

 

After all this, I compile webpack config. And voilĂ , the bundle is ready for me to include into tampermonkey, and it runs exactly what I wanted.

From then on, I added multiple features to my automation tool. The ease of webpack’s watch mode really helps me during development, as I just need to refresh the page and the new code is already deployed.

4 Responses

  1. see more says:

    You offer some great points within this post, but aren’t you lacking something crucial?

  2. I’m unsure about the bullet points.. maybe a bit redundant.

  3. Shawnee says:

    Hi there! Such a good short article, thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *