diff --git a/public/css/theme_default.css b/public/css/theme_default.css index 3a68ffc..afaa9dc 100644 --- a/public/css/theme_default.css +++ b/public/css/theme_default.css @@ -227,6 +227,15 @@ .message .arrowout { color: #dc0f00; } +.message.m_ctcp_response, +.message.m_ctcp_request { + color: #39b7dd; + font-weight: bold; +} +.message.m_ctcp_response .asterisk, +.message.m_ctcp_request .asterisk { + color: #05abe0; +} .message.m_quit, .message.m_part, .message.m_kick { diff --git a/public/css/theme_night.css b/public/css/theme_night.css index 6a51dde..645cfe2 100644 --- a/public/css/theme_night.css +++ b/public/css/theme_night.css @@ -242,6 +242,15 @@ a:hover { .message .arrowout { color: #dc0f00; } +.message.m_ctcp_response, +.message.m_ctcp_request { + color: #39b7dd; + font-weight: bold; +} +.message.m_ctcp_response .asterisk, +.message.m_ctcp_request .asterisk { + color: #05abe0; +} .message.m_quit, .message.m_part, .message.m_kick { @@ -352,11 +361,11 @@ a:hover { } .message .irc-bg11, .topicbar .irc-bg11 { - background-color: #0ff; + background-color: #00d2d2; } .message .irc-bg12, .topicbar .irc-bg12 { - background-color: #0091bd; + background-color: #004aff; } .message .irc-bg13, .topicbar .irc-bg13 { @@ -440,7 +449,7 @@ a:hover { } .message .irc-fg12, .topicbar .irc-fg12 { - color: #00f; + color: #004aff; } .message .irc-fg13, .topicbar .irc-fg13 { diff --git a/public/js/main.js b/public/js/main.js index 0a874e1..d5bf89d 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -321,6 +321,14 @@ let composer = { element.innerHTML += " "+sender+""; element.innerHTML += " "+message+""; break; + case "ctcp_response": + element.innerHTML += " CTCP response from "+sender+" "; + element.innerHTML += ""+message+""; + break; + case "ctcp_request": + element.innerHTML += " CTCP request to "+sender+" "; + element.innerHTML += ""+message+""; + break; default: if(sender) { element.innerHTML += ""+sender+" "+message+""; @@ -454,6 +462,17 @@ let commands = { irc.socket.emit("userinput", {command: "privmsg", server: buffer.server, message: listargs.slice(2).join(" "), arguments: [listargs[1]]}); }, description: " - Sends a message to target.", aliases: ['privmsg', 'q', 'query', 'say']}, + ctcp: {execute: function(buffer, handler, command, message, listargs) { + if(!listargs[1] || !listargs[2]) + return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!'); + if(listargs[1] == '*') + listargs[1] = buffer.name; + + listargs[2] = listargs[2].toUpperCase(); + + irc.socket.emit("userinput", {command: "ctcp", server: buffer.server, message: listargs.slice(2).join(" "), arguments: listargs.slice(1)}); + }, description: " [arguments] - Sends a CTCP request to target."}, + notice: {execute: function(buffer, handler, command, message, listargs) { if(!listargs[1] || !listargs[2]) return handler.commandError(buffer, listargs[0].toUpperCase()+': Missing parameters!'); @@ -1345,7 +1364,10 @@ class InputHandler { } keyUpHandle(e, key) { - if(key == 38 || key == 40 || key == 9) return; + if(key == 38 || key == 40) { + clientdom.input.selectionStart = clientdom.input.value.length; + clientdom.input.selectionEnd = clientdom.input.value.length; + } else if(key == 9) return; let input = clientdom.input.value; let word = input.split(/ |\n/).pop(); @@ -1360,6 +1382,7 @@ class InputHandler { for(let n in this.tabWords) this.tabWords[n] += ": "; } + } keyDownHandle(e, key) { @@ -1374,8 +1397,6 @@ class InputHandler { if(selection) { clientdom.input.value = selection; - clientdom.input.selectionStart = selection.length; - clientdom.input.selectionEnd = selection.length; this.tabCompleteReset(); } @@ -1392,8 +1413,6 @@ class InputHandler { if(!this.history[this.historyCaret]) selection = ''; - clientdom.input.selectionStart = selection.length; - clientdom.input.selectionEnd = selection.length; clientdom.input.value = selection; this.tabCompleteReset(); diff --git a/public/stylus/theme_default.styl b/public/stylus/theme_default.styl index 7932a8d..94b036c 100644 --- a/public/stylus/theme_default.styl +++ b/public/stylus/theme_default.styl @@ -178,6 +178,11 @@ box-shadow() color: #00ab00 .arrowout color: #dc0f00 + &.m_ctcp_response, &.m_ctcp_request + color: #39b7dd + font-weight: bold + .asterisk + color: #05abe0 &.m_quit, &.m_part, &.m_kick color: red &.m_join diff --git a/public/stylus/theme_night.styl b/public/stylus/theme_night.styl index d356b1f..7879625 100644 --- a/public/stylus/theme_night.styl +++ b/public/stylus/theme_night.styl @@ -188,6 +188,11 @@ a:hover color: #00ab00 .arrowout color: #dc0f00 + &.m_ctcp_response, &.m_ctcp_request + color: #39b7dd + font-weight: bold + .asterisk + color: #05abe0 &.m_quit, &.m_part, &.m_kick color: red &.m_join @@ -243,9 +248,9 @@ a:hover .irc-bg10 background-color: teal .irc-bg11 - background-color: cyan + background-color: #00d2d2 .irc-bg12 - background-color: #0091bd + background-color: #004aff .irc-bg13 background-color: pink .irc-bg14 @@ -277,7 +282,7 @@ a:hover .irc-fg11 color: #00d2d2 .irc-fg12 - color: blue + color: #004aff .irc-fg13 color: pink .irc-fg14 diff --git a/server/irc.js b/server/irc.js index f429779..37d5ce6 100644 --- a/server/irc.js +++ b/server/irc.js @@ -54,6 +54,18 @@ class IRCConnectionHandler { case "list": this.conn.write(data.command.toUpperCase()); break; + case "ctcp": + let ctcpmsg = ''; + + if(data.arguments[1].toLowerCase() == 'ping') + ctcpmsg = 'PING '+Math.floor(Date.now()/1000); + else + ctcpmsg = data.message; + + this.conn.write('PRIVMSG {0} :\x01{1}\x01'.format(data.arguments[0], ctcpmsg)); + this.conn.emit('pass_to_client', {type: "message", messageType: "ctcp_request", to: this.conn.config.nickname, + user: {nickname: data.arguments[0]}, message: ctcpmsg, server: data.server}); + break; default: this.conn.write(data.command.toUpperCase()+' '+data.message); } @@ -193,18 +205,29 @@ class IRCConnectionHandler { delete this.conn.queue["names"]; break; case "PRIVMSG": - let type = "privmsg"; - if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) return this.ctcpManage(line); if(line.user.nickname != "") - this.conn.emit('pass_to_client', {type: "message", messageType: type, to: line.arguments[0], + this.conn.emit('pass_to_client', {type: "message", messageType: "privmsg", to: line.arguments[0], user: line.user, message: line.trailing, server: serverName}); else - this.conn.emit('pass_to_client', {type: "server_message", messageType: type, message: line.trailing, server: serverName, from: realServerName}); + this.conn.emit('pass_to_client', {type: "server_message", messageType: "privmsg", message: line.trailing, server: serverName, from: realServerName}); break; case "NOTICE": + if(line.trailing.indexOf('\x01') == 0 && line.trailing.indexOf('\x01ACTION') != 0) { + let composethis = line.trailing.replace(/\x01/g,'').trim().split(" "); + composethis[0] = composethis[0].toUpperCase(); + let message = composethis.join(" "); + + if(composethis[0] == 'PING') + message = Math.floor(Date.now()/1000) - composethis[1]+"s"; + + this.conn.emit('pass_to_client', {type: "message", messageType: "ctcp_response", to: line.arguments[0], + user: line.user, message: message, server: serverName}); + return; + } + if(line.user.nickname != "") this.conn.emit('pass_to_client', {type: "message", messageType: "notice", to: line.arguments[0], user: line.user, message: line.trailing, server: serverName}); @@ -386,6 +409,10 @@ class IRCConnectionHandler { this.conn.emit('pass_to_client', {type: "listedchan", channel: line.arguments[1], users: line.arguments[2], topic: line.trailing, server: serverName, from: realServerName}); break; + case "CAP": + // might come in the future, who knows + this.conn.write("CAP END"); + break; } } } diff --git a/server/parser.js b/server/parser.js index dff41fc..827e5d4 100644 --- a/server/parser.js +++ b/server/parser.js @@ -3,6 +3,23 @@ // or // :hostname command arg ume nts :trailing +function parseERROR(line) { + let final = { + user: { nickname: "", username: "", hostname: "" }, + command: "ERROR", + message: "", + raw: line.join(" ") + } + + let pass1 = line.slice(1).join(" "); + if(pass1.indexOf(":") == 0) + pass1 = pass1.substring(1); + + final.message = pass1; + + return final; +} + module.exports = function(rawline) { let final = { user: { @@ -10,7 +27,7 @@ module.exports = function(rawline) { username: "", hostname: "" }, - command: "error", + command: "", arguments: [], trailing: "", raw: rawline @@ -18,7 +35,7 @@ module.exports = function(rawline) { let pass1 = (rawline.indexOf(':') == 0 ? rawline.substring(1).split(" ") : rawline.split(" ")); if (pass1[0] === "ERROR") - return final; + return parseERROR(pass1); if(pass1[0].indexOf("!") != -1) { let nickuser = pass1[0].split('!'); diff --git a/teemant.js b/teemant.js index 7814828..73b7388 100755 --- a/teemant.js +++ b/teemant.js @@ -159,21 +159,12 @@ io.sockets.on('connection', function (socket) { } newConnection.on('connerror', (data) => { - let message = "An error occured"; - let inconnect = true; - - if(data['message']) - message = data.message; - - if(newConnection.authenticated == false) { - message = "Failed to connect to the server!"; - inconnect = false; - } - if(config.server.debug) console.log(data); - socket.emit('act_client', {type: (inconnect == true ? 'server_message' : 'connect_message'), server: connectiondata.server, message: message, error: true}); + if(newConnection.authenticated == false) + socket.emit('act_client', {type: 'connect_message', server: connectiondata.server, + message: "Failed to connect to the server!", error: true}); }); newConnection.on('pass_to_client', (data) => { @@ -181,21 +172,13 @@ io.sockets.on('connection', function (socket) { }); newConnection.on('closed', (data) => { - let message = "Connection closed"; - let inconnect = true; + if(config.server.debug) + console.log(data); - if(newConnection.authenticated == false) { - message = "Failed to connect to the server!"; - - if(config.server.debug) - console.log(data); - - inconnect = false; - } - - socket.emit('act_client', {type: (inconnect == true ? 'server_message' : 'connect_message'), server: connectiondata.server, message: message, error: true}); - - if(inconnect) + if(newConnection.authenticated == false) + socket.emit('act_client', {type: 'connect_message', server: connectiondata.server, + message: "Failed to connect to the server!", error: true}); + else socket.emit('act_client', {type: 'event_server_quit', server: connectiondata.server}); }); });