mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-06-06 20:55:30 +02:00
Added ERC Module
This commit is contained in:
parent
b6cada6f3c
commit
be6af161ec
4 changed files with 318 additions and 58 deletions
|
@ -34,7 +34,7 @@ var _ = require('lodash');
|
||||||
//
|
//
|
||||||
// Editors - BBS
|
// Editors - BBS
|
||||||
// * https://github.com/M-griffin/Enthral/blob/master/src/msg_fse.cpp
|
// * https://github.com/M-griffin/Enthral/blob/master/src/msg_fse.cpp
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// Editors - Other
|
// Editors - Other
|
||||||
// * http://joe-editor.sourceforge.net/
|
// * http://joe-editor.sourceforge.net/
|
||||||
|
@ -55,12 +55,12 @@ var _ = require('lodash');
|
||||||
|
|
||||||
//
|
//
|
||||||
// To-Do
|
// To-Do
|
||||||
//
|
//
|
||||||
// * Index pos % for emit scroll events
|
// * Index pos % for emit scroll events
|
||||||
// * Some of this shoudl be async'd where there is lots of processing (e.g. word wrap)
|
// * Some of this shoudl be async'd where there is lots of processing (e.g. word wrap)
|
||||||
// * Fix backspace when col=0 (e.g. bs to prev line)
|
// * Fix backspace when col=0 (e.g. bs to prev line)
|
||||||
// * Add back word delete
|
// * Add back word delete
|
||||||
// *
|
// *
|
||||||
|
|
||||||
|
|
||||||
var SPECIAL_KEY_MAP_DEFAULT = {
|
var SPECIAL_KEY_MAP_DEFAULT = {
|
||||||
|
@ -114,6 +114,11 @@ function MultiLineEditTextView(options) {
|
||||||
this.topVisibleIndex = 0;
|
this.topVisibleIndex = 0;
|
||||||
this.mode = options.mode || 'edit'; // edit | preview | read-only
|
this.mode = options.mode || 'edit'; // edit | preview | read-only
|
||||||
|
|
||||||
|
if (this.mode == 'edit') {
|
||||||
|
this.autoScroll = options.autoScroll || 'true';
|
||||||
|
} else {
|
||||||
|
this.autoScroll = options.autoScroll || 'false';
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// cursorPos represents zero-based row, col positions
|
// cursorPos represents zero-based row, col positions
|
||||||
// within the editor itself
|
// within the editor itself
|
||||||
|
@ -179,7 +184,7 @@ function MultiLineEditTextView(options) {
|
||||||
|
|
||||||
this.eraseRows = function(startRow, endRow) {
|
this.eraseRows = function(startRow, endRow) {
|
||||||
self.client.term.rawWrite(self.getSGRFor('text') + ansi.hideCursor());
|
self.client.term.rawWrite(self.getSGRFor('text') + ansi.hideCursor());
|
||||||
|
|
||||||
var absPos = self.getAbsolutePosition(startRow, 0);
|
var absPos = self.getAbsolutePosition(startRow, 0);
|
||||||
var absPosEnd = self.getAbsolutePosition(endRow, 0);
|
var absPosEnd = self.getAbsolutePosition(endRow, 0);
|
||||||
var eraseFiller = new Array(self.dimens.width).join(' ');
|
var eraseFiller = new Array(self.dimens.width).join(' ');
|
||||||
|
@ -216,7 +221,7 @@ function MultiLineEditTextView(options) {
|
||||||
if(!_.isNumber(index)) {
|
if(!_.isNumber(index)) {
|
||||||
index = self.getTextLinesIndex();
|
index = self.getTextLinesIndex();
|
||||||
}
|
}
|
||||||
return self.textLines[index].text.replace(/\t/g, ' ');
|
return self.textLines[index].text.replace(/\t/g, ' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getText = function(index) {
|
this.getText = function(index) {
|
||||||
|
@ -266,19 +271,19 @@ function MultiLineEditTextView(options) {
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getOutputText = function(startIndex, endIndex, eolMarker) {
|
this.getOutputText = function(startIndex, endIndex, eolMarker) {
|
||||||
let lines = self.getTextLines(startIndex, endIndex);
|
let lines = self.getTextLines(startIndex, endIndex);
|
||||||
let text = '';
|
let text = '';
|
||||||
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
|
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
|
||||||
|
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
text += line.text.replace(re, '\t');
|
text += line.text.replace(re, '\t');
|
||||||
if(eolMarker && line.eol) {
|
if(eolMarker && line.eol) {
|
||||||
text += eolMarker;
|
text += eolMarker;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +307,7 @@ function MultiLineEditTextView(options) {
|
||||||
/*
|
/*
|
||||||
this.editTextAtPosition = function(editAction, text, index, col) {
|
this.editTextAtPosition = function(editAction, text, index, col) {
|
||||||
switch(editAction) {
|
switch(editAction) {
|
||||||
case 'insert' :
|
case 'insert' :
|
||||||
self.insertCharactersInText(text, index, col);
|
self.insertCharactersInText(text, index, col);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -329,7 +334,7 @@ function MultiLineEditTextView(options) {
|
||||||
newLines[newLines.length - 1].eol = true;
|
newLines[newLines.length - 1].eol = true;
|
||||||
|
|
||||||
Array.prototype.splice.apply(
|
Array.prototype.splice.apply(
|
||||||
self.textLines,
|
self.textLines,
|
||||||
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
||||||
|
|
||||||
return wrapped.firstWrapRange;
|
return wrapped.firstWrapRange;
|
||||||
|
@ -337,7 +342,7 @@ function MultiLineEditTextView(options) {
|
||||||
|
|
||||||
this.removeCharactersFromText = function(index, col, operation, count) {
|
this.removeCharactersFromText = function(index, col, operation, count) {
|
||||||
if('right' === operation) {
|
if('right' === operation) {
|
||||||
self.textLines[index].text =
|
self.textLines[index].text =
|
||||||
self.textLines[index].text.slice(col, count) +
|
self.textLines[index].text.slice(col, count) +
|
||||||
self.textLines[index].text.slice(col + count);
|
self.textLines[index].text.slice(col + count);
|
||||||
|
|
||||||
|
@ -354,11 +359,11 @@ function MultiLineEditTextView(options) {
|
||||||
} else if ('backspace' === operation) {
|
} else if ('backspace' === operation) {
|
||||||
// :TODO: method for splicing text
|
// :TODO: method for splicing text
|
||||||
self.textLines[index].text =
|
self.textLines[index].text =
|
||||||
self.textLines[index].text.slice(0, col - (count - 1)) +
|
self.textLines[index].text.slice(0, col - (count - 1)) +
|
||||||
self.textLines[index].text.slice(col + 1);
|
self.textLines[index].text.slice(col + 1);
|
||||||
|
|
||||||
self.cursorPos.col -= (count - 1);
|
self.cursorPos.col -= (count - 1);
|
||||||
|
|
||||||
self.updateTextWordWrap(index);
|
self.updateTextWordWrap(index);
|
||||||
self.redrawRows(self.cursorPos.row, self.dimens.height);
|
self.redrawRows(self.cursorPos.row, self.dimens.height);
|
||||||
|
|
||||||
|
@ -405,9 +410,9 @@ function MultiLineEditTextView(options) {
|
||||||
|
|
||||||
this.insertCharactersInText = function(c, index, col) {
|
this.insertCharactersInText = function(c, index, col) {
|
||||||
self.textLines[index].text = [
|
self.textLines[index].text = [
|
||||||
self.textLines[index].text.slice(0, col),
|
self.textLines[index].text.slice(0, col),
|
||||||
c,
|
c,
|
||||||
self.textLines[index].text.slice(col)
|
self.textLines[index].text.slice(col)
|
||||||
].join('');
|
].join('');
|
||||||
|
|
||||||
//self.cursorPos.col++;
|
//self.cursorPos.col++;
|
||||||
|
@ -443,13 +448,13 @@ function MultiLineEditTextView(options) {
|
||||||
//
|
//
|
||||||
absPos = self.getAbsolutePosition(self.cursorPos.row, self.cursorPos.col);
|
absPos = self.getAbsolutePosition(self.cursorPos.row, self.cursorPos.col);
|
||||||
self.client.term.write(
|
self.client.term.write(
|
||||||
ansi.hideCursor() +
|
ansi.hideCursor() +
|
||||||
self.getSGRFor('text') +
|
self.getSGRFor('text') +
|
||||||
self.getRenderText(index).slice(self.cursorPos.col - c.length) +
|
self.getRenderText(index).slice(self.cursorPos.col - c.length) +
|
||||||
ansi.goto(absPos.row, absPos.col) +
|
ansi.goto(absPos.row, absPos.col) +
|
||||||
ansi.showCursor(), false
|
ansi.showCursor(), false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getRemainingTabWidth = function(col) {
|
this.getRemainingTabWidth = function(col) {
|
||||||
|
@ -541,7 +546,7 @@ function MultiLineEditTextView(options) {
|
||||||
.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g);
|
.split(/\r\n|[\n\v\f\r\x85\u2028\u2029]/g);
|
||||||
|
|
||||||
var wrapped;
|
var wrapped;
|
||||||
|
|
||||||
for(var i = 0; i < text.length; ++i) {
|
for(var i = 0; i < text.length; ++i) {
|
||||||
wrapped = self.wordWrapSingleLine(
|
wrapped = self.wordWrapSingleLine(
|
||||||
text[i], // input
|
text[i], // input
|
||||||
|
@ -556,7 +561,7 @@ function MultiLineEditTextView(options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getAbsolutePosition = function(row, col) {
|
this.getAbsolutePosition = function(row, col) {
|
||||||
return {
|
return {
|
||||||
row : self.position.row + row,
|
row : self.position.row + row,
|
||||||
col : self.position.col + col,
|
col : self.position.col + col,
|
||||||
};
|
};
|
||||||
|
@ -610,7 +615,7 @@ function MultiLineEditTextView(options) {
|
||||||
|
|
||||||
this.keyPressDown = function() {
|
this.keyPressDown = function() {
|
||||||
var lastVisibleRow = Math.min(
|
var lastVisibleRow = Math.min(
|
||||||
self.dimens.height,
|
self.dimens.height,
|
||||||
(self.textLines.length - self.topVisibleIndex)) - 1;
|
(self.textLines.length - self.topVisibleIndex)) - 1;
|
||||||
|
|
||||||
if(self.cursorPos.row < lastVisibleRow) {
|
if(self.cursorPos.row < lastVisibleRow) {
|
||||||
|
@ -714,7 +719,7 @@ function MultiLineEditTextView(options) {
|
||||||
var nextEolIndex = self.getNextEndOfLineIndex(index);
|
var nextEolIndex = self.getNextEndOfLineIndex(index);
|
||||||
var text = self.getContiguousText(index, nextEolIndex);
|
var text = self.getContiguousText(index, nextEolIndex);
|
||||||
var newLines = self.wordWrapSingleLine(text.slice(self.cursorPos.col), 'tabsIntact').wrapped;
|
var newLines = self.wordWrapSingleLine(text.slice(self.cursorPos.col), 'tabsIntact').wrapped;
|
||||||
|
|
||||||
newLines.unshift( { text : text.slice(0, self.cursorPos.col), eol : true } );
|
newLines.unshift( { text : text.slice(0, self.cursorPos.col), eol : true } );
|
||||||
for(var i = 1; i < newLines.length; ++i) {
|
for(var i = 1; i < newLines.length; ++i) {
|
||||||
newLines[i] = { text : newLines[i] };
|
newLines[i] = { text : newLines[i] };
|
||||||
|
@ -722,7 +727,7 @@ function MultiLineEditTextView(options) {
|
||||||
newLines[newLines.length - 1].eol = true;
|
newLines[newLines.length - 1].eol = true;
|
||||||
|
|
||||||
Array.prototype.splice.apply(
|
Array.prototype.splice.apply(
|
||||||
self.textLines,
|
self.textLines,
|
||||||
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
[ index, (nextEolIndex - index) + 1 ].concat(newLines));
|
||||||
|
|
||||||
// redraw from current row to end of visible area
|
// redraw from current row to end of visible area
|
||||||
|
@ -844,9 +849,9 @@ function MultiLineEditTextView(options) {
|
||||||
self.client.term.rawWrite(ansi.left(move));
|
self.client.term.rawWrite(ansi.left(move));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'up' :
|
case 'up' :
|
||||||
case 'down' :
|
case 'down' :
|
||||||
//
|
//
|
||||||
// Jump to the tabstop nearest the cursor
|
// Jump to the tabstop nearest the cursor
|
||||||
//
|
//
|
||||||
var newCol = self.tabStops.reduce(function r(prev, curr) {
|
var newCol = self.tabStops.reduce(function r(prev, curr) {
|
||||||
|
@ -890,7 +895,7 @@ function MultiLineEditTextView(options) {
|
||||||
this.cursorBeginOfNextLine = function() {
|
this.cursorBeginOfNextLine = function() {
|
||||||
// e.g. when scrolling right past eol
|
// e.g. when scrolling right past eol
|
||||||
var linesBelow = self.getRemainingLinesBelowRow();
|
var linesBelow = self.getRemainingLinesBelowRow();
|
||||||
|
|
||||||
if(linesBelow > 0) {
|
if(linesBelow > 0) {
|
||||||
var lastVisibleRow = Math.min(self.dimens.height, self.textLines.length) - 1;
|
var lastVisibleRow = Math.min(self.dimens.height, self.textLines.length) - 1;
|
||||||
if(self.cursorPos.row < lastVisibleRow) {
|
if(self.cursorPos.row < lastVisibleRow) {
|
||||||
|
@ -1007,9 +1012,9 @@ MultiLineEditTextView.prototype.setText = function(text) {
|
||||||
MultiLineEditTextView.prototype.addText = function(text) {
|
MultiLineEditTextView.prototype.addText = function(text) {
|
||||||
this.insertRawText(text);
|
this.insertRawText(text);
|
||||||
|
|
||||||
if(this.isEditMode()) {
|
if(this.autoScroll) {
|
||||||
this.cursorEndOfDocument();
|
this.cursorEndOfDocument();
|
||||||
} else if(this.isPreviewMode()) {
|
} else {
|
||||||
this.cursorStartOfDocument();
|
this.cursorStartOfDocument();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1027,7 +1032,7 @@ MultiLineEditTextView.prototype.setPropertyValue = function(propName, value) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var HANDLED_SPECIAL_KEYS = [
|
var HANDLED_SPECIAL_KEYS = [
|
||||||
'up', 'down', 'left', 'right',
|
'up', 'down', 'left', 'right',
|
||||||
'home', 'end',
|
'home', 'end',
|
||||||
'page up', 'page down',
|
'page up', 'page down',
|
||||||
'line feed',
|
'line feed',
|
||||||
|
@ -1045,7 +1050,7 @@ MultiLineEditTextView.prototype.onKeyPress = function(ch, key) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var handled;
|
var handled;
|
||||||
|
|
||||||
if(key) {
|
if(key) {
|
||||||
HANDLED_SPECIAL_KEYS.forEach(function aKey(specialKey) {
|
HANDLED_SPECIAL_KEYS.forEach(function aKey(specialKey) {
|
||||||
if(self.isKeyMapped(specialKey, key.name)) {
|
if(self.isKeyMapped(specialKey, key.name)) {
|
||||||
|
|
||||||
|
@ -1068,6 +1073,22 @@ MultiLineEditTextView.prototype.onKeyPress = function(ch, key) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MultiLineEditTextView.prototype.scrollUp = function() {
|
||||||
|
this.scrollDocumentUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiLineEditTextView.prototype.scrollDown = function() {
|
||||||
|
this.scrollDocumentDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiLineEditTextView.prototype.deleteLine = function(line) {
|
||||||
|
this.textLines.splice(line, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiLineEditTextView.prototype.getLineCount = function() {
|
||||||
|
return this.textLines.length;
|
||||||
|
}
|
||||||
|
|
||||||
MultiLineEditTextView.prototype.getTextEditMode = function() {
|
MultiLineEditTextView.prototype.getTextEditMode = function() {
|
||||||
return this.overtypeMode ? 'overtype' : 'insert';
|
return this.overtypeMode ? 'overtype' : 'insert';
|
||||||
};
|
};
|
||||||
|
@ -1075,11 +1096,10 @@ MultiLineEditTextView.prototype.getTextEditMode = function() {
|
||||||
MultiLineEditTextView.prototype.getEditPosition = function() {
|
MultiLineEditTextView.prototype.getEditPosition = function() {
|
||||||
var currentIndex = this.getTextLinesIndex() + 1;
|
var currentIndex = this.getTextLinesIndex() + 1;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
row : this.getTextLinesIndex(this.cursorPos.row),
|
row : this.getTextLinesIndex(this.cursorPos.row),
|
||||||
col : this.cursorPos.col,
|
col : this.cursorPos.col,
|
||||||
percent : Math.floor(((currentIndex / this.textLines.length) * 100)),
|
percent : Math.floor(((currentIndex / this.textLines.length) * 100)),
|
||||||
below : this.getRemainingLinesBelowRow(),
|
below : this.getRemainingLinesBelowRow(),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
BIN
mods/art/erc.ans
Normal file
BIN
mods/art/erc.ans
Normal file
Binary file not shown.
184
mods/erc_client.js
Normal file
184
mods/erc_client.js
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
/* jslint node: true */
|
||||||
|
'use strict';
|
||||||
|
var MenuModule = require('../core/menu_module.js').MenuModule;
|
||||||
|
|
||||||
|
const async = require('async');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const net = require('net');
|
||||||
|
|
||||||
|
const packageJson = require('../package.json');
|
||||||
|
|
||||||
|
/*
|
||||||
|
Expected configuration block:
|
||||||
|
|
||||||
|
ercClient: {
|
||||||
|
art: erc
|
||||||
|
module: erc_client
|
||||||
|
config: {
|
||||||
|
host: 192.168.1.171
|
||||||
|
port: 5001
|
||||||
|
bbsTag: SUPER
|
||||||
|
}
|
||||||
|
|
||||||
|
form: {
|
||||||
|
0: {
|
||||||
|
mci: {
|
||||||
|
MT1: {
|
||||||
|
width: 79
|
||||||
|
height: 21
|
||||||
|
mode: preview
|
||||||
|
autoScroll: true
|
||||||
|
}
|
||||||
|
ET3: {
|
||||||
|
autoScale: false
|
||||||
|
width: 77
|
||||||
|
argName: chattxt
|
||||||
|
focus: true
|
||||||
|
submit: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submit: {
|
||||||
|
*: [
|
||||||
|
{
|
||||||
|
value: { chattxt: null }
|
||||||
|
action: @method:processInput
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
actionKeys: [
|
||||||
|
{
|
||||||
|
keys: [ "tab" ]
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keys: [ "up arrow" ]
|
||||||
|
action: @method:scrollDown
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keys: [ "down arrow" ]
|
||||||
|
action: @method:scrollUp
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
function ErcClientModule(options) {
|
||||||
|
MenuModule.call(this, options);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
this.config = options.menuConfig.config;
|
||||||
|
this.chatConnection = null;
|
||||||
|
this.finishedLoading = function() {
|
||||||
|
async.series(
|
||||||
|
[
|
||||||
|
function validateConfig(callback) {
|
||||||
|
if(_.isString(self.config.host) &&
|
||||||
|
_.isNumber(self.config.port) &&
|
||||||
|
_.isString(self.config.bbsTag))
|
||||||
|
{
|
||||||
|
callback(null);
|
||||||
|
} else {
|
||||||
|
callback(new Error('Configuration is missing required option(s)'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function connectToServer(callback) {
|
||||||
|
const connectOpts = {
|
||||||
|
port : self.config.port,
|
||||||
|
host : self.config.host,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var chatMessageView = self.viewControllers.menu.getView(MciViewIds.chatDisplay);
|
||||||
|
chatMessageView.setText("Connecting to server...");
|
||||||
|
chatMessageView.redraw();
|
||||||
|
self.viewControllers.menu.switchFocus(MciViewIds.inputArea);
|
||||||
|
self.chatConnection = net.createConnection(connectOpts.port, connectOpts.host);
|
||||||
|
|
||||||
|
self.chatConnection.on('data', data => {
|
||||||
|
var chatMessageView = self.viewControllers.menu.getView(MciViewIds.chatDisplay);
|
||||||
|
|
||||||
|
if (data.toString().substring(0, 12) == "ERCHANDSHAKE") {
|
||||||
|
self.chatConnection.write("ERCMAGIC|" + self.config.bbsTag + "|" + self.client.user.username + "\r\n");
|
||||||
|
} else {
|
||||||
|
chatMessageView.addText(data.toString());
|
||||||
|
if (chatMessageView.getLineCount() > 30) {
|
||||||
|
chatMessageView.deleteLine(0);
|
||||||
|
chatMessageView.scrollDown();
|
||||||
|
}
|
||||||
|
chatMessageView.redraw();
|
||||||
|
self.viewControllers.menu.switchFocus(MciViewIds.inputArea);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.chatConnection.once('end', () => {
|
||||||
|
return callback(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.chatConnection.once('error', err => {
|
||||||
|
self.client.log.info(`Telnet bridge connection error: ${err.message}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
err => {
|
||||||
|
if(err) {
|
||||||
|
self.client.log.warn( { error : err.message }, 'Telnet connection error');
|
||||||
|
}
|
||||||
|
|
||||||
|
self.prevMenu();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.menuMethods = {
|
||||||
|
processInput : function(data, cb) {
|
||||||
|
let chatInput = self.viewControllers.menu.getView(MciViewIds.inputArea);
|
||||||
|
let chatData = chatInput.getData();
|
||||||
|
if (chatData[0] === '/') {
|
||||||
|
if (chatData[1] === 'q' || chatInput[1] === 'Q') {
|
||||||
|
self.chatConnection.end();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.chatConnection.write(chatData + "\r\n");
|
||||||
|
chatInput.clearText();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
scrollUp : function(data, cb) {
|
||||||
|
let chatInput = self.viewControllers.menu.getView(MciViewIds.inputArea);
|
||||||
|
let chatMessageView = self.viewControllers.menu.getView(MciViewIds.chatDisplay);
|
||||||
|
chatMessageView.scrollUp();
|
||||||
|
chatMessageView.redraw();
|
||||||
|
chatInput.setFocus(true);
|
||||||
|
},
|
||||||
|
scrollDown : function(data, cb) {
|
||||||
|
let chatInput = self.viewControllers.menu.getView(MciViewIds.inputArea);
|
||||||
|
let chatMessageView = self.viewControllers.menu.getView(MciViewIds.chatDisplay);
|
||||||
|
chatMessageView.scrollDown();
|
||||||
|
chatMessageView.redraw();
|
||||||
|
chatInput.setFocus(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
require('util').inherits(ErcClientModule, MenuModule);
|
||||||
|
|
||||||
|
ErcClientModule.prototype.mciReady = function(mciData, cb) {
|
||||||
|
this.standardMCIReadyHandler(mciData, cb);
|
||||||
|
};
|
102
mods/menu.hjson
102
mods/menu.hjson
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
ENiGMA½ Menu Configuration
|
ENiGMA½ Menu Configuration
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// Another SSH specialization: If the user logs in with a new user
|
// Another SSH specialization: If the user logs in with a new user
|
||||||
// name (e.g. "new", "apply", ...) they will be directed to the
|
// name (e.g. "new", "apply", ...) they will be directed to the
|
||||||
// application process.
|
// application process.
|
||||||
//
|
//
|
||||||
sshConnectedNewUser: {
|
sshConnectedNewUser: {
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logoff: {
|
logoff: {
|
||||||
art: LOGOFF
|
art: LOGOFF
|
||||||
desc: Logging Off
|
desc: Logging Off
|
||||||
next: @systemMethod:logoff
|
next: @systemMethod:logoff
|
||||||
|
@ -264,7 +264,7 @@
|
||||||
action: @systemMethod:prevMenu
|
action: @systemMethod:prevMenu
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@
|
||||||
action: @systemMethod:prevMenu
|
action: @systemMethod:prevMenu
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,10 +375,10 @@
|
||||||
status: Feedback to SysOp
|
status: Feedback to SysOp
|
||||||
module: msg_area_post_fse
|
module: msg_area_post_fse
|
||||||
next: [
|
next: [
|
||||||
{
|
{
|
||||||
acs: AS2
|
acs: AS2
|
||||||
next: fullLoginSequenceLoginArt
|
next: fullLoginSequenceLoginArt
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
next: newUserInactiveDone
|
next: newUserInactiveDone
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@
|
||||||
module: last_callers
|
module: last_callers
|
||||||
art: LASTCALL
|
art: LASTCALL
|
||||||
options: { pause: true }
|
options: { pause: true }
|
||||||
next: fullLoginSequenceWhosOnline
|
next: fullLoginSequenceWhosOnline
|
||||||
}
|
}
|
||||||
fullLoginSequenceWhosOnline: {
|
fullLoginSequenceWhosOnline: {
|
||||||
desc: Who's Online
|
desc: Who's Online
|
||||||
|
@ -644,6 +644,10 @@
|
||||||
value: { command: "K" }
|
value: { command: "K" }
|
||||||
action: @menu:mainMenuFeedbackToSysOp
|
action: @menu:mainMenuFeedbackToSysOp
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
value: { command: "CHAT"}
|
||||||
|
action: @menu:ercClient
|
||||||
|
}
|
||||||
{
|
{
|
||||||
value: 1
|
value: 1
|
||||||
action: @menu:mainMenu
|
action: @menu:mainMenu
|
||||||
|
@ -665,7 +669,7 @@
|
||||||
mainMenuUserStats: {
|
mainMenuUserStats: {
|
||||||
desc: User Stats
|
desc: User Stats
|
||||||
art: STATUS
|
art: STATUS
|
||||||
options: { pause: true }
|
options: { pause: true }
|
||||||
}
|
}
|
||||||
mainMenuSystemStats: {
|
mainMenuSystemStats: {
|
||||||
desc: System Stats
|
desc: System Stats
|
||||||
|
@ -907,6 +911,58 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ercClient: {
|
||||||
|
art: erc
|
||||||
|
module: erc_client
|
||||||
|
config: {
|
||||||
|
host: 192.168.1.171
|
||||||
|
port: 5001
|
||||||
|
bbsTag: SUPER
|
||||||
|
}
|
||||||
|
|
||||||
|
form: {
|
||||||
|
0: {
|
||||||
|
mci: {
|
||||||
|
MT1: {
|
||||||
|
width: 79
|
||||||
|
height: 21
|
||||||
|
mode: preview
|
||||||
|
autoScroll: true
|
||||||
|
}
|
||||||
|
ET3: {
|
||||||
|
autoScale: false
|
||||||
|
width: 77
|
||||||
|
argName: chattxt
|
||||||
|
focus: true
|
||||||
|
submit: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submit: {
|
||||||
|
*: [
|
||||||
|
{
|
||||||
|
value: { chattxt: null }
|
||||||
|
action: @method:processInput
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
actionKeys: [
|
||||||
|
{
|
||||||
|
keys: [ "tab" ]
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keys: [ "up arrow" ]
|
||||||
|
action: @method:scrollDown
|
||||||
|
}
|
||||||
|
{
|
||||||
|
keys: [ "down arrow" ]
|
||||||
|
action: @method:scrollUp
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
// Doors Menu
|
// Doors Menu
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
@ -948,12 +1004,12 @@
|
||||||
|
|
||||||
doorPimpWars: {
|
doorPimpWars: {
|
||||||
desc: Playing PimpWars
|
desc: Playing PimpWars
|
||||||
module: abracadabra
|
module: abracadabra
|
||||||
config: {
|
config: {
|
||||||
name: PimpWars
|
name: PimpWars
|
||||||
dropFileType: DORINFO
|
dropFileType: DORINFO
|
||||||
cmd: /home/nuskooler/DOS/scripts/pimpwars.sh
|
cmd: /home/nuskooler/DOS/scripts/pimpwars.sh
|
||||||
args: [
|
args: [
|
||||||
"{node}",
|
"{node}",
|
||||||
"{dropFile}",
|
"{dropFile}",
|
||||||
"{srvPort}",
|
"{srvPort}",
|
||||||
|
@ -966,12 +1022,12 @@
|
||||||
|
|
||||||
doorDarkLands: {
|
doorDarkLands: {
|
||||||
desc: Playing Dark Lands
|
desc: Playing Dark Lands
|
||||||
module: abracadabra
|
module: abracadabra
|
||||||
config: {
|
config: {
|
||||||
name: DARKLANDS
|
name: DARKLANDS
|
||||||
dropFileType: DOOR
|
dropFileType: DOOR
|
||||||
cmd: /home/nuskooler/dev/enigma-bbs/doors/darklands/start.sh
|
cmd: /home/nuskooler/dev/enigma-bbs/doors/darklands/start.sh
|
||||||
args: [
|
args: [
|
||||||
"{node}",
|
"{node}",
|
||||||
"{dropFile}",
|
"{dropFile}",
|
||||||
"{srvPort}",
|
"{srvPort}",
|
||||||
|
@ -981,7 +1037,7 @@
|
||||||
io: socket
|
io: socket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doorLORD: {
|
doorLORD: {
|
||||||
desc: Playing L.O.R.D.
|
desc: Playing L.O.R.D.
|
||||||
module: abracadabra
|
module: abracadabra
|
||||||
|
@ -1056,7 +1112,7 @@
|
||||||
{
|
{
|
||||||
value: 1
|
value: 1
|
||||||
action: @menu:messageArea
|
action: @menu:messageArea
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1300,7 @@
|
||||||
{
|
{
|
||||||
keys: [ "n", "shift + n" ]
|
keys: [ "n", "shift + n" ]
|
||||||
action: @method:nextMessage
|
action: @method:nextMessage
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
keys: [ "r", "shift + r" ]
|
keys: [ "r", "shift + r" ]
|
||||||
action: @method:replyMessage
|
action: @method:replyMessage
|
||||||
|
@ -1259,7 +1315,7 @@
|
||||||
{
|
{
|
||||||
keys: [ "?" ]
|
keys: [ "?" ]
|
||||||
action: @method:viewModeMenuHelp
|
action: @method:viewModeMenuHelp
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
keys: [ "down arrow", "up arrow", "page up", "page down" ]
|
keys: [ "down arrow", "up arrow", "page up", "page down" ]
|
||||||
action: @method:movementKeyPressed
|
action: @method:movementKeyPressed
|
||||||
|
@ -1295,7 +1351,7 @@
|
||||||
validate: @systemMethod:validateNonEmpty
|
validate: @systemMethod:validateNonEmpty
|
||||||
}
|
}
|
||||||
ET3: {
|
ET3: {
|
||||||
argName: subject
|
argName: subject
|
||||||
maxLength: 72
|
maxLength: 72
|
||||||
submit: true
|
submit: true
|
||||||
validate: @systemMethod:validateNonEmpty
|
validate: @systemMethod:validateNonEmpty
|
||||||
|
@ -1395,7 +1451,7 @@
|
||||||
width: 79
|
width: 79
|
||||||
height: 4
|
height: 4
|
||||||
argName: quote
|
argName: quote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
submit: {
|
submit: {
|
||||||
|
@ -1552,7 +1608,7 @@
|
||||||
"mci" : {
|
"mci" : {
|
||||||
"VM1" : {
|
"VM1" : {
|
||||||
"items" : [
|
"items" : [
|
||||||
"Single Line Text Editing Views",
|
"Single Line Text Editing Views",
|
||||||
"Spinner & Toggle Views",
|
"Spinner & Toggle Views",
|
||||||
"Mask Edit Views",
|
"Mask Edit Views",
|
||||||
"Multi Line Text Editor",
|
"Multi Line Text Editor",
|
||||||
|
@ -1735,7 +1791,7 @@
|
||||||
"form" : {
|
"form" : {
|
||||||
"0" : {
|
"0" : {
|
||||||
"BTMT" : {
|
"BTMT" : {
|
||||||
"mci" : {
|
"mci" : {
|
||||||
"MT1" : {
|
"MT1" : {
|
||||||
"width" : 70,
|
"width" : 70,
|
||||||
"height" : 17,
|
"height" : 17,
|
||||||
|
@ -2019,6 +2075,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue