To open a new category “Learning by hacking”, today I gonna show to how to apply promise and await in order to cheat 10fastfingers.com with. Before we start, just keep in mind that the purpose of this post is we find an enjoyable way to learn the new knowledge, so don’t expect to learn to cheat anything here.

Now let start.

At the first step, we must access https://10fastfingers.com/multiplayer and play around with it. The rule of this game is very simple, we have to type as fast and correct as possible to defeat other people. Who has the highest score will win the game. If you’re like me can’t type fast, we need a little cheat here. Why don’t let the computer type for us? Who can defeat the speed of the computer?

To cheat that game, we need 2 essential things: how to get or retrieve the text for typing and how to send that text to the input field

Retrieve the text for typing

By using our best friend “Developer tool”, we can inspect the element which is highlighted for the current word like

We can easily detect that the text “children” which we want to retrieve is put inside a div element with a class name highlight. To get that value, just easily write

let text = document.querySelector(".highlight").textContent;

try to run this in console window:

We has finished retrieving the word job. Now move on to step 2

Sending the text to the input field

Besides sending the retrieved text to input, we also need to fire and InputEvent in order to let the system to recognize the text and continue with the following texts. SImply like this

 let text = document.querySelector(".highlight").textContent + " ";
 document.querySelector("input").value = text;
 var inputEvent = new InputEvent("input");
 document.querySelector("input").dispatchEvent(inputEvent)

Try to run this block of code in the console window to see. If you’re lucky, you will get the error message instead of the input is auto-filled.

Why does this happen? Because you’re unlucky. I’m just kidding :), the problem is because we’re trying to access the “highlight” and “input” element which are not the same frame we run the code. Our code at the moment running at “top” frame, but “highlight” and “input” are rendered under other frame named “10ff.net”. To fix this problem just simple seclect “10ff.net” as a context in console window and try one more time

Yeah, it works. But how can we defeat other people with we need to paste the code and enter so many times, this process is even slower than your typing, we need to make this code run continuously.

Run the code continuously

Beside run the code continuously, we also need to wait a few moments between each turn in order to let the system render the next word for us. We can use setTimeout at different time. Something like this:

var i = 0;
while (i < 100) {
    i++;
    setTimeout(() => {
        let text = document.querySelector(".highlight").textContent + " ";
        document.querySelector("input").value = text
        var inputEvent = new InputEvent("input");
        document.querySelector("input").dispatchEvent(inputEvent)
    }, i * 100) //Each turn is 100 miliseconds apart 
}

We won !! But we still have a problem that we set the number of turns we want to run the code at the beginning, in this case, we set 100 times. In the beginning, we create 100 timeout functions, which is 100 milliseconds apart this way works well. However it’s not good enough because in some cases, the number of words is different from 100, so our code may don’t run enough time or run more times than we need. So we need to determine exactly the number of the turn we want to run during the execution time rather than in the beginning time. How can we do that? promiseis our answer. The promise in javascript give 2 possibilitis to run the next turn: resolve lets us run the next turn or reject lets us break the loop. Lets convert our code to using Promise

var run = () => new Promise((resolve, reject) => {
    if (!document.querySelector(".highlight")) {
        console.log("stop")
        reject("stop")
    }
    let text = document.querySelector(".highlight").textContent + " ";
    document.querySelector("input").value = text
    var inputEvent = new InputEvent("input");
    document.querySelector("input").dispatchEvent(inputEvent)
    setTimeout(() => resolve("next"), 10)
})
while (true) {
    try {
        await run();
    } catch (e) {
        console.error("stop");
        break;
    }
}

Enjoy your champion!

Wrap up

In this tutorial, we have just learned the way to inspect element, retrieve the data as well as the way to trigger an input event to simulate the user action. Moreover, we also learned how to create a loop which has the gap between each turn by using Promise come with await. For deeper learning about Promise, you can visit this post https://frontend.cloudaccess.host/promise-in-javascript/ and this https://frontend.cloudaccess.host/await-and-async-%e2%80%8bin-javascript/. Please take you time to do this cheating by yourself and learn the new thing, See you soon in the next post

Leave a Reply

Your email address will not be published.