Skip to content
Snippets Groups Projects
Commit 38349d4b authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Merge branch 'master' into 'master'

MRC Enhancements: Server Stats & additional tweaks

See merge request !367
parents f25e8e59 e7cfa82b
No related branches found
No related tags found
2 merge requests!463MRC mods by Codefenix (2024-10-20),!367MRC Enhancements: Server Stats & additional tweaks
NHC@HOT@N@CLEAR@
4CK
C HYChat Menu N4K
CK0B
WB4 HWJoin a Chat NBWB
HCJY NCJoin/initiate multinode chatWB
HCPNC Join/start private node/node chatG B
HCCY NCChat with Sysop: HY@SYSAVAIL-L####@NG B
HCTY NCTalk with The Guru (AI)WB
HCFY NCFinger (query) remote user/systemW B
HCRY NCInternet Relay Chat (IRC)WB
HCIY NCInterBBS Instant MessagingWB
۲4 HWToggles NBIJ
HCD NCChat availabilityWCstate: HY@PAGER-L3@W NB
HCA NCNode activity alertsWCstate: HY@ALERTS-L3@NG B
HC SY NCSplit-screen chatWCstate:G HY@SPLITP-L3@N B
۲4 HWMRC Stats NBIJ
W HCM NCMulti-Relay ChatWCActivity:WB
4K 0WCBBSes:WCRooms:WCUsers:WH4C
NB۲IJ
HCQY NCQuit chat menuWB
4K C HYAnytime: C^UN4Csers online H^PN4Crivate msgH
N@EXEC:mrc-display-menu-stats@Z
\ No newline at end of file
// Chat Section for any/all Synchronet command shells
"use strict";
require("sbbsdefs.js", 'USER_EXPERT');
require("nodedefs.js", 'NODE_CHAT');
require("text.js", 'R_Chat');
// Over-ride these default values by creating/modifying the [chat] section in your ctrl/modopts.ini file
var options = load("modopts.js", "chat");
if (!options)
options = load("modopts.js", "chat_sec");
if (!options)
options = {};
if (options.irc === undefined)
options.irc = true;
var irc_servers = ["irc.synchro.net 6667"];
if (options.irc_server !== undefined)
irc_servers = options.irc_server.split(',');
var irc_channels = ["#Synchronet"];
if (options.irc_channel !== undefined)
irc_channels = options.irc_channel.split(',');
if (options.irc_seclevel === undefined)
options.irc_seclevel = 90;
if (options.finger === undefined)
options.finger = true;
if (options.imsg === undefined)
options.imsg = true;
for(var i in irc_servers)
irc_servers[i] = irc_servers[i].trim();
for(var i in irc_channels)
irc_channels[i] = irc_channels[i].trim();
if(user.security.restrictions & UFLAG_C) {
write(bbs.text(R_Chat));
exit(0);
}
function on_or_off(on)
{
return bbs.text(on ? On : Off);
}
// Set continue point for main menu commands
menu:
while(bbs.online && !console.aborted) {
var str="";
// Display TEXT\MENU\CHAT.* if not in expert mode
if(!(user.settings & USER_EXPERT)) {
bbs.menu("chat");
}
// Update node status
bbs.node_action = NODE_CHAT;
bbs.nodesync();
write(bbs.text(ChatPrompt));
var keys = "ACDJMPQST?\r"; // M added as a valid option for MRC
if(options.imsg && user.compare_ars(options.imsg_requirements))
keys += "I";
if(options.irc && user.compare_ars(options.irc_requirements))
keys += "R";
if(options.finger && user.compare_ars(options.finger_requirements))
keys += "F";
switch(console.getkeys(keys, K_UPPER)) {
case "S":
var val = user.chat_settings ^= CHAT_SPLITP;
write("\x01n\r\nPrivate split-screen chat is now: \x01h");
writeln(on_or_off(val & CHAT_SPLITP));
break;
case "A":
var val = user.chat_settings ^= CHAT_NOACT;
write("\x01n\r\nNode activity alerts are now: \x01h");
writeln(on_or_off(!(val & CHAT_NOACT)));
system.node_list[bbs.node_num-1].misc ^= NODE_AOFF;
break;
case 'D':
var val = user.chat_settings ^= CHAT_NOPAGE;
write("\x01n\r\nUser chat/messaging availability is now: \x01h");
writeln(on_or_off(!(val & CHAT_NOPAGE)));
system.node_list[bbs.node_num-1].misc ^= NODE_POFF;
break;
case 'F':
writeln("");
load("finger.js");
break;
case 'I':
writeln("");
load({}, "sbbsimsg.js");
break;
case 'R':
{
var server = irc_servers[0];
if(irc_servers.length > 1) {
for(var i = 0; i < irc_servers.length; i++)
console.uselect(i, "IRC Server", irc_servers[i]);
var i = console.uselect();
if(i < 0)
break;
server = irc_servers[i];
}
if(user.security.level >= options.irc_seclevel || user.security.exemptions&UFLAG_C) {
write("\r\n\x01n\x01y\x01hIRC Server: ");
server = console.getstr(server, 40, K_EDIT|K_LINE|K_AUTODEL);
if(console.aborted || server.length < 4)
break;
}
// Optional list of channels per server (e.g. irc.synchro.net = #synchronet, #bbs)
var channel_list = irc_channels;
if(options[server] !== undefined)
channel_list = options[server].split(',');
var channel;
if(channel_list.length > 1) {
for(var i = 0; i < channel_list.length; i++) {
channel_list[i] = channel_list[i].trim();
console.uselect(i, "IRC Channel", channel_list[i]);
}
var i = console.uselect();
if(i < 0)
break;
channel = channel_list[i];
} else {
write("\r\n\x01n\x01y\x01hIRC Channel: ");
channel = console.getstr(channel_list[0], 40, K_EDIT|K_LINE|K_AUTODEL);
}
if(server.indexOf(' ') < 0)
server += " 6667";
if(!console.aborted && channel.length) {
log("IRC to " + server + " " + channel);
bbs.exec("?irc -a " + server + " " + channel); // can't be load()ed because it calls exit()
}
break;
}
case 'J':
bbs.multinode_chat();
break;
case 'P':
bbs.private_chat();
break;
case 'C':
if(!bbs.page_sysop()
&& !deny(format(bbs.text(ChatWithGuruInsteadQ), system.guru || "The Guru")))
bbs.page_guru();
break;
case 'T':
bbs.page_guru();
break;
case '?':
if(user.settings & USER_EXPERT)
bbs.menu("chat");
break;
case 'M': // this will directly run the MRC
bbs.exec_xtrn("MRC"); // external program
break;
default:
break menu;
}
}
......@@ -31,49 +31,49 @@ f.close();
f = undefined;
const NICK_COLOURS = [
'\1h\1r',
'\1h\1g',
'\1h\1y',
'\1h\1b',
'\1h\1m',
'\1h\1c',
'\1h\1w',
'\x01h\x01r',
'\x01h\x01g',
'\x01h\x01y',
'\x01h\x01b',
'\x01h\x01m',
'\x01h\x01c',
'\x01h\x01w',
// Low colours with reasonable contrast
'\1n\1r',
'\1n\1g',
'\1n\1y',
'\1n\1m',
'\1n\1c',
'\1n\1w'
'\x01n\x01r',
'\x01n\x01g',
'\x01n\x01y',
'\x01n\x01m',
'\x01n\x01c',
'\x01n\x01w'
];
const PIPE_COLOURS = [2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15];
function pipe_to_ctrl_a(str) {
str = str.replace(/\|00/g, "\1N\1K");
str = str.replace(/\|01/g, "\1N\1B");
str = str.replace(/\|02/g, "\1N\1G");
str = str.replace(/\|03/g, "\1N\1C");
str = str.replace(/\|04/g, "\1N\1R");
str = str.replace(/\|05/g, "\1N\1M");
str = str.replace(/\|06/g, "\1N\1Y");
str = str.replace(/\|07/g, "\1N\1W");
str = str.replace(/\|08/g, "\1H\1K");
str = str.replace(/\|09/g, "\1H\1B");
str = str.replace(/\|10/g, "\1H\1G");
str = str.replace(/\|11/g, "\1H\1C");
str = str.replace(/\|12/g, "\1H\1R");
str = str.replace(/\|13/g, "\1H\1M");
str = str.replace(/\|14/g, "\1H\1Y");
str = str.replace(/\|15/g, "\1H\1W");
str = str.replace(/\|16/g, "\001" + 0);
str = str.replace(/\|17/g, "\001" + 4);
str = str.replace(/\|18/g, "\001" + 2);
str = str.replace(/\|19/g, "\001" + 6);
str = str.replace(/\|20/g, "\001" + 1);
str = str.replace(/\|21/g, "\001" + 5);
str = str.replace(/\|22/g, "\001" + 3);
str = str.replace(/\|23/g, "\001" + 7);
str = str.replace(/\|00/g, "\x01N\x01K");
str = str.replace(/\|01/g, "\x01N\x01B");
str = str.replace(/\|02/g, "\x01N\x01G");
str = str.replace(/\|03/g, "\x01N\x01C");
str = str.replace(/\|04/g, "\x01N\x01R");
str = str.replace(/\|05/g, "\x01N\x01M");
str = str.replace(/\|06/g, "\x01N\x01Y");
str = str.replace(/\|07/g, "\x01N\x01W");
str = str.replace(/\|08/g, "\x01H\x01K");
str = str.replace(/\|09/g, "\x01H\x01B");
str = str.replace(/\|10/g, "\x01H\x01G");
str = str.replace(/\|11/g, "\x01H\x01C");
str = str.replace(/\|12/g, "\x01H\x01R");
str = str.replace(/\|13/g, "\x01H\x01M");
str = str.replace(/\|14/g, "\x01H\x01Y");
str = str.replace(/\|15/g, "\x01H\x01W");
str = str.replace(/\|16/g, "\x01" + 0);
str = str.replace(/\|17/g, "\x01" + 4);
str = str.replace(/\|18/g, "\x01" + 2);
str = str.replace(/\|19/g, "\x01" + 6);
str = str.replace(/\|20/g, "\x01" + 1);
str = str.replace(/\|21/g, "\x01" + 5);
str = str.replace(/\|22/g, "\x01" + 3);
str = str.replace(/\|23/g, "\x01" + 7);
return str;
}
......@@ -82,11 +82,10 @@ function resize_nicklist(frames, nicks) {
return c.length > a ? c.length : a;
}, 0)) : 0;
frames.nicklist.moveTo(frames.top.x + frames.top.width - 1 - maxlen - 1, 2);
frames.nicklist_divider.moveTo(frames.nicklist.x, 2);
frames.nicks.moveTo(frames.nicklist.x + 1, 2);
frames.nicklist.width = maxlen + 2;
frames.nicklist.width = maxlen + (show_nicks ? 2 : 1);
frames.nicks.width = maxlen + 1;
frames.output.width = frames.top.width - frames.nicklist.width;
frames.output.width = (frames.top.width - frames.nicklist.width) + 1;
}
function redraw_nicklist(frames, nicks, colours) {
......@@ -94,7 +93,7 @@ function redraw_nicklist(frames, nicks, colours) {
if (show_nicks) {
nicks.forEach(function (e, i) {
frames.nicks.gotoxy(1, i + 1);
frames.nicks.putmsg(colours[e] + e + '\1n\1w');
frames.nicks.putmsg(colours[e] + e + '\x01n\x01w');
});
}
}
......@@ -107,13 +106,8 @@ function init_display() {
f.output = new Frame(1, 2, 1, h - 3, BG_BLACK|LIGHTGRAY, f.top);
f.divider = new Frame(1, h - 1, w, 1, BG_BLUE|WHITE, f.top);
f.nicklist = new Frame(w - 2, 2, 2, h - 3, BG_BLACK|LIGHTGRAY, f.top);
f.nicklist_divider = new Frame(w - 2, 2, 1, h - 3, BG_BLACK|LIGHTGRAY, f.nicklist);
f.nicks = new Frame(w - 1, 2, 1, h - 3, BG_BLACK|LIGHTGRAY, f.nicklist);
f.input = new Frame(1, h, w, 1, BG_BLACK|WHITE, f.top);
for (var n = 0; n < f.nicklist_divider.height; n++) {
f.nicklist_divider.gotoxy(1, n + 1);
f.nicklist_divider.putmsg(ascii(179));
}
f.output_scroll = new ScrollBar(f.output, { autohide: true });
f.nick_scroll = new ScrollBar(f.nicks, { autohide: true });
f.output.word_wrap = true;
......@@ -123,6 +117,19 @@ function init_display() {
return f;
}
function refresh_stats(frames, stats) {
const activity = new Array(
/* 0: NUL */ "\x01H\x01KNUL",
/* 1: LOW */ "\x01H\x01YLOW",
/* 2: MED */ "\x01H\x01GMED",
/* 3: HI */ "\x01H\x01RHI"
);
frames.divider.clear();
frames.divider.putmsg(format("\x01w\x01hSTATS\x01b\x01h> \x01w\x01hBBSes \x01b\x01h[\x01w\x01h%d\x01b\x01h] \x01nRooms \x01b\x01h[\x01w\x01h%d\x01b\x01h] \x01nUsers \x01b\x01h[\x01w\x01h%d\x01b\x01h] \x01nLevel \x01b\x01h[%s\x01b\x01h]\x01n", stats[0], stats[1], stats[2], activity[Number(stats[3])]));
frames.divider.gotoxy(frames.divider.width - 5, 1);
frames.divider.putmsg('\x01w\x01h/help');
}
function append_message(frames, msg) {
const top = frames.output.offset.y;
if (frames.output.data_height > frames.output.height) {
......@@ -131,23 +138,27 @@ function append_message(frames, msg) {
}
frames.output.gotoxy(1, frames.output.height);
}
frames.output.putmsg("\1k\1h" + (new Date()).toLocaleTimeString() + "\1k\1h " + msg + '\r\n');
frames.output.putmsg("\x01k\x01h" + getShortTime(new Date()) + "\x01n " + msg + '\r\n');
frames.output.scroll(0, -1);
if (input_state == 'scroll') frames.output.scrollTo(0, top);
}
function getShortTime(d) {
return format( "%02d:%02d", d.getHours(), d.getMinutes() );
}
function display_message(frames, msg, colour) {
const body = pipe_to_ctrl_a(truncsp(msg.body) || '').split(' ');
append_message(frames, body[0] + '\1n\1w: ' + body.slice(1).join(' ') + '\1n\1w');
append_message(frames, body[0] + '\x01n\x01w ' + body.slice(1).join(' ') + '\x01n\x01w');
}
function display_server_message(frames, msg) {
append_message(frames, '\1h\1w' + pipe_to_ctrl_a(truncsp(msg) || ''));
append_message(frames, '\x01h\x01w' + pipe_to_ctrl_a(truncsp(msg) || ''));
}
function display_title(frames, room, title) {
frames.title.clear();
frames.title.putmsg('MRC - #' + room + ' - ' + title);
frames.title.putmsg('MRC\x01b\x01h>\x01w\x01h #' + room + ' - ' + title);
}
function set_alias(alias) {
......@@ -203,25 +214,25 @@ function main() {
});
session.on('help', function (cmd, help, ars) {
if (!ars || user.compare_ars(ars)) {
display_server_message(frames, format('\1h\1w/\1h\1c%s \1h\1w- \1n\1w%s', cmd, help));
display_server_message(frames, format('\x01h\x01w/\x01h\x01c%s \x01h\x01w- \x01n\x01w%s', cmd, help));
}
});
session.on('local_help', function (msg) {
display_server_message(frames, '\1h\1w/\1h\1cscroll \1h\1w- \1n\1wScroll the output area');
display_server_message(frames, '\1h\1w/\1h\1cscroll_nicks \1h\1w- \1n\1wScroll the nicklist');
display_server_message(frames, '\1h\1w/\1h\1cnick_prefix \1h\1w- \1n\1wSet a single-character prefix for your handle, eg. /nick_prefix @');
display_server_message(frames, '\x01h\x01w/\x01h\x01cscroll \x01h\x01w- \x01n\x01wScroll the output area');
display_server_message(frames, '\x01h\x01w/\x01h\x01cscroll_nicks \x01h\x01w- \x01n\x01wScroll the nicklist');
display_server_message(frames, '\x01h\x01w/\x01h\x01cnick_prefix \x01h\x01w- \x01n\x01wSet a single-character prefix for your handle, eg. /nick_prefix @');
display_server_message(
frames,
'\1h\1w/\1h\1cnick_color \1h\1w- \1n\1wSet your nick color to one of '
'\x01h\x01w/\x01h\x01cnick_color \x01h\x01w- \x01n\x01wSet your nick color to one of '
+ PIPE_COLOURS.reduce(function (a, c) {
a += format('|%02d%s ', c, c);
return a;
}, '')
+ ', eg. /nick_color 11'
);
display_server_message(frames, '\1h\1w/\1h\1cnick_suffix \1h\1w- \1n\1wSet an eight-character suffix for your handle, eg. /nick_suffix <poop>');
display_server_message(frames, '\1h\1w/\1h\1ctoggle_nicks \1h\1w- \1n\1wShow/hide the nicklist');
display_server_message(frames, '\1h\1w/\1h\1cquit \1n\1w- \1h\1wExit the program');
display_server_message(frames, '\x01h\x01w/\x01h\x01cnick_suffix \x01h\x01w- \x01n\x01wSet an eight-character suffix for your handle, eg. /nick_suffix <poop>');
display_server_message(frames, '\x01h\x01w/\x01h\x01ctoggle_nicks \x01h\x01w- \x01n\x01wShow/hide the nicklist');
display_server_message(frames, '\x01h\x01w/\x01h\x01cquit \x01n\x01w- \x01h\x01wExit the program');
});
session.on('message', function (msg) {
if (msg.from_user == 'SERVER') {
......@@ -243,6 +254,11 @@ function main() {
session.on('topic', function (room, topic) {
display_title(frames, room, topic);
});
session.on('stats', function (stats) {
if (input_state == 'chat') {
refresh_stats(frames, stats);
}
});
if (settings.startup.motd) session.motd();
if (settings.startup.banners) session.banners();
......@@ -364,9 +380,7 @@ function main() {
} else if (user_input == '' || user_input == 'q') {
frames.output.scrollTo(1, frames.output.data_height - frames.output.height);
frames.output_scroll.cycle();
frames.divider.clear();
frames.divider.gotoxy(frames.divider.width - 5, 1);
frames.divider.putmsg('/help');
refresh_stats(frames, session.stats);
input_state = 'chat';
}
}
......@@ -378,6 +392,7 @@ function main() {
}
yield();
}
}
main();
......@@ -86,6 +86,10 @@ function validate_message(msg) {
);
}
function request_stats(sock){
mrc_send(sock, 'CLIENT', '', 'SERVER', '', '', 'STATS');
}
function client_receive(c, no_log) {
const line = c.socket.recvline(1024, settings.timeout);
if (!line || line == '') return;
......@@ -210,6 +214,12 @@ function mrc_receive(sock) {
mrc_send(sock, 'CLIENT', '', 'SERVER', 'ALL', '', 'IMALIVE:' + SYSTEM_NAME);
return;
}
if (message.from_user == 'SERVER' && message.body.toUpperCase().substr(0,6) == 'STATS:') {
var fMa = new File(js.exec_dir + "mrcstats.dat");
fMa.open("w", false);
fMa.write(message.body.substr(message.body.indexOf(':')+1).trim());
fMa.close();
}
if (['', 'ALL', FROM_SITE].indexOf(message.to_site) > -1) {
if (['', 'CLIENT', 'ALL', 'NOTME'].indexOf(message.to_user) > -1) {
// Forward to all clients
......@@ -227,6 +237,7 @@ function main() {
var mrc_sock;
var die = false;
var loop = 1800;
while (!die && !js.terminated) {
yield();
......@@ -234,6 +245,12 @@ function main() {
mrc_sock = mrc_connect(settings.server, settings.port);
continue;
}
mswait(10);
loop += 1
if (loop > 2000) {
request_stats(mrc_sock);
loop = 0;
}
client_accept();
......@@ -261,9 +278,8 @@ function main() {
}
}
});
mrc_receive(mrc_sock);
}
log(LOG_INFO, 'Disconnecting from MRC');
......
load('sbbsdefs.js');
/// -- constants start -- /////////////////////////////////////////////////////
const PATH_TO_MRC_STATS = "../xtrn/mrc/mrcstats.dat";
const ACTIVITY = new Array(
/* 0: NUL */ "\x01H\x01KNUL",
/* 1: LOW */ "\x01H\x01YLOW",
/* 2: MED */ "\x01H\x01GMED",
/* 3: HI */ "\x01H\x01RHI"
);
const BBSES_X = 12;
const BBSES_Y = 19;
const ROOMS_X = 23;
const ROOMS_Y = 19;
const USERS_X = 34;
const USERS_Y = 19;
const LEVEL_X = 34;
const LEVEL_Y = 18;
const STAT_COLOR = "\x01C\x01H";
/// -- constants end -- ///////////////////////////////////////////////////////
var bbses = '\x01H\x01K---';
var rooms = '\x01H\x01K---';
var users = '\x01H\x01K---';
var level = '\x01H\x01K---';
var fMs = new File(PATH_TO_MRC_STATS);
if (fMs.open("r", true)) {
var mrcStats = fMs.readAll()[0].split(' ');
if (mrcStats.length >= 4) {
bbses = mrcStats[0];
rooms = mrcStats[1];
users = mrcStats[2];
level = ACTIVITY[Number(mrcStats[3])];
}
fMs.close();
}
console.gotoxy(BBSES_X, BBSES_Y);
printf("%s%s", STAT_COLOR, bbses);
console.gotoxy(ROOMS_X, ROOMS_Y);
printf("%s%s", STAT_COLOR, rooms);
console.gotoxy(USERS_X, USERS_Y);
printf("%s%s", STAT_COLOR, users);
console.gotoxy(LEVEL_X, LEVEL_Y);
printf("%s%s", STAT_COLOR, level);
......@@ -13,7 +13,8 @@ function MRC_Session(host, port, user, pass, alias) {
output_buffer: [],
last_ping: 0,
last_send: 0,
alias: alias || user
alias: alias || user,
stats: ['-','-','-','0']
};
const callbacks = {
......@@ -55,26 +56,36 @@ function MRC_Session(host, port, user, pass, alias) {
}
function handle_message(msg) {
var uidx;
if (msg.from_user == 'SERVER') {
const params = msg.body.split(':');
switch (params[0]) {
const cmd = msg.body.substr(0, msg.body.indexOf(':')); // cmd is everything left of the first colon (:)
const params = msg.body.substr(msg.body.indexOf(':')+1).trim(); // params are everything right of the first colon (:), including any additional colons to follow
switch (cmd) {
case 'BANNER':
emit('banner', params[1].replace(/^\s+/, ''));
emit('banner', params.replace(/^\s+/, ''));
break;
case 'ROOMTOPIC':
emit('topic', params[1], params.slice(2).join(' '));
case 'ROOMTOPIC':
const room = params.substr(0, params.indexOf(':')); // room is everything left of the first colon (:)
const topic = params.substr(params.indexOf(':')+1).trim(); // topic is everything right of the first colon (:), including any additional colons to follow
emit('topic', room, topic);
break;
case 'USERLIST':
state.nicks = params[1].split(',');
state.nicks = params.split(',');
emit('nicks', state.nicks);
break;
case 'STATS':
state.stats = params.split(' ');
emit('stats', state.stats);
break;
default:
emit('message', msg);
break;
}
} else if (msg.to_user == 'SERVER') {
if (msg.body == 'LOGOFF') {
const uidx = state.nicks.indexOf(msg.from_user);
uidx = state.nicks.indexOf(msg.from_user);
if (uidx > -1) {
state.nicks.splice(uidx, 1);
emit('nicks', state.nicks);
......@@ -84,14 +95,12 @@ function MRC_Session(host, port, user, pass, alias) {
if (msg.to_room == '' || msg.to_room == state.room) {
emit('message', msg);
}
if (msg.to_room == state.room
&& state.nicks.indexOf(msg.from_user) < 0
) {
if (msg.to_room == state.room && state.nicks.indexOf(msg.from_user) < 0) {
send_command('USERLIST', 'ALL');
}
} else if (msg.to_user == 'NOTME') {
if (msg.body.search(/left\ the\ (room|server)\.*$/ > -1)) {
const udix = state.nicks.indexOf(msg.from_user);
uidx = state.nicks.indexOf(msg.from_user);
if (uidx > -1) {
state.nicks.splice(uidx, 1);
emit('nicks', state.nicks);
......@@ -177,7 +186,7 @@ function MRC_Session(host, port, user, pass, alias) {
help: {
help: 'Display this help message',
callback: function (str) {
emit('help', 'List of available commands:');
emit('help', 'List of available commands:', '');
for (var c in commands) {
emit('help', c, commands[c].help, commands[c].ars);
}
......@@ -215,6 +224,15 @@ function MRC_Session(host, port, user, pass, alias) {
}
}
},
t: { // added as shorthand for /msg
help: 'Shorthand for /msg: /t nick message goes here',
callback: function (str) {
const cmd = str.split(' ');
if (cmd.length > 1 && state.nicks.indexOf(cmd[0]) > -1) {
this.send_private_messsage(cmd[0], cmd.slice(1).join(' '));
}
}
},
quote: {
help: 'Send a raw command to the server',
callback: function (str) {
......
......@@ -24,7 +24,6 @@ setup differs.
Port=5000
Options=STATIC | LOOP
Command=../xtrn/mrc/mrc-connector.js
JavaScriptTimeLimit=0
- In SCFG, add a new External Program with the following options, leaving all
other options at their default values:
......@@ -34,12 +33,6 @@ setup differs.
Start-up Directory: /sbbs/xtrn/mrc
Command Line: ?mrc-client.js
- If you want to run from the chat menu instead of via a door, copy chat_sec.js to
/sbbs/mods and edit accordingly, adding the following and don't forget to add the
key to be used to the "keys" variable.
bbs.exec("?../xtrn/mrc/mrc-client.js",null,"/sbbs/xtrn/mrc/");
- Your services and BBS threads should automatically recycle once they are free
to do so, but you may want to restart your BBS now to force these changes to
take effect.
......@@ -85,6 +78,24 @@ mrc-client.ini:
on startup, and whether the Message of the Day and banners are displayed.
4) MRC Stats
MRC-Connector makes requests for server stats every 20 seconds. These stats
are displayed on the MRC-Client screen as well as stored in the mrcstats.dat
file for display elsewhere.
The file "chat-with-mrc-stats-example.msg" is included as an exammple to
demonstrate how to display MRC stats on a menu file. The script file
"mrc-display-menu-stats.js" must be copied to the /sbbs/mods directory in order
for this msg file to work, since it calls this script directly.
If you do decide to make use of this msg file, rename it as chat.msg and copy
it to your /sbbs/text/menu directory, replacing the old chat.msg file. Also be
sure to copy "chat_sec-with-mrc-example.js" to your /sbbs/mods directory and
rename it "chat_sec.js", in order to add M as a valid menu option for
Multi-Relay Chat.
4) Support
- Post a message to 'echicken' in the Synchronet Sysops area on DOVE-Net
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment