enigma-bbs/mods/erc_client.js

173 lines
4.3 KiB
JavaScript
Raw Normal View History

2016-06-27 07:29:17 +00:00
/* jslint node: true */
'use strict';
var MenuModule = require('../core/menu_module.js').MenuModule;
// deps
2016-06-27 07:29:17 +00:00
const async = require('async');
const _ = require('lodash');
const net = require('net');
/*
Expected configuration block example:
2016-06-27 07:29:17 +00:00
config: {
host: 192.168.1.171
port: 5001
bbsTag: SOME_TAG
2016-06-27 07:29:17 +00:00
}
2016-06-27 07:29:17 +00:00
*/
exports.getModule = ErcClientModule;
exports.moduleInfo = {
name : 'ENiGMA Relay Chat Client',
desc : 'Chat with other ENiGMA BBSes',
author : 'Andrew Pamment',
};
var MciViewIds = {
ChatDisplay : 1,
InputArea : 3,
2016-06-27 07:29:17 +00:00
};
function ErcClientModule(options) {
MenuModule.call(this, options);
const self = this;
this.config = options.menuConfig.config;
2016-06-27 07:29:17 +00:00
this.chatEntryFormat = this.config.chatEntryFormat || '[{bbsTag}] {userName}: {message}';
this.systemEntryFormat = this.config.systemEntryFormat || '[*SYSTEM*] {message}';
this.finishedLoading = function() {
async.waterfall(
2016-06-27 07:29:17 +00:00
[
function validateConfig(callback) {
if(_.isString(self.config.host) &&
_.isNumber(self.config.port) &&
_.isString(self.config.bbsTag))
{
return callback(null);
2016-06-27 07:29:17 +00:00
} else {
return callback(new Error('Configuration is missing required option(s)'));
2016-06-27 07:29:17 +00:00
}
},
function connectToServer(callback) {
const connectOpts = {
2016-06-27 07:29:17 +00:00
port : self.config.port,
host : self.config.host,
};
const chatMessageView = self.viewControllers.menu.getView(MciViewIds.ChatDisplay);
chatMessageView.setText('Connecting to server...');
2016-06-27 07:29:17 +00:00
chatMessageView.redraw();
self.viewControllers.menu.switchFocus(MciViewIds.InputArea);
2016-06-27 07:29:17 +00:00
self.chatConnection = net.createConnection(connectOpts.port, connectOpts.host);
self.chatConnection.on('data', data => {
data = data.toString();
if(data.startsWith('ERCHANDSHAKE')) {
self.chatConnection.write(`ERCMAGIC|${self.config.bbsTag}|${self.client.user.username}\r\n`);
} else if(data.startsWith('{')) {
try {
data = JSON.parse(data);
} catch(e) {
return self.client.log.warn( { error : e.message }, 'ERC: Error parsing ERC data from server');
}
2016-06-27 07:29:17 +00:00
let text;
try {
if(data.userName) {
// user message
text = self.chatEntryFormat.format(data);
} else {
// system message
text = self.systemEntryFormat.format(data);
}
} catch(e) {
return self.client.log.warn( { error : e.message }, 'ERC: chatEntryFormat error');
}
chatMessageView.addText(text);
if(chatMessageView.getLineCount() > 30) { // :TODO: should probably be ChatDisplay.height?
2016-06-27 07:29:17 +00:00
chatMessageView.deleteLine(0);
chatMessageView.scrollDown();
}
2016-06-27 07:29:17 +00:00
chatMessageView.redraw();
self.viewControllers.menu.switchFocus(MciViewIds.InputArea);
2016-06-27 07:29:17 +00:00
}
});
self.chatConnection.once('end', () => {
return callback(null);
});
self.chatConnection.once('error', err => {
self.client.log.info(`ERC connection error: ${err.message}`);
2016-06-27 07:29:17 +00:00
});
}
2016-06-27 07:29:17 +00:00
],
err => {
if(err) {
self.client.log.warn( { error : err.message }, 'ERC error');
2016-06-27 07:29:17 +00:00
}
self.prevMenu();
}
);
};
this.scrollHandler = function(keyName) {
const inputAreaView = self.viewControllers.menu.getView(MciViewIds.InputArea);
const chatDisplayView = self.viewControllers.menu.getView(MciViewIds.ChatDisplay);
if('up arrow' === keyName) {
chatDisplayView.scrollUp();
} else {
chatDisplayView.scrollDown();
}
chatDisplayView.redraw();
inputAreaView.setFocus(true);
};
2016-06-27 07:29:17 +00:00
this.menuMethods = {
inputAreaSubmit : function() {
const inputAreaView = self.viewControllers.menu.getView(MciViewIds.InputArea);
const inputData = inputAreaView.getData();
2016-06-27 07:29:17 +00:00
if('/quit' === inputData.toLowerCase()) {
self.chatConnection.end();
} else {
try {
self.chatConnection.write(`${inputData}\r\n`);
} catch(e) {
self.client.log.warn( { error : e.message }, 'ERC error');
}
inputAreaView.clearText();
}
},
scrollUp : function(formData) {
self.scrollHandler(formData.key.name);
},
scrollDown : function(formData) {
self.scrollHandler(formData.key.name);
}
};
2016-06-27 07:29:17 +00:00
}
require('util').inherits(ErcClientModule, MenuModule);
ErcClientModule.prototype.mciReady = function(mciData, cb) {
this.standardMCIReadyHandler(mciData, cb);
};