diff --git a/xtrn/chat_pager/example-settings.ini b/xtrn/chat_pager/example-settings.ini new file mode 100644 index 0000000000000000000000000000000000000000..617e31f54f6e0690f7191f3b492690056beacf36 --- /dev/null +++ b/xtrn/chat_pager/example-settings.ini @@ -0,0 +1,20 @@ +; Make a copy of this file in the same directory, and name it 'settings.ini' +; Edit the values to your liking. + +[queue] +queue_name = chat_pager + +[scanner] +semaphore_scan_interval = 2500 + +[ircbot] +notification_format = %s is paging the sysop from node %s. + +[terminal] +wait_time = 30000 +wait_message = Please wait here. %s will respond if they are available. +cancel_message = [ Hit any key to cancel ] +irc_pull = true +irc_server = irc.synchro.net +irc_port = 6667 +irc_channel = #my_bbs_channel diff --git a/xtrn/chat_pager/ircbot/for-ircbot.ini b/xtrn/chat_pager/ircbot/for-ircbot.ini new file mode 100644 index 0000000000000000000000000000000000000000..02cc0c1d873d3afdafcceea52a73818b9c2c2425 --- /dev/null +++ b/xtrn/chat_pager/ircbot/for-ircbot.ini @@ -0,0 +1,6 @@ +; Paste this into your 'ctrl/ircbot.ini' file +; Edit the 'channels' list to suit your needs +[module_pager] +channels = #my_bbs_channel +lib = event-timer.js,../xtrn/chat_pager/lib.js +dir = ../xtrn/chat_pager/ircbot diff --git a/xtrn/chat_pager/ircbot/pager.js b/xtrn/chat_pager/ircbot/pager.js new file mode 100644 index 0000000000000000000000000000000000000000..43a7c2b4c5413052c0a748cf56825778ce2670f1 --- /dev/null +++ b/xtrn/chat_pager/ircbot/pager.js @@ -0,0 +1,72 @@ +function get_config(module) { + var cfg = null; + var fn = system.ctrl_dir + 'ircbot.ini'; + if (file_exists(fn)) { + var f = new File(fn); + if (f.open('r')) { + var cfg = f.iniGetObject(module); + f.close(); + if (typeof cfg.channels !== 'undefined') { + cfg.channels = cfg.channels.split(',').map( + function (e) { return e.replace(/\s.*/g, ''); } + ); + } else { + cfg.channels = []; + } + } + } + return cfg; +} + +var bot_cfg = get_config('module_pager'); +var settings = load_settings(fullpath(this.dir + '../settings.ini')); + +if (bot_cfg !== null && settings !== null) { + + var queue = new Queue(settings.queue.queue_name); + var timer = new Timer(); + var scanner = new Scanner(settings.scanner); + var messages = []; + + function scan_nodes() { + var nodes_paging = scanner.scan(); + nodes_paging.forEach( + function (e, i) { + var un = user_online(i); + if (e == PAGE_NEW && un > 0) { + var u = new User(un); + messages.push( + format( + settings.ircbot.notification_format, u.alias, i + 1 + ) + ); + } + } + ); + } + + timer.addEvent(settings.scanner.semaphore_scan_interval, true, scan_nodes); + + function main(srv, target) { + timer.cycle(); + while (messages.length > 0) { + bot_cfg.channels.forEach( + function (e) { + srv.o(e, messages.shift()); + } + ); + } + } + + Bot_Commands["CHAT"] = new Bot_Command(0, false, false); + Bot_Commands["CHAT"].usage = get_cmd_prefix() + "!chat [node]"; + Bot_Commands["CHAT"].command = function (target, onick, ouh, srv, lbl, cmd) { + var valname = "chat_" + cmd[1]; + queue.write(system.timer, valname); + } + +} else { + + log(LOG_ERR, 'Unable to load pager settings.'); + +} diff --git a/xtrn/chat_pager/lib.js b/xtrn/chat_pager/lib.js new file mode 100644 index 0000000000000000000000000000000000000000..c5c324d7efeecb17b04999baf74193c00c53dc19 --- /dev/null +++ b/xtrn/chat_pager/lib.js @@ -0,0 +1,74 @@ +const PAGE_NEW = 0; +const PAGE_REPEAT = 1; +const PAGE_NONE = 2; + +function load_settings(fp) { + var ret = {}; + if (file_exists(fp)) { + var f = new File(fp); + if (f.open('r')) { + var ini = f.iniGetAllObjects(); + f.close(); + ini.forEach( + function (e) { + ret[e.name] = e; + delete ret[e.name].name; + } + ) + } + } + return ret; +} + +function user_online(n) { + return ( + system.node_list[n].status == 3 || system.node_list[n].status == 4 + ? system.node_list[n].useron : 0 + ); +} + +// Returns array of 1-based node numbers that are currently paging the sysop +function nodes_paging() { + return directory( + system.ctrl_dir + 'syspage.*' + ).map( + function (e) { + return parseInt(e.split('.').pop()); + } + ).filter( + function (e) { + return (!isNaN(e) && e > 0 && e <= system.node_list.length); + } + ); +} + +var Scanner = function (settings) { + + var node_stat; + + this.reset = function () { + node_stat = system.node_list.map(function () { return PAGE_NONE }); + } + + // Returns an array (index is zero-based node number) of PAGE_* status + this.scan = function () { + var np = nodes_paging(); + node_stat = node_stat.map( + function (e, i) { + if (e == PAGE_NONE && np.indexOf(i+1) >= 0) { + return PAGE_NEW; + } else if ( + (e == PAGE_NEW || e == PAGE_REPEAT) && np.indexOf(i+1) >= 0 + ) { + return PAGE_REPEAT; + } else { + return PAGE_NONE; + } + } + ); + return node_stat; + } + + this.reset(); + +} diff --git a/xtrn/chat_pager/page_sysop.js b/xtrn/chat_pager/page_sysop.js new file mode 100644 index 0000000000000000000000000000000000000000..0184b7c609bc8920882c151799be4f6c45a8d3c3 --- /dev/null +++ b/xtrn/chat_pager/page_sysop.js @@ -0,0 +1,71 @@ +load('sbbsdefs.js'); +load(js.exec_dir + 'lib.js'); +load('progress-bar.js'); + +function get_last_queued_value(queue, valname) { + var val, temp_val; + while (typeof (temp_val = queue.read(valname)) !== 'undefined') { + val = temp_val; + } + return val; +} + +function await_page_response(settings) { + var queue = new Queue(settings.queue.queue_name); + var valname = "chat_" + bbs.node_num; + var answered = false; + var stime = system.timer; + var utime = system.timer; + var progress_bar = new ProgressBar(1, 2); + progress_bar.init(); + while ( + (system.timer - stime) * 1000 < settings.terminal.wait_time && + console.inkey(K_NONE) == '' && + !answered + ) { + var now = system.timer; + if (now - utime >= 1) { + progress_bar.set_progress( + (((now - stime) * 1000) / settings.terminal.wait_time) * 100 + ); + progress_bar.cycle(); + utime = now; + } + var val = get_last_queued_value(queue, valname); + if (typeof val == 'number' && val > stime) answered = true; + yield(); + } + progress_bar.set_progress(100); + progress_bar.cycle(); + progress_bar.close(); + return answered; +} + +function main() { + var settings = load_settings(js.exec_dir + 'settings.ini'); + console.clear(WHITE); + console.home(0, 0); + console.center(format(settings.terminal.wait_message, system.operator)); + console.crlf(); + console.center(settings.terminal.cancel_message); + var xy = console.getxy(); + if (settings !== null && await_page_response(settings)) { + if (settings.terminal.irc_pull) { + bbs.exec( + format( + '?irc.js -a %s %s %s', + settings.terminal.irc_server, + settings.terminal.irc_port, + settings.terminal.irc_channel + ) + ); + } + } else { + console.gotoxy(xy); + console.clearline(); + console.center(format(bbs.text(522).trim(), system.operator)); + console.pause(); + } +} + +main(); diff --git a/xtrn/chat_pager/readme.txt b/xtrn/chat_pager/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..1f5e5903401d6c2ef2c7716d1172d031997a1924 --- /dev/null +++ b/xtrn/chat_pager/readme.txt @@ -0,0 +1,55 @@ +Some kinda page-sysop thingie +by echicken, November 2017 +echicken at bbs.electronicchicken.com + +1) Setup + +- Run scfg +- Select 'Chat Features' +- Select 'External Sysop Chat Pagers' +- Hit enter on the blank line at the bottom to create a new record +- Set the 'Command Line' to: ?/sbbs/xtrn/chat_pager/page_sysop.js + +2) Configuration + +- Browse to the 'xtrn/chat_pager/' directory +- Copy 'example-settings.ini' to a new file, name it 'settings.ini' +- Edit 'settings.ini' +- In the [terminal] section, edit irc_server, irc_port, and irc_channel as needed + +3) IRC Bot setup + +- Browse to the 'xtrn/chat_pager/ircbot/' directory +- Open 'for-ircbot.ini' with a text editor +- Copy its contents to your clipboard +- Browse to your 'ctrl/' directory +- Open 'ircbot.ini' with a text editor +- Paste the previously copied file contents into the bottom of this file + +4) Finishing Up + +- Synchronet will need to recycle the terminal server thread to pick up changes +- It may be necessary to restart your BBS +- You will need to issue the 'restart' command to your IRC bot + +5) Using + +Users who page the sysop will be shown a progress/time bar while they wait for +you to respond. + +Your IRC bot will notify you in the channel you've configured that somebody is +paging you. Respond with the command '!chat n', where 'n' is the node number, +to pull the user into IRC chat. + +6) Notes + +I haven't tested this much. Use at your own risk. + +If you run your IRC bot via jsexec, the 'IRC Pull' feature will not work; I will +add a workaround for that soon. It will work if you run your IRC bot as a +service. + +Additional notification methods (other than IRC) may be added in the future. + +You don't have to use the 'IRC Pull' feature; you can always go to your host +system and break into chat with the built in tools (from sbbsctrl or umonitor).