GNJOY GunBound - Patcher

Zilch

Administrator
Staff member
For the new GunBound server run by Gravity Games, they use a unique patching system created using Electron.

Anyways, while packet-sniffing, the patcher connects to this URL to check for updates (note port 9627):
http://54.207.135.149:9627/files-update

I am guessing it stores files at this URL (lacking port):
http://54.207.135.149/files-update/

Right now there's no further GET response beyond "?" but the API shows this:
JSON:
[
  {
    "name": "version.txt",
    "version": "1",
    "endpoint": "http://54.207.135.149/files-update/version.txt",
    "hash": "f053ddb33a01ef331339f35d551e151926d9a008",
    "filesize": ""
  }
]

So breaking that API into an array:
  1. name: version.txt
  2. version: 1
  3. endpoint: http://54.207.135.149/files-update/version.txt
  4. hash: f053ddb33a01ef331339f35d551e151926d9a008
  5. filesize: *blank*
More to figure out, but that's the gist of it so far. There's not enough data to go off of yet, as Gravity Games/GNJOY has not released any game patches, so we need to wait and see how that plays out before fully figuring out how this API works to scrape patch data.

Additional note: There is also a "version.txt" file in the root directory of the launcher. Whenever this file is modified or deleted (basically, at current time, if it doesn't say exactly "v0.1.0" inside of it), it will always attempt to download a new version.txt to replace it. Making the values higher or lower, doesn't matter, it will fix itself back to v0.1.0. Unsure what this file is used for at this time.

When attempting to send username/password data to the server, it sends encrypted packets to 54.94.2.93 on port 50715. At the moment, I don't have an account to test any further, so responses back from the server are incorrect credentials each time. I am curious if the patcher is talking to a Serv3 Broker/Center, or if it's something else entirely unique (likely), which then simply authenticates and gives the OK and command line args to launch the game client in game/gunbound.exe (which is technically the GME).
 
Last edited:
They did an update!
The API now shows this:
JSON:
[
  {
    "name": "plugin.dll",
    "version": "3",
    "endpoint": "http://54.207.135.149/files-update/game/plugin.dll",
    "hash": "9039293bbbb5c054f9a1c6f850afb7e3eded5041",
    "filesize": ""
  },
  {
    "name": "version.txt",
    "version": "3",
    "endpoint": "http://54.207.135.149/files-update/version.txt",
    "hash": "f053ddb33a01ef331339f35d551e151926d9a008",
    "filesize": ""
  }
]

And the files look like this in the directory:

1730994155231.png

And inside the game folder...
1730994182001.png
 
Last edited:
if you want to emulate their API, here's some quick script thrown together that will work to make this output.

Create table in database for patcher API

SQL:
CREATE TABLE files_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    version INT,
    endpoint VARCHAR(255),  -- Store the relative path here
    hash VARCHAR(255),
    filesize VARCHAR(255) DEFAULT ''
);

Add data (in this case, we will refer to the current files listed)

SQL:
INSERT INTO files_data (name, version, endpoint, hash)
VALUES
('plugin.dll', 3, '/files-update/game/plugin.dll', '9039293bbbb5c054f9a1c6f850afb7e3eded5041'),
('version.txt', 3, '/files-update/version.txt', 'f053ddb33a01ef331339f35d551e151926d9a008');

PHP JSON script itself

PHP:
<?php
// Set the source directory base URL
$source_dir = "http://54.207.135.149";  // Replace with your base URL

// MySQL Database connection settings
$servername = "localhost";
$username = "root"; // Replace with your MySQL username
$password = ""; // Replace with your MySQL password
$dbname = "your_database_name"; // Replace with your database name

// Create a connection to the database
$conn = new mysqli($servername, $username, $password, $dbname);

// Check if the connection was successful
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Query to fetch all file data
$sql = "SELECT name, version, endpoint, hash, filesize FROM files_data";
$result = $conn->query($sql);

// Initialize an empty array to store the response data
$response = [];

// Check if there are results
if ($result->num_rows > 0) {
    // Loop through the results and process each file data
    while ($row = $result->fetch_assoc()) {
        $name = $row['name'];
        $version = $row['version'];
        $endpoint = $row['endpoint'];
        $hash = $row['hash'];
        $filesize = $row['filesize'];

        // Prepend the source directory URL to the endpoint
        $full_endpoint = $source_dir . $endpoint;

        // Add each record to the response array in the API format
        $response[] = [
            'name' => $name,
            'version' => $version,
            'endpoint' => $full_endpoint,
            'hash' => $hash,
            'filesize' => $filesize
        ];
    }
} else {
    // If no records are found, output an empty array
    $response = [];
}

// Set the content type to JSON and output the response
header('Content-Type: application/json');
echo json_encode($response, JSON_PRETTY_PRINT);

// Close the database connection
$conn->close();
?>

Output example:
JSON:
[
    {
        "name": "plugin.dll",
        "version": 3,
        "endpoint": "http://54.207.135.149/files-update/game/plugin.dll",
        "hash": "9039293bbbb5c054f9a1c6f850afb7e3eded5041",
        "filesize": ""
    },
    {
        "name": "version.txt",
        "version": 3,
        "endpoint": "http://54.207.135.149/files-update/version.txt",
        "hash": "f053ddb33a01ef331339f35d551e151926d9a008",
        "filesize": ""
    }
]
 
Last edited:
Congratulations on the research, I would say this is quite interesting, does a Serv3 really exist? I hope so
 
When attempting to send username/password data to the server, it sends encrypted packets to 54.94.2.93 on port 50715. At the moment, I don't have an account to test any further, so responses back from the server are incorrect credentials each time. I am curious if the patcher is talking to a Serv3 Broker/Center, or if it's something else entirely unique (likely), which then simply authenticates and gives the OK and command line args to launch the game client in game/gunbound.exe (which is technically the GME).

Seeing there's a bug right now with e-mails being accepted which then refuses the client to launch (because the emails could never be used as a login credential in GunBound) its very likely its indeed custom. Not sure if it supports stuff like bans yet since there's no records of actual bans yet, but worst case it doesn't and reject the user at the World List instead.
 
if you want to emulate their API, here's some quick script thrown together that will work to make this output.

Create table in database for patcher API

SQL:
CREATE TABLE files_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    version INT,
    endpoint VARCHAR(255),  -- Store the relative path here
    hash VARCHAR(255),
    filesize VARCHAR(255) DEFAULT ''
);

Add data (in this case, we will refer to the current files listed)

SQL:
INSERT INTO files_data (name, version, endpoint, hash)
VALUES
('plugin.dll', 3, '/files-update/game/plugin.dll', '9039293bbbb5c054f9a1c6f850afb7e3eded5041'),
('version.txt', 3, '/files-update/version.txt', 'f053ddb33a01ef331339f35d551e151926d9a008');

PHP JSON script itself

PHP:
<?php
// Set the source directory base URL
$source_dir = "http://54.207.135.149";  // Replace with your base URL

// MySQL Database connection settings
$servername = "localhost";
$username = "root"; // Replace with your MySQL username
$password = ""; // Replace with your MySQL password
$dbname = "your_database_name"; // Replace with your database name

// Create a connection to the database
$conn = new mysqli($servername, $username, $password, $dbname);

// Check if the connection was successful
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

// Query to fetch all file data
$sql = "SELECT name, version, endpoint, hash, filesize FROM files_data";
$result = $conn->query($sql);

// Initialize an empty array to store the response data
$response = [];

// Check if there are results
if ($result->num_rows > 0) {
    // Loop through the results and process each file data
    while ($row = $result->fetch_assoc()) {
        $name = $row['name'];
        $version = $row['version'];
        $endpoint = $row['endpoint'];
        $hash = $row['hash'];
        $filesize = $row['filesize'];

        // Prepend the source directory URL to the endpoint
        $full_endpoint = $source_dir . $endpoint;

        // Add each record to the response array in the API format
        $response[] = [
            'name' => $name,
            'version' => $version,
            'endpoint' => $full_endpoint,
            'hash' => $hash,
            'filesize' => $filesize
        ];
    }
} else {
    // If no records are found, output an empty array
    $response = [];
}

// Set the content type to JSON and output the response
header('Content-Type: application/json');
echo json_encode($response, JSON_PRETTY_PRINT);

// Close the database connection
$conn->close();
?>

Output example:
JSON:
[
    {
        "name": "plugin.dll",
        "version": 3,
        "endpoint": "http://54.207.135.149/files-update/game/plugin.dll",
        "hash": "9039293bbbb5c054f9a1c6f850afb7e3eded5041",
        "filesize": ""
    },
    {
        "name": "version.txt",
        "version": 3,
        "endpoint": "http://54.207.135.149/files-update/version.txt",
        "hash": "f053ddb33a01ef331339f35d551e151926d9a008",
        "filesize": ""
    }
]
I looked at the update structure, and it closely resembles the update system used in Gravity's Ragnarok game.
 
I looked at the update structure, and it closely resembles the update system used in Gravity's Ragnarok game.
I wouldn’t doubt that they ported the same launcher over. This was a thought of mine too, but I’ve also never played RO.
 
I would really like them to abandon the .xfs extension and start using .grf, everything would be much easier and better,

There is the update system used in Gravity's Ragnarok somewhere on github, I'll look for it and show you
 
I would really like them to abandon the .xfs extension and start using .grf, everything would be much easier and better,

There is the update system used in Gravity's Ragnarok somewhere on github, I'll look for it and show you
Honestly they probably only use .xfs because the game client makes it necessary, but I think they just replace all files at once each update now.

EDIT: Also they updated the site again to show version 1...
 
who know the command for send the master room to another player?
These are custom commands not from the original game:
/drag - Toggle between shaking or non-shaking Drag
/only <mobile> - Forces your room to only have x mobile. Can be combined with other mobiles by typing a different one after it
/senha <password> - Changes your room's password
/removersenha - REMOVES your password (this gives no chat response)
/rt - Enable random teams which will occur on game start (this gives no chat response)
/transferirsala <nickname> - Transfers the Master to <nickname>
 
These are custom commands not from the original game:
/drag - Toggle between shaking or non-shaking Drag
/only <mobile> - Forces your room to only have x mobile. Can be combined with other mobiles by typing a different one after it
/senha <password> - Changes your room's password
/removersenha - REMOVES your password (this gives no chat response)
/rt - Enable random teams which will occur on game start (this gives no chat response)
/transferirsala <nickname> - Transfers the Master to <nickname>
only works this command /onlymobile aduka and /drag if you find the command for send the key master room to another player I will be happy
 
Noticable changes (English version)

- Font type have been changed to GIS version
- Many assets have been reverted to GIS vanilla instead of their weird ass edit. Though, they messed some stuff up like the F8 button in new interface being Portuguese
vmplayer_nnIQbgHMGf.png
1733081962635.png
1733081867997.png


World List now have a display bug as well

vmplayer_9q7f3DBnfS.png

- Language.txt file is still their weird custom translated english for whatever reason
- Sets items button in the avatar shop have been removed
- Cash Charge buttons are now properly gone instead of invisible (that was funny)
 
Last edited:
Back
Top