+void CoreUserInputHandler::handleAway(const BufferInfo &bufferInfo, const QString &msg,
+ const bool skipFormatting)
+{
+ Q_UNUSED(bufferInfo)
+ if (msg.startsWith("-all")) {
+ if (msg.length() == 4) {
+ coreSession()->globalAway(QString(), skipFormatting);
+ return;
+ }
+ Q_ASSERT(msg.length() > 4);
+ if (msg[4] == ' ') {
+ coreSession()->globalAway(msg.mid(5), skipFormatting);
+ return;
+ }
+ }
+ issueAway(msg, true /* force away */, skipFormatting);
+}
+
+
+void CoreUserInputHandler::issueAway(const QString &msg, bool autoCheck, const bool skipFormatting)
+{
+ QString awayMsg = msg;
+ IrcUser *me = network()->me();
+
+ // Only apply timestamp formatting when requested
+ // This avoids re-processing any existing away message when the core restarts, so chained escape
+ // percent signs won't get down-processed.
+ if (!skipFormatting) {
+ // Apply the timestamp formatting to the away message (if empty, nothing will happen)
+ awayMsg = formatCurrentDateTimeInString(awayMsg);
+ }
+
+ // if there is no message supplied we have to check if we are already away or not
+ if (autoCheck && msg.isEmpty()) {
+ if (me && !me->isAway()) {
+ Identity *identity = network()->identityPtr();
+ if (identity) {
+ awayMsg = formatCurrentDateTimeInString(identity->awayReason());
+ }
+ if (awayMsg.isEmpty()) {
+ awayMsg = tr("away");
+ }
+ }
+ }
+ if (me)
+ me->setAwayMessage(awayMsg);
+
+ putCmd("AWAY", serverEncode(awayMsg));
+}
+
+
+void CoreUserInputHandler::handleBan(const BufferInfo &bufferInfo, const QString &msg)
+{
+ banOrUnban(bufferInfo, msg, true);
+}
+
+
+void CoreUserInputHandler::handleUnban(const BufferInfo &bufferInfo, const QString &msg)
+{
+ banOrUnban(bufferInfo, msg, false);
+}
+
+
+void CoreUserInputHandler::banOrUnban(const BufferInfo &bufferInfo, const QString &msg, bool ban)
+{
+ QString banChannel;
+ QString banUser;
+
+ QStringList params = msg.split(" ");
+
+ if (!params.isEmpty() && isChannelName(params[0])) {
+ banChannel = params.takeFirst();
+ }
+ else if (bufferInfo.type() == BufferInfo::ChannelBuffer) {
+ banChannel = bufferInfo.bufferName();
+ }
+ else {
+ emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", QString("Error: channel unknown in command: /BAN %1").arg(msg));
+ return;
+ }
+
+ if (!params.isEmpty() && !params.contains("!") && network()->ircUser(params[0])) {
+ IrcUser *ircuser = network()->ircUser(params[0]);
+ // generalizedHost changes <nick> to *!ident@*.sld.tld.
+ QString generalizedHost = ircuser->host();
+ if (generalizedHost.isEmpty()) {
+ emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", QString("Error: host unknown in command: /BAN %1").arg(msg));
+ return;
+ }
+
+ static QRegExp ipAddress("\\d+\\.\\d+\\.\\d+\\.\\d+");
+ if (ipAddress.exactMatch(generalizedHost)) {
+ int lastDotPos = generalizedHost.lastIndexOf('.') + 1;
+ generalizedHost.replace(lastDotPos, generalizedHost.length() - lastDotPos, '*');
+ }
+ else if (generalizedHost.lastIndexOf(".") != -1 && generalizedHost.lastIndexOf(".", generalizedHost.lastIndexOf(".")-1) != -1) {
+ int secondLastPeriodPosition = generalizedHost.lastIndexOf(".", generalizedHost.lastIndexOf(".")-1);
+ generalizedHost.replace(0, secondLastPeriodPosition, "*");
+ }
+ banUser = QString("*!%1@%2").arg(ircuser->user(), generalizedHost);
+ }
+ else {
+ banUser = params.join(" ");
+ }
+
+ QString banMode = ban ? "+b" : "-b";
+ QString banMsg = QString("MODE %1 %2 %3").arg(banChannel, banMode, banUser);
+ emit putRawLine(serverEncode(banMsg));
+}
+
+
+void CoreUserInputHandler::handleCtcp(const BufferInfo &bufferInfo, const QString &msg)
+{
+ Q_UNUSED(bufferInfo)
+
+ QString nick = msg.section(' ', 0, 0);
+ QString ctcpTag = msg.section(' ', 1, 1).toUpper();
+ if (ctcpTag.isEmpty())
+ return;
+
+ QString message = msg.section(' ', 2);
+ QString verboseMessage = tr("sending CTCP-%1 request to %2").arg(ctcpTag).arg(nick);
+
+ if (ctcpTag == "PING") {
+ message = QString::number(QDateTime::currentMSecsSinceEpoch());
+ }
+
+ // FIXME make this a proper event
+ coreNetwork()->coreSession()->ctcpParser()->query(coreNetwork(), nick, ctcpTag, message);
+ emit displayMsg(Message::Action, BufferInfo::StatusBuffer, "", verboseMessage,
+ network()->myNick(), Message::Flag::Self);
+}
+
+
+void CoreUserInputHandler::handleDelkey(const BufferInfo &bufferInfo, const QString &msg)
+{
+ QString bufname = bufferInfo.bufferName().isNull() ? "" : bufferInfo.bufferName();
+#ifdef HAVE_QCA2
+ if (!bufferInfo.isValid())
+ return;
+
+ if (!Cipher::neededFeaturesAvailable()) {
+ emit displayMsg(Message::Error, typeByTarget(bufname), bufname, tr("Error: QCA provider plugin not found. It is usually provided by the qca-ossl plugin."));
+ return;
+ }