Last active
January 2, 2016 08:09
-
-
Save l1am9111/8275035 to your computer and use it in GitHub Desktop.
clientaway with auto away for specific ips
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (C) 2004-2012 See the AUTHORS file for details. | |
* | |
* This program is free software; you can redistribute it and/or modify it | |
* under the terms of the GNU General Public License version 2 as published | |
* by the Free Software Foundation. | |
*/ | |
#include <znc/Modules.h> | |
#include <znc/User.h> | |
#include <znc/IRCNetwork.h> | |
#include <znc/Chan.h> | |
using std::vector; | |
#define AWAY_DEFAULT_REASON "Auto away at %time%" | |
class CClientAwayMod : public CModule { | |
public: | |
CString GetAwayReason() const { | |
CString sAway = GetNV("reason"); | |
if (sAway.empty()) { | |
sAway = AWAY_DEFAULT_REASON; | |
} | |
if (m_pNetwork) { | |
return m_pNetwork->ExpandString(sAway); | |
} | |
return m_pUser->ExpandString(sAway); | |
} | |
bool GetAutoAway() const { | |
return GetNV("autoaway").ToBool(); | |
} | |
void ListCommand(const CString &sLine) { | |
CTable Table; | |
Table.AddColumn("Host"); | |
Table.AddColumn("Network"); | |
Table.AddColumn("Away"); | |
const vector<CClient*> vClients = m_pUser->GetAllClients(); | |
for (vector<CClient*>::const_iterator it = vClients.begin(); it != vClients.end(); ++it) { | |
CClient *pClient = *it; | |
Table.AddRow(); | |
Table.SetCell("Host", pClient->GetRemoteIP()); | |
if (pClient->GetNetwork()) { | |
Table.SetCell("Network", pClient->GetNetwork()->GetName()); | |
} | |
Table.SetCell("Away", CString(pClient->IsAway())); | |
} | |
PutModule(Table); | |
} | |
void SetAwayReasonCommand(const CString &sLine) { | |
CString sReason = sLine.Token(1, true); | |
if (!sReason.empty()) { | |
SetNV("reason", sReason); | |
PutModule("Away reason set to [" + sReason + "]"); | |
} | |
PutModule("Away message will be expanded to [" + GetAwayReason() + "]"); | |
} | |
void AutoAwayCommand(const CString &sLine) { | |
SetNV("autoaway", sLine.Token(1)); | |
if (GetAutoAway()) { | |
PutModule("Auto away when last client goes away or disconnects enabled."); | |
} else { | |
PutModule("Auto away when last client goes away or disconnects disabled."); | |
} | |
} | |
void AutoAwayIpCommand(const CString &sLine) { | |
CString ip = sLine.Token(1, true); | |
if(ip.empty()) | |
{ | |
PutModule(GetNV("autoawayip") + " is currently selected auto away hosts"); | |
return; | |
} | |
SetNV("autoawayip", ip); | |
PutModule(ip + " has been selected as auto away hosts"); | |
SetIpsAway(); | |
} | |
void SetAwayCommand(const CString &sLine) { | |
const vector<CClient*> vClients = m_pUser->GetAllClients(); | |
CString sHostname = sLine.Token(1); | |
unsigned int count = 0; | |
for (vector<CClient*>::const_iterator it = vClients.begin(); it != vClients.end(); ++it) { | |
CClient *pClient = *it; | |
if (sHostname.empty() || pClient->GetRemoteIP().Equals(sHostname)) { | |
pClient->SetAway(true); | |
++count; | |
} | |
} | |
if (count == 1) { | |
PutModule(CString(count) + " client has been set away"); | |
} else { | |
PutModule(CString(count) + " clients have been set away"); | |
} | |
} | |
void SetIpsAway() { | |
const vector<CClient*> vClients = m_pUser->GetAllClients(); | |
CString sHostname = GetNV("autoawayip"); | |
VCString vcHostnames; | |
unsigned int count = 0; | |
if(sHostname.empty()) return; | |
sHostname.Split(" ", vcHostnames); | |
for (vector<CClient*>::const_iterator it = vClients.begin(); it != vClients.end(); ++it) { | |
CClient *pClient = *it; | |
CString RemoteIP = pClient->GetRemoteIP(); | |
for (vector<CString>::const_iterator hit = vcHostnames.begin(); hit != vcHostnames.end(); ++hit) { | |
CString pHostname = *hit; | |
if (RemoteIP.Equals(pHostname) && !pClient->IsAway()) { | |
pClient->SetAway(true); | |
++count; | |
} | |
} | |
} | |
} | |
MODCONSTRUCTOR(CClientAwayMod) { | |
AddHelpCommand(); | |
AddCommand("List", static_cast<CModCommand::ModCmdFunc>(&CClientAwayMod::ListCommand), | |
"", "List all clients"); | |
AddCommand("Reason", static_cast<CModCommand::ModCmdFunc>(&CClientAwayMod::SetAwayReasonCommand), | |
"[reason]", "Prints and optionally sets the away reason."); | |
AddCommand("AutoAway", static_cast<CModCommand::ModCmdFunc>(&CClientAwayMod::AutoAwayCommand), | |
"yes or no", "Should we auto away you when the last client goes away or disconnects"); | |
AddCommand("AutoAwayIp", static_cast<CModCommand::ModCmdFunc>(&CClientAwayMod::AutoAwayIpCommand), | |
"hostnames separated with a space", "Auto aways hostnames"); | |
AddCommand("SetAway", static_cast<CModCommand::ModCmdFunc>(&CClientAwayMod::SetAwayCommand), | |
"hostname", "Set any clients matching hostname as away/unaway"); | |
} | |
virtual void OnClientLogin() { | |
SetIpsAway(); | |
if (GetAutoAway() && m_pNetwork && m_pNetwork->IsIRCAway()) { | |
PutIRC("AWAY"); | |
} | |
} | |
virtual void OnClientDisconnect() { | |
if (GetAutoAway() && m_pNetwork && !m_pNetwork->IsIRCAway() && !m_pNetwork->IsUserOnline()) { | |
PutIRC("AWAY :" + GetAwayReason()); | |
} | |
} | |
virtual void OnIRCConnected() { | |
if (GetAutoAway() && !m_pNetwork->IsUserOnline()) { | |
PutIRC("AWAY :" + GetAwayReason()); | |
} | |
} | |
virtual EModRet OnUserRaw(CString& sLine) { | |
CString sCmd = sLine.Token(0); | |
if (sCmd.Equals("AWAY")) { | |
if (m_pClient->IsAway()) { | |
m_pClient->SetAway(false); | |
m_pClient->PutClient(":irc.znc.in 305 " + m_pClient->GetNick() + " :You are no longer marked as being away"); | |
if (m_pNetwork) { | |
const vector<CChan*>& vChans = m_pNetwork->GetChans(); | |
vector<CChan*>::const_iterator it; | |
for (it = vChans.begin(); it != vChans.end(); ++it) { | |
// Skip channels which are detached or we don't use keepbuffer | |
if (!(*it)->IsDetached() && (*it)->AutoClearChanBuffer()) { | |
(*it)->ClearBuffer(); | |
} | |
} | |
m_pNetwork->ClearQueryBuffer(); | |
if (GetAutoAway() && m_pNetwork->IsIRCAway()) { | |
PutIRC("AWAY"); | |
} | |
} | |
} else { | |
m_pClient->SetAway(true); | |
m_pClient->PutClient(":irc.znc.in 306 " + m_pClient->GetNick() + " :You have been marked as being away"); | |
if (GetAutoAway() && m_pNetwork && !m_pNetwork->IsIRCAway() && !m_pNetwork->IsUserOnline()) { | |
// Use the supplied reason if there was one | |
CString sAwayReason = sLine.Token(1, true).TrimPrefix_n(); | |
if (sAwayReason.empty()) { | |
sAwayReason = GetAwayReason(); | |
} | |
PutIRC("AWAY :" + sAwayReason); | |
} | |
} | |
return HALTCORE; | |
} | |
return CONTINUE; | |
} | |
virtual EModRet OnRaw(CString& sLine) { | |
// We do the same as ZNC would without the OnRaw hook, | |
// except we do not forward 305's or 306's to clients | |
CString sCmd = sLine.Token(1); | |
if (sCmd.Equals("305")) { | |
m_pNetwork->SetIRCAway(false); | |
return HALTCORE; | |
} else if (sCmd.Equals("306")) { | |
m_pNetwork->SetIRCAway(true); | |
return HALTCORE; | |
} | |
return CONTINUE; | |
} | |
}; | |
template<> void TModInfo<CClientAwayMod>(CModInfo& Info) { | |
Info.SetWikiPage("clientaway"); | |
Info.AddType(CModInfo::NetworkModule); | |
} | |
USERMODULEDEFS(CClientAwayMod, "This module allows you to set clients away independently, and auto away") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment