The updater module can be used to download the latest packet ids and assets from the game.
npm install @n2/updater
If you intend to use the unpackSwf
method, you will also need to install a Java Runtime Environment and add it to your PATH so that it may be invoked from the command line.
This package has been tested using JRE 8u181.
The updater can be imported using the CommonJS style
const Updater = require('@n2/updater');
Or using the ES style
import Updater from '@n2/updater';
For downloading assets, the updater has two methods available.
getGroundTypes()
- Fetches theGroundTypes.json
resource.getObjects()
- Fetches theObjects.json
resource.
Both of these download the resources into an in-memory buffer. They return a promise which resolves when the download has completed.
const Updater = require('@n2/updater');
console.log('Downloading ground types.');
Updater.getGroundTypes().then((groundTypes) => {
console.log('Downloaded ground types.');
}).catch((error) => {
console.log('Error while downloading ground types.');
console.error(error);
});
A WriteStream
object can be used to save the buffer contents to the disk.
const Updater = require('@n2/updater');
const fs = require('fs');
const path = require('path');
// create the stream.
const stream = fs.createWriteStream(path.join(__dirname, 'ground-types.json'));
// download the ground types.
Updater.getGroundTypes().then((groundTypes) => {
// write the buffer to the stream, then close it.
stream.end(groundTypes);
console.log('Ground types saved to ./ground-types.json');
});
Since writing the buffer contents to the disk is extremely common, the getGroundTypes
method accepts a writable stream as an argument for convenience. If one is provided, the data will be piped int the stream, and it will be automatically closed when the download has finished.
const Updater = require('@n2/updater');
const fs = require('fs');
const path = require('path');
// create the stream.
const stream = fs.createWriteStream(path.join(__dirname, 'ground-types.json'));
// download the ground types, but pass the stream in this time.
Updater.getGroundTypes(stream).then((groundTypes) => {
// no need to write to the stream this time.
console.log('Ground types saved to ./ground-types.json');
});
A stream can also be passed as an optional argument to the getClient
and getObjects
methods.
This is a lightweight example. It is a good idea to attach an event listener to the error
event of the write stream. If there is no event listener attached when an error occurs the program will be terminated.
There are several methods which can are used to download the game client and extract the packet IDs from it. All of these methods return promises which resolve when the operations have been completed.
getRemoteClientVersion()
- Fetches the latest client version number.getClient(version: string)
- Fetches the game client with the specified version. Downloads the client to an in-memory buffer.unpackSwf(swfPath: string)
- Decompiles the file located atswfPath
.
There are two additional methods which don't return promises.
makeGSCPath(base: string)
- Creates a filepath frombase
to theGameServerConnection.as
file.extractPacketInfo(source: string)
- Extracts the packet IDs from the source of aGameServerConnection.as
file.
const Updater = require('@n2/updater');
const fs = require('fs');
const path = require('path');
// create the stream.
const stream = fs.createWriteStream(path.join(__dirname, 'client.swf'));
// get the current client version.
Updater.getRemoteClientVersion().then((version) => {
// download the latest client.
return Updater.getClient(version, stream);
}).then((client) => {
// unpack the client.
return Updater.unpackSwf(path.join(__dirname, 'client.swf'));
}).then(() => {
// get the contents of the GameServerConnection.as file.
const pathToGSC = Updater.makeGSCPath(path.join(__dirname, 'decompiled'));
const gscFileContents = fs.readFileSync(pathToGSC, { encoding: 'utf8' });
// extract the packet info and save it to the disk.
const packets = Updater.extractPacketInfo(gscFileContents);
fs.writeFileSync(path.join(__dirname, 'packets.json'), JSON.stringify(packets));
});