aboutsummaryrefslogtreecommitdiff
path: root/third_party/websockify/include/wsirc.js
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/websockify/include/wsirc.js')
-rw-r--r--third_party/websockify/include/wsirc.js235
1 files changed, 235 insertions, 0 deletions
diff --git a/third_party/websockify/include/wsirc.js b/third_party/websockify/include/wsirc.js
new file mode 100644
index 00000000..bef8f8de
--- /dev/null
+++ b/third_party/websockify/include/wsirc.js
@@ -0,0 +1,235 @@
+/*
+ * WebSockets IRC client
+ * Copyright (C) 2011 Joel Martin
+ * Licensed under LGPL-3 (see LICENSE.txt)
+ *
+ * Includes VT100.js from:
+ * http://code.google.com/p/sshconsole
+ * Which was modified from:
+ * http://fzort.org/bi/o.php#vt100_js
+
+ * IRC Client protocol:
+ * http://www.faqs.org/rfcs/rfc2812.html
+ */
+
+
+function IRC(target, connect_callback, disconnect_callback) {
+
+var that = {}, // Public API interface
+ vt100, ws, sQ = [],
+ state = "unconnected",
+ irc_nick, irc_channel,
+ termType = "VT100";
+
+
+Array.prototype.pushStr = function (str) {
+ var n = str.length;
+ for (var i=0; i < n; i++) {
+ this.push(str.charCodeAt(i));
+ }
+}
+
+function do_send() {
+ if (sQ.length > 0) {
+ Util.Debug("Sending " + sQ);
+ ws.send(sQ);
+ sQ = [];
+ }
+}
+
+function do_recv() {
+ console.log(">> do_recv");
+ var rQ, rQi, i;
+
+ while (ws.rQlen() > 1) {
+ rQ = ws.get_rQ();
+ rQi = ws.get_rQi();
+ for (i = rQi; i < rQ.length; i++) {
+ if (rQ[i] === 10) {
+ break;
+ }
+ }
+ if (i >= rQ.length) {
+ // No line break found
+ break;
+ }
+ recvMsg(ws.rQshiftStr((i-rQi) + 1));
+ }
+ //console.log("<< do_recv");
+}
+
+// Handle an IRC message
+function recvMsg(msg) {
+ Util.Debug(">> recvMsg('" + msg + "')");
+
+ var tokens = msg.split(' '), in_params = true,
+ prefix, command, params = [], trailing = [];
+
+ Util.Info(" tokens: " + tokens);
+
+ if (tokens[0].charAt(0) === ":") {
+ prefix = tokens.shift();
+ }
+
+ command = tokens.shift();
+
+ while (tokens.length > 0) {
+ if (tokens[0].charAt(0) === ":") {
+ in_params = false;
+ }
+ if (in_params) {
+ params.push(tokens.shift());
+ } else {
+ trailing.push(tokens.shift());
+ }
+ }
+
+ Util.Info(" prefix: " + prefix);
+ Util.Info(" command: " + command);
+ Util.Info(" params: " + params);
+ Util.Info(" trailing: " + trailing);
+
+ // Show raw received
+ vt100.write(msg);
+
+ switch (command) {
+ case "004":
+ state = "registered";
+ vt100.write("Joining channel #" + irc_channel);
+ sendCmd("JOIN #" + irc_channel);
+ break;
+ case "JOIN":
+ state = "joined";
+ vt100.write("Joined channel #" + irc_channel);
+ break;
+
+ }
+
+ Util.Debug("<< recvMsg('" + msg + "')");
+}
+
+function sendCmd(msg) {
+ Util.Info("Sending: " + msg);
+ sQ.pushStr(msg + "\r\n");
+ do_send();
+}
+
+that.sendMsg = function(msg) {
+ // TODO parse into message
+ sendCmd("PRIVMSG #" + irc_channel + " :" + msg);
+}
+
+
+that.connect = function(host, port, encrypt, nick, channel) {
+ var host = host,
+ port = port,
+ scheme = "ws://", uri;
+
+ irc_nick = nick;
+ irc_channel = channel;
+
+ Util.Debug(">> connect");
+ if ((!host) || (!port)) {
+ alert("must set host and port");
+ return false;
+ }
+
+ if (ws) {
+ ws.close();
+ }
+
+ if (encrypt) {
+ scheme = "wss://";
+ }
+ uri = scheme + host + ":" + port;
+ Util.Info("connecting to " + uri);
+
+ ws.open(uri);
+
+ Util.Debug("<< connect");
+
+ return true;
+}
+
+that.disconnect = function() {
+ Util.Debug(">> disconnect");
+ if (ws) {
+ ws.close();
+ }
+
+ disconnect_callback();
+ Util.Debug("<< disconnect");
+}
+
+
+function constructor() {
+ /* Initialize Websock object */
+ ws = new Websock();
+
+ ws.on('message', do_recv);
+ ws.on('open', function(e) {
+ Util.Info(">> WebSockets.onopen");
+ // Send registration commands
+ state = "connected";
+ sendCmd("NICK " + irc_nick);
+ // TODO: how to determine this?
+ sendCmd("USER joelm 0 * :Joel Martin");
+ connect_callback();
+ Util.Info("<< WebSockets.onopen");
+ });
+ ws.on('close', function(e) {
+ Util.Info(">> WebSockets.onclose");
+ that.disconnect();
+ Util.Info("<< WebSockets.onclose");
+ });
+ ws.on('error', function(e) {
+ Util.Info(">> WebSockets.onerror");
+ that.disconnect();
+ Util.Info("<< WebSockets.onerror");
+ });
+
+ /* Initialize the terminal emulator/renderer */
+
+ vt100 = new VT100(80, 24, target);
+
+ // Show cursor
+ vt100.curs_set(true, false);
+
+ /*
+ * Override VT100 I/O routines
+ */
+
+ // Set handler for sending characters
+ vt100.getch(
+ function send_chr(chr, vt) {
+ var i;
+ Util.Debug(">> send_chr: " + chr);
+ for (i = 0; i < chr.length; i++) {
+ sQ.push(chr.charCodeAt(i));
+ }
+ do_send();
+ vt100.getch(send_chr);
+ }
+ );
+
+ vt100.debug = function(message) {
+ Util.Debug(message + "\n");
+ }
+
+ vt100.warn = function(message) {
+ Util.Warn(message + "\n");
+ }
+
+ vt100.curs_set = function(vis, grab, eventist)
+ {
+ this.debug("curs_set:: vis: " + vis + ", grab: " + grab);
+ if (vis !== undefined)
+ this.cursor_vis_ = (vis > 0);
+ }
+
+ return that;
+}
+
+return constructor(); // Return the public API interface
+
+} // End of Telnet()