--- trunk/irc/ArchBlackmann/ArchBlackmann.cpp 2005-06-03 17:09:47 UTC (rev 15751)
+++ trunk/irc/ArchBlackmann/ArchBlackmann.cpp 2005-06-03 17:28:53 UTC (rev 15752)
@@ -12,18 +12,11 @@
#include "trim.h"
#include "IRCClient.h"
+#include "config.h"
using std::string;
using std::vector;
-#if defined(_DEBUG) && 0
-const char* BOTNAME = "RoyBot";
-const char* CHANNEL = "#RoyBotTest";
-#else
-const char* BOTNAME = "ArchBlackmann";
-const char* CHANNEL = "#ReactOS";
-#endif
-
//vector<string> tech, module, dev, stru, period, status, type, func, irql, curse, cursecop;
class List
@@ -157,14 +150,46 @@
return false;
}
+
// do custom stuff with the IRCClient from your subclass via the provided callbacks...
class MyIRCClient : public IRCClient
{
File flog;
+ clock_t brake_silence;
+
+ // wait another 30 mins to brake the silence
+ #define NOIDLE brake_silence = clock () + 30 * CLK_TCK * 60
+
+ void CheckIdle ( void )
+ {
+ while (true) // _inRun
+ {
+ while (clock() < brake_silence)
+ Sleep(10000);
+
+ string out = TaggedReply("idle");
+
+ if ( !strnicmp ( out.c_str(), "/me ", 4 ) )
+ Action ( CHANNEL, &out[4] );
+ else
+ PrivMsg ( CHANNEL, out );
+
+ NOIDLE;
+ }
+ }
+
+ static void THREADAPI CallMe ( MyIRCClient* irc )
+ {
+ irc->CheckIdle();
+ }
+
public:
+
MyIRCClient()
{
- flog.open ( "arch.log", "w+" );
+ NOIDLE;
+ ThreadPool::Instance().Launch ( (ThreadPoolFunc*)MyIRCClient::CallMe, this );
+ flog.open ( "arch.log", "r+" );
}
// see IRCClient.h for documentation on these callbacks...
bool OnConnected()
@@ -173,7 +198,7 @@
}
bool OnJoin ( const string& user, const string& channel )
{
- printf ( "user '%s' joined channel '%s'\n", user.c_str(), channel.c_str() );
+ //printf ( "user '%s' joined channel '%s'\n", user.c_str(), channel.c_str() );
return true;
}
bool OnPart ( const std::string& user, const std::string& channel )
@@ -207,11 +232,18 @@
}
bool OnPrivMsg ( const string& from, const string& text )
{
+ //flog.flush();
printf ( "<%s> %s\n", from.c_str(), text.c_str() );
flog.printf ( "<%s> %s\n", from.c_str(), text.c_str() );
- if ( strnicmp ( text.c_str(), "!say ", 5 ) || !isop(from) )
+
+ if ( !isop(from) )
return PrivMsg ( from, "hey, your tongue doesn't belong there!" );
+
+ else if ( strnicmp ( text.c_str(), "!say ", 5 ) )
+ return PrivMsg ( from, "Talk to me on normal Chanel" );
+
string say = trim(&text[5]);
+
if ( !strnicmp ( say.c_str(), "/me ", 4 ) )
return Action ( CHANNEL, trim(&say[4]) );
else
@@ -219,140 +251,176 @@
}
bool OnChannelMsg ( const string& channel, const string& from, const string& text )
{
+ fflush ( flog );
printf ( "%s <%s> %s\n", channel.c_str(), from.c_str(), text.c_str() );
flog.printf ( "%s <%s> %s\n", channel.c_str(), from.c_str(), text.c_str() );
+ NOIDLE; // add 30 mins till idle
+
bool found_name = false;
string text2 ( text );
strlwr ( &text2[0] );
if ( !strnicmp ( text.c_str(), BOTNAME, strlen(BOTNAME) ) )
found_name = true;
- else if ( !strnicmp ( text.c_str(), "arch ", 5 ) )
- found_name = true;
+ string s ( text );
+
if ( found_name )
+ gobble ( s, " \t" ); // remove bot name
+
+ // command
+ if ( s[0] == '!' )
{
- string s ( text );
- gobble ( s, " \t" ); // remove bot name
- found_name = true;
- if ( s[0] == '!' )
+ bool from_op = isop(from);
+ string cmd = gobble ( s, " \t" );
+
+ // from all
+ if ( false && cmd == "!svn" && from == "TechBot" ) // || cmd == "!help" && !TechBotOnline
{
- bool from_op = isop(from);
- string cmd = gobble ( s, " \t" );
- if ( !from_op )
+ PrivMsg ( channel, "For my help try !what." );
+ }
+
+ // from normel user
+ else if ( !from_op )
+ {
+ if ( cmd == "!grovel" )
{
- if ( cmd == "!grovel" )
- {
- string out = ssprintf(TaggedReply("nogrovel").c_str(),from.c_str());
- if ( !strnicmp ( out.c_str(), "/me ", 4 ) )
- return Action ( channel, &out[4] );
- else
- return PrivMsg ( channel, out );
- }
- return PrivMsg ( channel, ssprintf("%s: I don't take commands from non-ops",from.c_str()) );
+ string out = ssprintf(TaggedReply("nogrovel").c_str(),from.c_str());
+ if ( !strnicmp ( out.c_str(), "/me ", 4 ) )
+ return Action ( channel, &out[4] );
+ else
+ return PrivMsg ( channel, out );
}
- if ( cmd == "!add" )
+
+ else if ( cmd == "!what" )
{
- string listname = gobble ( s, " \t" );
- int i = GetListIndex ( listname.c_str() );
- if ( i == -1 )
- return PrivMsg ( channel, ssprintf("%s: I don't have a list named '%s'",from.c_str(),listname.c_str()) );
- List& list = lists[i];
- if ( s[0] == '\"' || s[0] == '\'' )
- {
- char delim = s[0];
- const char* p = &s[1];
- const char* p2 = strchr ( p, delim );
- if ( !p2 )
- return PrivMsg ( channel, ssprintf("%s: Couldn't add, unmatched quotes",from.c_str()) );
- s = string ( p, p2-p );
- }
- for ( i = 0; i < list.list.size(); i++ )
- {
- if ( list.list[i] == s )
- return PrivMsg ( channel, ssprintf("%s: entry already exists in list '%s'",from.c_str(),listname.c_str()) );
- }
- if ( !stricmp ( listname.c_str(), "curse" ) )
- strlwr ( &s[0] );
- list.list.push_back ( s );
- {
- File f ( ssprintf("%s.txt",list.name.c_str()), "w" );
- for ( i = 0; i < list.list.size(); i++ )
- f.printf ( "%s\n", list.list[i].c_str() );
- }
- return PrivMsg ( channel, ssprintf("%s: entry added to list '%s'",from.c_str(),listname.c_str()) );
+ return PrivMsg ( channel, ssprintf("For you, %s, I only support the \"!grovel\" command.", from.c_str()).c_str() );
}
- else if ( cmd == "!remove" )
+
+ else if ( cmd == "!grovel" || cmd == "!kiss" || cmd == "!hug"
+ || cmd == "!give" || cmd == "!what" || cmd == "!add" || cmd == "!remove" )
{
- string listname = gobble ( s, " \t" );
- int i = GetListIndex ( listname.c_str() );
- if ( i == -1 )
- return PrivMsg ( channel, ssprintf("%s: I don't have a list named '%s'",from.c_str(),listname.c_str()) );
- List& list = lists[i];
- if ( s[0] == '\"' || s[0] == '\'' )
- {
- char delim = s[0];
- const char* p = &s[1];
- const char* p2 = strchr ( p, delim );
- if ( !p2 )
- return PrivMsg ( channel, ssprintf("%s: Couldn't add, unmatched quotes",from.c_str()) );
- s = string ( p, p2-p );
- }
- for ( i = 0; i < list.list.size(); i++ )
- {
- if ( list.list[i] == s )
- {
- list.list.erase ( &list.list[i] );
- {
- File f ( ssprintf("%s.txt",list.name.c_str()), "w" );
- for ( i = 0; i < list.list.size(); i++ )
- f.printf ( "%s\n", list.list[i].c_str() );
- }
- return PrivMsg ( channel, ssprintf("%s: entry removed from list '%s'",from.c_str(),listname.c_str()) );
- }
- }
- return PrivMsg ( channel, ssprintf("%s: entry doesn't exist in list '%s'",from.c_str(),listname.c_str()) );
+ PrivMsg ( channel, ssprintf("%s: I only take commands from ops",from.c_str()) );
}
- else if ( cmd == "!grovel" )
+ }
+
+ // from op
+ else if ( cmd == "!grovel" )
+ {
+ string out = ssprintf(TaggedReply("grovel").c_str(),from.c_str());
+ if ( !strnicmp ( out.c_str(), "/me ", 4 ) )
+ return Action ( channel, &out[4] );
+ else
+ return PrivMsg ( channel, out );
+ }
+ else if ( cmd == "!kiss" )
+ {
+ if ( s.size() )
+ return Action ( channel, ssprintf("kisses %s",s.c_str()) );
+ else
+ return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ }
+ else if ( cmd == "!hug" )
+ {
+ if ( s.size() )
+ return Action ( channel, ssprintf("hugs %s",s.c_str()) );
+ else
+ return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ }
+ else if ( cmd == "!give" )
+ {
+ string who = gobble(s," \t");
+ if ( who.size() && s.size() )
+ return Action ( channel, ssprintf("gives %s a %s",who.c_str(),s.c_str()) );
+ else
+ return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ }
+ else if ( cmd == "!what" )
+ {
+ PrivMsg ( channel, "For ops I support the following commands:" );
+ PrivMsg ( channel, "!grovel" );
+ PrivMsg ( channel, "!kiss" );
+ PrivMsg ( channel, "!hug" );
+ PrivMsg ( channel, "!give" );
+ PrivMsg ( channel, "!say (the input is a private message)" );
+ PrivMsg ( channel, "!add" );
+ PrivMsg ( channel, "!remove" );
+ PrivMsg ( channel, " - for more info see wiki" );
+ }
+ else if ( cmd == "!add" )
+ {
+ string listname = gobble ( s, " \t" );
+ int i = GetListIndex ( listname.c_str() );
+ if ( i == -1 )
+ return PrivMsg ( channel, ssprintf("%s: I don't have a list named '%s'",from.c_str(),listname.c_str()) );
+ List& list = lists[i];
+ if ( s[0] == '\"' || s[0] == '\'' )
{
- string out = ssprintf(TaggedReply("grovel").c_str(),from.c_str());
- if ( !strnicmp ( out.c_str(), "/me ", 4 ) )
- return Action ( channel, &out[4] );
- else
- return PrivMsg ( channel, out );
+ char delim = s[0];
+ const char* p = &s[1];
+ const char* p2 = strchr ( p, delim );
+ if ( !p2 )
+ return PrivMsg ( channel, ssprintf("%s: Couldn't add, unmatched quotes",from.c_str()) );
+ s = string ( p, p2-p );
}
- else if ( cmd == "!kiss" )
+ for ( i = 0; i < list.list.size(); i++ )
{
- if ( s.size() )
- return Action ( channel, ssprintf("kisses %s",s.c_str()) );
- else
- return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ if ( list.list[i] == s )
+ return PrivMsg ( channel, ssprintf("%s: entry already exists in list '%s'",from.c_str(),listname.c_str()) );
}
- else if ( cmd == "!hug" )
+ if ( !stricmp ( listname.c_str(), "curse" ) )
+ strlwr ( &s[0] );
+ list.list.push_back ( s );
{
- if ( s.size() )
- return Action ( channel, ssprintf("hugs %s",s.c_str()) );
- else
- return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ File f ( ssprintf("%s.txt",list.name.c_str()), "w" );
+ for ( i = 0; i < list.list.size(); i++ )
+ f.printf ( "%s\n", list.list[i].c_str() );
}
- else if ( cmd == "!give" )
+ return PrivMsg ( channel, ssprintf("%s: entry added to list '%s'",from.c_str(),listname.c_str()) );
+ }
+ else if ( cmd == "!remove" )
+ {
+ string listname = gobble ( s, " \t" );
+ int i = GetListIndex ( listname.c_str() );
+ if ( i == -1 )
+ return PrivMsg ( channel, ssprintf("%s: I don't have a list named '%s'",from.c_str(),listname.c_str()) );
+ List& list = lists[i];
+ if ( s[0] == '\"' || s[0] == '\'' )
{
- string who = gobble(s," \t");
- if ( who.size() && s.size() )
- return Action ( channel, ssprintf("gives %s a %s",who.c_str(),s.c_str()) );
- else
- return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ char delim = s[0];
+ const char* p = &s[1];
+ const char* p2 = strchr ( p, delim );
+ if ( !p2 )
+ return PrivMsg ( channel, ssprintf("%s: Couldn't add, unmatched quotes",from.c_str()) );
+ s = string ( p, p2-p );
}
- else
+ for ( i = 0; i < list.list.size(); i++ )
{
- return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ if ( list.list[i] == s )
+ {
+ list.list.erase ( &list.list[i] );
+ {
+ File f ( ssprintf("%s.txt",list.name.c_str()), "w" );
+ for ( i = 0; i < list.list.size(); i++ )
+ f.printf ( "%s\n", list.list[i].c_str() );
+ }
+ return PrivMsg ( channel, ssprintf("%s: entry removed from list '%s'",from.c_str(),listname.c_str()) );
+ }
}
+ return PrivMsg ( channel, ssprintf("%s: entry doesn't exist in list '%s'",from.c_str(),listname.c_str()) );
}
- }
+ else
+ {
+ if (found_name)
+ return PrivMsg ( channel, ssprintf("%s: huh?",from.c_str()) );
+ }
+
+ } // if (command)
bool found_curse = false;
static vector<string>& curse = GetList("curse").list;
- text2 = ssprintf(" %s ",text2.c_str());
+ text2 = " " + text2 + " ";
+
for ( int i = 0; i < curse.size() && !found_curse; i++ )
{
if ( strstr ( text2.c_str(), curse[i].c_str() ) )
@@ -363,7 +431,12 @@
static List& cursecop = GetList("cursecop");
return PrivMsg ( channel, ssprintf("%s: %s", from.c_str(), ListRand(cursecop)) );
}
- else if ( found_name )
+
+ string botname (BOTNAME);
+ strlwr ( &botname[0] );
+ //botname = " " + botname + " ";
+
+ if ( strstr(text2.c_str(), botname.c_str()) || strstr(text2.c_str(), " arch ") || found_name )
{
string out = ssprintf("%s: %s", from.c_str(), TaggedReply("tech").c_str());
flog.printf ( "TECH-REPLY: %s\n", out.c_str() );
@@ -373,7 +446,9 @@
return PrivMsg ( channel, out );
}
return true;
- }
+
+ } // On Chanel Message
+
bool OnChannelMode ( const string& channel, const string& mode )
{
//printf ( "OnChannelMode(%s,%s)\n", channel.c_str(), mode.c_str() );
@@ -439,6 +514,16 @@
//printf ( "\n" );
return true;
}
+ bool OnKick ( void )
+ {
+ Join(CHANNEL);
+ return true;
+ }
+ bool OnBanned ( const std::string& channel )
+ {
+ Sleep(10000);
+ return Join(CHANNEL);
+ }
};
int main ( int argc, char** argv )
@@ -461,50 +546,59 @@
ImportList ( "cursecop", false );
ImportList ( "grovel", false );
ImportList ( "nogrovel", false );
+ ImportList ( "idle", false );
#ifdef _DEBUG
printf ( "initializing IRCClient debugging\n" );
IRCClient::SetDebug ( true );
#endif//_DEBUG
- printf ( "calling suStartup()\n" );
- suStartup();
- printf ( "creating IRCClient object\n" );
- MyIRCClient irc;
- printf ( "connecting to freenode\n" );
- //const char* server = "212.204.214.114";
- const char* server = "irc.freenode.net";
+ while (true)
+ {
+ printf ( "calling suStartup()\n" );
+ suStartup();
+ printf ( "creating IRCClient object\n" );
+ MyIRCClient irc;
+ printf ( "connecting to freenode\n" );
- if ( !irc.Connect ( server ) ) // irc.freenode.net
- {
- printf ( "couldn't connect to server\n" );
- return -1;
+ if ( !irc.Connect ( SERVER ) ) // irc.freenode.net
+ {
+ printf ( "couldn't connect to server\n" );
+ Sleep(10000);
+ continue;
+ }
+ printf ( "sending user command\n" );
+ if ( !irc.User ( BOTNAME, "reactos.com", SERVER, "ArchBlackmann" ) )
+ {
+ printf ( "USER command failed, retying ...\n" );
+ Sleep(10000);
+ continue;
+ }
+ printf ( "sending nick\n" );
+ if ( !irc.Nick ( BOTNAME ) )
+ {
+ printf ( "NICK command failed, retying ...\n" );
+ Sleep(10000);
+ continue;
+ }
+ printf ( "setting mode\n" );
+ if ( !irc.Mode ( MODE ) )
+ {
+ printf ( "MODE command failed, retying ...\n" );
+ Sleep(10000);
+ continue;
+ }
+ printf ( "joining channel\n" );
+ if ( !irc.Join ( CHANNEL ) )
+ {
+ printf ( "JOIN command failed, retying ...\n" );
+ Sleep(10000);
+ continue;
+ }
+
+ printf ( "entering irc client processor\n" );
+ irc.Run ( false ); // do the processing in this thread...
}
- printf ( "sending user command\n" );
- if ( !irc.User ( BOTNAME, "", "irc.freenode.net", BOTNAME ) )
- {
- printf ( "USER command failed\n" );
- return -1;
- }
- printf ( "sending nick\n" );
- if ( !irc.Nick ( BOTNAME ) )
- {
- printf ( "NICK command failed\n" );
- return -1;
- }
- printf ( "setting mode\n" );
- if ( !irc.Mode ( "+i" ) )
- {
- printf ( "MODE command failed\n" );
- return -1;
- }
- printf ( "joining channel\n" );
- if ( !irc.Join ( CHANNEL ) )
- {
- printf ( "JOIN command failed\n" );
- return -1;
- }
- printf ( "entering irc client processor\n" );
- irc.Run ( false ); // do the processing in this thread...
+
return 0;
}
--- trunk/irc/ArchBlackmann/IRCClient.cpp 2005-06-03 17:09:47 UTC (rev 15751)
+++ trunk/irc/ArchBlackmann/IRCClient.cpp 2005-06-03 17:28:53 UTC (rev 15752)
@@ -16,6 +16,7 @@
#include "chomp.h"
#include "SplitJoin.h"
#include "base64.h"
+#include "config.h"
using std::string;
using std::stringstream;
@@ -23,6 +24,8 @@
bool IRCClient::_debug = true;
+// see rfc1459 for IRC-Protocoll Reference
+
IRCClient::IRCClient()
: _timeout(10*60*1000), _inRun(false)
{
@@ -51,7 +54,9 @@
IRCClient::Nick ( const string& nick )
{
_nick = nick;
- return Send ( "NICK " + _nick + "\n" );
+ Send ( "NICK " + _nick + "\n" );
+ PrivMsg ("NickServ", "IDENTIFY " + (string)PASS);
+ return true;
}
bool
@@ -75,7 +80,7 @@
bool
IRCClient::Join ( const string& channel )
{
- return Send ( "JOIN " + channel + "\n" );
+ return Send("JOIN " + channel + "\n");
}
bool
@@ -145,7 +150,7 @@
{
ThreadPool::Instance().Launch ( (ThreadPoolFunc*)IRCClient::Callback, this );
return 1;
- }
+ }
_inRun = true;
if ( _debug ) printf ( "IRCClient::Run() - waiting for responses\n" );
string buf;
@@ -296,6 +301,7 @@
}
else if ( cmd == "join" )
{
+ mychannel = text;
OnJoin ( src, text );
}
else if ( cmd == "part" )
@@ -306,14 +312,20 @@
{
OnNick ( src, text );
}
+ else if ( cmd == "kick" )
+ {
+ OnKick ();
+ }
else if ( isdigit(cmd[0]) )
{
int i = atoi(cmd.c_str());
switch ( i )
{
+
case 1: // "Welcome!" - i.e. it's okay to issue commands now...
OnConnected();
break;
+
case 353: // user list for channel....
{
p = text.c_str();
@@ -336,6 +348,7 @@
OnChannelUsers ( channel, users );
}
break;
+
case 366: // END of user list for channel
{
p = text.c_str();
@@ -345,6 +358,38 @@
OnEndChannelUsers ( channel );
}
break;
+
+ case 474: // You are banned
+ {
+ p = text.c_str();
+ p2 = strpbrk ( p, " :" );
+ if ( !p2 ) continue;
+ string channel ( p, p2-p );
+ OnBanned ( channel );
+ }
+ break;
+
+ case 433: // Nick in Use
+ {
+ string nick = _nick;
+ Nick (nick + "_");
+
+ PrivMsg ("NickServ", "GHOST " + nick + " " + PASS);
+
+ // HACK HACK HACK
+ Mode ( "+i" );
+ Join ( CHANNEL ); // this is because IRC client does not review if his commands were sucessfull
+
+ Sleep ( 1000 );
+ Nick ( nick );
+ }
+ break;
+
+ case 2: //MOTD
+ case 376: //MOTD
+ case 372:
+ break;
+
default:
if ( _debug ) printf ( "unknown command %i: %s", i, buf.c_str() );
break;