+162
| var Ws = require('ws'), | ||
| EventEmitter = require('events').EventEmitter, | ||
| util = require('util'), | ||
| uuid = require('uuid'), | ||
| JsonRPc = require('jr2-helper'), | ||
| utils = require('./utils.js'); | ||
| var JR_PROTOCOL = 'jsonrpc2'; | ||
| var mix = utils.mix, | ||
| Guard = utils.guard; | ||
| var protocolsHandle = function(protList, cb){ | ||
| if(protList.length){ | ||
| if(protList.indexOf(JR_PROTOCOL) > -1){ | ||
| cb(true, JR_PROTOCOL); | ||
| } else { | ||
| cb(true, protList[0] || undefined); | ||
| } | ||
| } else { | ||
| cb(true, undefined); | ||
| } | ||
| } | ||
| var msgParse = function(message, protocol){ | ||
| var message = message.toString(); | ||
| if(protocol === JR_PROTOCOL){ | ||
| return JsonRPc.parse(message, true); | ||
| } | ||
| return message; | ||
| } | ||
| var send = Ws.prototype.send; | ||
| mix(Ws.prototype, { | ||
| _send : send, | ||
| send : function(msg){ | ||
| if(this.readyState === Ws.OPEN){ | ||
| this._send(msg); | ||
| } | ||
| this.guard.reset(); | ||
| } | ||
| }, true); | ||
| function Track(port, opts){ | ||
| if(!(this instanceof Track)){ | ||
| return new Track(port, opts); | ||
| } | ||
| this.init(port, opts); | ||
| } | ||
| util.inherits(Track, EventEmitter); | ||
| mix(Track.prototype, { | ||
| init : function(port, opts){ | ||
| if (typeof port === 'object') { | ||
| opts = port; | ||
| } | ||
| var opts = mix({ | ||
| timeout : 5, | ||
| handleProtocols : protocolsHandle, | ||
| msgParse : msgParse | ||
| }, opts, true); | ||
| mix(opts, { | ||
| port : port | ||
| }); | ||
| this.opts = opts; | ||
| this.clients = {}; | ||
| var wss = new Ws.Server(opts); | ||
| this.wss = wss; | ||
| this.handles(); | ||
| }, | ||
| handles : function(){ | ||
| var self = this, | ||
| wss = this.wss; | ||
| wss.on('headers', function(headersData){ | ||
| self.emit('headers', headersData); | ||
| }); | ||
| }, | ||
| start : function(){ | ||
| var self = this, | ||
| opts = this.opts, | ||
| timeout = opts.timeout, | ||
| msgParse = opts.msgParse, | ||
| wss = this.wss; | ||
| wss.on('connection', function(ws){ | ||
| var cid = uuid.v4().replace(/-/g, ''), | ||
| protocol = ws.protocol, | ||
| guard = Guard(timeout * 60 * 1000); | ||
| ws.guard = guard; | ||
| ws.cid = cid; | ||
| self.clients[cid] = ws; | ||
| ws.on('error', function(message) { | ||
| self.emit('clientError', { | ||
| cid : cid, | ||
| err : err | ||
| }); | ||
| }); | ||
| ws.on('close', function() { | ||
| self.clients[cid] = null; | ||
| guard.stop(); | ||
| ws.guard = null; | ||
| self.emit('clientClose', cid); | ||
| }); | ||
| ws.on('message', function(message) { | ||
| if(msgParse){ | ||
| message = msgParse(message, protocol); | ||
| } | ||
| self.emit('message', { | ||
| cid : cid, | ||
| msg : message | ||
| }); | ||
| guard.reset(); | ||
| }); | ||
| guard.then(function(){ | ||
| ws.close(); | ||
| }); | ||
| self.emit('connection', cid); | ||
| }); | ||
| }, | ||
| sendTo : function(cids, msg){ | ||
| cids = util.isArray(cids) ? cids : [cids]; | ||
| for(var i = 0, l = cids.length; i < l; i++){ | ||
| var client = this.clients[cids[i]]; | ||
| client && client.send(msg); | ||
| } | ||
| }, | ||
| broadcast : function(msg) { | ||
| var clientIds = Object.keys(this.clients); | ||
| this.sendTo(clientIds, msg); | ||
| }, | ||
| getWs : function(cid){ | ||
| var client = this.clients[cid]; | ||
| return client ? client : null; | ||
| }, | ||
| getReq : function(cid){ | ||
| var client = this.clients[cid]; | ||
| return client ? client.upgradeReq : null; | ||
| }, | ||
| close : function(cid, code, data){ | ||
| var client = this.clients[cid]; | ||
| client && client.close(code, data); | ||
| }, | ||
| stop : function(){ | ||
| var cids = Object.keys(this.clients); | ||
| for(var i = 0, l = cids.length; i < l; i++){ | ||
| var client = this.clients[cids[i]]; | ||
| client && client.close(); | ||
| } | ||
| this.wss.close(); | ||
| this.wss = null; | ||
| } | ||
| }); | ||
| Track.JSONRPC2_ERROR_CODES = JsonRPc.ERROR_CODES; | ||
| Track.utils = utils; | ||
| module.exports = Track; |
+118
-121
@@ -1,143 +0,140 @@ | ||
| var Ws = require('ws'), | ||
| var utils = require('./utils.js'), | ||
| Track = require('./track.js'), | ||
| EventEmitter = require('events').EventEmitter, | ||
| when = require('when'), | ||
| Musk = require('musk'), | ||
| path = require('path'), | ||
| fs = require('fs'), | ||
| util = require('util'), | ||
| uuid = require('uuid'), | ||
| JsonRPc = require('jr2-helper'), | ||
| utils = require('./utils.js'); | ||
| Client = Musk.Client, | ||
| mix = utils.mix; | ||
| var JR_PROTOCOL = 'jsonrpc2'; | ||
| var mix = utils.mix, | ||
| Guard = utils.guard; | ||
| var protocolsHandle = function(protList, cb){ | ||
| if(protList.length){ | ||
| if(protList.indexOf(JR_PROTOCOL) > -1){ | ||
| cb(true, JR_PROTOCOL); | ||
| } else { | ||
| cb(true, protList[0] || undefined); | ||
| } | ||
| } else { | ||
| cb(true, undefined); | ||
| } | ||
| function exit(msg){ | ||
| console.error(Array.prototype.join.call(arguments, ' ')); | ||
| process.exit(); | ||
| } | ||
| var msgParse = function(message, protocol){ | ||
| var message = message.toString(); | ||
| if(protocol === JR_PROTOCOL){ | ||
| return JsonRPc.parse(message, true); | ||
| } | ||
| return message; | ||
| } | ||
| var proxyObj = {}; | ||
| mix(proxyObj, EventEmitter.prototype); | ||
| var send = Ws.prototype.send; | ||
| mix(Ws.prototype, { | ||
| _send : send, | ||
| send : function(msg){ | ||
| if(this.readyState === Ws.OPEN){ | ||
| this._send(msg); | ||
| } | ||
| this.guard.reset(); | ||
| } | ||
| }, true); | ||
| function Elon(port, opts){ | ||
| if(!(this instanceof Elon)){ | ||
| return new Elon(port, opts); | ||
| } | ||
| this.init(port, opts); | ||
| } | ||
| util.inherits(Elon, EventEmitter); | ||
| function Elon(opts){ | ||
| var root = opts && opts.root || process.cwd(); | ||
| this.opts = mix({ | ||
| root : root, | ||
| modPath : root + '/app/mod', | ||
| actpath : root + '/app/act' | ||
| }, opts, true); | ||
| }; | ||
| mix(Elon.prototype, { | ||
| init : function(port, opts){ | ||
| if (typeof port === 'object') { | ||
| opts = port; | ||
| addMods : function(mods){ | ||
| var _mods = this._mods || {}; | ||
| for(var name in mods){ | ||
| var mod = mods[name]; | ||
| if(mod.file){ | ||
| var pre = mod.file.substr(0,1) === '/' ? '' : process.cwd(), | ||
| filePath = path.join(pre, mod.file); | ||
| if(fs.existsSync(filePath)){ | ||
| _mods[name] = require(filePath); | ||
| } else { | ||
| exit('file : ', filePath, 'is not exists'); | ||
| } | ||
| } else if (mod.sock || mod.ws || mod.http) { | ||
| var type = Object.keys(mod)[0], | ||
| argv = util.isArray(mod[type]) ? mod[type] : [mod[type]], | ||
| srv = Client.create(type, argv); | ||
| _mods[name] = srv.ready(); | ||
| srv.on('err', function(err){ | ||
| exit('mode "', name, '"error. ->', err); | ||
| }); | ||
| } else { | ||
| exit('mod', name, 'config error : '); | ||
| } | ||
| } | ||
| var opts = mix({ | ||
| timeout : 5, | ||
| handleProtocols : protocolsHandle, | ||
| msgParse : msgParse | ||
| }, opts, true); | ||
| mix(opts, { | ||
| port : port | ||
| }); | ||
| this.opts = opts; | ||
| this.clients = {}; | ||
| this._mods = _mods; | ||
| }, | ||
| handles : function(){ | ||
| addLocalModules : function(modulesPath){ | ||
| if(!fs.existsSync(modulesPath)){ | ||
| return; | ||
| } | ||
| var modFiles = fs.readdirSync(modulesPath), | ||
| localModConf = {}; | ||
| for(var i = 0, l = modFiles.length; i < l; i++){ | ||
| var file = modFiles[i], | ||
| name = path.basename(file).toLowerCase().replace(/\.(js|json|node)$/, '') | ||
| ext = path.extname(file).toLowerCase().replace('.', '') | ||
| if(ext === 'js' || ext === 'json' || ext === 'node'){ | ||
| var modName = name.replace(/[^a-zA-Z0-9](\w)/g, function(m, c){ | ||
| return c.toUpperCase(); | ||
| }); | ||
| localModConf[modName] = { | ||
| 'file' : path.join(modulesPath, file) | ||
| } | ||
| } | ||
| } | ||
| return localModConf; | ||
| }, | ||
| start : function(){ | ||
| var self = this, | ||
| opts = this.opts, | ||
| timeout = opts.timeout, | ||
| msgParse = opts.msgParse, | ||
| wss = new Ws.Server(this.opts); | ||
| wss.on('connection', function(ws){ | ||
| var cid = uuid.v4().replace(/-/g, ''), | ||
| protocol = ws.protocol, | ||
| guard = Guard(timeout * 60 * 1000); | ||
| initActivitys : function(actPath){ | ||
| var acts = this.addLocalModules(actPath); | ||
| for(var k in acts){ | ||
| var actMod = require(acts[k].file); | ||
| if(actMod.init){ | ||
| actMod.init(this.track, this.mods, proxyObj); | ||
| } | ||
| } | ||
| }, | ||
| initMods : function(){ | ||
| var self = this, | ||
| defer = when.defer(); | ||
| this.addMods(this.addLocalModules(this.opts.modPath)); | ||
| var _mods = this._mods, | ||
| modsKeys = Object.keys(_mods), | ||
| modsValues = [], | ||
| mods = {}; | ||
| for(var name in _mods){ | ||
| modsValues.push(_mods[name]); | ||
| } | ||
| self.clients[cid] = ws; | ||
| ws.on('message', function(message) { | ||
| if(msgParse){ | ||
| message = msgParse(message, protocol); | ||
| when.settle(modsValues).then(function(pmods){ | ||
| for(var i = 0, l = pmods.length; i < l; i++){ | ||
| var mod = pmods[i]; | ||
| if(mod.state === 'fulfilled'){ | ||
| mods[modsKeys[i]] = mod.value; | ||
| } else if(mod.state === 'rejected'){ | ||
| exit(mod.reason); | ||
| } | ||
| self.emit('message', { | ||
| cid : cid, | ||
| msg : message | ||
| }); | ||
| guard.reset(); | ||
| }); | ||
| ws.on('close', function() { | ||
| self.clients[cid] = null; | ||
| guard.stop(); | ||
| ws.guard = null; | ||
| self.emit('clientClose', cid); | ||
| }); | ||
| guard.then(function(){ | ||
| ws.close(); | ||
| }); | ||
| ws.guard = guard; | ||
| self.emit('connection', cid); | ||
| if(i == l - 1){ | ||
| self.mods = mods; | ||
| defer.resolve(); | ||
| } | ||
| } | ||
| }); | ||
| this.wss = wss; | ||
| this.handles(); | ||
| return defer.promise; | ||
| }, | ||
| sendTo : function(cids, msg){ | ||
| cids = util.isArray(cids) ? cids : [cids]; | ||
| for(var i = 0, l = cids.length; i < l; i++){ | ||
| var client = this.clients[cids[i]]; | ||
| client && client.send(msg); | ||
| } | ||
| startTrack : function(port, opts){ | ||
| var track = new Track(port, opts); | ||
| this.track = track; | ||
| track.start(); | ||
| }, | ||
| broadcast : function(msg) { | ||
| var clientIds = Object.keys(this.clients); | ||
| this.sendTo(clientIds, msg); | ||
| run : function(port, opts){ | ||
| var self = this; | ||
| return this.initMods().then(function(){ | ||
| self.startTrack(port, opts); | ||
| self.initActivitys(self.opts.actpath); | ||
| return { | ||
| track : self.track, | ||
| mods : self.mods, | ||
| proxy : proxyObj | ||
| } | ||
| }); | ||
| }, | ||
| close : function(cid, code, data){ | ||
| var client = this.clients[cid]; | ||
| client && client.close(code, data); | ||
| }, | ||
| stop : function(){ | ||
| var cids = Object.keys(this.clients); | ||
| for(var i = 0, l = cids.length; i < l; i++){ | ||
| var client = this.clients[cids[i]]; | ||
| client && client.close(); | ||
| } | ||
| this.wss.close(); | ||
| this.wss = null; | ||
| this.mods = null; | ||
| this.track.stop(); | ||
| } | ||
| }); | ||
| Elon.JSONRPC2_ERROR_CODES = JsonRPc.ERROR_CODES; | ||
| Elon.utils = utils; | ||
| Elon.Track = Track; | ||
| Elon.Musk = Musk; | ||
| module.exports = Elon; |
+6
-3
| { | ||
| "name": "elon", | ||
| "version": "0.0.0", | ||
| "description": "", | ||
| "version": "0.0.1", | ||
| "description": "A websocket game srv", | ||
| "main": "lib/index.js", | ||
@@ -17,3 +17,5 @@ "scripts": { | ||
| "ws": "~0.4.31", | ||
| "when": "~3.0.1", | ||
| "uuid": "~1.4.1", | ||
| "musk" : ">0.0.2", | ||
| "jr2-helper": "" | ||
@@ -23,3 +25,4 @@ }, | ||
| "url": "https://github.com/ivershuo/elon/issues" | ||
| } | ||
| }, | ||
| "homepage": "https://github.com/ivershuo/elon" | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
No website
QualityPackage does not have a website.
8513
97.06%4
33.33%325
91.18%2
-33.33%5
66.67%4
Infinity%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added