Bot for Flash games / Embed in Flash


    As part of the week of bots for browser games.

    This week is rich in articles about bots for browser games .
    In all articles, AutoIT was used to control the bot. This is a simple and good way to start making the bot “head on”, it does not require any knowledge of the game, except knowledge of the rules and the graphical interface. For the server side of the game, such a bot will generally look like a regular user, if you do not take into account the incredible perseverance and performance of such a player.

    But this method requires recognition of the world, which adds a lot of errors, and sometimes it is not possible to determine the necessary value at all.

    In the first article, I came across a comment with a link to a postAdobe Profiler Fail , which prompted me to explore this feature in order to automate actions in Flash games.

    Victim selection


    First of all, I tried this method on the Diamond Dash game on Google+, which immediately dutifully agreed to fulfill all my wishes. For an article on Habré, I tried to choose some other of the presented games on Google+, but some of them require an understanding of the rules, a few more games in JavaScript, and the remaining simple ones in Flash turned out to be more stable and require significant preliminary preparation. I will discuss the implementation in the last in a separate article when I prepare the necessary tools.

    Therefore, I will dissect again Diamond Dash. For one, compare the results with the results from the first article.

    Idea


    The obvious solution to the problem of recognizing the world is to introduce the game into the insides in order to obtain accurate data on the state of the world. Two ways come to mind:
    1. Decompile, embed your code and build it back
    2. Some other way to access objects

    If someone tried to compile the decompiled code, then he knows very well that this is not so easy, it will take a long time to restore parts of the code that the decompiler could not handle. And if this is when several thousand lines, then the task does not justify itself at all.
    And then we need to solve the problem of launching our SWF file in a trusted domain so that it easily communicates with the server.

    Therefore, we will go the second way. This will save us learning all the code and allow us to focus only on the most important thing.

    Prerequisites


    To complete our task, you will need:

    Research


    Let's start exploring the game by connecting it to De Monster Debugger. This is a very interesting tool for debugging Flash. Even if you are not going to set records in browser games, I recommend setting it at least in order to play a small quest that demonstrates the capabilities of this debugger.

    After installing Monster and completing the quest, we will write a small piece of code:

    MonsterConnector.as
    The resulting SWF file will serve as a wrapper for all loaded swf and connect them to the debugger, after we write the path to it in% USERPROFILE% \ mm.cfg:

    PreloadSWF = c: \ temp \ MonsterConnector.swf

    We restart the browser and go play Diamond Dash. As soon as the game loads, our preloader connects it to the Monster Debugger:


    You can dig deeper into the game through the debugger itself to understand its structure a little. In the future, this eliminates the analysis of all source code. In our case, having inspected the playing field, you can quickly find out that the class of the cube is called Brick (unexpectedly, right?).

    Now we still need to decompile the code, but not for the purpose of modifying it, but only then to study a bit. Sothink SWF Decompiler is
    perfect for these purposes , or you can use the free ASDec(it is still in the early beta stage, but it allows you to edit the bytecode, which in research may also be useful to someone).

    First, find what happens when you click the mouse. Having searched for MouseEvent in the text, we come across a Brick class that we already know , which responds to a mouse click:



    And it generates an EVENT_BRICK_CRASH event for GameManager.instance with its coordinates:



    As you can see, the GameManager class has a public static property instance . This is in our favor - just find this class and you can start generating fake clicks.
    Find the class:

    gameManager = loader.applicationDomain.getDefinition ('pl.fabrykagier.collapse :: GameManager');

    Quickly looking at the code of the GameManager class , we find the EVENT_START_GAME event . By subscribing to it, we will know when you can start clicking.

    Now let's play


    We no longer need the monster, then we will work independently. You can remove the Monster code and add a check to the address of the loaded swf so as not to try to play banners on the Habr :)

    if (loader.loaderURL! = 'https: //secure.f**tprint.net/w**ga/g**gle_test/Diamond.swf') return;

    And now let's try to generate clicks on all the blocks in a row:


    MonsterConnector.as

    Restart the browser, start the game ...



    It works!
    But we can’t achieve good results in this way, and the crystals that appear during error-free clicks will never be seen in this way.

    Now it's time to determine the state of the field and act more meaningfully.

    Having examined the code a bit, we will find that all the cubes are stored in the grid property of an object of type GameArea , but the trouble is that this property is private and we cannot directly access it. The GameArea class itself does not provide us with any public methods for obtaining the position of the blocks. It also has a findBiggestGroup functionto identify the largest group that could be useful to us, but it turned out to be private as evil.
    But at the beginning of the article, we already saw the Brick class in Monster. So we can just find all these cubes in the scene.

    I did this simply recursively sorting through all the visible objects in the scene. Perhaps there is a simpler way.



    Well, now copy the findBiggestGroup function found earlier , adapting it to our data representation. Lovers of algorithms and haters of recursive functions can write their own :)

    Another launch ... The



    whole field was unmistakably “disassembled”, for which they gave us a bunch of crystals that we forgot to collect. Despite this, we got a good result by surpassing the bot on AutoIT!



    The crystals are the same Brick instances , but with a value of color = 21 . We will click on them immediately upon detection.



    We start again, wait a minute, and ...



    In fact, the result should be slightly less, because the bot continues to play when the game has already ended and bonus points are being calculated.
    This can be fixed in a couple of lines of code. I suggest the reader to deal with this on his own.

    The final version of MonsterConnector.as

    Summary


    Embedding into the Flash application is quite simple, especially if the developer has kindly provided us with a link to an instance of the most important class.
    It’s not much harder to find objects in the scene knowing only the name of the class, and then use their properties if the developer has not separated the flies from the cutlets from the model from the presentation.

    Next time I’ll try to tell what can be done if the developer was more prudent and did not leave public properties and functions, or simply strictly adheres to the MVC model, depriving us of the opportunity to find data in the scene.

    Also popular now: