ircchanneladapter.cpp
1 //------------------------------------------------------------------------------
2 // ircchanneladapter.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2010 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "irc/configuration/ircconfig.h"
24 #include "irc/ircglobal.h"
25 #include "irc/ircmessageclass.h"
26 #include "irc/ircnetworkadapter.h"
27 #include "irc/ircuserinfo.h"
28 #include "irc/ircuserlist.h"
29 #include "ircchanneladapter.h"
30 
31 IRCChannelAdapter::IRCChannelAdapter(IRCNetworkAdapter *pNetwork, const QString &recipient)
32  : IRCChatAdapter(pNetwork, recipient)
33 {
34  users = new IRCUserList();
35 }
36 
37 IRCChannelAdapter::~IRCChannelAdapter()
38 {
39  if (this->pNetwork != nullptr)
40  sendMessage("/part " + this->recipientName + " " + gIRCConfig.personal.quitMessage);
41 
42  delete users;
43 }
44 
46 {
47  const QString &myNickname = pNetwork->myNickname();
48  return isOperator(myNickname);
49 }
50 
52 {
53  if (users->appendNameToCachedList(IRCUserInfo(name, network())))
54  {
55  IRCUserInfo user = users->userCopy(name);
56  emit nameAdded(user);
57  }
58 }
59 
60 void IRCChannelAdapter::appendNamesToCachedList(const QStringList &names)
61 {
62  for (const QString &name : names)
63  {
64  appendNameToCachedList(name);
65  }
66 }
67 
68 void IRCChannelAdapter::banUser(const QString &nickname, const QString &reason)
69 {
70  pNetwork->banUser(nickname, reason, this->recipientName);
71 }
72 
74 {
75  emit nameListUpdated(*users);
76 }
77 
78 void IRCChannelAdapter::emitChatMessage(const QString &sender, const QString &content)
79 {
80  // Ensure that all nickname artifacts are preserved.
81  const IRCUserInfo *pUserInfo = users->user(sender);
82 
83  QString actualSenderName = sender;
84  if (pUserInfo != nullptr)
85  actualSenderName = pUserInfo->prefixedName();
86 
87  // Check if content has our nickname.
88  // (do not play sounds for our own messages)
89  const QString &myNickname = pNetwork->myNickname();
90  if (content.contains(myNickname, Qt::CaseInsensitive)
91  && sender.compare(myNickname, Qt::CaseInsensitive) != 0)
92  {
93  emit myNicknameUsed();
94  }
95 
96  IRCChatAdapter::emitChatMessage(actualSenderName, content);
97 }
98 
99 bool IRCChannelAdapter::hasUser(const QString &nickname)
100 {
101  return users->hasUser(nickname);
102 }
103 
104 bool IRCChannelAdapter::isOperator(const QString &nickname) const
105 {
106  const IRCUserInfo *pUser = users->user(nickname);
107  if (pUser != nullptr)
108  return pUser->isOp();
109 
110  return false;
111 }
112 
113 void IRCChannelAdapter::kickUser(const QString &nickname, const QString &reason)
114 {
115  if (hasUser(nickname))
116  {
117  QString cleanNickname = IRCUserInfo(nickname, pNetwork).cleanNickname();
118  this->sendMessage(QString("/kick %1 %2 %3").arg(this->recipientName, cleanNickname, reason));
119  }
120 }
121 
123 {
124  IRCUserInfo user = users->userCopy(name);
125 
126  if (!users->removeNameFromCachedList(name))
127  emit error(QString(R"(Attempted to remove name "%1" from the "%2" channel's name list but no such name is on the list.)").arg(name, this->recipientName));
128  else
129  emit nameRemoved(user);
130 }
131 
132 void IRCChannelAdapter::setHalfOp(const QString &nickname, bool bSet)
133 {
134  pNetwork->setChannelMode(this->recipientName, nickname, "h", bSet);
135 }
136 
137 void IRCChannelAdapter::setOp(const QString &nickname, bool bSet)
138 {
139  pNetwork->setChannelMode(this->recipientName, nickname, "o", bSet);
140 }
141 
142 void IRCChannelAdapter::setVoiced(const QString &nickname, bool bSet)
143 {
144  pNetwork->setChannelMode(this->recipientName, nickname, "v", bSet);
145 }
146 
147 void IRCChannelAdapter::userChangesNickname(const QString &oldNickname, const QString &newNickname)
148 {
149  if (hasUser(oldNickname))
150  {
151  IRCUserInfo oldName = users->userCopy(oldNickname);
152 
153  users->changeNick(oldNickname, newNickname);
154  emit nameRemoved(oldName);
155  emit nameAdded(users->userCopy(newNickname));
156 
157  emit messageWithClass(tr("%1 is now known as %2").arg(oldNickname, newNickname),
158  IRCMessageClass::ChannelAction);
159  }
160 }
161 
162 void IRCChannelAdapter::userJoins(const QString &nickname, const QString &fullSignature)
163 {
164  appendNameToCachedList(nickname);
165 
166  emit messageWithClass(tr("User %1 [%2] has joined the channel.").arg(nickname, fullSignature),
167  IRCMessageClass::ChannelAction);
168 }
169 
170 void IRCChannelAdapter::userLeaves(const QString &nickname, const QString &farewellMessage, IRCQuitType quitType)
171 {
172  if (!hasUser(nickname))
173  {
174  // Nothing to do here. This user was not even on the channel.
175  return;
176  }
177 
178  removeNameFromCachedList(nickname);
179 
180  switch (quitType)
181  {
182  case IRCChatAdapter::ChannelPart:
183  emit messageWithClass(tr("User %1 has left the channel. (PART: %2)").arg(nickname, farewellMessage),
184  IRCMessageClass::ChannelAction);
185  break;
186 
187  case IRCChatAdapter::NetworkKill:
188  emit messageWithClass(tr("Connection for user %1 has been killed. (KILL: %2)").arg(nickname, farewellMessage),
189  IRCMessageClass::NetworkAction);
190  break;
191 
192  case IRCChatAdapter::NetworkQuit:
193  emit messageWithClass(tr("User %1 has quit the network. (QUIT: %2)").arg(nickname, farewellMessage),
194  IRCMessageClass::NetworkAction);
195  break;
196 
197  default:
198  emit error(tr("Unknown quit type from user %1.").arg(nickname));
199  break;
200  }
201 }
202 
203 void IRCChannelAdapter::userModeChanges(const QString &nickname,
204  const QList<char> &addedFlags, const QList<char> &removedFlags)
205 {
206  const IRCUserInfo *pUserInfo = this->users->user(nickname);
207  if (pUserInfo != nullptr)
208  {
209  IRCUserInfo newUserInfo = *pUserInfo;
210  for (char mode : addedFlags)
211  {
212  newUserInfo.setMode(mode);
213  }
214  for (char mode : removedFlags)
215  {
216  newUserInfo.unsetMode(mode);
217  }
218 
219  this->users->setUserModes(nickname, newUserInfo.modes());
220  emit nameUpdated(newUserInfo);
221  }
222 }
Interprets communication between the client and the IRC server.
void userLeaves(const QString &nickname, const QString &farewellMessage, IRCQuitType quitType) override
Use this to register the fact that user has left the chat.
Allows to perform operation on a list of users.
Definition: ircuserlist.h:42
void emitCachedNameListUpdated()
Emits cached list of names. This should be called when end of names list message is received for this...
void kickUser(const QString &nickname, const QString &reason)
Kicks user from the channel.
void userJoins(const QString &nickname, const QString &fullSignature) override
Use this to register the fact that user has joined the chat.
void removeNameFromCachedList(const QString &name)
Removes a name from the sortecd cachedNames list.
void setHalfOp(const QString &nickname, bool bSet)
Sets half op mode for given user.
void appendNamesToCachedList(const QStringList &names)
Appends a list of names to cachedNames list. This ensures that no duplicate names are found on the li...
QString cleanNickname() const
Returns nickname with no prefixes, contrary to the prefixedName() .
Definition: ircuserinfo.cpp:48
void userChangesNickname(const QString &oldNickname, const QString &newNickname) override
virtual void emitChatMessage(const QString &sender, const QString &content)
Emits message() signal formatting it to present sender&#39;s message.
QString prefixedName() const
Will generate prefix based on the user flags.
bool amIOperator() const
Checks if this client is an operator on this channel.
Handles chatting through IRC.
void banUser(const QString &nickname, const QString &reason)
Bans and kicks user from the channel.
void emitChatMessage(const QString &sender, const QString &content) override
Emits message() signal formatting it to present sender&#39;s message.
void setVoiced(const QString &nickname, bool bSet)
Sets voice mode for given user.
Holds information flags about given nickname.
Definition: ircuserinfo.h:35
void setOp(const QString &nickname, bool bSet)
Sets op mode for given user.
virtual IRCNetworkAdapter * network()=0
The idea of the adapter system is that each adapter is either a network or is a child of a network...
void userModeChanges(const QString &nickname, const QList< char > &addedFlags, const QList< char > &removedFlags) override
bool isOperator(const QString &nickname) const
Checks if user is an operator on this channel.
void appendNameToCachedList(const QString &name)
Appends a single name to the sorted cachedNames list.