mirror of
https://github.com/znc/znc.git
synced 2026-08-06 17:03:14 +02:00
Add MoveChan and SwapChans commands
This commit is contained in:
@@ -93,6 +93,9 @@ class CIRCNetwork : private CCoreTranslationMixin {
|
||||
bool AddChan(CChan* pChan);
|
||||
bool AddChan(const CString& sName, bool bInConfig);
|
||||
bool DelChan(const CString& sName);
|
||||
bool MoveChan(const CString& sChan, unsigned int index, CString& sError);
|
||||
bool SwapChans(const CString& sChan1, const CString& sChan2,
|
||||
CString& sError);
|
||||
void JoinChans();
|
||||
void JoinChans(std::set<CChan*>& sChans);
|
||||
|
||||
|
||||
@@ -453,6 +453,46 @@ void CClient::UserCommand(CString& sLine) {
|
||||
PutStatus(t_p("Disabled {1} channel", "Disabled {1} channels",
|
||||
uDisabled)(uDisabled));
|
||||
}
|
||||
} else if (sCommand.Equals("MOVECHAN")) {
|
||||
if (!m_pNetwork) {
|
||||
PutStatus(t_s(
|
||||
"You must be connected with a network to use this command"));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sChan = sLine.Token(1);
|
||||
const auto sTarget = sLine.Token(2);
|
||||
if (sChan.empty() || sTarget.empty()) {
|
||||
PutStatus(t_s("Usage: MoveChan <#chan> <index>"));
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int uIndex = sTarget.ToUInt();
|
||||
|
||||
CString sError;
|
||||
if (m_pNetwork->MoveChan(sChan, uIndex - 1, sError))
|
||||
PutStatus(t_f("Moved channel {1} to index {2}")(sChan, uIndex));
|
||||
else
|
||||
PutStatus(sError);
|
||||
} else if (sCommand.Equals("SWAPCHANS")) {
|
||||
if (!m_pNetwork) {
|
||||
PutStatus(t_s(
|
||||
"You must be connected with a network to use this command"));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sChan1 = sLine.Token(1);
|
||||
const auto sChan2 = sLine.Token(2);
|
||||
if (sChan1.empty() || sChan2.empty()) {
|
||||
PutStatus(t_s("Usage: SwapChans <#chan1> <#chan2>"));
|
||||
return;
|
||||
}
|
||||
|
||||
CString sError;
|
||||
if (m_pNetwork->SwapChans(sChan1, sChan2, sError))
|
||||
PutStatus(t_f("Swapped channels {1} and {2}")(sChan1, sChan2));
|
||||
else
|
||||
PutStatus(sError);
|
||||
} else if (sCommand.Equals("LISTCHANS")) {
|
||||
if (!m_pNetwork) {
|
||||
PutStatus(t_s(
|
||||
@@ -1786,6 +1826,11 @@ void CClient::HelpUser(const CString& sFilter) {
|
||||
t_s("Enable channels", "helpcmd|EnableChan|desc"));
|
||||
AddCommandHelp("DisableChan", t_s("<#chans>", "helpcmd|DisableChan|args"),
|
||||
t_s("Disable channels", "helpcmd|DisableChan|desc"));
|
||||
AddCommandHelp("MoveChan", t_s("<#chan> <index>", "helpcmd|MoveChan|args"),
|
||||
t_s("Move channel in sort order", "helpcmd|MoveChan|desc"));
|
||||
AddCommandHelp(
|
||||
"SwapChans", t_s("<#chan1> <#chan2>", "helpcmd|SwapChans|args"),
|
||||
t_s("Swap channels in sort order", "helpcmd|SwapChans|desc"));
|
||||
AddCommandHelp("Attach", t_s("<#chans>", "helpcmd|Attach|args"),
|
||||
t_s("Attach to channels", "helpcmd|Attach|desc"));
|
||||
AddCommandHelp("Detach", t_s("<#chans>", "helpcmd|Detach|args"),
|
||||
|
||||
@@ -942,6 +942,49 @@ bool CIRCNetwork::DelChan(const CString& sName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CIRCNetwork::MoveChan(const CString& sChan, unsigned int uIndex,
|
||||
CString& sError) {
|
||||
if (uIndex >= m_vChans.size()) {
|
||||
sError = t_s("Invalid index");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = m_vChans.begin();
|
||||
for (; it != m_vChans.end(); ++it)
|
||||
if ((*it)->GetName().Equals(sChan)) break;
|
||||
if (it == m_vChans.end()) {
|
||||
sError = t_f("You are not on {1}")(sChan);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto pChan = *it;
|
||||
m_vChans.erase(it);
|
||||
m_vChans.insert(m_vChans.begin() + uIndex, pChan);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CIRCNetwork::SwapChans(const CString& sChan1, const CString& sChan2,
|
||||
CString& sError) {
|
||||
auto it1 = m_vChans.begin();
|
||||
for (; it1 != m_vChans.end(); ++it1)
|
||||
if ((*it1)->GetName().Equals(sChan1)) break;
|
||||
if (it1 == m_vChans.end()) {
|
||||
sError = t_f("You are not on {1}")(sChan1);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it2 = m_vChans.begin();
|
||||
for (; it2 != m_vChans.end(); ++it2)
|
||||
if ((*it2)->GetName().Equals(sChan2)) break;
|
||||
if (it2 == m_vChans.end()) {
|
||||
sError = t_f("You are not on {1}")(sChan2);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::swap(*it1, *it2);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CIRCNetwork::JoinChans() {
|
||||
// Avoid divsion by zero, it's bad!
|
||||
if (m_vChans.empty()) return;
|
||||
|
||||
@@ -307,5 +307,41 @@ TEST_F(ZNCTest, StatusEchoMessage) {
|
||||
client3.ReadUntil(":*status!znc@znc.in PRIVMSG nick :Unknown command");
|
||||
}
|
||||
|
||||
TEST_F(ZNCTest, MoveChannels) {
|
||||
auto znc = Run();
|
||||
auto ircd = ConnectIRCd();
|
||||
|
||||
auto client = LoginClient();
|
||||
client.Write("JOIN #foo,#bar");
|
||||
client.Close();
|
||||
|
||||
ircd.Write(":server 001 nick :Hello");
|
||||
ircd.ReadUntil("JOIN #foo,#bar");
|
||||
ircd.Write(":nick JOIN :#foo");
|
||||
ircd.Write(":server 353 nick #foo :nick");
|
||||
ircd.Write(":server 366 nick #foo :End of /NAMES list");
|
||||
ircd.Write(":nick JOIN :#bar");
|
||||
ircd.Write(":server 353 nick #bar :nick");
|
||||
ircd.Write(":server 366 nick #bar :End of /NAMES list");
|
||||
|
||||
client = LoginClient();
|
||||
client.ReadUntil(":nick JOIN :#foo");
|
||||
client.ReadUntil(":nick JOIN :#bar");
|
||||
client.Write("znc movechan #foo 2");
|
||||
client.ReadUntil("Moved channel #foo to index 2");
|
||||
client.Close();
|
||||
|
||||
client = LoginClient();
|
||||
client.ReadUntil(":nick JOIN :#bar");
|
||||
client.ReadUntil(":nick JOIN :#foo");
|
||||
client.Write("znc swapchans #foo #bar");
|
||||
client.ReadUntil("Swapped channels #foo and #bar");
|
||||
client.Close();
|
||||
|
||||
client = LoginClient();
|
||||
client.ReadUntil(":nick JOIN :#foo");
|
||||
client.ReadUntil(":nick JOIN :#bar");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace znc_inttest
|
||||
|
||||
Reference in New Issue
Block a user