diff --git a/README.md b/README.md index 96292c142..88c269a99 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ ENiGMA has been tested with many terminals. However, the following are suggested * [SyncTERM](http://syncterm.bbsdev.net/) * [EtherTerm](https://github.com/M-griffin/EtherTerm) * [NetRunner](http://mysticbbs.com/downloads.html) -* [MagiTerm](https://magickabbs.com/index.php/magiterm/) +* [MagiTerm](https://gitlab.com/magickabbs/MagiTerm) ## Some Boards * :skull: [Xibalba - ENiGMA WHQ](https://l33t.codes/xibalba-bbs) :skull: (**ssh://xibalba.l33t.codes:44511** or **telnet://xibalba.l33t.codes:44510**) diff --git a/core/config_default.js b/core/config_default.js index 266cd9f46..350e9aeac 100644 --- a/core/config_default.js +++ b/core/config_default.js @@ -409,6 +409,8 @@ module.exports = () => { enabled: false, serverHostname: 'mrc.bottomlessabyss.net', serverPort: 5000, + serverSslPort: 5001, + useSsl: false, retryDelay: 10000, multiplexerPort: 5000, }, diff --git a/core/goldmine.js b/core/goldmine.js index f086616ee..8259a0098 100644 --- a/core/goldmine.js +++ b/core/goldmine.js @@ -25,8 +25,8 @@ exports.getModule = class GoldmineModule extends MenuModule { this.setConfigWithExtraArgs(options); // http://goldminebbs.com/ - this.config.host = this.config.host || '165.232.153.209'; - this.config.rloginPort = this.config.rloginPort || 513; + this.config.host = this.config.host || 'goldminedoors.com'; + this.config.rloginPort = this.config.rloginPort || 2513; } initSequence() { diff --git a/core/mrc.js b/core/mrc.js index 11533dbd2..835e48bfe 100644 --- a/core/mrc.js +++ b/core/mrc.js @@ -47,7 +47,7 @@ const MciViewIds = { const helpText = ` |15General Chat|08: |03/|11rooms |08& |03/|11join |03 |08- |07List all or join a room -|03/|11pm |03 |08- |07Send a private message +|03/|11pm |03 |08- |07Send a private message |08(/t /tell /msg) ---- |03/|11whoon |08- |07Who's on what BBS |03/|11chatters |08- |07Who's in what room @@ -57,6 +57,7 @@ const helpText = ` |03/|11meetups |08- |07Info about MRC MeetUps |03/|11quote |08- |07Send raw command to server |03/|11help |08- |07Server-side commands help +|03/|11quit |08- |07Quit MRC |08(/q) --- |03/|11l33t |03 |08- |07l337 5p34k |03/|11kewl |03 |08- |07BBS KeWL SPeaK @@ -275,21 +276,7 @@ exports.getModule = class mrcModule extends MenuModule { const chatLogView = this.viewControllers.mrcChat.getView( MciViewIds.mrcChat.chatLog ); - const messageLength = stripMciColorCodes(msg).length; - const chatWidth = chatLogView.dimens.width; - let padAmount = 0; - let spaces = 2; - - if (messageLength > chatWidth) { - padAmount = chatWidth - (messageLength % chatWidth) - spaces; - } else { - padAmount = chatWidth - messageLength - spaces; - } - - if (padAmount < 0) padAmount = 0; - - const padding = ' |00' + ' '.repeat(padAmount); - chatLogView.addText(pipeToAnsi(msg + padding)); + chatLogView.addText(pipeToAnsi(msg)); if (chatLogView.getLineCount() > this.config.maxScrollbackLines) { chatLogView.deleteLine(0); @@ -380,7 +367,7 @@ exports.getModule = class mrcModule extends MenuModule { // Deliver PrivMsg else if ( - message.to_user.toLowerCase() == this.state.alias.toLowerCase() + message.to_user.toUpperCase() == this.state.alias.toUpperCase() ) { const currentTime = moment().format( this.client.currentTheme.helpers.getTimeFormat() @@ -437,11 +424,11 @@ exports.getModule = class mrcModule extends MenuModule { const messageFormat = this.config.messageFormat || - '|00|10<|02{fromUserName}|10>|00 |03{message}|00'; + '|00|10<|02{fromUserName}|10>|00 |03{message}'; const privateMessageFormat = this.config.outgoingPrivateMessageFormat || - '|00|10<|02{fromUserName}|10|14->|02{toUserName}>|00 |03{message}|00'; + '|00|10<|02{fromUserName}|10|14->|02{toUserName}>|00 |03{message}'; let formattedMessage = ''; if (to_user == undefined) { @@ -450,6 +437,14 @@ exports.getModule = class mrcModule extends MenuModule { } else { // pm formattedMessage = stringFormat(privateMessageFormat, textFormatObj); + + // Echo PrivMSG to chat log (the server does not echo it back) + const currentTime =moment().format( + this.client.currentTheme.helpers.getTimeFormat() + ); + this.addMessageToChatLog( + '|08' + currentTime + '|00 ' + formattedMessage + '|00' + ); } try { @@ -477,6 +472,9 @@ exports.getModule = class mrcModule extends MenuModule { cmd[0] = cmd[0].substr(1).toLowerCase(); switch (cmd[0]) { + case 't': + case 'tell': + case 'msg': case 'pm': const newmsg = cmd.slice(2).join(' '); this.processOutgoingMessage(newmsg, cmd[1]); @@ -562,6 +560,7 @@ exports.getModule = class mrcModule extends MenuModule { /** * Process known additional server commands directly */ + case 'afk': this.sendServerMessage(`AFK ${message.substr(5)}`); break; @@ -578,6 +577,10 @@ exports.getModule = class mrcModule extends MenuModule { this.sendServerMessage(`STATUS ${message.substr(8)}`); break; + case 'topics': + this.sendServerMessage(`TOPICS ${message.substr(8)}`); + break; + case 'lastseen': this.sendServerMessage(`LASTSEEN ${message.substr(10)}`); break; @@ -594,6 +597,31 @@ exports.getModule = class mrcModule extends MenuModule { this.sendServerMessage(cmd[0].toUpperCase()); break; + /** + * MRC Trust commands + */ + + case 'trust': + this.sendServerMessage(`TRUST ${message.substr(7)}`); + break; + + case 'register': + this.sendServerMessage(`REGISTER ${message.substr(10)}`); + break; + + case 'identify': + this.sendServerMessage(`IDENTIFY ${message.substr(10)}`); + break; + + case 'update': + this.sendServerMessage(`UPDATE ${message.substr(8)}`); + break; + + /** + * Local client commands + */ + + case 'q': case 'quit': return this.prevMenu(); @@ -621,6 +649,13 @@ exports.getModule = class mrcModule extends MenuModule { chatLogView.setText(''); } + /** + * MRC Server flood protection requires messages to be spaced in time + */ + msgDelay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + /** * Creates a json object, stringifies it and sends it to the MRC multiplexer */ @@ -657,21 +692,26 @@ exports.getModule = class mrcModule extends MenuModule { /** * Joins a room, unsurprisingly */ - joinRoom(room) { + async joinRoom(room) { // room names are displayed with a # but referred to without. confusing. room = room.replace(/^#/, ''); this.state.room = room; this.sendServerMessage(`NEWROOM:${this.state.room}:${room}`); + + await this.msgDelay(100); this.sendServerMessage('USERLIST'); } /** * Things that happen when a local user connects to the MRC multiplexer */ - clientConnect() { - this.sendServerMessage('MOTD'); + async clientConnect() { + this.sendHeartbeat(); + await this.msgDelay(100); + this.joinRoom('lobby'); + await this.msgDelay(100); + this.sendServerMessage('STATS'); - this.sendHeartbeat(); } }; diff --git a/core/servers/chat/mrc_multiplexer.js b/core/servers/chat/mrc_multiplexer.js index abdc64a41..c0d7827a8 100644 --- a/core/servers/chat/mrc_multiplexer.js +++ b/core/servers/chat/mrc_multiplexer.js @@ -15,8 +15,8 @@ const _ = require('lodash'); const os = require('os'); // MRC -const protocolVersion = '1.2.9'; -const lineDelimiter = new RegExp('\r\n|\r|\n'); // eslint-disable-line no-control-regex +const clientVersion = '1.3.1'; +const lineDelimiter = new RegExp('\r\n|\r|\n|\n\r'); // eslint-disable-line no-control-regex const ModuleInfo = (exports.moduleInfo = { name: 'MRC', @@ -35,12 +35,24 @@ exports.getModule = class MrcModule extends ServerModule { this.log = Log.child({ server: 'MRC' }); const config = Config(); - this.boardName = config.general.prettyBoardName || config.general.boardName; - this.mrcConnectOpts = { + this.boardName = config.general.boardName; + + // Use prettyBoardName only if non-default + if (config.general.prettyBoardName != '|08XXXXX') this.boardName = config.general.prettyBoardName; + + this.mrcConfig = { host: config.chatServers.mrc.serverHostname || 'mrc.bottomlessabyss.net', port: config.chatServers.mrc.serverPort || 5000, + sslport: config.chatServers.mrc.serverSslPort || 5001, retryDelay: config.chatServers.mrc.retryDelay || 10000, + useSsl: config.chatServers.mrc.useSsl || false, }; + + this.mrcConnectOpts = { + host: this.mrcConfig.host, + port: this.mrcConfig.port, + retryDelay: this.mrcConfig.retryDelay + } } _connectionHandler() { @@ -48,7 +60,7 @@ exports.getModule = class MrcModule extends ServerModule { const handshake = `${ this.boardName - }~${enigmaVersion}/${os.platform()}.${os.arch()}/${protocolVersion}`; + }~${enigmaVersion}/${os.platform()}.${os.arch()}/${clientVersion}`; this.log.debug({ handshake: handshake }, 'Handshaking with MRC server'); this.sendRaw(handshake); @@ -96,13 +108,27 @@ exports.getModule = class MrcModule extends ServerModule { connectToMrc() { const self = this; - // create connection to MRC server - this.mrcClient = net.createConnection( + if (this.mrcConfig.useSsl) { + this.mrcConnectOpts.port = this.mrcConfig.sslport; + } + + // Create connection + this.mrcSocket = net.createConnection( this.mrcConnectOpts, self._connectionHandler.bind(self) ); - this.mrcClient.requestedDisconnect = false; + this.mrcSocket.requestedDisconnect = false; + + // Check if we upgrade the connection to SSL + if (this.mrcConfig.useSsl) { + const tls = require('tls') + this.mrcSecureSocket = new tls.TLSSocket(this.mrcSocket, { isServer: false }); + this.mrcClient = this.mrcSecureSocket; + } + else { + this.mrcClient = this.mrcSocket; + } // do things when we get data from MRC central let buffer = new Buffer.from(''); @@ -219,8 +245,7 @@ exports.getModule = class MrcModule extends ServerModule { connectedSockets.forEach(client => { if ( message.to_user == '' || - // Fix PrivMSG delivery on case mismatch - message.to_user.toUpperCase() == client.username.toUpperCase() || + message.to_user == client.username.toUpperCase() || message.to_user == 'CLIENT' || message.from_user == client.username || message.to_user == 'NOTME' @@ -302,7 +327,7 @@ exports.getModule = class MrcModule extends ServerModule { * Takes an MRC message and parses it into something usable */ parseMessage(line) { - const [from_user, from_site, from_room, to_user, to_site, to_room, body] = + let [from_user, from_site, from_room, to_user, to_site, to_room, body] = line.split('~'); // const msg = line.split('~'); @@ -310,6 +335,10 @@ exports.getModule = class MrcModule extends ServerModule { // return; // } + // Make sure to_user and from_user are always uppercase + to_user = (to_user || '').toUpperCase(); + from_user = (from_user || '').toUpperCase(); + return { from_user, from_site, from_room, to_user, to_site, to_room, body }; } diff --git a/core/servers/login/websocket.js b/core/servers/login/websocket.js index de9e09aa9..5b2fec200 100644 --- a/core/servers/login/websocket.js +++ b/core/servers/login/websocket.js @@ -71,6 +71,25 @@ class WebSocketClient extends TelnetClient { })(ws); super(wsDuplex); + + Log.trace({ headers: req.headers }, 'WebSocket connection headers'); + + // + // If the config allows it, look for 'x-forwarded-proto' as "https" + // to override |isSecure| + // + if ( + true === _.get(Config(), 'loginServers.webSocket.proxied') && + 'https' === req.headers['x-forwarded-proto'] + ) { + Log.debug( + `Assuming secure connection due to X-Forwarded-Proto of "${req.headers['x-forwarded-proto']}"` + ); + this.proxied = true; + } else { + this.proxied = false; + } + wsDuplex.setClient(this, req); // fudge remoteAddress on socket, which is now TelnetSocket @@ -91,24 +110,6 @@ class WebSocketClient extends TelnetClient { ws.isConnectionAlive = true; }); - Log.trace({ headers: req.headers }, 'WebSocket connection headers'); - - // - // If the config allows it, look for 'x-forwarded-proto' as "https" - // to override |isSecure| - // - if ( - true === _.get(Config(), 'loginServers.webSocket.proxied') && - 'https' === req.headers['x-forwarded-proto'] - ) { - Log.debug( - `Assuming secure connection due to X-Forwarded-Proto of "${req.headers['x-forwarded-proto']}"` - ); - this.proxied = true; - } else { - this.proxied = false; - } - // start handshake process this.banner(); } diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 8176ae451..f611a3eee 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -77,22 +77,24 @@ GEM rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.4.0) minitest (5.19.0) - nokogiri (1.15.4-aarch64-linux) + nokogiri (1.16.5-aarch64-linux) racc (~> 1.4) - nokogiri (1.15.4-x86_64-linux) + nokogiri (1.16.5-x86_64-linux) racc (~> 1.4) pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (5.0.3) - racc (1.7.1) + racc (1.8.1) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rexml (3.2.6) + rexml (3.3.6) + strscan rouge (3.30.0) safe_yaml (1.0.5) sassc (2.4.0) ffi (~> 1.9) + strscan (3.1.0) terminal-table (2.0.0) unicode-display_width (~> 1.1, >= 1.1.1) tzinfo (2.0.6) diff --git a/docs/_docs/admin/administration.md b/docs/_docs/admin/administration.md index 8bd308df6..6f437cbc7 100644 --- a/docs/_docs/admin/administration.md +++ b/docs/_docs/admin/administration.md @@ -33,11 +33,16 @@ done ### Backup Tools There are many backup solutions available across all platforms. Configuration of such tools is outside the scope of this documentation. With that said, the author has had great success with [Borg](https://www.borgbackup.org/). -## General Maintenance Tasks +## General Maintenance +### Default Maintenance Tasks +Several default maintenance tasks are defined as events in `core/config_default.js`, in the section `eventScheduler`. These events run at various times and perform several maintenance tasks. An example is the `trimMessageAreas` event, which is run every 24 hours and defines that the action `trimMessageAreasScheduledEvent` is performed. + ### Vacuuming Database Files SQLite database files become less performant over time and waste space. It is recommended to periodically vacuum your databases. Before proceeding, you should make a backup! Example: ```bash -sqlite3 ./db/message.sqlite3 "vacuum;" +for dbfile in /path/to/enigma-bbs/db/*.sqlite3; do + sqlite3 ./db/message.sqlite3 "vacuum;" +done ``` diff --git a/docs/_docs/art/mci.md b/docs/_docs/art/mci.md index 15b7b6733..5a65de400 100644 --- a/docs/_docs/art/mci.md +++ b/docs/_docs/art/mci.md @@ -108,8 +108,8 @@ There are many predefined MCI codes that can be used anywhere on the system (pla | `NT` | Total *new* users *today* | | `NM` | Count of new messages **address to the current user** across all message areas in which they have access | | `NP` | Count of new private mail to the current user | -| `IA` | Indicator as to rather the current user is **available** or not. See also `getStatusAvailIndicators()` in [Themes](themes.md) | -| `IV` | Indicator as to rather the current user is **visible** or not. See also `getStatusVisibleIndicators()` in [Themes](themes.md) | +| `IA` | Indicator as to whether the current user is **available** or not. See also `getStatusAvailIndicators()` in [Themes](themes.md) | +| `IV` | Indicator as to whether the current user is **visible** or not. See also `getStatusVisibleIndicators()` in [Themes](themes.md) | | `PI` | Ingress bytes for the current process (since ENiGMA started up) | | `PE` | Egress bytes for the current process (since ENiGMA started up) | diff --git a/docs/_docs/configuration/acs.md b/docs/_docs/configuration/acs.md index d6014bdac..edc05550f 100644 --- a/docs/_docs/configuration/acs.md +++ b/docs/_docs/configuration/acs.md @@ -7,7 +7,7 @@ title: Access Condition System (ACS) ENiGMA½ uses an Access Condition System (ACS) that is both familiar to oldschool BBS operators and has it's own style. With ACS, SysOp's are able to control access to various areas of the system based on various conditions such as group membership, connection type, etc. Various touch points in the system are configured to allow for `acs` checks. In some cases ACS is a simple boolean check while others (via ACS blocks) allow to define what conditions must be true for certain _rights_ such as `read` and `write` (though others exist as well). ## Group Membership -ENiGMA½ does not utilize legacy "security levels" (see note below) but instead utilizes a group system. Users may be long to one or more groups which can be checked by the `GM` ACS (See [ACS Codes](#acs-codes) below). Two special groups exist out of the box: +ENiGMA½ does not utilize legacy "security levels" (see note below) but instead utilizes a group system. Users may belong to one or more groups which can be checked by the `GM` ACS (See [ACS Codes](#acs-codes) below). Two special groups exist out of the box: 1. `users`: Any regular user 2. `sysops`: System Operators. The first user (your root, or admin) will alwasy belong to this group. diff --git a/docs/_docs/installation/manual.md b/docs/_docs/installation/manual.md index 2b4c40b0e..fd60b8a88 100644 --- a/docs/_docs/installation/manual.md +++ b/docs/_docs/installation/manual.md @@ -22,21 +22,22 @@ are OK) for Windows users. Note that you **should only need the Visual C++ compo Node Version Manager (NVM) is an excellent way to install and manage Node.js versions on most UNIX-like environments. [Get the latest version here](https://github.com/creationix/nvm). The nvm install may look _something_ like this: ```bash -curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash ``` > :information_source: Do not cut+paste the above command! Visit the [NVM](https://github.com/creationix/nvm) page and run the latest version! Next, install Node.js with NVM: ```bash -nvm install 14 -nvm use 14 -nvm alias default 14 +nvm install 18 +nvm use 18 +nvm alias default 18 ``` If the above steps completed without errors, you should now have `nvm`, `node`, and `npm` installed and in your environment. For Windows nvm-like systems exist ([nvm-windows](https://github.com/coreybutler/nvm-windows), ...) or [just download the installer](https://nodejs.org/en/download/). +> :information_source: Please note that Node v18 is the latest release that is supported for ENiGMA BBS. Support for Node v20 is being worked on in [this Github issue](https://github.com/NuSkooler/enigma-bbs/issues/539). ## ENiGMA BBS ```bash @@ -48,6 +49,7 @@ git clone https://github.com/NuSkooler/enigma-bbs.git cd enigma-bbs npm install # yarn also works ``` +> :information_source: At the moment you might see a few warnings about packages being deprecated or replaced. This is a known issue that will be resolved in the future. ## Other Recommended Packages ENiGMA BBS makes use of a few packages for archive and legacy protocol support. They're not pre-requisites for running ENiGMA, but without them you'll miss certain functionality. Once installed, they should be made available on your systems `PATH`. diff --git a/docs/_docs/messageareas/configuring-a-message-area.md b/docs/_docs/messageareas/configuring-a-message-area.md index 2214e4373..336d64dd4 100644 --- a/docs/_docs/messageareas/configuring-a-message-area.md +++ b/docs/_docs/messageareas/configuring-a-message-area.md @@ -53,10 +53,14 @@ Message Areas are topic specific containers for messages that live within a part | `desc` | :+1: | Friendly area description. | | `sort` | :-1: | Set to a number to override the default alpha-numeric sort order based on the `name` field. | | `default` | :-1: | Specify `true` to make this the default area (e.g. assigned to new users) | -| `acs` | :-1: | A standard [ACS](../configuration/acs.md) block. See **ACS** below. | +| `acs` | :-1: | A standard [ACS](../configuration/acs.md) block. See **ACS** below. | +| `maxMessages` | :-1: | The maximum number of messages to keep in the area. Defaults to `1024`. | +| `maxAgeDays` | :-1: | The maximum age of messages to keep in the area. Defaults to `0`, which means unlimited. | | `autoSignatures` | :-1: | Set to `false` to disable auto-signatures in this area. | | `realNames` | :-1: | Set to `true` to use real names in this area. | +The default values for `maxMessages` and `maxAgeDays` can be changed globally in `core/config_default.js`, they're located in the section `messageAreaDefaults`. The same file also defines several default events to be scheduled, which are located under `eventScheduler`. For example, the `trimMessageAreas` event is run every 24 hours and defines that the action `trimMessageAreasScheduledEvent` is performed. + ### ACS An optional standard [ACS](../configuration/acs.md) block can be supplied with the following rules: * `read`: ACS required to read (see) this area. Defaults to `GM[users]`. @@ -74,6 +78,8 @@ messageConferences: { desc: ENiGMA 1/2 development and discussion! sort: 1 default: true + maxMessages: 2000 // keep at most 2000 messages + maxAgeDays: 365 // delete anything older than 1 year acs: { read: GM[users] // default write: GM[l33t] // super elite ENiGMA 1/2 users! diff --git a/docs/_docs/messageareas/netmail.md b/docs/_docs/messageareas/netmail.md index f43c2a4b1..dd8faedc8 100644 --- a/docs/_docs/messageareas/netmail.md +++ b/docs/_docs/messageareas/netmail.md @@ -2,11 +2,11 @@ layout: page title: Netmail --- -ENiGMA support import and export of Netmail from the Private Mail area. `RiPuk @ 21:1/136` and `RiPuk <21:1/136>` 'To' address formats are supported. +ENiGMA supports import and export of Netmail from the Private Mail area. `RiPuk @ 21:1/136` and `RiPuk <21:1/136>` 'To' address formats are supported. ## Netmail Routing -A configuration block must be added to the `scannerTossers::ftn_bso` `config.hjson` section to tell the ENiGMA½ tosser where to route NetMail. +A configuration block must be added to the `scannerTossers::ftn_bso` section in `config.hjson` to tell the ENiGMA½ tosser where to route NetMail. The following configuration would tell ENiGMA½ to route all netmail addressed to 21:* through 21:1/100, and all 46:* netmail through 46:1/100: diff --git a/docs/_docs/modding/wfc.md b/docs/_docs/modding/wfc.md index 11638d275..4b57ad5f7 100644 --- a/docs/_docs/modding/wfc.md +++ b/docs/_docs/modding/wfc.md @@ -60,11 +60,11 @@ The following MCI codes are available: * `text`: Username or `*Pre Auth*`. * `action`: Current action/menu. * `affils`: Any affiliations related to the if `authenticated`, else "N/A". - * `authenticated`: Boolean rather the node is authenticated (logged in) or not. + * `authenticated`: Boolean whether the node is authenticated (logged in) or not. * `availIndicator`: Indicator of availability (e.g. for messaging)? Displayed via `statusAvailableIndicators` or system theme. See also [Themes](../art/themes.md). - * `isAvailalbe`: Boolean rather the node is availalbe (e.g. for messaging) or not. + * `isAvailable`: Boolean whether the node is available (e.g. for messaging) or not. * `isSecure`: Is the node securely connected (ie: SSL)? - * `isVisible`: Boolean rather the node is visible to others or not. + * `isVisible`: Boolean whether the node is visible to others or not. * `node`: The node ID. * `realName`: Real name of authenticated user, or "N/A". * `serverName`: Name of connected server such as "Telnet" or "SSH". @@ -90,7 +90,7 @@ The following MCI codes are available: * `quickLogLevelMessagePrefixes`: A **map** of log level names (see above) to message prefixes. Commonly used for changing message color with pipe codes, such as `|04` for red errors. * `message`: Log message. * `MT3` or `ET3`: Selected node status information. May be a single or multi line view. - * Set `nodeStatusSelectionFormat` to the format desired including `\n` for line feeds in as `MT` view. The availalbe format keys are the same as the node status list above. + * Set `nodeStatusSelectionFormat` to the format desired including `\n` for line feeds in as `MT` view. The available format keys are the same as the node status list above. * MCI 10...99: Custom entries with the following format keys available: * `nowDate`: Current date in the `dateFormat` style, defaulting to `short`. * `nowTime`: Current time in the `timeFormat` style, defaulting to `short`. @@ -121,7 +121,7 @@ The following MCI codes are available: * `systemCurrentLoad`: System current load. * `newPrivateMail`: Number of new **private** mail for current user. * `newMessagesAddrTo`: Number of new messages **addressed to the current user**. - * `availIndicator`: Is the current user availalbe? Displayed via `statusAvailableIndicators` or system theme. See also [Themes](../art/themes.md). + * `availIndicator`: Is the current user available? Displayed via `statusAvailableIndicators` or system theme. See also [Themes](../art/themes.md). * `visIndicator`: Is the current user visible? Displayed via `statusVisibleIndicators` or system theme. See also [Themes](../art/themes.md). * `processBytesIngress`: Ingress bytes since ENiGMA started. * `processBytesEgress`: Egress bytes since ENiGMA started. diff --git a/docs/_docs/servers/loginservers/websocket.md b/docs/_docs/servers/loginservers/websocket.md index 511fb5221..52f69c3be 100644 --- a/docs/_docs/servers/loginservers/websocket.md +++ b/docs/_docs/servers/loginservers/websocket.md @@ -90,7 +90,7 @@ webserver, and unpack it to a temporary directory. xScale: 1, initStr: "", defPageAttr: 0x1010, - defCrsrAttr: 0x0207, + defCrsrAttr: ['thick', 'horizontal'], defCellAttr: 0x0007, telnet: 1, autoConnect: 0 diff --git a/misc/config_template.in.hjson b/misc/config_template.in.hjson index 07720a265..16b0c5176 100644 --- a/misc/config_template.in.hjson +++ b/misc/config_template.in.hjson @@ -335,9 +335,13 @@ // Make sure to adjust 'prettyBoardName' to your liking in your config before enabling mrc: { - enabled : false - serverHostname : 'mrc.bottomlessabyss.net' - serverPort : 5000 + enabled : false + serverHostname : 'mrc.bottomlessabyss.net' + serverPort : 5000 + serverSslPort : 5001 + useSsl : true + retryDelay : 10000 + multiplexerPort : 5000 } }