2021-06-21 18:46:01 +08:00
# include <znc/IRCNetwork.h>
# include <znc/Chan.h>
2021-06-22 13:46:00 +08:00
using std : : map ;
2021-06-21 18:46:01 +08:00
class CIdleRPGMod ;
2021-06-22 13:46:00 +08:00
# define IDLERPG_JOIN_LOGIN_WAIT_TIME 10
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
class CIdleRPGChannel {
public :
CIdleRPGChannel ( ) { }
CIdleRPGChannel ( const CString & sLine ) {
FromString ( sLine ) ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
virtual ~ CIdleRPGChannel ( ) { }
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
const CString & GetChannel ( ) const {
return m_Channel ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
const CString & GetBotnick ( ) const {
return m_Botnick ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
const CString & GetUsername ( ) const {
return m_Username ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
const CString & GetPassword ( ) const {
return m_Password ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
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 ) ;
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
return ! m_Channel . empty ( ) & & ! m_Botnick . empty ( ) & & ! m_Username . empty ( ) & & ! m_Password . empty ( ) ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
CString ToString ( ) const {
return GetChannel ( ) + " " + GetBotnick ( ) + " " + GetUsername ( ) + " " + GetPassword ( ) ;
}
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
private :
protected :
CString m_Channel ;
CString m_Botnick ;
CString m_Username ;
CString m_Password ;
} ;
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
class CIdleRPGModTimer : public CTimer {
public :
CIdleRPGModTimer ( CModule * pModule , CIdleRPGChannel * sChannel , unsigned int uInterval ,
unsigned int uCycles , const CString & sLabel ,
const CString & sDescription )
: CTimer ( pModule , uInterval , uCycles , sLabel , sDescription ) {
pChannel = sChannel ;
}
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
~ CIdleRPGModTimer ( ) override { }
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
protected :
void RunJob ( ) override ;
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
private :
CIdleRPGChannel * pChannel ;
} ;
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
class CIdleRPGMod : public CModule {
2021-06-21 18:46:01 +08:00
public :
MODCONSTRUCTOR ( CIdleRPGMod ) {
AddHelpCommand ( ) ;
2021-06-22 13:46:00 +08:00
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 ) ; } ) ;
2021-06-21 18:46:01 +08:00
}
~ CIdleRPGMod ( ) override { }
bool OnLoad ( const CString & sArgs , CString & sMessage ) override {
2021-06-22 13:46:00 +08:00
// 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 ;
}
}
2021-06-21 18:46:01 +08:00
return true ;
}
2021-06-22 13:46:00 +08:00
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 ;
}
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> " ) ) ;
2021-06-21 18:46:01 +08:00
return ;
}
2021-06-22 13:46:00 +08:00
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 " ) ;
2021-06-22 11:27:23 +08:00
return ;
}
2021-06-22 13:46:00 +08:00
if ( sBotnick . empty ( ) ) {
PutModule ( " Botnick not supplied " ) ;
return ;
}
if ( sUsername . empty ( ) ) {
PutModule ( " Username not supplied " ) ;
return ;
}
if ( sPassword . empty ( ) ) {
PutModule ( " Password not supplied " ) ;
2021-06-21 18:46:01 +08:00
return ;
}
2021-06-22 13:46:00 +08:00
CIdleRPGChannel * pChannel = new CIdleRPGChannel ( ) ;
pChannel - > FromString ( sChannel + " " + sBotnick + " " + sUsername + " " + sPassword ) ;
m_Channels [ pChannel - > GetChannel ( ) ] = pChannel ;
SetNV ( pChannel - > GetChannel ( ) , pChannel - > ToString ( ) ) ;
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
PutModule ( t_f ( " Saved settings for channel {1} " ) ( pChannel - > GetChannel ( ) ) ) ;
}
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 ;
}
delete it - > second ;
m_Channels . erase ( it ) ;
DelNV ( sChannel ) ;
PutModule ( t_f ( " Channel {1} removed " ) ( sChannel ) ) ;
}
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 ;
}
Login ( fChannel ) ;
return ;
}
// Go through all channels and login
for ( const auto & it : m_Channels ) {
Login ( it . second ) ;
}
}
void CommandClear ( ) {
ClearNV ( ) ;
m_Channels . clear ( ) ;
PutModule ( t_s ( " All settings cleared! " ) ) ;
}
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 ( CIdleRPGChannel * sChan ) {
// Valid channel?
CChan * pChan = this - > GetNetwork ( ) - > FindChan ( sChan - > GetChannel ( ) ) ;
2021-06-21 18:46:01 +08:00
if ( ! pChan ) {
2021-06-22 13:46:00 +08:00
PutModule ( t_f ( " Error logging in: Invalid channel [{1}] " ) ( sChan - > GetChannel ( ) ) ) ;
2021-06-21 18:46:01 +08:00
return ;
}
// Botnick on channel?
2021-06-22 13:46:00 +08:00
CNick * pBot = pChan - > FindNick ( sChan - > GetBotnick ( ) ) ;
2021-06-21 18:46:01 +08:00
if ( ! pBot ) {
2021-06-22 13:46:00 +08:00
PutModule ( t_f ( " Error logging in: Bot [{1}] not found in channel [{2}] " ) ( sChan - > GetBotnick ( ) , sChan - > GetChannel ( ) ) ) ;
2021-06-21 18:46:01 +08:00
return ;
}
// Bot has op?
if ( ! pBot - > HasPerm ( CChan : : Op ) ) {
2021-06-22 13:46:00 +08:00
PutModule ( t_f ( " Error logging in: Bot [{1}] not operator in in channel [{2}] " ) ( sChan - > GetBotnick ( ) , sChan - > GetChannel ( ) ) ) ;
2021-06-21 18:46:01 +08:00
return ;
}
2021-06-22 13:46:00 +08:00
PutIRC ( " PRIVMSG " + sChan - > GetBotnick ( ) + " :login " + sChan - > GetUsername ( ) + " " + sChan - > GetPassword ( ) ) ;
PutModule ( t_s ( " Logging you in with " + sChan - > GetBotnick ( ) + " on " + sChan - > GetChannel ( ) ) ) ;
}
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
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 ;
}
2021-06-21 18:46:01 +08:00
2021-06-22 13:46:00 +08:00
// Either Bot or user joins
if ( Nick . GetNick ( ) ! = fChannel - > GetBotnick ( ) & & ! GetNetwork ( ) - > GetCurNick ( ) . Equals ( Nick . GetNick ( ) ) ) {
2021-06-21 18:46:01 +08:00
return ;
}
2021-06-22 13:46:00 +08:00
QueueLogin ( fChannel ) ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
private :
map < CString , CIdleRPGChannel * > m_Channels ;
2021-06-21 18:46:01 +08:00
} ;
2021-06-22 13:46:00 +08:00
void CIdleRPGModTimer : : RunJob ( ) { ( ( CIdleRPGMod * ) GetModule ( ) ) - > Login ( pChannel ) ; }
2021-06-21 18:46:01 +08:00
template < >
void TModInfo < CIdleRPGMod > ( CModInfo & Info ) {
Info . AddType ( CModInfo : : NetworkModule ) ;
2021-06-22 11:27:23 +08:00
Info . SetWikiPage ( " idlerpg " ) ;
2021-06-21 18:46:01 +08:00
}
2021-06-22 13:46:00 +08:00
NETWORKMODULEDEFS ( CIdleRPGMod , t_s ( " Automatically handles your login to IdleRPG games/channels " ) )