Some new features like Login, Config.h and Idle message Modified: trunk/irc/ArchBlackmann/ArchBlackmann.cpp Modified: trunk/irc/ArchBlackmann/ArchBlackmann.dsp Modified: trunk/irc/ArchBlackmann/IRCClient.cpp Modified: trunk/irc/ArchBlackmann/IRCClient.h Added: trunk/irc/ArchBlackmann/config.h Modified: trunk/irc/ArchBlackmann/curse.txt Added: trunk/irc/ArchBlackmann/idle.txt _____
Modified: trunk/irc/ArchBlackmann/ArchBlackmann.cpp --- 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; } _____
Modified: trunk/irc/ArchBlackmann/ArchBlackmann.dsp --- trunk/irc/ArchBlackmann/ArchBlackmann.dsp 2005-06-03 17:09:47 UTC (rev 15751) +++ trunk/irc/ArchBlackmann/ArchBlackmann.dsp 2005-06-03 17:28:53 UTC (rev 15752) @@ -110,6 +110,10 @@
# End Source File # Begin Source File
+SOURCE=.\config.h +# End Source File +# Begin Source File + SOURCE=.\cram_md5.cpp # End Source File # Begin Source File _____
Modified: trunk/irc/ArchBlackmann/IRCClient.cpp --- 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; _____
Modified: trunk/irc/ArchBlackmann/IRCClient.h --- trunk/irc/ArchBlackmann/IRCClient.h 2005-06-03 17:09:47 UTC (rev 15751) +++ trunk/irc/ArchBlackmann/IRCClient.h 2005-06-03 17:28:53 UTC (rev 15752) @@ -12,9 +12,11 @@
class IRCClient : public suBufferedRecvSocket { + public: IRCClient();
+ std::string mychannel; static bool GetDebug() { return _debug; } static bool SetDebug ( bool debug ) { bool old = _debug; _debug = debug; return old; }
@@ -99,6 +101,12 @@ virtual bool OnChannelUsers ( const std::string& channel, const std::vectorstd::string& users ) { return true; }
+ // OnKick: if the client has been kicked + virtual bool OnKick ( void ) { return true; } + + // OnKick: if the client has been kicked + virtual bool OnBanned ( const std::string& channel ) { return true; } + // notification that you have received the entire list of users for a channel virtual bool OnEndChannelUsers ( const std::string& channel ) { return true; }
_____
Added: trunk/irc/ArchBlackmann/config.h --- trunk/irc/ArchBlackmann/config.h 2005-06-03 17:09:47 UTC (rev 15751) +++ trunk/irc/ArchBlackmann/config.h 2005-06-03 17:28:53 UTC (rev 15752) @@ -0,0 +1,7 @@
+ + +#define SERVER "irc.freenode.net" +#define BOTNAME "ArchBlackmann" +#define CHANNEL "#ReactOS" +#define MODE "+i" +#define PASS "ilovebunnies" _____
Modified: trunk/irc/ArchBlackmann/curse.txt --- trunk/irc/ArchBlackmann/curse.txt 2005-06-03 17:09:47 UTC (rev 15751) +++ trunk/irc/ArchBlackmann/curse.txt 2005-06-03 17:28:53 UTC (rev 15752) @@ -24,3 +24,4 @@
ekush akshor poop +guten morgen _____
Added: trunk/irc/ArchBlackmann/idle.txt --- trunk/irc/ArchBlackmann/idle.txt 2005-06-03 17:09:47 UTC (rev 15751) +++ trunk/irc/ArchBlackmann/idle.txt 2005-06-03 17:28:53 UTC (rev 15752) @@ -0,0 +1 @@
+/me is bored