multiple channels
This commit is contained in:
parent
671e01d8a0
commit
9f12e9721f
2 changed files with 210 additions and 124 deletions
|
@ -1,12 +1,11 @@
|
|||
# znc-idlerpg
|
||||
ZNC module to handle logins to an IdleRPG game/channel on IRC automatically
|
||||
ZNC module to handle logins to IdleRPG games/channels on IRC automatically. It can handle multiple channels on a network at the same time.
|
||||
|
||||
## Instructions
|
||||
- Can be loaded as a network module
|
||||
- Compile the module with `znc-buildmod idlerpg.cpp` and copy it to your modules directory (and/or refer to https://wiki.znc.in/Compiling_modules for help)
|
||||
- Load the mod in each network your want it to be active via `/znc loadmod idlerpg`
|
||||
- Setup your IRPG account via `/znc *idlerpg set #channel irpgbotnickname username password`
|
||||
- Setup your IRPG account(s) via `/znc *idlerpg add #channel irpgbotnickname username password`
|
||||
- That's it!
|
||||
|
||||
## Functionality
|
||||
Trying to login if the bot joins the channel or if you join the channel (possibly after a disconnect of either). It'll wait 10 seconds before it does after the join and only does so if the botnick is on the channel and has operator status (to make sure you are not sending your login to an imposter). Technically, most of it can be done via the perform module already, but this won't check if the bot actually is online and has operator status and also won't work if the bot reconnects and doesn't log you in automatically.
|
||||
It'll try to login when the bot joins the channel or if you join the channel (possibly after a reconnect of either). It'll wait 10 seconds after the join to login and only does so if the botnick is on the channel and has operator status (to make sure you are not sending your login to an imposter). Technically, most of it can be done via the perform module already, but this won't check if the bot actually is online and has operator status and also won't work if the bot reconnects and doesn't log you in automatically.
|
289
idlerpg.cpp
289
idlerpg.cpp
|
@ -1,34 +1,142 @@
|
|||
#include <znc/IRCNetwork.h>
|
||||
#include <znc/Chan.h>
|
||||
|
||||
#define IDLERPG_JOIN_LOGIN_WAIT_TIME 10
|
||||
using std::map;
|
||||
|
||||
class CIdleRPGMod;
|
||||
|
||||
#define IDLERPG_JOIN_LOGIN_WAIT_TIME 10
|
||||
|
||||
class CIdleRPGChannel {
|
||||
public:
|
||||
CIdleRPGChannel() {}
|
||||
CIdleRPGChannel(const CString& sLine) {
|
||||
FromString(sLine);
|
||||
}
|
||||
virtual ~CIdleRPGChannel() {}
|
||||
|
||||
const CString& GetChannel() const {
|
||||
return m_Channel;
|
||||
}
|
||||
const CString& GetBotnick() const {
|
||||
return m_Botnick;
|
||||
}
|
||||
const CString& GetUsername() const {
|
||||
return m_Username;
|
||||
}
|
||||
const CString& GetPassword() const {
|
||||
return m_Password;
|
||||
}
|
||||
|
||||
bool FromString(const CString& sLine) {
|
||||
m_Channel = sLine.Token(0).AsLower();
|
||||
m_Botnick = sLine.Token(1);
|
||||
m_Username = sLine.Token(2);
|
||||
m_Password = sLine.Token(3);
|
||||
|
||||
return !m_Channel.empty() && !m_Botnick.empty() && !m_Username.empty() && !m_Password.empty();
|
||||
}
|
||||
|
||||
CString ToString() const {
|
||||
return GetChannel() + " " + GetBotnick() + " " + GetUsername() + " " + GetPassword();
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
CString m_Channel;
|
||||
CString m_Botnick;
|
||||
CString m_Username;
|
||||
CString m_Password;
|
||||
};
|
||||
|
||||
class CIdleRPGModTimer : public CTimer {
|
||||
public:
|
||||
CIdleRPGModTimer(CModule* pModule, unsigned int uInterval,
|
||||
CIdleRPGModTimer(CModule* pModule, CIdleRPGChannel* sChannel, unsigned int uInterval,
|
||||
unsigned int uCycles, const CString& sLabel,
|
||||
const CString& sDescription)
|
||||
: CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {}
|
||||
: CTimer(pModule, uInterval, uCycles, sLabel, sDescription) {
|
||||
pChannel = sChannel;
|
||||
}
|
||||
|
||||
~CIdleRPGModTimer() override {}
|
||||
|
||||
protected:
|
||||
void RunJob() override;
|
||||
|
||||
private:
|
||||
CIdleRPGChannel* pChannel;
|
||||
};
|
||||
|
||||
class CIdleRPGMod : public CModule {
|
||||
void Set (const CString& sCommand) {
|
||||
if (sCommand.Token(1).empty()) {
|
||||
PutModule(t_s("Usage: <#channel> <botnick> <username> <password>"));
|
||||
public:
|
||||
MODCONSTRUCTOR(CIdleRPGMod) {
|
||||
AddHelpCommand();
|
||||
|
||||
AddCommand("Add", t_d("<#channel> <botnick> <username> <password>"), t_d("Adds a new channel or updates a channel"), [=](const CString& sLine) { CommandAdd(sLine); });
|
||||
AddCommand("Del", t_d("<#channel>"), t_d("Removes a channel"), [=](const CString& sLine) { CommandDel(sLine); });
|
||||
AddCommand("Clear", "", t_d("Clears all current settings"), [=](const CString& sLine) { CommandClear(); });
|
||||
AddCommand("List", "", t_d("Displays current settings"), [=](const CString& sLine) { CommandList(); });
|
||||
AddCommand("Login", t_d("[<#channel>]"), t_d("Manually triggers login now (either for specific channel or all channels)"), [=](const CString& sLine) { CommandLogin(sLine); });
|
||||
}
|
||||
|
||||
~CIdleRPGMod() override {}
|
||||
|
||||
bool OnLoad(const CString& sArgs, CString& sMessage) override {
|
||||
// Load current channels
|
||||
for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) {
|
||||
const CString& sLine = it->second;
|
||||
CIdleRPGChannel* pChannel = new CIdleRPGChannel;
|
||||
|
||||
if (!pChannel->FromString(sLine) || FindChannel(pChannel->GetChannel())) {
|
||||
delete pChannel;
|
||||
} else {
|
||||
m_Channels[pChannel->GetChannel()] = pChannel;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CIdleRPGChannel* FindChannel(const CString& sChannel) {
|
||||
map<CString, CIdleRPGChannel*>::iterator it =
|
||||
m_Channels.find(sChannel);
|
||||
|
||||
return (it != m_Channels.end()) ? it->second : nullptr;
|
||||
}
|
||||
|
||||
void CommandList () {
|
||||
if (m_Channels.empty()) {
|
||||
PutModule(t_s("No channels setup yet. Try: help add"));
|
||||
return;
|
||||
}
|
||||
|
||||
CString sChannel = sCommand.Token(1);
|
||||
CString sBotnick = sCommand.Token(2);
|
||||
CString sUsername = sCommand.Token(3);
|
||||
CString sPassword = sCommand.Token(4);
|
||||
CTable Table;
|
||||
Table.AddColumn(t_s("Channel"));
|
||||
Table.AddColumn(t_s("Botnick"));
|
||||
Table.AddColumn(t_s("Username"));
|
||||
Table.AddColumn(t_s("Password"));
|
||||
|
||||
for (const auto& it : m_Channels) {
|
||||
Table.AddRow();
|
||||
Table.SetCell(t_s("Channel"), it.second->GetChannel());
|
||||
Table.SetCell(t_s("Botnick"), it.second->GetBotnick());
|
||||
Table.SetCell(t_s("Username"), it.second->GetUsername());
|
||||
Table.SetCell(t_s("Password"), it.second->GetPassword());
|
||||
}
|
||||
|
||||
PutModule(Table);
|
||||
}
|
||||
|
||||
void CommandAdd (const CString& sLine) {
|
||||
if (sLine.Token(1).empty()) {
|
||||
PutModule(t_s("Usage: Add <#channel> <botnick> <username> <password>"));
|
||||
return;
|
||||
}
|
||||
|
||||
CString sChannel = sLine.Token(1).AsLower();
|
||||
CString sBotnick = sLine.Token(2);
|
||||
CString sUsername = sLine.Token(3);
|
||||
CString sPassword = sLine.Token(4);
|
||||
|
||||
if (sChannel.empty()) {
|
||||
PutModule("Channel not supplied");
|
||||
|
@ -47,133 +155,115 @@ class CIdleRPGMod : public CModule {
|
|||
return;
|
||||
}
|
||||
|
||||
m_channel = sChannel;
|
||||
m_botnick = sBotnick;
|
||||
m_username = sUsername;
|
||||
m_password = sPassword;
|
||||
Save();
|
||||
CIdleRPGChannel* pChannel = new CIdleRPGChannel();
|
||||
pChannel->FromString(sChannel+" "+sBotnick+" "+sUsername+" "+sPassword);
|
||||
m_Channels[pChannel->GetChannel()] = pChannel;
|
||||
SetNV(pChannel->GetChannel(), pChannel->ToString());
|
||||
|
||||
PutModule(t_s("Settings saved!"));
|
||||
PutModule(t_f("Saved settings for channel {1}")(pChannel->GetChannel()));
|
||||
}
|
||||
|
||||
void Get (const CString& sCommand) {
|
||||
if (m_channel.empty()) {
|
||||
PutModule(t_s("No settings found."));
|
||||
void CommandDel (const CString& sLine) {
|
||||
if (sLine.Token(1).empty()) {
|
||||
PutModule(t_s("Usage: Del <#channel>"));
|
||||
return;
|
||||
}
|
||||
CString sChannel = sLine.Token(1).AsLower();
|
||||
|
||||
map<CString, CIdleRPGChannel*>::iterator it =
|
||||
m_Channels.find(sChannel);
|
||||
|
||||
if (it == m_Channels.end()) {
|
||||
PutModule(t_f("Channel {1} not found")(sChannel));
|
||||
return;
|
||||
}
|
||||
|
||||
PutModule(t_s("Current settings are as following:"));
|
||||
PutModule(t_f("Channel: {1} - Botnick: {2} - Username: {3} - Password: {4}")(m_channel, m_botnick, m_username, m_password));
|
||||
delete it->second;
|
||||
m_Channels.erase(it);
|
||||
DelNV(sChannel);
|
||||
PutModule(t_f("Channel {1} removed")(sChannel));
|
||||
}
|
||||
|
||||
void Clear (const CString& sCommand) {
|
||||
m_channel = "";
|
||||
m_botnick = "";
|
||||
m_username = "";
|
||||
m_password = "";
|
||||
Save();
|
||||
|
||||
PutModule(t_s("All settings cleared."));
|
||||
}
|
||||
|
||||
void LoginCommand (const CString& sCommand) {
|
||||
if (m_channel.empty()) {
|
||||
PutModule(t_s("You need to configure this module first. Try: help set"));
|
||||
void CommandLogin (const CString& sLine) {
|
||||
CString sChannel = sLine.Token(1).AsLower();
|
||||
if (!sChannel.empty()) {
|
||||
CIdleRPGChannel* fChannel = FindChannel(sChannel);
|
||||
if (!fChannel) {
|
||||
PutModule(t_f("Invalid channel {1}")(sChannel));
|
||||
return;
|
||||
}
|
||||
|
||||
QueueLogin(0);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
MODCONSTRUCTOR(CIdleRPGMod) {
|
||||
AddHelpCommand();
|
||||
|
||||
AddCommand("Set", t_d("<#channel> <botnick> <username> <password>"), t_d("Sets all the required information to function."), [=](const CString& sLine) { Set(sLine); });
|
||||
AddCommand("Get", "", t_d("Displays current saved settings"), [=](const CString& sLine) { Get(sLine); });
|
||||
AddCommand("Clear", "", t_d("Resets all settings"), [=](const CString& sLine) { Clear(sLine); });
|
||||
AddCommand("Login", "", t_d("Manually triggers login now"), [=](const CString& sLine) { LoginCommand(sLine); });
|
||||
}
|
||||
|
||||
~CIdleRPGMod() override {}
|
||||
|
||||
bool OnLoad(const CString& sArgs, CString& sMessage) override {
|
||||
m_channel = GetNV("channel");
|
||||
m_botnick = GetNV("botnick");
|
||||
m_username = GetNV("username");
|
||||
m_password = GetNV("password");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnJoin(const CNick& Nick, CChan& Channel) override {
|
||||
// Setup done?
|
||||
if (m_channel.empty()) {
|
||||
Login(fChannel);
|
||||
return;
|
||||
}
|
||||
|
||||
// Correct channel?
|
||||
if (Channel.GetName().AsLower() != m_channel.AsLower()) {
|
||||
return;
|
||||
// Go through all channels and login
|
||||
for (const auto& it : m_Channels) {
|
||||
Login(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
// Either Bot or user joins
|
||||
if (Nick.GetNick() != m_botnick && !GetNetwork()->GetCurNick().Equals(Nick.GetNick())) {
|
||||
return;
|
||||
void CommandClear () {
|
||||
ClearNV();
|
||||
m_Channels.clear();
|
||||
PutModule(t_s("All settings cleared!"));
|
||||
}
|
||||
|
||||
QueueLogin(IDLERPG_JOIN_LOGIN_WAIT_TIME);
|
||||
void QueueLogin(CIdleRPGChannel* sChan) {
|
||||
RemTimer("idlerpg_login_timer_"+sChan->GetChannel());
|
||||
AddTimer(new CIdleRPGModTimer(this, sChan, IDLERPG_JOIN_LOGIN_WAIT_TIME, 1, "idlerpg_login_timer_"+sChan->GetChannel(), "Tries login to IdleRPG bot"));
|
||||
}
|
||||
|
||||
void Login () {
|
||||
void Login(CIdleRPGChannel* sChan) {
|
||||
// Valid channel?
|
||||
CChan* pChan = this->GetNetwork()->FindChan(m_channel);
|
||||
CChan* pChan = this->GetNetwork()->FindChan(sChan->GetChannel());
|
||||
if (!pChan) {
|
||||
PutModule(t_f("Error logging in: Invalid channel [{1}]")(m_channel));
|
||||
PutModule(t_f("Error logging in: Invalid channel [{1}]")(sChan->GetChannel()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Botnick on channel?
|
||||
CNick* pBot = pChan->FindNick(m_botnick);
|
||||
CNick* pBot = pChan->FindNick(sChan->GetBotnick());
|
||||
if (!pBot) {
|
||||
PutModule(t_f("Error logging in: Bot [{1}] not found in channel [{2}]")(m_botnick, m_channel));
|
||||
PutModule(t_f("Error logging in: Bot [{1}] not found in channel [{2}]")(sChan->GetBotnick(), sChan->GetChannel()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Bot has op?
|
||||
if (!pBot->HasPerm(CChan::Op)) {
|
||||
PutModule(t_f("Error logging in: Bot [{1}] not operator in in channel [{2}]")(m_botnick, m_channel));
|
||||
PutModule(t_f("Error logging in: Bot [{1}] not operator in in channel [{2}]")(sChan->GetBotnick(), sChan->GetChannel()));
|
||||
return;
|
||||
}
|
||||
|
||||
PutIRC("PRIVMSG " + m_botnick + " :login " + m_username + " " + m_password);
|
||||
PutModule(t_s("Logging you in..."));
|
||||
PutIRC("PRIVMSG " + sChan->GetBotnick() + " :login " + sChan->GetUsername() + " " + sChan->GetPassword());
|
||||
PutModule(t_s("Logging you in with "+sChan->GetBotnick()+" on "+sChan->GetChannel()));
|
||||
}
|
||||
|
||||
void OnJoin(const CNick& Nick, CChan& Channel) override {
|
||||
// Setup done?
|
||||
if (m_Channels.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Correct channel?
|
||||
CIdleRPGChannel* fChannel = FindChannel(Channel.GetName().AsLower());
|
||||
if (!fChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Either Bot or user joins
|
||||
if (Nick.GetNick() != fChannel->GetBotnick() && !GetNetwork()->GetCurNick().Equals(Nick.GetNick())) {
|
||||
return;
|
||||
}
|
||||
|
||||
QueueLogin(fChannel);
|
||||
}
|
||||
|
||||
private:
|
||||
CString m_channel;
|
||||
CString m_botnick;
|
||||
CString m_username;
|
||||
CString m_password;
|
||||
|
||||
void QueueLogin(int seconds) {
|
||||
if (m_channel.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RemTimer("idlerpg_login_timer");
|
||||
AddTimer(new CIdleRPGModTimer(this, seconds, 1, "idlerpg_login_timer", "Tries login to IdleRPG bot"));
|
||||
}
|
||||
void Save() {
|
||||
SetNV("channel", m_channel);
|
||||
SetNV("botnick", m_botnick);
|
||||
SetNV("username", m_username);
|
||||
SetNV("password", m_password);
|
||||
}
|
||||
map<CString, CIdleRPGChannel*> m_Channels;
|
||||
};
|
||||
|
||||
void CIdleRPGModTimer::RunJob() { ((CIdleRPGMod*)GetModule())->Login(); }
|
||||
void CIdleRPGModTimer::RunJob() { ((CIdleRPGMod*)GetModule())->Login(pChannel); }
|
||||
|
||||
template <>
|
||||
void TModInfo<CIdleRPGMod>(CModInfo& Info) {
|
||||
|
@ -181,7 +271,4 @@ void TModInfo<CIdleRPGMod>(CModInfo& Info) {
|
|||
Info.SetWikiPage("idlerpg");
|
||||
}
|
||||
|
||||
NETWORKMODULEDEFS(
|
||||
CIdleRPGMod,
|
||||
t_s("Automatically handles your login to an IdleRPG game/channel")
|
||||
)
|
||||
NETWORKMODULEDEFS(CIdleRPGMod, t_s("Automatically handles your login to IdleRPG games/channels"))
|
Loading…
Add table
Reference in a new issue