Merge pull request #200 from M2Ys4U/socks
authorDarren <darren@darrenwhitlen.com>
Mon, 1 Apr 2013 20:45:03 +0000 (13:45 -0700)
committerDarren <darren@darrenwhitlen.com>
Mon, 1 Apr 2013 20:45:03 +0000 (13:45 -0700)
SOCKS proxy support

16 files changed:
README.md
client/assets/css/style.css
client/assets/dev/app.js
client/assets/dev/applet_scripteditor.js
client/assets/dev/applet_settings.js
client/assets/dev/index.html.tmpl
client/assets/dev/model_application.js
client/assets/dev/model_gateway.js
client/assets/dev/model_panel.js
client/assets/dev/view.js
config.example.js
server/client.js
server/identd.js [new file with mode: 0644]
server/irc/channel.js
server/irc/state.js
server/kiwi.js

index 5f1904811ee18cf38d7c2304dbb79852a8963416..7868c356695a02ba7d0c3c1a58c1861e0009cc47 100755 (executable)
--- a/README.md
+++ b/README.md
@@ -2,16 +2,19 @@
 Kiwi IRC is a fully featured IRC client that can be extended to suit almost any needs.\r
 Using the web application is extremly simple even without any IRC knowledge as all the common needs are built directly into the UI.\r
 \r
-For more information see http://kiwiirc.com or an example of the application can be found at http://kiwiirc.com/client/\r
+For more information see https://kiwiirc.com or an example of the application can be found at https://kiwiirc.com/client/.\r
+Our development IRC channel is on the Freenode network, irc.freenode.net #kiwiirc\r
 \r
 \r
 ### Installation\r
 \r
+*Note: This requires Node.js to run. Make sure you have installed Node.js first! http://nodejs.org/download/*\r
+\r
 1. Download the Kiwi source or clone the git repository:\r
 \r
     `$ git clone git@github.com:prawnsalad/KiwiIRC.git && cd KiwiIRC`\r
 \r
-2. Install the dependancies:\r
+2. Install the dependencies:\r
 \r
     `$ npm install`\r
 \r
index a83b227757bcd2cbcc72bc19d81bd1000308f31a..7af1011787df29e719b2046e247f4b0a55dab0f3 100644 (file)
@@ -114,7 +114,7 @@ html, body { height:100%; }
  * Control box
  */
 #kiwi #controlbox .input {
-    height:1.7em;
+    height:1.7em; position:relative;
 }
 
 /* The nick label */
@@ -136,6 +136,10 @@ html, body { height:100%; }
 #kiwi #controlbox .nickchange input { }
 #kiwi #controlbox .nickchange button { }
 
+/* Plugin tools */
+#kiwi #controlbox .input_tools { float:right; }
+#kiwi #controlbox .input_tools .tool { margin:0 1em; display:inline; }
+
 
 
 /**
@@ -337,7 +341,7 @@ html, body { height:100%; }
 #kiwi.theme_relaxed .messages a { text-decoration:none; }
 
 #kiwi.theme_relaxed .messages .msg { border-bottom: 1px solid #DEDEDE; padding: 1px; font-family:arial; font-size:0.9em; }
-#kiwi.theme_relaxed .messages .msg .time { width:6em; float:left; color:#777; display:none; }
+#kiwi.theme_relaxed .messages .msg .time { width:5em; float:left; color:#777; padding:5px; display:none; }
 #kiwi.theme_relaxed .messages .msg .nick { width:11em; float:left; font-size:12px; font-family:Arial; text-align:right; padding: 5px; overflow:hidden; }
 #kiwi.theme_relaxed .messages .msg .text { display:block; margin-left:12em; border-left: 1px solid #DEDEDE; white-space:pre-wrap; word-wrap:break-word; font-family:arial; padding:5px; }
 
@@ -364,6 +368,9 @@ html, body { height:100%; }
     padding:0.5em; margin-top:1em; margin-bottom:1em; margin-right:2em;
 }
 
+#kiwi.theme_relaxed.timestamps .messages .msg .time { display:block; }
+#kiwi.theme_relaxed.timestamps .messages .msg .text { margin-left:17em; }
+
 #kiwi.theme_relaxed .messages .msg.global_nick_highlight,
 #kiwi.theme_relaxed .messages .msg.highlight { background:#D9D9D9; }
 
@@ -907,6 +914,9 @@ html, body { height:100%; }
 #kiwi.theme_cli #toolbar .panellist li .activity { display:inline; margin-left:0.5em; font-style:italic; font-size:0.8em; }
 #kiwi.theme_cli #toolbar .panellist li .activity:before { content:"("; }
 #kiwi.theme_cli #toolbar .panellist li .activity:after { content:")"; }
+#kiwi.theme_cli #toolbar .panellist li.alert_highlight .activity {
+    color: #fff; background: #a60400; padding:2px; border-radius:3px;
+}
 
 
 #kiwi.theme_cli #memberlists { background:#222222; }
@@ -956,6 +966,7 @@ html, body { height:100%; }
 }
 
 #kiwi.theme_cli .messages .msg.global_nick_highlight { background:#111111; }
+#kiwi.theme_cli .messages .msg.highlight { background:#111111; }
 
 
 
@@ -1044,4 +1055,255 @@ html, body { height:100%; }
 #kiwi.theme_cli.chanlist_treeview #toolbar #tabs { position:absolute; left:0px; bottom:0px; top:0px; margin:0; width:200px; background:#1B1B1B; overflow-y:auto; }
 #kiwi.theme_cli.chanlist_treeview #tabs ul li { display:block; float:none; }
 #kiwi.theme_cli.chanlist_treeview #tabs ul li .activity { float:right; }
-#kiwi.theme_cli.chanlist_treeview #tabs ul li.active { padding-left:1em; }
\ No newline at end of file
+#kiwi.theme_cli.chanlist_treeview #tabs ul li.active { padding-left:1em; }
+
+
+
+
+
+
+
+
+
+
+/**
+ * Basic theme
+ */
+#kiwi.theme_basic {
+    background: #FFF;
+    color: #555555;
+}
+#kiwi.theme_basic,
+#kiwi.theme_basic input,
+#kiwi.theme_basic button,
+#kiwi.theme_basic textarea {
+    font-family:Arial, Helvetica, sans-serif;
+    font-size:14px; line-height:1.4em;
+}
+#kiwi.theme_basic input, textarea {
+    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.5),0 1px 0px rgba(255, 255, 255, 0.3);
+    border: none;
+    border-radius: 3px;
+}
+#kiwi.theme_basic #toolbar {
+    background-color:#1B1B1B; font-size:0.9em;
+}
+#kiwi.theme_basic #controlbox { background-color:#1B1B1B; }
+#kiwi.theme_basic #memberlists_resize_handle {
+    display:none; width:0;
+}
+#kiwi.theme_basic #toolbar .panellist li {
+    line-height: 1.4em;
+    vertical-align: middle;
+    
+    border-radius:5px;
+    -moz-border-radius:5px;
+    -webkit-border-radius:5px;
+    -khtml-border-radius:5px;
+
+    border: 1px solid #333;
+    background-color: #eee;
+}
+
+#kiwi.theme_basic #toolbar #tabs { margin-right:0 !important; }
+#kiwi.theme_basic #toolbar .panellist .alert_highlight { font-weight:bold; color:red; }
+#kiwi.theme_basic #toolbar .panellist .alert_activity { font-weight:normal; color:green; }
+#kiwi.theme_basic #toolbar .panellist .alert_action { font-weight:normal; color:green; }
+
+#kiwi.theme_basic #toolbar .panellist .active { padding-right:23px; }
+#kiwi.theme_basic #toolbar .panellist li .part {}
+#kiwi.theme_basic #toolbar .panellist li .part:after { content:"[x]"; }
+
+#kiwi.theme_basic #toolbar .panellist li.server span { }
+
+/* Tab texts are within a span */
+#kiwi.theme_basic #toolbar .panellist li span  { line-height:20px; vertical-align:middle; display:inline-block; }
+
+#kiwi.theme_basic #toolbar .panellist li .activity { display:inline; margin-left:0.5em; font-style:italic; font-size:0.8em; }
+#kiwi.theme_basic #toolbar .panellist li .activity:before { content:"("; }
+#kiwi.theme_basic #toolbar .panellist li .activity:after { content:")"; }
+
+#kiwi.theme_basic #status_message {
+    background: #FEEFB3; color: #9F6000;
+    border-bottom: 1px solid;
+    padding: 0.9em;
+    text-align: center; font-size:1.1em;
+}
+#kiwi.theme_basic #status_message.err { color:#D8000C; background:#FFBABA; }
+
+#kiwi.theme_basic .messages {  }
+#kiwi.theme_basic .messages.active { }
+#kiwi.theme_basic .messages a { text-decoration:underline; }
+
+#kiwi.theme_basic .messages .msg { }
+#kiwi.theme_basic .messages .msg > div { font-family: Consolas, "Lucida Console", monospace; font-size:0.9em; }
+#kiwi.theme_basic .messages .msg { border: none; }
+#kiwi.theme_basic .messages .msg .time { display:inline; margin-right:1em; margin-left:2px; color:gray; }
+#kiwi.theme_basic .messages .msg .nick { display:inline; margin-right:1em; }
+#kiwi.theme_basic .messages .msg .nick:before { content:"<"; }
+#kiwi.theme_basic .messages .msg .nick:after { content:">"; }
+#kiwi.theme_basic .messages .msg .text { white-space:pre-wrap; word-wrap:break-word; color:#1e1e1e; }
+
+#kiwi.theme_basic .messages .msg.action .nick,
+#kiwi.theme_basic .messages .msg.static .nick,
+#kiwi.theme_basic .messages .msg.topic .nick { display:none; }
+
+#kiwi.theme_basic .messages .msg.action .text { color:#009900; font-style:italic; }
+#kiwi.theme_basic .messages .msg.action.join { color:#009900; }
+#kiwi.theme_basic .messages .msg.action.part .text { color:#900; }
+#kiwi.theme_basic .messages .msg.action.quit .text { color:#900; }
+#kiwi.theme_basic .messages .msg.action.kick .text { color:#900; }
+
+#kiwi.theme_basic .messages .msg.motd { border:none; }
+/*#kiwi.theme_basic .messages .msg.motd .nick { display:none; }*/
+#kiwi.theme_basic .messages .msg.motd .text { color:#666; }
+#kiwi.theme_basic .messages .msg.whois .nick { font-weight:normal; }
+#kiwi.theme_basic .messages .msg.whois .text { padding-left:1em; border-left:1px dashed #999; }
+#kiwi.theme_basic .messages .msg.error .text {
+    border:1px solid #A33F3F; background-color:#D28A8A;
+    padding:0.5em; margin-top:1em; margin-bottom:1em; margin-right:2em;
+}
+
+#kiwi.theme_basic .messages .msg.global_nick_highlight,
+#kiwi.theme_basic .messages .msg.highlight { background:#D9D9D9; }
+
+
+
+#kiwi.theme_basic #memberlists {
+    background-color: #DADADA;
+    border-left: 1px dashed #8A8A8A;
+}
+#kiwi.theme_basic #memberlists ul { list-style: none; margin-left:2px; }
+#kiwi.theme_basic #memberlists ul.active { }
+#kiwi.theme_basic #memberlists ul li { padding:0 2px; }
+#kiwi.theme_basic #memberlists ul li:hover {}
+#kiwi.theme_basic #memberlists ul li a.nick { display:block; color:black; }
+
+#kiwi.theme_basic #memberlists ul li .userbox { margin:0 1em 5px 1em; padding-bottom:0.7em; font-size:.9em; }
+#kiwi.theme_basic #memberlists ul li .userbox a { display:block; text-decoration:none; margin-bottom:2px; }
+#kiwi.theme_basic #memberlists ul li .userbox a i { font-size:1.1em; margin-right:5px; }
+
+
+#kiwi.theme_basic #controlbox .input {
+    background:#fff; margin:3px;
+    height:1.7em;
+}
+#kiwi.theme_basic #controlbox .input .nick {
+    text-align: right;
+    width: 11em;
+    left: 0px;
+    position: absolute;
+    padding: 2px;
+    overflow: hidden;
+}
+#kiwi.theme_basic #controlbox .input .nick:after { content:">"; margin-left:3px; top:2px; }
+#kiwi.theme_basic #controlbox .input .nick a { text-decoration:none; color:black; }
+#kiwi.theme_basic #controlbox .input .input_wrap {
+    position:absolute;
+    right:3px; left:12em;
+    height:1.7em;
+}
+#kiwi.theme_basic #controlbox .input .inp {
+    line-height:1.7em;
+    border: medium none;
+    box-shadow: none;
+    border-radius: 0;
+    resize:none;
+    overflow:hidden;
+    position:relative;
+    height:100%; width:100%;
+    display: block;
+}
+
+
+#kiwi.theme_basic #controlbox .nickchange {
+    padding:10px; left: 0px;
+    background: #1B1B1B; color:#eeeeee;
+}
+#kiwi.theme_basic #controlbox .nickchange input { padding:0.3em 0.5em; }
+#kiwi.theme_basic #controlbox .nickchange button { padding:0.5em; }
+
+
+
+#kiwi.theme_basic #topic {  }
+#kiwi.theme_basic #topic div {
+    top:2; bottom:2px; left:0; width:100%;
+    padding: 0.2em 1em;
+    text-align: center;
+    box-shadow: none;
+    border-radius: 0;
+    background-color:#FFF;
+    height: 1.5em;
+    overflow: hidden;
+    outline: none;
+}
+#kiwi.theme_basic #topic:hover div {
+    min-height:1.5em;
+    white-space:pre-wrap; word-wrap:break-word;
+    overflow:visible;
+    background-color:#FFF;
+    z-index: 1;
+    height:auto; bottom:auto;
+    border-bottom: 1px dotted #1B1B1B;
+}
+
+
+#kiwi.theme_basic #toolbar .app_tools { padding-left:10px; color:#D4D4D4; }
+#kiwi.theme_basic #toolbar .app_tools ul li {
+    font-size:26px;
+    -webkit-transition: all .3s ease;
+    -moz-transition: all .3s ease;
+    transition: all .3s ease;
+    margin-left:10px;
+}
+#kiwi.theme_basic #toolbar .app_tools ul li:hover { color:#88C56A; }
+#kiwi.theme_basic #toolbar .app_tools img { }
+
+
+/* The server select dialog */
+#kiwi.theme_basic .server_select { width:730px;  padding:3em 0 2em 0; margin: 0 auto; }
+#kiwi.theme_basic .server_select a { text-decoration: none; }
+#kiwi.theme_basic .server_select .more { display: none; width:270px; margin:0 auto; }
+#kiwi.theme_basic .server_select table tr td { padding:5px; }
+#kiwi.theme_basic .server_select button { float:right; padding:3px 7px; }
+#kiwi.theme_basic .server_select input { padding:3px 7px; width:150px; }
+#kiwi.theme_basic .server_select label { }
+#kiwi.theme_basic .server_select br { clear:both; }
+#kiwi.theme_basic .server_select .basic input, .server_select .basic button { font-size:1em; padding:0.5em 1em; }
+#kiwi.theme_basic .server_select .basic input { width:170px; }
+#kiwi.theme_basic .server_select .basic label { font-size:1.3em; margin-top:4px; }
+#kiwi.theme_basic .server_select .basic tr.have_pass { font-size:0.8em; }
+#kiwi.theme_basic .server_select .basic tr.channel td { padding-top:1em; }
+#kiwi.theme_basic .server_select .basic { border-bottom: 1px dashed gray; margin-bottom:1em; }
+#kiwi.theme_basic .server_select .basic .show_more { display: block; width:110px; margin:10px 0 0 0; font-size:0.8em; background: url(../img/more.png) no-repeat right 7px; }
+#kiwi.theme_basic .server_select.single_server .basic { border:none; }
+#kiwi.theme_basic .server_select .status { text-align: center; font-weight: bold; padding:1em; }
+#kiwi.theme_basic .server_select .status.ok { }
+#kiwi.theme_basic .server_select .status.error {
+    border:1px solid #A33F3F; background-color:#D28A8A;
+    padding:0.5em; margin-top:1em; margin-bottom:1em; margin-right:2em;
+}
+
+
+#kiwi.theme_basic .server_select .kiwi_logo { text-align: center; display:block; }
+#kiwi.theme_basic .server_select .kiwi_logo h1 {
+    font-size:20px;
+    line-height:48px; vertical-align: middle;
+    color: #555555;
+}
+#kiwi.theme_basic .server_select .kiwi_logo img { }
+
+
+#kiwi.theme_basic.chanlist_treeview #panels { left:160px; }
+#kiwi.theme_basic.chanlist_treeview #toolbar { position:static; }
+#kiwi.theme_basic.chanlist_treeview #toolbar .app_tools { float:none; }
+#kiwi.theme_basic.chanlist_treeview #toolbar > div { margin-left:160px; }
+#kiwi.theme_basic.chanlist_treeview #toolbar #tabs { position:absolute; left:0px; bottom:0px; top:0px; margin:0; width:160px; background:#1B1B1B; overflow-y:auto; }
+#kiwi.theme_basic.chanlist_treeview #tabs ul li { display:block; float:none; }
+#kiwi.theme_basic.chanlist_treeview #tabs ul li .activity { float:right; }
+#kiwi.theme_basic.chanlist_treeview #tabs ul li.active {
+    margin-right:0;
+    border-right-width:0;
+    border-bottom-right-radius:0;
+    border-top-right-radius:0;
+}
\ No newline at end of file
index ee1ff68b85ac82be4ea6ec9f9012f2f35561a514..046eb3fbd123ab6283a0f4d42ba50fe35c00cdad 100644 (file)
@@ -15,7 +15,7 @@ _kiwi.applets = {};
  * and data (think: plugins)\r
  */\r
 _kiwi.global = {\r
-       settings: undefined,\r
+       settings: undefined, // Instance of _kiwi.model.DataStore\r
        plugins: undefined,\r
        utils: undefined, // TODO: Re-usable methods\r
        user: undefined, // TODO: Limited user methods\r
@@ -32,6 +32,7 @@ _kiwi.global = {
                }\r
 \r
                _.extend(this, Backbone.Events);\r
+               this._source = event_source;\r
 \r
                // Proxy the events to this dispatcher\r
                event_source.on('all', proxyEvent, this);\r
@@ -40,6 +41,7 @@ _kiwi.global = {
                this.dispose = function () {\r
                    event_source.off('all', proxyEvent);\r
                    this.off();\r
+                   delete this.event_source;\r
                };\r
            },\r
 \r
@@ -48,13 +50,14 @@ _kiwi.global = {
                var funcs = {\r
                        kiwi: 'kiwi', raw: 'raw', kick: 'kick', topic: 'topic',\r
                        part: 'part', join: 'join', action: 'action', ctcp: 'ctcp',\r
-                       notice: 'notice', msg: 'privmsg'\r
+                       notice: 'notice', msg: 'privmsg',\r
+                       get: 'get'\r
                };\r
 \r
                _.each(funcs, function(gateway_fn, func_name) {\r
                        obj[func_name] = function() {\r
                                var fn_name = gateway_fn;\r
-                               _kiwi.gateway[fn_name].apply(_kiwi.gateway, arguments);\r
+                               return _kiwi.gateway[fn_name].apply(_kiwi.gateway, arguments);\r
                        };\r
                });\r
 \r
@@ -68,7 +71,10 @@ _kiwi.global = {
                };\r
 \r
                _.each(funcs, function(controlbox_fn, func_name) {\r
-                       obj[func_name] = _kiwi.app.controlbox[controlbox_fn];\r
+                       obj[func_name] = function() {\r
+                               var fn_name = controlbox_fn;\r
+                               return _kiwi.app.controlbox[fn_name].apply(_kiwi.app.controlbox, arguments);\r
+                       };\r
                });\r
 \r
                return obj;\r
index 851212947334e0f4a65e21e0afd89e63f0a47ba7..ace02ef25e75bb437ae14c0eb032605ee4b28a77 100644 (file)
@@ -10,7 +10,7 @@
 
                 this.model.on('applet_loaded', function () {
                     that.$el.parent().css('height', '100%');
-                    $script('http://d1n0x3qji82z53.cloudfront.net/src-min-noconflict/ace.js', function (){ that.createAce(); });
+                    $script('https://d1n0x3qji82z53.cloudfront.net/src-min-noconflict/ace.js', function (){ that.createAce(); });
                 });
             },
 
index 93a222f762684ea6d4d82b80735d7c554f637599..78d235a00c8a78284c0e3fa148a62567b4a03a23 100644 (file)
             } else {\r
                 this.$el.find('.setting-show_joins_parts').attr('checked', false);\r
             }\r
+\r
+            if (typeof settings.get('show_timestamps') === 'undefined' || !settings.get('show_timestamps')) {\r
+                this.$el.find('.setting-show_timestamps').attr('checked', false);\r
+            } else {\r
+                this.$el.find('.setting-show_timestamps').attr('checked', true);\r
+            }\r
         },\r
 \r
 \r
@@ -51,6 +57,7 @@
             settings.set('channel_list_style', $('.setting-channel_list_style', this.$el).val());\r
             settings.set('scrollback', $('.setting-scrollback', this.$el).val());\r
             settings.set('show_joins_parts', $('.setting-show_joins_parts', this.$el).is(':checked'));\r
+            settings.set('show_timestamps', $('.setting-show_timestamps', this.$el).is(':checked'));\r
 \r
             settings.save();\r
 \r
index efe8ea240236bdd6b37481dd9da831e511b870c6..b2caf936bfc42aacdfadfb56d975a1018c805420 100644 (file)
@@ -8,7 +8,7 @@
 <title> KiwiIRC </title>\r
 \r
 <link rel="stylesheet" type="text/css" href="<%base_path%>/assets/css/style.css" />\r
-<link rel="stylesheet" type="text/css" href="<%base_path%>/assets/css/font-awesome.css" />\r
+<link rel="stylesheet" type="text/css" href="<%base_path%>/assets/css/font-awesome.min.css" />\r
 <!--[if IE 7]>\r
 <link rel="stylesheet" type="text/css" href="/kiwi/assets/css/font-awesome-ie7.css" />\r
 <![endif]-->\r
@@ -19,7 +19,7 @@
             <div class="app_tools">\r
                 <ul class="main">\r
                     <li class="settings"><i class="icon-cogs" title="Settings"></i></li>\r
-                    <li><a href="http://kiwiirc.com/" target="_blank"><img src="<%base_path%>/assets/img/ico.png" alt="KiwiIRC" title="KiwiIRC" /></a></li>\r
+                    <li><a href="https://kiwiirc.com/" target="_blank"><img src="<%base_path%>/assets/img/ico.png" alt="KiwiIRC" title="KiwiIRC" /></a></li>\r
                 </ul>\r
             </div>\r
 \r
@@ -47,6 +47,7 @@
             <div class="input">\r
                 <span class="nick"> </span>\r
                 <div class="input_wrap"><textarea class="inp"></textarea></div>\r
+                <div class="input_tools"></div>\r
             </div>\r
         </div>\r
     </div>\r
             </div>\r
 \r
             <div class="about_kiwi" style="position:relative;float:left;width:320px;margin-left:3em;color:#555555;">\r
-                <a class="kiwi_logo" href="http://www.kiwiirc.com/" target="_blank">\r
+                <a class="kiwi_logo" href="https://kiwiirc.com/" target="_blank">\r
                     <img src="<%base_path%>/assets/img/ico.png" alt="KiwiIRC Logo" title="Kiwi IRC" /> <br />\r
                     <h1>Powered by Kiwi IRC</h1>\r
                 </a>\r
 \r
                 <p style="font-style:italic;">A <strong>hand-crafted IRC client</strong> that you can enjoy. Designed to be used <strong>easily</strong> and <strong>freely</strong>.</p>\r
 \r
-                <p style="font-size:0.9em;margin-top:2em;">Peek at the <a href="http://www.kiwiirc.com/">Kiwi IRC homepage</a> for more information or to find out how to embed it on your own website. Looking for source code? Try the <a href="http://github.com/prawnsalad/KiwiIRC/">GitHub</a> page. This network of people may not be associated with Kiwi IRC itself.</p>\r
+                <p style="font-size:0.9em;margin-top:2em;">Peek at the <a href="https://kiwiirc.com/">Kiwi IRC homepage</a> for more information or to find out how to embed it on your own website. Looking for source code? Try the <a href="http://github.com/prawnsalad/KiwiIRC/">GitHub</a> page. This network of people may not be associated with Kiwi IRC itself.</p>\r
             </div>\r
         </div>\r
     </script>\r
                             <option value="relaxed">Relaxed</option>\r
                             <option value="mini">Mini</option>\r
                             <option value="cli">CLI</option>\r
+                            <option value="basic">Basic</option>\r
                         </select>\r
                     </td>\r
                 </tr>\r
                     <td class="setting"><input type="checkbox" class="setting-show_joins_parts" /></td>\r
                 </tr>\r
 \r
+                <tr>\r
+                    <td class="label">Show timestamps</td>\r
+                    <td class="setting"><input type="checkbox" class="setting-show_timestamps" /></td>\r
+                </tr>\r
+\r
                 <tr class="save">\r
                     <td colspan="2"><button class="save">Save</button>​​​​​​​​​</td>\r
                 </tr>\r
index 67bf66e58a0c5d0500b0213919308d20fe54205b..ba9313c41fbe237fe9f1e4b09258726ccaa48559 100644 (file)
@@ -142,11 +142,11 @@ _kiwi.model.Application = function () {
         this.populateDefaultServerSettings = function () {\r
             var parts;\r
             var defaults = {\r
-                nick: getQueryVariable('nick') || 'kiwi_?',\r
-                server: 'irc.kiwiirc.com',\r
+                nick: getQueryVariable('nick') || '',\r
+                server: '',\r
                 port: 6667,\r
                 ssl: false,\r
-                channel: window.location.hash || '#kiwiirc',\r
+                channel: window.location.hash || '#chat',\r
                 channel_key: ''\r
             };\r
             var uricheck;\r
@@ -248,7 +248,7 @@ _kiwi.model.Application = function () {
             // If any settings have been given by the server.. override any auto detected settings\r
             /**\r
              * Get any server restrictions as set in the server config\r
-             * These settings can not changed in the server selection dialog\r
+             * These settings can not be changed in the server selection dialog\r
              */\r
             if (this.server_settings && this.server_settings.connection) {\r
                 if (this.server_settings.connection.server) {\r
@@ -424,6 +424,11 @@ _kiwi.model.Application = function () {
                 var panel,\r
                     is_pm = (event.channel == _kiwi.gateway.get('nick'));\r
 \r
+                // An ignored user? don't do anything with it\r
+                if (gw.isNickIgnored(event.nick)) {\r
+                    return;\r
+                }\r
+\r
                 if (is_pm) {\r
                     // If a panel isn't found for this PM, create one\r
                     panel = that.panels.getByName(event.nick);\r
@@ -440,12 +445,17 @@ _kiwi.model.Application = function () {
                         panel = that.panels.server;\r
                     }\r
                 }\r
-                \r
+\r
                 panel.addMsg(event.nick, event.msg);\r
             });\r
 \r
 \r
             gw.on('onctcp_request', function (event) {\r
+                // An ignored user? don't do anything with it\r
+                if (gw.isNickIgnored(event.nick)) {\r
+                    return;\r
+                }\r
+\r
                 // Reply to a TIME ctcp\r
                 if (event.msg.toUpperCase() === 'TIME') {\r
                     gw.ctcp(false, event.type, event.nick, (new Date()).toString());\r
@@ -454,6 +464,11 @@ _kiwi.model.Application = function () {
 \r
 \r
             gw.on('onctcp_response', function (event) {\r
+                // An ignored user? don't do anything with it\r
+                if (gw.isNickIgnored(event.nick)) {\r
+                    return;\r
+                }\r
+                \r
                 that.panels.server.addMsg('[' + event.nick + ']', 'CTCP ' + event.msg);\r
             });\r
 \r
@@ -461,6 +476,11 @@ _kiwi.model.Application = function () {
             gw.on('onnotice', function (event) {\r
                 var panel;\r
 \r
+                // An ignored user? don't do anything with it\r
+                if (event.nick && gw.isNickIgnored(event.nick)) {\r
+                    return;\r
+                }\r
+\r
                 // Find a panel for the destination(channel) or who its from\r
                 panel = that.panels.getByName(event.target) || that.panels.getByName(event.nick);\r
                 if (!panel) {\r
@@ -475,6 +495,11 @@ _kiwi.model.Application = function () {
                 var panel,\r
                     is_pm = (event.channel == _kiwi.gateway.get('nick'));\r
 \r
+                // An ignored user? don't do anything with it\r
+                if (gw.isNickIgnored(event.nick)) {\r
+                    return;\r
+                }\r
+\r
                 if (is_pm) {\r
                     // If a panel isn't found for this PM, create one\r
                     panel = that.panels.getByName(event.nick);\r
@@ -834,7 +859,7 @@ _kiwi.model.Application = function () {
 \r
             controlbox.on('command:clear', clearCommand);\r
 \r
-            controlbox.on('command_ctcp', ctcpCommand);\r
+            controlbox.on('command:ctcp', ctcpCommand);\r
 \r
 \r
             controlbox.on('command:css', function (ev) {\r
@@ -861,11 +886,24 @@ _kiwi.model.Application = function () {
                     ev.params.shift();\r
 \r
                     value = ev.params.join(' ');\r
+\r
+                    // If we're setting a true boolean value..\r
+                    if (value === 'true')\r
+                        value = true;\r
+\r
+                    // If we're setting a false boolean value..\r
+                    if (value === 'false')\r
+                        value = false;\r
+\r
+                    // If we're setting a number..\r
+                    if (parseInt(value, 10).toString() === value)\r
+                        value = parseInt(value, 10);\r
+\r
                     _kiwi.global.settings.set(setting, value);\r
                 }\r
 \r
                 // Read the value to the user\r
-                _kiwi.app.panels.active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting));\r
+                _kiwi.app.panels.active.addMsg('', setting + ' = ' + _kiwi.global.settings.get(setting).toString());\r
             });\r
 \r
 \r
@@ -906,6 +944,48 @@ _kiwi.model.Application = function () {
                 controlbox.preprocessor.aliases[name] = rule;\r
             });\r
 \r
+            \r
+            controlbox.on('command:ignore', function (ev) {\r
+                var list = _kiwi.gateway.get('ignore_list');\r
+\r
+                // No parameters passed so list them\r
+                if (!ev.params[0]) {\r
+                    if (list.length > 0) {\r
+                        _kiwi.app.panels.active.addMsg(' ', 'Ignored nicks:');\r
+                        $.each(list, function (idx, ignored_pattern) {\r
+                            _kiwi.app.panels.active.addMsg(' ', ignored_pattern);\r
+                        });\r
+                    } else {\r
+                        _kiwi.app.panels.active.addMsg(' ', 'Not ignoring anybody');\r
+                    }\r
+                    return;\r
+                }\r
+\r
+                // We have a parameter, so add it\r
+                list.push(ev.params[0]);\r
+                _kiwi.gateway.set('ignore_list', list);\r
+                _kiwi.app.panels.active.addMsg(' ', 'Ignoring ' + ev.params[0]);\r
+            });\r
+\r
+\r
+            controlbox.on('command:unignore', function (ev) {\r
+                var list = _kiwi.gateway.get('ignore_list');\r
+\r
+                if (!ev.params[0]) {\r
+                    _kiwi.app.panels.active.addMsg(' ', 'Specifiy which nick you wish to stop ignoring');\r
+                    return;\r
+                }\r
+\r
+                list = _.reject(list, function(pattern) {\r
+                    return pattern === ev.params[0];\r
+                });\r
+\r
+                _kiwi.gateway.set('ignore_list', list);\r
+\r
+                _kiwi.app.panels.active.addMsg(' ', 'Stopped ignoring ' + ev.params[0]);\r
+            });\r
+\r
+\r
             controlbox.on('command:applet', appletCommand);\r
             controlbox.on('command:settings', settingsCommand);\r
             controlbox.on('command:script', scriptCommand);\r
@@ -925,10 +1005,22 @@ _kiwi.model.Application = function () {
 \r
             channel_names = ev.params.join(' ').split(',');\r
 \r
-            $.each(channel_names, function (index, channel_name) {\r
+            $.each(channel_names, function (index, channel_name_key) {\r
+                // We may have a channel key so split it off\r
+                var spli = channel_name_key.split(' '),\r
+                    channel_name = spli[0],\r
+                    channel_key = spli[1] || '';\r
+\r
                 // Trim any whitespace off the name\r
                 channel_name = channel_name.trim();\r
 \r
+                // If not a valid channel name, display a warning\r
+                if (!that.isChannelName(channel_name)) {\r
+                    _kiwi.app.panels.server.addMsg('', channel_name + ' is not a valid channel name');\r
+                    _kiwi.app.message.text(channel_name + ' is not a valid channel name', {timeout: 5000});\r
+                    return;\r
+                }\r
+\r
                 // Check if we have the panel already. If not, create it\r
                 channel = that.panels.getByName(channel_name);\r
                 if (!channel) {\r
@@ -936,7 +1028,7 @@ _kiwi.model.Application = function () {
                     _kiwi.app.panels.add(channel);\r
                 }\r
 \r
-                _kiwi.gateway.join(channel_name);\r
+                _kiwi.gateway.join(channel_name, channel_key);\r
             });\r
 \r
             if (channel) channel.view.show();\r
index 31766ea9e2999be4a02859f7a33dfbe43262e950..19fd043401bd119707d778e9e3db26a6355c29f7 100644 (file)
@@ -38,7 +38,13 @@ _kiwi.model.Gateway = function () {
         *   The URL to the Kiwi server\r
         *   @type   String\r
         */\r
-        kiwi_server: '//kiwi'\r
+        kiwi_server: '//kiwi',\r
+\r
+        /**\r
+        *   List of nicks we are ignoring\r
+        *   @type Array\r
+        */\r
+        ignore_list: []\r
     };\r
 \r
 \r
@@ -259,8 +265,7 @@ _kiwi.model.Gateway = function () {
                 $.each(data.options, function (name, value) {\r
                     switch (name) {\r
                     case 'CHANTYPES':\r
-                        // TODO: Check this. Why is it only getting the first char?\r
-                        that.set('channel_prefix', value.join('').charAt(0));\r
+                        that.set('channel_prefix', value.join(''));\r
                         break;\r
                     case 'NETWORK':\r
                         that.set('name', value);\r
@@ -515,5 +520,23 @@ _kiwi.model.Gateway = function () {
     };\r
 \r
 \r
+    // Check a nick alongside our ignore list\r
+    this.isNickIgnored = function (nick) {\r
+        var idx, list = this.get('ignore_list');\r
+        var pattern, regex;\r
+\r
+        for (idx = 0; idx < list.length; idx++) {\r
+            pattern = list[idx].replace(/([.+^$[\]\\(){}|-])/g, "\\$1")\r
+                .replace('*', '.*')\r
+                .replace('?', '.');\r
+\r
+            regex = new RegExp(pattern, 'i');\r
+            if (regex.test(nick)) return true;\r
+        }\r
+\r
+        return false;\r
+    }\r
+\r
+\r
     return new (Backbone.Model.extend(this))(arguments);\r
 };
\ No newline at end of file
index 5fdcc9c132ba5c50d68de852a385688fb3a6f81d..34ed74624a2c07538ba717d5e43a509f92b386ab 100644 (file)
@@ -44,13 +44,15 @@ _kiwi.model.Panel = Backbone.Model.extend({
 \r
         // Update the scrollback\r
         bs = this.get("scrollback");\r
-        bs.push(message_obj);\r
-\r
-        // Keep the scrolback limited\r
-        if (bs.length > scrollback) {\r
-            bs.splice(scrollback);\r
+        if (bs) {\r
+            bs.push(message_obj);\r
+\r
+            // Keep the scrolback limited\r
+            if (bs.length > scrollback) {\r
+                bs.splice(scrollback);\r
+            }\r
+            this.set({"scrollback": bs}, {silent: true});\r
         }\r
-        this.set({"scrollback": bs}, {silent: true});\r
 \r
         this.trigger("msg", message_obj);\r
     },\r
index 0e20aec8ef9c6c2f19641bfe1d2421cc0120205f..d9522a1e6783d561ff63d0b24efbe026a3721a9a 100644 (file)
@@ -150,6 +150,15 @@ _kiwi.view.ServerSelect = function () {
         },\r
 \r
         submitForm: function (event) {\r
+            event.preventDefault();\r
+\r
+            // Make sure a nick is chosen\r
+            if (!$('input.nick', this.$el).val().trim()) {\r
+                this.setStatus('Select a nickname first!');\r
+                $('input.nick', this.$el).select();\r
+                return;\r
+            }\r
+\r
             if (state === 'nick_change') {\r
                 this.submitNickChange(event);\r
             } else {\r
@@ -157,7 +166,7 @@ _kiwi.view.ServerSelect = function () {
             }\r
 \r
             $('button', this.$el).attr('disabled', 1);\r
-            return false;\r
+            return;\r
         },\r
 \r
         submitLogin: function (event) {\r
@@ -245,7 +254,7 @@ _kiwi.view.ServerSelect = function () {
             $('.status', this.$el)\r
                 .text(text)\r
                 .attr('class', 'status')\r
-                .addClass(class_name)\r
+                .addClass(class_name||'')\r
                 .show();\r
         },\r
         clearStatus: function () {\r
@@ -884,12 +893,20 @@ _kiwi.view.ControlBox = Backbone.View.extend({
             }\r
             \r
             (function () {\r
-                var tokens = inp_val.substring(0, inp[0].selectionStart).split(' '),\r
-                    val,\r
-                    p1,\r
-                    newnick,\r
-                    range,\r
-                    nick = tokens[tokens.length - 1];\r
+                var tokens,              // Words before the cursor position\r
+                    val,                 // New value being built up\r
+                    p1,                  // Position in the value just before the nick \r
+                    newnick,             // New nick to be displayed (cycles through)\r
+                    range,               // TextRange for setting new text cursor position\r
+                    nick,                // Current nick in the value\r
+                    trailing = ': ';     // Text to be inserted after a tabbed nick\r
+\r
+                tokens = inp_val.substring(0, inp[0].selectionStart).split(' ');\r
+                if (tokens[tokens.length-1] == ':')\r
+                    tokens.pop();\r
+\r
+                nick  = tokens[tokens.length - 1];\r
+\r
                 if (this.tabcomplete.prefix === '') {\r
                     this.tabcomplete.prefix = nick;\r
                 }\r
@@ -899,21 +916,31 @@ _kiwi.view.ControlBox = Backbone.View.extend({
                 });\r
 \r
                 if (this.tabcomplete.data.length > 0) {\r
+                    // Get the current value before cursor position\r
                     p1 = inp[0].selectionStart - (nick.length);\r
                     val = inp_val.substr(0, p1);\r
+\r
+                    // Include the current selected nick\r
                     newnick = this.tabcomplete.data.shift();\r
                     this.tabcomplete.data.push(newnick);\r
                     val += newnick;\r
+\r
+                    if (inp_val.substr(inp[0].selectionStart, 2) !== trailing)\r
+                        val += trailing;\r
+\r
+                    // Now include the rest of the current value\r
                     val += inp_val.substr(inp[0].selectionStart);\r
+\r
                     inp.val(val);\r
 \r
+                    // Move the cursor position to the end of the nick\r
                     if (inp[0].setSelectionRange) {\r
-                        inp[0].setSelectionRange(p1 + newnick.length, p1 + newnick.length);\r
+                        inp[0].setSelectionRange(p1 + newnick.length + trailing.length, p1 + newnick.length + trailing.length);\r
                     } else if (inp[0].createTextRange) { // not sure if this bit is actually needed....\r
                         range = inp[0].createTextRange();\r
                         range.collapse(true);\r
-                        range.moveEnd('character', p1 + newnick.length);\r
-                        range.moveStart('character', p1 + newnick.length);\r
+                        range.moveEnd('character', p1 + newnick.length + trailing.length);\r
+                        range.moveStart('character', p1 + newnick.length + trailing.length);\r
                         range.select();\r
                     }\r
                 }\r
@@ -983,7 +1010,7 @@ _kiwi.view.StatusMessage = Backbone.View.extend({
         opt.timeout = opt.timeout || 5000;\r
 \r
         this.$el.text(text).attr('class', opt.type);\r
-        this.$el.slideDown(_kiwi.app.view.doLayout);\r
+        this.$el.slideDown($.proxy(_kiwi.app.view.doLayout, this));\r
 \r
         if (opt.timeout) this.doTimeout(opt.timeout);\r
     },\r
@@ -1001,7 +1028,7 @@ _kiwi.view.StatusMessage = Backbone.View.extend({
     },\r
 \r
     hide: function () {\r
-        this.$el.slideUp(_kiwi.app.view.doLayout);\r
+        this.$el.slideUp($.proxy(_kiwi.app.view.doLayout, this));\r
     },\r
 \r
     doTimeout: function (length) {\r
@@ -1063,9 +1090,11 @@ _kiwi.view.AppToolbar = Backbone.View.extend({
 \r
 _kiwi.view.Application = Backbone.View.extend({\r
     initialize: function () {\r
-        $(window).resize(this.doLayout);\r
-        $('#toolbar').resize(this.doLayout);\r
-        $('#controlbox').resize(this.doLayout);\r
+        var that = this;\r
+\r
+        $(window).resize(function() { that.doLayout.apply(that); });\r
+        $('#toolbar').resize(function() { that.doLayout.apply(that); });\r
+        $('#controlbox').resize(function() { that.doLayout.apply(that); });\r
 \r
         // Change the theme when the config is changed\r
         _kiwi.global.settings.on('change:theme', this.updateTheme, this);\r
@@ -1074,6 +1103,9 @@ _kiwi.view.Application = Backbone.View.extend({
         _kiwi.global.settings.on('change:channel_list_style', this.setTabLayout, this);\r
         this.setTabLayout(_kiwi.global.settings.get('channel_list_style'));\r
 \r
+        _kiwi.global.settings.on('change:show_timestamps', this.displayTimestamps, this);\r
+        this.displayTimestamps(_kiwi.global.settings.get('show_timestamps'));\r
+\r
         this.doLayout();\r
 \r
         $(document).keydown(this.setKeyFocus);\r
@@ -1123,6 +1155,20 @@ _kiwi.view.Application = Backbone.View.extend({
     },\r
 \r
 \r
+    displayTimestamps: function (show_timestamps) {\r
+        // If called by the settings callback, get the correct new_value\r
+        if (show_timestamps === _kiwi.global.settings) {\r
+            show_timestamps = arguments[1];\r
+        }\r
+\r
+        if (show_timestamps) {\r
+            this.$el.addClass('timestamps');\r
+        } else {\r
+            this.$el.removeClass('timestamps');\r
+        }\r
+    },\r
+\r
+\r
     // Globally shift focus to the command input box on a keypress\r
     setKeyFocus: function (ev) {\r
         // If we're copying text, don't shift focus\r
@@ -1140,12 +1186,12 @@ _kiwi.view.Application = Backbone.View.extend({
 \r
 \r
     doLayout: function () {\r
-        var el_kiwi = $('#kiwi');\r
-        var el_panels = $('#panels');\r
-        var el_memberlists = $('#memberlists');\r
-        var el_toolbar = $('#toolbar');\r
-        var el_controlbox = $('#controlbox');\r
-        var el_resize_handle = $('#memberlists_resize_handle');\r
+        var el_kiwi = this.$el;\r
+        var el_panels = $('#kiwi #panels');\r
+        var el_memberlists = $('#kiwi #memberlists');\r
+        var el_toolbar = $('#kiwi #toolbar');\r
+        var el_controlbox = $('#kiwi #controlbox');\r
+        var el_resize_handle = $('#kiwi #memberlists_resize_handle');\r
 \r
         var css_heights = {\r
             top: el_toolbar.outerHeight(true),\r
@@ -1169,7 +1215,7 @@ _kiwi.view.Application = Backbone.View.extend({
 \r
         // If we have channel tabs on the side, adjust the height\r
         if (el_kiwi.hasClass('chanlist_treeview')) {\r
-            $('#kiwi #tabs').css(css_heights);\r
+            $('#tabs', el_kiwi).css(css_heights);\r
         }\r
 \r
         // Determine if we have a narrow window (mobile/tablet/or even small desktop window)\r
@@ -1191,6 +1237,9 @@ _kiwi.view.Application = Backbone.View.extend({
             // And move the handle just out of sight to the right\r
             el_resize_handle.css('left', el_panels.outerWidth(true));\r
         }\r
+\r
+        var input_wrap_width = parseInt($('#kiwi #controlbox .input_tools').outerWidth());\r
+        el_controlbox.find('.input_wrap').css('right', input_wrap_width + 7);\r
     },\r
 \r
 \r
@@ -1269,8 +1318,8 @@ _kiwi.view.Application = Backbone.View.extend({
         var that = this;\r
 \r
         if (!instant) {\r
-            $('#toolbar').slideUp({queue: false, duration: 400, step: this.doLayout});\r
-            $('#controlbox').slideUp({queue: false, duration: 400, step: this.doLayout});\r
+            $('#toolbar').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});\r
+            $('#controlbox').slideUp({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});\r
         } else {\r
             $('#toolbar').slideUp(0);\r
             $('#controlbox').slideUp(0);\r
@@ -1282,8 +1331,8 @@ _kiwi.view.Application = Backbone.View.extend({
         var that = this;\r
 \r
         if (!instant) {\r
-            $('#toolbar').slideDown({queue: false, duration: 400, step: this.doLayout});\r
-            $('#controlbox').slideDown({queue: false, duration: 400, step: this.doLayout});\r
+            $('#toolbar').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});\r
+            $('#controlbox').slideDown({queue: false, duration: 400, step: $.proxy(this.doLayout, this)});\r
         } else {\r
             $('#toolbar').slideDown(0);\r
             $('#controlbox').slideDown(0);\r
index 86b1b7c55089bd3d9299d6d34b966bf9cb473916..6d91eaa355c1bf589c2a4d723bff711f448bf479 100644 (file)
@@ -35,6 +35,15 @@ conf.servers.push({
 
 
 
+// Do we want to enable the built in Identd server?
+conf.identd = {
+    enabled: false,
+    port: 113,
+    address: "0.0.0.0"
+};
+
+
+
 
 
 
@@ -79,8 +88,8 @@ conf.webirc_pass = {
 
 // Some IRCDs require the clients IP via the username/ident
 conf.ip_as_username = [
-       "irc.network.com",
-       "127.0.0.1"
+    //"irc.network.com",
+    //"127.0.0.1"
 ];
 
 // Whether to verify IRC servers' SSL certificates against built-in well-known certificate authorities
@@ -158,7 +167,7 @@ conf.client = {
 };
 
 
-// If not empty, the client may only connect to this 1 IRC server
+// If set, the client may only connect to this 1 IRC server
 //conf.restrict_server = "irc.kiwiirc.com";
 //conf.restrict_server_port = 6667;
 //conf.restrict_server_ssl = false;
@@ -172,4 +181,4 @@ conf.client = {
 /*
  * Do not ammend the below lines unless you understand the changes!
  */
-module.exports.production = conf;
\ No newline at end of file
+module.exports.production = conf;
index 4bfeb1bf44beddcff72cef6c10b36c0e909a9bb9..66b5dd126a48bcd6751da2f915b7365c25bcc906 100755 (executable)
@@ -114,26 +114,14 @@ function kiwiCommand(command, callback) {
             if (command.hostname && command.port && command.nick) {
                 var con;
 
-                if (global.config.restrict_server) {
-                    this.state.connect(
-                        global.config.restrict_server,
-                        global.config.restrict_server_port,
-                        global.config.restrict_server_ssl,
-                        command.nick,
-                        {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.real_address},
-                        global.config.restrict_server_password,
-                        callback);
-
-                } else {
-                    this.state.connect(
-                        command.hostname,
-                        command.port,
-                        command.ssl,
-                        command.nick,
-                        {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.real_address},
-                        command.password,
-                        callback);
-                }
+                this.state.connect(
+                    (global.config.restrict_server || command.hostname),
+                    (global.config.restrict_server_port || command.port),
+                    (global.config.restrict_server_ssl || command.ssl),
+                    command.nick,
+                    {hostname: this.websocket.handshake.revdns, address: this.websocket.handshake.real_address},
+                    (global.config.restrict_server_password || command.password),
+                    callback);
             } else {
                 return callback('Hostname, port and nickname must be specified');
             }
@@ -155,4 +143,4 @@ function websocketDisconnect() {
 // TODO: Should this close all the websocket connections too?
 function websocketError() {
     this.dispose();
-}
\ No newline at end of file
+}
diff --git a/server/identd.js b/server/identd.js
new file mode 100644 (file)
index 0000000..2a8bfa5
--- /dev/null
@@ -0,0 +1,46 @@
+var net = require('net');
+
+function IdentdServer(opts) {
+
+    // Option defaults
+    opts = opts || {};
+    opts.bind_addr = opts.bind_addr || '0.0.0.0';
+    opts.bind_port = opts.bind_port || 113;
+    opts.system_id = opts.system_id || 'UNIX-KiwiIRC';
+    opts.user_id = opts.user_id || 'kiwi';
+
+
+    var server = net.createServer(function(socket) {
+        var user, system;
+
+        if (typeof opts.user_id === 'function') {
+            user = opts.user_id(socket).toString();
+        } else {
+            user = opts.user_id.toString();
+        }
+
+        if (typeof opts.system_id === 'function') {
+            system = opts.system_id(socket).toString();
+        } else {
+            system = opts.system_id.toString();
+        }
+
+        socket.end('25,25 : USERID : ' + system + ' : ' + user);
+    });
+
+    server.on('listening', function() {
+        console.log('Ident Server listening on ' + server.address().address + ':' +  server.address().port);
+    });
+
+
+    this.start = function() {
+        server.listen(opts.bind_port, opts.bind_addr);
+    };
+
+    this.stop = function(callback) {
+        server.close(callback);
+    };
+}
+
+
+module.exports = IdentdServer;
\ No newline at end of file
index dc7c18055eadb3e14530e72da9613ee4b01679fc..819e06c5a532546e606acd016952563641a5a52b 100644 (file)
@@ -101,12 +101,12 @@ function onMsg(event) {
 
 
 function onNotice(event) {
-    this.irc_connection.clientEvent('msg', {
+    this.irc_connection.clientEvent('notice', {
         nick: event.nick,
         ident: event.ident,
         hostname: event.hostname,
-        channel: this.name,
-        msg: event.trailing
+        target: event.target,
+        msg: event.msg
     });
 };
 
index aa531bee12fc87bf60cf2abe0aed1b5e2b34ba6a..cd99df446a09792fbfcef39ebde25eb785711d94 100755 (executable)
@@ -35,26 +35,14 @@ module.exports = State;
 State.prototype.connect = function (hostname, port, ssl, nick, user, pass, callback) {
     var that = this;
     var con, con_num;
-    if (global.config.restrict_server) {
-        con = new IrcConnection(
-            global.config.restrict_server,
-            global.config.restrict_server_port,
-            global.config.restrict_server_ssl,
-            nick,
-            user,
-            global.config.restrict_server_password,
-            this);
-
-    } else {
-        con = new IrcConnection(
-            hostname,
-            port,
-            ssl,
-            nick,
-            user,
-            pass,
-            this);
-    }
+    con = new IrcConnection(
+        hostname,
+        port,
+        ssl,
+        nick,
+        user,
+        pass,
+        this);
     
     con_num = this.next_connection++;
     this.irc_connections[con_num] = con;
index 3f426a9f558f376b061932d0bddfdb145b442d9f..014cac09a19ff74f40424b5f530d6da97614fb17 100755 (executable)
@@ -3,7 +3,8 @@ var fs          = require('fs'),
     WebListener = require('./weblistener.js'),
     config      = require('./configuration.js'),
     rehash      = require('./rehash.js'),
-    modules     = require('./modules.js');
+    modules     = require('./modules.js'),
+    Identd      = require('./identd.js');
 
 
 
@@ -13,7 +14,7 @@ config.loadConfig();
 
 // If we're not running in the forground and we have a log file.. switch
 // console.log to output to a file
-if (process.argv.indexOf('-f') === -1 && global.config.log) {
+if (process.argv.indexOf('-f') === -1 && global.config && global.config.log) {
     (function () {
         var log_file_name = global.config.log;
 
@@ -111,6 +112,19 @@ global.clients = {
 
 
 
+/*
+ * Identd server
+ */
+if (global.config.identd && global.config.identd.enabled) {
+    new Identd({
+        bind_addr: global.config.identd.address,
+        bind_port: global.config.identd.port
+    }).start();
+}
+
+
+
+
 /*
  * Web listeners
  */