New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

gbxremote

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gbxremote - npm Package Compare versions

Comparing version 0.1.4 to 0.2.0

.editorconfig

273

lib/client.js

@@ -1,6 +0,8 @@

var net = require('net')
, barse = require('barse')
, Serializer = require('./serializer')
, Deserializer = require('./deserializer')
;
var net = require('net');
var barse = require('barse');
var Promise = require('any-promise');
var toPromise = require('event-to-promise');
var toStream = require('string-to-stream');
var Serializer = require('xmlrpc/lib/serializer');
var Deserializer = require('xmlrpc/lib/deserializer');

@@ -11,28 +13,15 @@ /**

* @constructor
* @param {Object|String} options - Server options to make the HTTP request to.
* Either a URI string
* (e.g. 'http://localhost:9090') or an object
* with fields:
* - {String} host - (optional)
* - {Number} port
* @param {Boolean} isSecure - True if using https for making calls,
* otherwise false.
* @param {Number} port
* @param {String} host (optional)
* @return {Client}
*/
function Client(port, host, callback) {
function Client(port, host) {
// Invokes with new if called without
if (false === (this instanceof Client)) {
return new Client(port, host, callback)
if ((this instanceof Client) === false) {
return new Client(port, host);
}
// Set the options
if (typeof host === 'function') {
callback = host;
host = 'localhost';
}
this.host = host || 'localhost';
this.port = port;
this.isConnected = false;

@@ -42,4 +31,2 @@ this.isReady = false;

this.callbacks = {};
this.connect(callback);
}

@@ -52,69 +39,58 @@

* Connects to the server
*
* @param {Function} callback (optional) - function(error) { ... }
* - {Number} timeout (optional) - Timeout to connect
* @return {Promise} Resolves on connection
*/
Client.prototype.connect = function(callback, timeout) {
if (this.isConnected)
return;
var self = this
, timeout = typeof timeout === 'number' ? timeout : typeof callback === 'number' ? callback : 2000; // TODO: test
// Mess with the callback function so we never have to `if` it later
// If: no callback given, make an empty function
// Else: Untested: Only call the callback once.
// - E.g. If successfully connected to the server, and later some weird socket error occurs,
// then the callback function will be called twice. Once with success, and once with error.
// Thats what we're trying to prevent... >>> ^^^^^
if (typeof callback !== 'function') {
callback = function(){};
} else {
// Closure to hide `cb`
(function() { // TODO: test
var cb = callback;
callback = function() {
// Forward call
cb.apply(this, arguments);
// If called again, ignore
callback = function() {};
}
})();
Client.prototype.connect = function (timeout) {
if (this.isConnected) {
return Promise.resolve(this);
}
// Connect to the server
this.socket = net.connect(this.port, this.host);
// TODO: Move timeout out of onConnect? (currently timeout is a handshake timeout)
this.socket.on('connect', function() {
self.isConnected = true;
// Timeout for handshake
var to = setTimeout(function() {
var err = new Error('timeout - handshake timed out');
callback(err);
var self = this;
timeout = timeout || 2000;
return new Promise(function (resolve, reject) {
// Connect to the server
self.socket = net.connect(self.port, self.host);
self._setupParsers();
// TODO: Move timeout out of onConnect? (currently timeout is a handshake timeout)
self.socket.on('connect', function () {
self.isConnected = true;
// Timeout for handshake
var to = setTimeout(function () {
var err = new Error('timeout - handshake timed out');
self.emit('error', err);
self.terminate();
}, timeout);
self.on('connect', function () {
clearTimeout(to);
});
});
self.socket.on('error', function (err) {
self.isConnected = self.isReady = false;
self.emit('error', err);
self.terminate();
}, timeout);
self.on('connect', function() {
clearTimeout(to);
});
self.socket.on('close', function (hadError) {
self.emit('close', hadError);
});
self.on('error', function () {
reject();
});
self.on('connect', function () {
resolve(this);
});
});
this.socket.on('error', function(err) {
self.isConnected = self.isReady = false;
callback(err);
self.emit('error', err);
});
this.socket.on('close', function(had_error) {
self.emit('close', had_error);
});
};
Client.prototype._setupParsers = function () {
var self = this;
var handshakeParser = barse()

@@ -134,12 +110,11 @@ .readUInt32LE('length')

// Then switch to dataParser once handshakeParser is done
handshakeParser.once('data', function() {
handshakeParser.once('data', function () {
self.socket.unpipe(handshakeParser);
self.socket.pipe(dataParser);
})
});
// HANDSHAKE
handshakeParser.once('data', function(data) {
if (data.handshake != 'GBXRemote 2') {
handshakeParser.once('data', function (data) {
if (data.handshake !== 'GBXRemote 2') {
var err = new Error('transport error - wrong lowlevel protocol version');
callback(err);
self.emit('error', err);

@@ -151,32 +126,24 @@ return;

self.isReady = true;
callback();
self.emit('connect');
});
dataParser.on('data', function(data) {
dataParser.on('data', function (data) {
var deserializer = new Deserializer();
// TODO: Use reqhandle to determine if its a response or callback
var stream = toStream(data.xml);
// Reponse
if (self.callbacks.hasOwnProperty(data.reqhandle)) {
deserializer.deserializeMethodResponse(data.xml, function(a, b) {
self.callbacks[data.reqhandle].apply(this, arguments);
delete self.callbacks[data.reqhandle];
if (data.reqhandle > 0x80000000) {
deserializer.deserializeMethodResponse(stream, function (err, res) {
self.emit('response:' + data.reqhandle, [err, res]);
});
}
// Callback
else {
deserializer.deserializeMethodCall(data.xml, function(err, method, res) {
} else { // Callback
deserializer.deserializeMethodCall(stream, function (err, method, res) {
if (err) {
// This should never happen....
// There is nothing we can do about this one.
// Its not a response to a request, and its not a valid callback (MethodCall)
//console.log(err);
console.warn('Not a response, nor a callback! (reqhandle: 0x%s)', data.reqhandle.toString(16));
// Ignore
return;
} else {
// its a callback from the server
self.emit('callback', method, res);
self.emit(method, res);
}
// its a callback from the server
self.emit('callback', method, res);
self.emit(method, res);
});

@@ -187,4 +154,3 @@ }

Client.prototype.terminate = function() {
Client.prototype.terminate = function () {
if (this.socket) {

@@ -194,3 +160,3 @@ this.socket.end();

}
}
};

@@ -200,43 +166,35 @@ /**

*
* @param {String} method - The method name.
* @param {Array} params - Params to send in the call.
* @param {Function} callback - function(error, value) { ... }
* - {Object|null} error - Any errors when making the call, otherwise null.
* - {mixed} value - The value returned in the method response.
* @param {String} method - The method name.
* @param {Array} params - Params to send in the call.
* @return {Promise}
*/
Client.prototype.query = function(method, params, callback) {
Client.prototype.query = function (method, params) {
var self = this;
if (typeof (arguments[2] || arguments[1]) === 'function') {
throw new TypeError('.query does no longer take a callback. It returns a Promise!');
}
if (!this.isReady) {
// Call again when ready instead of erroring?.. maybe? yes? no?
var args = arguments;
this.once('connect', function() {
this.query.apply(this, args);
return toPromise(this, 'connect').then(function () {
return self.query.apply(self, args);
});
return false;
}
// An attempt on method overloading
if (typeof params === 'function') {
callback = params;
params = [];
if (!Array.isArray(params)) {
params = [params];
}
params = params || [];
// Make sure its an array
if (typeof params !== 'object')
params = [params];
// Returns JSON of the xml
var xml = Serializer.serializeMethodCall(method, params);
// Check if request (xml + header) is larger than 1024 Kbytes (limit of maniaplanet)
if (xml.length + 8 > 1024*1024) {
callback(new Error('transport error - request too large (' + xml.length + ')'));
return false;
if (xml.length + 8 > 1024 * 1024) {
var error = new Error('transport error - request too large (' + xml.length + ')');
return Promise.reject(error);
}
this.reqhandle++;
this.callbacks[this.reqhandle] = (typeof callback === 'function') ? callback : function() {};
// $bytes = pack('VVa*', strlen($xml), $this->reqhandle, $xml);

@@ -248,12 +206,19 @@ var len = Buffer.byteLength(xml);

buf.write(xml, 8);
this.socket.write(buf, 'utf8');
return true;
return toPromise(this, 'response:' + this.reqhandle, {
ignoreErrors: true
}).then(function (result) {
var err = result[0];
var res = result[1];
if (err) {
throw err;
}
return res;
});
};
// DEPRECATED - Function name changed.
Client.prototype.methodCall = Client.prototype.query;
module.exports = Client;

@@ -8,8 +8,12 @@ var Client = require('./client');

* @param {String} host
* @param {Function} callback
* @return {Client}
* @see Client
*/
exports.createClient = function(port, host, callback) {
return new Client(port, host, callback);
}
exports.createClient = function createClient(port, host) {
var client = new Client(port, host);
client.connect();
return client;
};
exports.Client = Client;

@@ -1,40 +0,55 @@

{ "name" : "gbxremote"
, "description" : "A pure JavaScript GBXRemote client."
, "keywords" : [ "xml-rpc", "xmlrpc", "xml", "rpc", "gbxremote", "maniaplanet", "trackmania", "shootmania", "questmania", "nadeo" ]
, "version" : "0.1.4"
, "preferGlobal" : false
, "homepage" : "https://github.com/MiniGod/node-gbxremote"
, "author" : "Kristjan Broder Lund <kristjan.1234@gmail.com> (https://github.com/MiniGod)"
, "repository" : {
"type" : "git"
, "url" : "git://github.com/MiniGod/node-gbxremote.git"
}
, "bugs" : {
"url" : "https://github.com/MiniGod/node-gbxremote/issues"
}
, "directories" : {
"lib" : "./lib"
}
, "main" : "./lib/gbxremote.js"
, "dependencies" : {
"sax" : "0.4.x"
, "xmlbuilder" : "0.3.1"
, "barse" : "~0.4.2"
}
, "devDependencies" : {
"vows" : "0.6.x"
}
, "scripts" : {
"test" : "make test"
}
, "engines" : {
"node" : ">=0.4",
"npm" : ">=1.0.0"
}
, "licenses" : [ {
"type" : "MIT"
, "url" : "https://github.com/MiniGod/node-gbxremote/raw/master/LICENSE"
{
"name": "gbxremote",
"description": "A pure JavaScript GBXRemote client.",
"keywords": [
"xml-rpc",
"xmlrpc",
"xml",
"rpc",
"gbxremote",
"maniaplanet",
"trackmania",
"shootmania",
"questmania",
"nadeo"
],
"version": "0.2.0",
"preferGlobal": false,
"homepage": "https://github.com/MiniGod/node-gbxremote",
"author": "Kristjan Broder Lund <kristjan.1234@gmail.com> (https://github.com/MiniGod)",
"repository": {
"type": "git",
"url": "git://github.com/MiniGod/node-gbxremote.git"
},
"bugs": {
"url": "https://github.com/MiniGod/node-gbxremote/issues"
},
"directories": {
"lib": "./lib"
},
"main": "./lib/gbxremote.js",
"dependencies": {
"any-promise": "^1.1.0",
"barse": "~0.4.2",
"event-to-promise": "^0.7.0",
"string-to-stream": "^1.0.1",
"xmlrpc": "^1.3.1"
},
"devDependencies": {
"nodemon": "^1.8.1",
"xo": "^0.12.1"
},
"scripts": {
"watch": "nodemon -x npm test",
"test": "xo"
},
"engines": {
"node": ">=0.10"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/MiniGod/node-gbxremote/raw/master/LICENSE"
}
]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc