We continue to tell you how our laser quest with the destruction of the server was arranged. Beginning in the previous article about solving the quest .
In total, the backend of the game had 6 architectural units, which we will analyze in this article:
- Backend of game entities that were responsible for game mechanisms
- Backend and site data exchange bus on VPS
- Translator from backend requests (game elements) to arduino and hardware on the site
- Arduino, who was in charge of relay control, received commands from the translator and did the actual work
- Actual devices: fan, daisies, floor lamps, etc.
- Frontend - the Falcon site itself, from which players controlled devices
Let's go through each of them.
Backend of game entities
The backend was implemented as a spring boot application: it had several rest controllers, a websocket endpoint, and services with game logic.
There were only three controllers:
- Megatron. The current page of Megatron was sent through GET requests: before and after power-on. The laser fired through a POST request.
- , . , ID .
- , - .
Websocket endpoint was used to control gadgets: lamps, garland and letters. It was chosen to synchronously display the current status of the device to all players: whether it is on or off, active or not, what color of the letter is currently on the wall. In order to slightly complicate the task of turning on the laser, we put authorization on the garland and the laser with the same admin / admin login and password.
Players could test it by turning on the garland and doing the same with the laser.
We have chosen such a trivial pair of login-password in order not to torment the players with unnecessary selection.
To make the task a little more interesting, object IDs from mongodb were used as identifiers of devices in the room.
ObjectId contains a timestamp: two random values, one of which is taken based on the device identifier, and the second based on the pid-process that generates it and the counter value. I wanted to make the identifiers generated at regular intervals and from different pid processes, but with a common counter, so that the selection of the identifier of the laser device was more interesting. However, in the end, everyone started up with identifiers that differ only in the value of the counter. Perhaps this made the stage too simple and did not require analysis of the structure of objectId identifiers.
Translator from backend requests
Python script that dealt with timers and translated from game abstractions into a physical model. For example "turn on the floor lamp" → "turn on relay N2".
The script connected to the RabbitMQ queue and passed requests from the queue to Arduino. It also implemented the logic of parallel switching on of the light: along with some devices, the light was turned on on them, for example, when the Megatron was initially powered, it was illuminated with stage light. Lighting design for a cinematic whole scene is a separate story about the great work of our project co-producer and production designer Ilya Serov, and we will tell about it in a separate post.
The translator was also responsible for the logic of starting the shredder by timer and transmitting the image to the TV: the timer for starting the shredder, the screaming capybara, the ad at the end of the game.
How the logic of generating the megatron token was arranged
Test shot
Every 25 seconds, a new token was generated, it could be used to turn on the laser for 10 seconds at 10/255 power. Link to github with Megatron code .
Then the laser was cooled for 1 minute - at this time it was unavailable and did not accept new requests for a shot.
This power was not enough to burn through the rope, but any player could shoot from Megatron and see the laser beam in action.
The MD5 hashing algorithm was used to generate the token. And the scheme was MD5 from MD5 + counter + secret for the combat token and without a secret for the test one.
MD5 is a reference to a commercial project that was made by Pavel, our backender. Just a couple of years ago, this project used MD5, and when he told the project architect that it was a legacy encryption algorithm, they started using MD5 from MD5. Since we decided to make the maximum Noob project, he remembered everything and decided to make a little reference.
Combat shot
Megatron's combat mode is 100% 3W laser power. This is quite enough for 2 minutes to burn the rope that was holding the weight to break the aquarium and fill the server with water.
We left a few hints on the project's github: namely, the token generation code, by which it was possible to understand that test and combat tokens are generated based on one counter indicator. In the case of a combat token, in addition to the counter value, salt is also used, which was almost completely left in the history of this gist, with the exception of the last two characters.
Knowing this data, it was possible to iterate over the last 2 symbols of salt and in fact find out that numbers from Lost were used for it, translated into the 16-digit system.
Then the players had to catch the counter value (by analyzing the test token) and generate a combat token using the next counter value and the salt selected in the last step.
The counter was simply incremented with each test shot and every 25 seconds. We have not written about this anywhere, it should have been a small game surprise.
Service for interaction with captcha
In the game world, this was the same captcha that had to be loaded in order to turn on the fan and open a flipchart with a hint. There was a laptop with load monitoring next to the camera.
The service calculated what to display in the monitoring as the current load: temperature and CPU Fan. Metrics were passed to the timebase database and rendered in grafana.
If in the last 5 seconds more than 50 requests for captcha display were received, then the load grew by fix + a random number of steps. The calculation was that 100% load could be obtained in two minutes.
In fact, there was more logic in the service than was displayed in the final game: we set the monitor in such a way that only the rotation of the CPU Fan was visible.
At the beginning of the quest, they wanted to leave Grafana accessible from the Sokol website. But it also contained springboot metrics for the backend application report, which we did not have time to clean up, so we decided to close access to it. And rightly so - at the beginning of the quest, some players guessed that the application was written in the springboot framework and even dug up the name of some services.
Hosting and data bus
A tool for transferring information from the backend to the site, the VPS server on which RabbitMQ was launched.
The backend and data bus were kept on our VPS . Its power was comparable to the computer you saw on the screen: a 2-core VPS with 2 gigabytes of RAM. The tariff was taken for resources, since the peak load was planned for only a few days - this is what our clients do, who are planning to load VPS for a short time. Then it turned out that the load was higher than we expected, and a fixed tariff would be more profitable. If you are going to do a quest, choose the tariffs of the turbo line .
To protect the server from DDoSa, we used Cloudflare.
It is worth saying that the VPS withstood everything with flying colors.
Arduino, who was in charge of relay control, received commands from the translator and did the actual work
This is more a topic for the next article about the hardware part of the project: the backend simply sent requests to enable a specific relay. It so happened that the backend knew almost all entities and requests from it looked like "enable this entity". We did this for early testing of the site (we have not yet collected all the Arduino and relays), in the end we left everything that way.
Frontend
We quickly created the site on tilde, it took one working day and saved us 30 thousand of the budget.
Initially, we thought to just export the site and throw in the logic we were missing, but we ran into terms of use that forbade us to do this.
We were not ready to violate the license, so there were two options: to make up everything ourselves or to contact Tilda directly, tell about the project and ask permission to change the code.
We chose the second option and they did not just meet us halfway, but even gave us a year of free business account, for which we are very grateful. It was very embarrassing to show them the design of Sokol's website.
As a result, we attached js logic to the frontend for sending requests to elementary devices, slightly changed the styles of the buttons for turning on and off game elements.
Site design
Search history, which is worth a separate chapter.
We wanted to create not just an old-fashioned site, but an absolutely nauseating one that violates all the basic design rules. At the same time, it was important to preserve believability: he had to not break the ENT stories, demonstrate the pretentiousness of the author, and the players would have to believe that such a site could exist and even bring clients. And he brought! While the game was running, we were twice asked to create websites.
At first, I did the design myself, trying to stick in more GIFs and shiny elements. But my husband, a designer with 10 years of experience, looked over his shoulder and dismissed him as "too good." To break design rules, you need to know them.
There are several color combinations that cause a persistent feeling of disgust: green and red of equal juiciness, gray and pink, blue plus brown. As a result, we settled on a combination of red and green as basic colors, added gifs with a cat and chose 3-4 photos of Sokolov himself on the photo stock. I had only a few requirements: a middle-aged man, in a poorly fitting suit a couple of sizes larger and in the pose of "professional photo shoot in the studio." For the test, they showed it to friends and asked, "How do you like it?"
In the process of developing the design, my husband had to lie down every half hour, and began to fly a helicopter. Pasha tried to open the developer's console to most of the screen, while he was finishing the frontend - he took care of his eyes.
Actual devices
Fans and lights were mounted through solid-state relays so that they did not turn on at full power right away - so that the power build-up would occur in parallel with monitoring.
But we'll talk about this in the next post, about the hardware part of the game and the actual construction of the site.
Stay tuned!
Other articles about the quest with the destruction of the server
- Beginning of the game
- First clue
- Who stopped the shredder or how it was necessary to complete the quest with the destruction of the server