NovaYoshi

New NovaBot

Jul 1st, 2011
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 34.30 KB | None | 0 0
  1. #include "xchat-plugin.h"
  2.  
  3. // Config settings
  4. #define MyNick "NovaYoshi"
  5. #define Enable_System 1
  6. #define Enable_Direct 1
  7. #define BITLBEE_SERVER "im.bitlbee.org"
  8. #define PLUGIN_IPC_NAME "NovaBotBase"
  9.  
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <time.h>
  13. #include <ctype.h>
  14. #include <stdlib.h>
  15. #define PNAME "NovaBotBase"
  16. #define PDESC "8====D~~~~~~"
  17. #define PVERSION "5.0.6b"
  18. #define BotOwnerListSize 8
  19. #define SpawnListSize 64
  20. static xchat_plugin *ph;   /* plugin handle, needed for any XChat call */
  21.  
  22. static unsigned int PowerTildeLock = 1;
  23. static int PrepOkay;
  24.  
  25. struct SpawnInfo {
  26.   int Slot;
  27.   int TriggerOnClear;
  28.   int TimeAmount;
  29.   char User[64];
  30.   char Command[1024];
  31.   char Server[256];
  32.   char Channel[256];
  33.   xchat_context *Context; // if NULL, have to find it using two above fields
  34. };
  35.  
  36. static xchat_hook *SpawnHook[SpawnListSize] = {[0 ... SpawnListSize-1] = NULL};
  37. static struct SpawnInfo *SpawnInfos[SpawnListSize];
  38.  
  39. static int spawntimer_cb(void *userdata) {
  40.   struct SpawnInfo *Spawn = (struct SpawnInfo *)userdata;
  41.   if(Spawn) {
  42.     if(xchat_set_context(ph,Spawn->Context))
  43.       xchat_command(ph, Spawn->Command);
  44.     else
  45.       xchat_printf(ph, "Context switch failed for spawn %i \n", Spawn->Slot);
  46.     SpawnHook[Spawn->Slot]=NULL;
  47.     free(Spawn);
  48.   }
  49.   return 0;
  50. }
  51. static int ClearSpawns(char *User) {
  52.   int Freed = 0; int Slot;
  53.   for(Slot=0;Slot<SpawnListSize;Slot++)
  54.     if(SpawnHook[Slot]!=NULL) {
  55.       if(User != NULL && strcasecmp(User, SpawnInfos[Slot]->User))
  56.         continue;
  57.       struct SpawnInfo *FreeMe = xchat_unhook(ph, SpawnHook[Slot]);
  58.       if(FreeMe != NULL) {
  59.         if(FreeMe->TriggerOnClear)
  60.         free(FreeMe);
  61.       }
  62.       SpawnHook[Slot]=NULL;
  63.       Freed++;
  64.     }
  65.   return(Freed);
  66. }
  67. static int SpawnTimeCalc(char *Amount, char *Unit) {
  68.   double Time = strtod(Amount, NULL);
  69.   switch(*Unit) {
  70.     case 'd':
  71.       Time*=24;
  72.     case 'h':
  73.       Time*=60;
  74.     case 'm':
  75.       Time*=60;
  76.     case 's':
  77.       Time*=1000;
  78.   }
  79.   return Time;
  80. }
  81. static struct SpawnInfo* CreateSpawn(int Time, char *Command) {
  82.   struct SpawnInfo *Spawn = (struct SpawnInfo*)malloc(sizeof(struct SpawnInfo));
  83.   if(Spawn == NULL) return NULL;
  84.   int Slot;
  85.   for(Slot = 0; Slot<16; Slot++)
  86.     if(SpawnHook[Slot] == NULL)
  87.       if(Spawn != NULL) {
  88.         strcpy(Spawn->Command, Command);
  89.         strcpy(Spawn->User, "$");
  90.         strcpy(Spawn->Channel, xchat_get_info(ph, "channel"));
  91.         Spawn->TriggerOnClear = 0;
  92.         Spawn->Context = xchat_get_context(ph);
  93.         Spawn->Slot = Slot;
  94.         SpawnHook[Slot] = xchat_hook_timer(ph, Time, spawntimer_cb, Spawn);
  95.         SpawnInfos[Slot] = Spawn;
  96.         return(Spawn);
  97.       }
  98.   xchat_printf(ph, "Could not find a free spawn slot\n");
  99.   free(Spawn);
  100.   return NULL;
  101. }
  102.  
  103. // Config strings
  104. static char HelpSite[256]        = "http://www.smwiki.net/wiki/NovaBot";
  105. static char BotNick[64]          = "NovaBot";
  106. static char BotOwner[BotOwnerListSize][64]      = {"NovaYoshi","NovaChakat","NovaRooey","NovaPony","","","",""};
  107. static char BotPrefix[16]        = "nb.";
  108.  
  109. // Config flags
  110. static char BridgeEnabled        = 0;
  111. static char ErrorOnBadCommand    = 1;
  112. static char RandomFunnyStuff     = 1;
  113. static char NoticeCommands       = 1;
  114. static char BlockExec            = 1;
  115. static char ErrorOnNoCmdPM       = 1;
  116. static char AllowSetProfiles     = 1;
  117. static char AllowGetProfiles     = 1;
  118. static char AllowNickFix         = 1;
  119. static char AllowMiscCommands    = 1;
  120. static char JoinOnInvite         = 1;
  121. static char ShowPluginIPC        = 0;
  122.  
  123. enum ConfigTypes {
  124.   CONFIG_STRING,
  125.   CONFIG_BOOLEAN,
  126.   CONFIG_INTEGER,
  127. };
  128.  
  129. struct {
  130.   char *Name;        // Name to recognize the option by
  131.   void *Data;        // Pointer to the data OR a function pointer
  132.   char Type;         // Data type. Set it to something in ConfigTypes
  133.   short Len;         // String length, so there aren't any overflows
  134.   const char *Desc;  // A description that isn't used anywhere!
  135. } ConfigOptions[] = {
  136.   {"Nick",          BotNick,            CONFIG_STRING,  64, "When 'nickfix' is used, the bot will change to this"},
  137.   {"Owner1",        BotOwner[0],        CONFIG_STRING,  64, "1st nick allowed to use /notice commands"},
  138.   {"Owner2",        BotOwner[1],        CONFIG_STRING,  64, "2nd nick allowed to use /notice commands"},
  139.   {"Owner3",        BotOwner[2],        CONFIG_STRING,  64, "3rd nick allowed to use /notice commands"},
  140.   {"Owner4",        BotOwner[3],        CONFIG_STRING,  64, "4th nick allowed to use /notice commands"},
  141.   {"Prefix",        BotPrefix,          CONFIG_STRING,  16, "Prefix used for all bot commands"},
  142.   {"HelpSite",      HelpSite,           CONFIG_STRING,  256, "Site for the 'help' command"},
  143.   {"Bridge",        &BridgeEnabled,     CONFIG_BOOLEAN, 0, "If ON, bot will bridge identically named channels"},
  144.   {"ErrOnBadCmd",   &ErrorOnBadCommand, CONFIG_BOOLEAN, 0, "If ON, bot will give a link to the help site if nothing traps a command"},
  145.   {"FunnyStuff",    &RandomFunnyStuff,  CONFIG_BOOLEAN, 0, "If ON, bot will do various stupid things"},
  146.   {"NoticeCmds",    &NoticeCommands,    CONFIG_BOOLEAN, 0 ,"If ON, bot will allow /notice admin commands to be used"},
  147.   {"BlockExec",     &BlockExec,         CONFIG_BOOLEAN, 0, "If ON, bot will trap and stop /exec"},
  148.   {"ErrOnNoCmdPM",  &ErrorOnNoCmdPM,    CONFIG_BOOLEAN, 0, "If ON, bot will complain when people PM it something that isn't a command"},
  149.   {"AllowFurGet",   &AllowGetProfiles,  CONFIG_BOOLEAN, 0, "If ON, users can use the 'furget' command"},
  150.   {"AllowFurSet",   &AllowSetProfiles,  CONFIG_BOOLEAN, 0, "If ON, users can use the 'furset' command"},
  151.   {"AllowMiscCmd",  &AllowMiscCommands, CONFIG_BOOLEAN, 0, "If ON, users can use the various built-in commands"},
  152.   {"AllowNickFix",  &AllowNickFix,      CONFIG_BOOLEAN, 0, "If ON, users can use the 'nickfix' command"},
  153.   {"JoinOnInvite",  &JoinOnInvite,      CONFIG_BOOLEAN, 0, "If ON, bot will join channels it is invited to"},
  154.   {"ShowPluginIPC", &ShowPluginIPC,     CONFIG_BOOLEAN, 0, "If ON, plugin IPC messages will be shown"},
  155.   {NULL}, // <-- end marker
  156. };
  157.  
  158. // returns NULL if okay, otherwise it returns an error message
  159. char *SetConfigByName(char *Item, char *Value) {
  160.   int i;
  161.   char *CharPointer;
  162.   for(i=0;ConfigOptions[i].Name != NULL;i++) {
  163.     if(!strcasecmp(Item, ConfigOptions[i].Name)) {
  164.       if(ConfigOptions[i].Data == NULL)
  165.         return "Config item points to NULL";
  166.       switch(ConfigOptions[i].Type) {
  167.         case CONFIG_STRING:
  168.           if(strlen(Value) < ConfigOptions[i].Len) {
  169.             strcpy((char*)ConfigOptions[i].Data, Value);
  170.             return NULL;
  171.           }
  172.           else
  173.             return "String's too long";
  174.         case CONFIG_BOOLEAN:
  175.           CharPointer = ConfigOptions[i].Data;
  176.           if(!strcasecmp(Value, "on"))
  177.             *CharPointer=1;
  178.           else if(!strcasecmp(Value, "off"))
  179.             *CharPointer=0;
  180.           else
  181.             return "Must be \"on\" or \"off\"";
  182.           return NULL;
  183.         default:
  184.           return "Unknown type?";
  185.       }
  186.     }
  187.   }
  188.   return "No options by that name?";  
  189. }
  190.  
  191. int GetConfigByName(char *Item, char **Str, int *Int) {
  192.   int i;
  193.   if(Str != NULL)
  194.     *Str = NULL;
  195.   for(i=0;ConfigOptions[i].Name != NULL;i++) {
  196.     if(!strcasecmp(Item, ConfigOptions[i].Name)) {
  197.       if(ConfigOptions[i].Data == NULL)
  198.         return -2;
  199.       switch(ConfigOptions[i].Type) {
  200.         case CONFIG_STRING:
  201.           *Str = (char*)ConfigOptions[i].Data;
  202.           return 1;
  203.         case CONFIG_BOOLEAN:
  204.           *Int = *(char*)ConfigOptions[i].Data;
  205.           return 3;
  206.         default:
  207.           return -3;
  208.       }
  209.     }
  210.   }
  211.   return -1;
  212. }
  213.  
  214. // Create a pointer to someone's database entry
  215. static char *CreateDataPath2(char *Buffer, char *Group, char *Nick, char *FileType) {
  216.   char NickBuf[512];
  217.   int i=0;
  218.   while(1) {
  219.     NickBuf[i]=tolower(Nick[i]);
  220.     if(NickBuf[i]=='/' || NickBuf[i]=='\\')
  221.       NickBuf[i] = '-';
  222.     if(0==Nick[i++])
  223.       break;
  224.   }
  225.   sprintf(Buffer, "%s/NovaBot/data/%s%s%s", xchat_get_info(ph, "xchatdirfs"),Group,NickBuf,FileType);
  226.   return(Buffer);
  227. }
  228.  
  229. // Check if a message starts with a given command, and if so, return the argument
  230. static int RecognizeCommand(char *Msg, const char *Cmd, char **ArgPtr) {
  231.   if(!memcmp(Msg, Cmd, strlen(Cmd))) {
  232.     if(ArgPtr != NULL)
  233.       *ArgPtr = Msg+strlen(Cmd);
  234.     if(**ArgPtr == 0) return(0);
  235.     return(1);
  236.   }
  237.   return(0);
  238. }
  239.  
  240. // Strips out any colors or text effects, then does a nick comparison
  241. static int MyNickCmp(char *N1, char *N2) {
  242.    static char *StripName;
  243.    StripName = xchat_strip(ph, N1, -1, 3);
  244.    if(!strcasecmp(StripName, N2)) {
  245.      xchat_free(ph, StripName);
  246.      return 0;
  247.    }
  248.    xchat_free(ph, StripName);
  249.    return 1;
  250. }
  251.  
  252. // Find someone in the bot owner list (-1 if they're not in it)
  253. static int IsBotOwner(char *Nick, xchat_context *Context) {
  254.   int i;
  255.   for(i=0;i<BotOwnerListSize;i++)
  256.     if(!MyNickCmp(Nick,BotOwner[i]))
  257.       return i;
  258.   return -1;
  259. }
  260.  
  261. // Pretty much the core of NovaBot
  262. static int ReactGlobalCommand(xchat_context *Context, char *Nick, char *Message, char *ReplyCmd, char *ModeChar) {
  263.    static char Temp[512];
  264.    int already = 0;
  265.    int i;
  266.    xchat_set_context(ph,Context);
  267.  
  268.    char LowerBuffer[2048]; // big buffer sizes
  269.    char *MkLowPeek = Message;
  270.    char *MkLowPoke = LowerBuffer;
  271.  
  272.    // Make a useless lowercase version of the message
  273.    while(*MkLowPeek)
  274.      *(MkLowPoke++)=tolower(*(MkLowPeek++));
  275.    *MkLowPoke = 0;
  276.  
  277.   char *ArgPtr;        // pass to RecognizeCommand
  278.   char *MessageNoPF;   // pointer to the actual command name past the prefix
  279.   if(!RecognizeCommand(LowerBuffer, BotPrefix, &MessageNoPF)) {
  280.     xchat_print(ph, "???");
  281.     return 0;
  282.   }
  283.   MessageNoPF = MessageNoPF - LowerBuffer + Message;
  284.   if((RecognizeCommand(MessageNoPF, "furget ", &ArgPtr)|| !strcasecmp(MessageNoPF,"furget")) && !already && AllowGetProfiles) {
  285.     if(!strcasecmp(MessageNoPF, "furget")) ArgPtr = Nick;
  286.     char *Trim = strchr(ArgPtr, ' ');
  287.     if(Trim != NULL)
  288.       *Trim = 0;
  289.     CreateDataPath2(Temp, "furprofile/", ArgPtr, ".txt");
  290.     FILE *Profile = fopen(Temp, "rb");
  291.     if(Profile!=NULL) {
  292.       MkLowPoke = Temp;
  293.       for(i=5;i!=EOF;) {
  294.         i=fgetc(Profile);
  295.         *MkLowPoke = i;
  296.         if(i == '`'){*MkLowPoke = 0; break;}
  297.         MkLowPoke++;
  298.       }
  299.      fclose(Profile);
  300.      xchat_commandf(ph, "%s %s is: %s", ReplyCmd, ArgPtr, Temp);
  301.     } else {
  302.       xchat_commandf(ph, "%s I don't think %s has a profile yet. (You can set one for yourself with nb.furset Your Description Here)", ReplyCmd, ArgPtr);
  303.     }
  304.     already = 1;
  305.   }
  306.   if(!strcasecmp(MessageNoPF,"furset") || !strcasecmp(MessageNoPF,"furset ")) {
  307.     xchat_commandf(ph, "%s You have to put text after nb.furset or I'm not going to know what to set your description to", ReplyCmd);
  308.     already = 1;
  309.   }
  310.   if(RecognizeCommand(MessageNoPF, "furset ", &ArgPtr) && !already && AllowSetProfiles) {
  311.     CreateDataPath2(Temp, "furprofile/", Nick, ".txt");
  312.     int Error = 0;
  313.     char *Test;
  314.  
  315.     FILE *Profile = fopen(Temp, "wb");
  316.     if(Profile!=NULL) {
  317.      sprintf(Temp, "%s ", Nick);
  318.      if(RecognizeCommand(ArgPtr, Temp, &Test)) {
  319.        Error = 1;
  320.        ArgPtr = Test;
  321.      }
  322.      if(RecognizeCommand(ArgPtr, "is ", &Test) || RecognizeCommand(ArgPtr, "Is ", &Test)) {
  323.        Error = 1;
  324.        ArgPtr = Test;
  325.      }
  326.      fprintf(Profile, "%s`", ArgPtr);
  327.      if(!Error)
  328.        xchat_commandf(ph, "%s Saved :3", ReplyCmd);
  329.      else
  330.        xchat_commandf(ph, "%s Saved (Automatically fixed)", ReplyCmd);
  331.      fclose(Profile);
  332.     } else {
  333.       xchat_commandf(ph, "%s Couldn't open your profile", ReplyCmd);
  334.     }
  335.     already = 1;
  336.   }
  337.  
  338.   if(already) return 2;
  339.   ArgPtr = "";
  340.   strcpy(Temp, MessageNoPF);
  341.   char *Find = strchr(Temp, ' ');
  342.   if(Find != NULL) {
  343.     *Find = 0;
  344.     if(Find[1]) ArgPtr = Find+1;
  345.   }
  346.   xchat_commandf(ph,"NB_ExtCmd \"%s\" \"%s\" \"%s\" \"%s\" -A %s", ReplyCmd, Temp, Nick, ModeChar, ArgPtr);
  347.  
  348.   return 1;
  349. }
  350.  
  351. // Left over from when NovaBot was a bridgebot and not a yiffbot
  352. static void Prep() { // Make sure this context is okay
  353.   PrepOkay=0;
  354.   if(xchat_get_info(ph,"channel")==NULL) {
  355.     xchat_print(ph, "Channel returned null! \n"); return;
  356.   }
  357.   if(xchat_get_info(ph,"server")==NULL) {
  358.     xchat_print(ph, "Server returned null! \n"); return;
  359.   }
  360.   if(!BridgeEnabled)
  361.     return;
  362.   PrepOkay=1;
  363. }
  364.  
  365. //Emit the command in every suitable channel but the origin
  366. static void AllOthers(char *String, const char *Origin, const char *PassServer) {
  367.   xchat_list *list = xchat_list_get(ph, "channels");
  368.   if(list) {
  369.     while(xchat_list_next(ph, list))
  370.       if(!strcasecmp(xchat_list_str(ph, list, "channel"),Origin))
  371.         if( strcasecmp(xchat_list_str(ph, list, "server"),PassServer)) {
  372.           if( xchat_set_context(ph,(xchat_context *)xchat_list_str(ph, list, "context")) == 0)
  373.             xchat_printf(ph,"Oops! Bad context! \n");
  374.           else
  375.             xchat_command(ph, String);
  376.         }
  377.     xchat_list_free(ph, list);
  378.   }
  379. }
  380.  
  381. // Hook for when NovaBot talks, so it can bridge that too
  382. static int imessage_cb(char *word[], void *userdata) {
  383.   static char Temp[512]; Prep();   
  384.   // sloppy check to see if it is a bridged message already
  385.   if(word[2][0] == '*' || word[2][1] == '*') return XCHAT_EAT_NONE;
  386.   if(word[2][0] == ':' || word[2][1] == ':') return XCHAT_EAT_NONE;
  387.   if(word[2][0] == 2   || word[2][1] == 2) return XCHAT_EAT_NONE;
  388.   sprintf(Temp, "NBBSAY \2\2:NovaBot: %s", word[2]);
  389.   if(PrepOkay==1)
  390.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  391.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  392. }
  393.  
  394. // Hook for when NovaBot yiffs
  395. static int iaction_cb(char *word[], void *userdata) {
  396.   static char Temp[512];    Prep();
  397.   // sloppy check to see if it is a bridged message already
  398.   if(word[2][0] == '*' || word[2][1] == '*') return XCHAT_EAT_NONE;
  399.   if(word[2][0] == ':' || word[2][1] == ':') return XCHAT_EAT_NONE;
  400.   if(word[2][0] == 2   || word[2][1] == 2) return XCHAT_EAT_NONE;
  401.   sprintf(Temp, "NBBSAY *NovaBot %s", word[2]);
  402.   if(PrepOkay==1)
  403.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  404.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  405. }
  406.  
  407. // Doesn't do anything yet
  408. static int ijoin_cb(char *word[], void *userdata) {
  409.   return XCHAT_EAT_NONE;
  410. }
  411.  
  412. // Hook for receiving notices
  413. static int notice_cb(char *word[], void *userdata) {
  414.   int FindIt;
  415.   FILE *ReadPass;
  416.  
  417.   if(!NoticeCommands)
  418.     xchat_commandf(ph, "notice %s /notice commands are disabled",word[1]);
  419.  
  420.   if(!strcasecmp(word[2], "isbot"))
  421.     xchat_commandf(ph, "quote mode %s +B",xchat_get_info(ph,"nick"));
  422.  
  423.   char SecurityBuff[512];
  424.   int i=0;
  425.   for(i=0;;) {
  426.     SecurityBuff[i]=tolower(word[2][i]);
  427.     if(0==word[2][i++])
  428.       break;
  429.   }
  430.  
  431.   FindIt=0;
  432.   char *ArgPtr;  
  433.  
  434.   if(-1 != IsBotOwner(word[1], xchat_get_context(ph))) { // Ignore comands if given by someone who isn't me
  435.     if(RecognizeCommand(word[2], "clearallspawn", &ArgPtr)) {
  436.       xchat_commandf(ph, "notice %s Cleared %i spawn slots", word[1],  ClearSpawns(NULL));
  437.     }
  438.     if(RecognizeCommand(word[2], "clearspawn ", &ArgPtr)) {
  439.       xchat_commandf(ph, "notice %s Cleared %i spawn slots", word[1],  ClearSpawns(ArgPtr));
  440.     }
  441.  
  442.     if(RecognizeCommand(word[2], "^~", &ArgPtr)) {
  443.       int SkipSecurity=0;
  444.       char *P;
  445.       if(RecognizeCommand(ArgPtr, "rsay ", &P)) SkipSecurity = 1;
  446.       if(RecognizeCommand(ArgPtr, "ract ", &P)) SkipSecurity = 1;
  447.      
  448.       int ErrSecurity=0;
  449.  
  450.       if(RecognizeCommand(ArgPtr, "ns ", &P)) ErrSecurity = 1;
  451.       if(RecognizeCommand(ArgPtr, "cs ", &P)) ErrSecurity = 1;
  452.       if(RecognizeCommand(ArgPtr, "msg nickserv ", &P)) ErrSecurity = 1;
  453.       if(RecognizeCommand(ArgPtr, "msg chanserv ", &P)) ErrSecurity = 1;
  454.  
  455.       if(NULL!=strstr(SecurityBuff,"nickserv ")) ErrSecurity = 1;
  456.       if(NULL!=strstr(SecurityBuff,"chanserv ")) ErrSecurity = 1;
  457.       if(NULL!=strstr(SecurityBuff,"botserv "))  ErrSecurity = 1;
  458.       if(NULL!=strstr(SecurityBuff,"memoserv ")) ErrSecurity = 1;
  459.       if(NULL!=strstr(SecurityBuff,"hostserv ")) ErrSecurity = 1;
  460.       if(NULL!=strstr(SecurityBuff,"drop "))     ErrSecurity = 1;
  461.       if(NULL!=strstr(SecurityBuff,"access "))   ErrSecurity = 1;
  462.       if(NULL!=strstr(SecurityBuff,"ms "))      ErrSecurity = 1;
  463.       if(NULL!=strstr(SecurityBuff,"hs "))      ErrSecurity = 1;
  464.       if(NULL!=strstr(SecurityBuff,"bs "))      ErrSecurity = 1;
  465.       if(NULL!=strstr(SecurityBuff,"cs "))      ErrSecurity = 1;
  466.       if(NULL!=strstr(SecurityBuff,"ns "))      ErrSecurity = 1;
  467.  
  468.       if(!SkipSecurity && (ErrSecurity == 1)) { xchat_commandf(ph, "notice %s driving 125 miles to your house \2right now",word[1]); return XCHAT_EAT_NONE; }
  469.  
  470.       if(PowerTildeLock == 0)
  471.         xchat_commandf(ph, "notice %s PowerTilde is locked right now",word[1]);
  472.       else
  473.         xchat_commandf(ph, "%s", ArgPtr);
  474.       return XCHAT_EAT_NONE;
  475.     }
  476.     int LockCmd = 0;
  477.  
  478.     if(!strcasecmp(word[2], "spawnclearall")) {
  479.       xchat_commandf(ph, "notice %s cleared %i spawns", word[1], ClearSpawns(NULL));
  480.       return XCHAT_EAT_NONE;
  481.     }
  482.     if(RecognizeCommand(word[2], "spawnclear ", &ArgPtr)) {
  483.       xchat_commandf(ph, "notice %s cleared %i spawns", word[1], ClearSpawns(ArgPtr));
  484.       return XCHAT_EAT_NONE;
  485.     }
  486.  
  487.     if(RecognizeCommand(word[2], "lock ", &ArgPtr))
  488.       LockCmd = 1;
  489.     if(RecognizeCommand(word[2], "unlock ", &ArgPtr))
  490.       LockCmd = 2;
  491.     if(LockCmd) {
  492.       char Buffer[512];
  493.       sprintf(Buffer, "%s/NovaBot/tildepass.txt", xchat_get_info(ph, "xchatdirfs"));
  494.  
  495.       ReadPass = fopen(Buffer,"rb");
  496.       if(ReadPass != NULL) {
  497.         char CheckBuffer[50];
  498.         char *PokePass = CheckBuffer;
  499.         for(i=5;i!=EOF;) {
  500.           i=fgetc(ReadPass);
  501.           *PokePass = i;
  502.           if(i == '~'){*PokePass = 0; break;}
  503.             PokePass++;
  504.         }
  505.         if(!strcasecmp(ArgPtr, CheckBuffer)) {
  506.           PowerTildeLock = LockCmd-1;
  507.           xchat_commandf(ph, "notice %s a winrar is you (%i)", word[1], PowerTildeLock);
  508.         }
  509.         else {
  510.           xchat_commandf(ph, "notice %s That isn't my password", word[1]);
  511.         }
  512.         fclose(ReadPass);
  513.       } else
  514.         xchat_commandf(ph, "notice %s file didn't open", word[1]);    
  515.     }
  516.   }
  517.  
  518.   return XCHAT_EAT_NONE;
  519. }
  520.  
  521. // Handler for when someone joins so we can voice aginas
  522. static int join_cb(char *word[], void *userdata) {
  523.   static char Temp[512]; Prep();   
  524.   sprintf(Temp,"NBBSAY \02%s\x0f has joined this channel on %s", word[1],xchat_get_info(ph,"server"));
  525.   if(RandomFunnyStuff) {
  526.     if((!MyNickCmp(word[1],"Haruto")))
  527.       xchat_commandf(ph, "bssay [Haruto] gotta do the shit ya miss");
  528.  
  529.     if(NULL !=strstr(word[1],"agina"))
  530.       xchat_commandf(ph, "VOICE %s", word[1]);        
  531.     if((!MyNickCmp(word[1],"agina")))
  532.       xchat_commandf(ph, "VOICE agina"); // set mode +v agina
  533.     if((!MyNickCmp(word[1],"irgin")))
  534.       xchat_commandf(ph, "VOICE irgin"); // set mode +v irgin
  535.     if((!MyNickCmp(word[1],"irgin_mobile")))
  536.       xchat_commandf(ph, "VOICE irgin_mobile"); // set mode +v irgin
  537.     if((!MyNickCmp(word[1],"iagra")))
  538.       xchat_commandf(ph, "VOICE iagra"); // set mode +v iagra
  539.   }
  540.   if(PrepOkay==1)
  541.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  542.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  543. }
  544.  
  545. // For when someone leaves
  546. static int part_cb(char *word[], void *userdata) {
  547.   static char Temp[512]; Prep();
  548.   sprintf(Temp,"NBBSAY \02%s\x0f has left this channel on %s", word[1],xchat_get_info(ph,"server"));
  549.   if(PrepOkay==1)
  550.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  551.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  552. }
  553.  
  554. // For when someone leaves and gives a reason
  555. static int partr_cb(char *word[], void *userdata) {
  556.   static char Temp[512]; Prep();
  557.   sprintf(Temp,"NBBSAY \02%s\x0f has left this channel on %s (%s)", word[1], xchat_get_info(ph,"server"), word[4]);
  558.   if(PrepOkay==1)
  559.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  560.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  561. }
  562.  
  563. /* When the bot gets kicked, this code runs */
  564. static int kicked_cb(char *word[], void *userdata) {
  565.   if(!strcasecmp(xchat_get_info(ph, "server"),BITLBEE_SERVER))
  566.     xchat_command(ph, "JOIN &bitlbee"); // for taking over old connections
  567.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  568. }
  569.  
  570. //  Whenever someone uses /me in a channel, this code runs
  571. static int emote_cb(char *word[], void *userdata) {
  572.   static char Temp[512];  Prep();
  573.   sprintf(Temp,"NBBSAY *%s\x0f %s", word[1],word[2]);
  574.   if(PrepOkay==1)
  575.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  576.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  577. }
  578.  
  579. // NovaBot should join when invited
  580. static int invited_cb(char *word[], void *userdata) {
  581.   if(JoinOnInvite)
  582.     if(strcasecmp(word[1],"#dontjoinitsatrap")) {
  583.       xchat_commandf(ph,"join %s",word[1]);
  584.  
  585.       char Command[512];
  586.       sprintf(Command, "msg %s (invited by %s)", word[1], word[2]);
  587.       CreateSpawn(2000, Command);
  588.     }
  589.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  590. }
  591.  
  592. // Is someone PMing the bot?
  593. static int private_cb(char *word[], void *userdata) {
  594.   if(!strncasecmp(word[2] ,BotPrefix, strlen(BotPrefix))) {
  595.     char ReplyWith[100];
  596.     sprintf(ReplyWith, "msg %s", word[1] );
  597.     ReactGlobalCommand(xchat_get_context(ph), word[1], word[2], ReplyWith, ".");
  598.     return XCHAT_EAT_NONE;
  599.   }
  600.   else
  601.     if(!strcasecmp(BotOwner[0],"NovaYoshi"))
  602.       if(strcasecmp(word[1],"AlcaRobot"))
  603.         if(strcasecmp(word[1],"AlcaRobot_"))
  604.           xchat_commandf(ph,"msg %s Not a valid command. Maybe you were trying to contact NovaYoshi instead? (use MemoServ if you have to)",  word[1]);
  605.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  606. }
  607.  
  608. // handler for channel messages
  609. static int message_cb(char *word[], void *userdata) {
  610.   static char Temp[512];
  611.   char LowerBuffer[512];
  612.   char *MkLowPeek = word[2];  
  613.   char *MkLowPoke = LowerBuffer;
  614.   int already = 0;
  615.  
  616.   xchat_context *BackTo = xchat_get_context(ph);
  617.  
  618.   Prep();
  619.   sprintf(Temp,"NBBSAY \2\2:%c\2\2%s\x0f: %s", word[1][0], word[1]+1,word[2]);
  620.   if(PrepOkay==1)
  621.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  622.   xchat_set_context(ph,BackTo);
  623.   while(*MkLowPeek)
  624.     *(MkLowPoke++)=tolower(*(MkLowPeek++));
  625.   *MkLowPoke = 0;
  626.  
  627.   if( ( NULL != strstr(LowerBuffer,"lose") || NULL != strstr(LowerBuffer,"lost") )  && NULL != strstr(LowerBuffer," electron") )     xchat_commandf(ph, "SAY Are you sure?"); // Yes I'm positive
  628.  
  629. /*
  630.   if(!strcasecmp(xchat_get_info(ph,"channel"),"#novaforest")) {
  631.     if(NULL != strstr(LowerBuffer,"what the fuck")
  632.     || NULL != strstr(LowerBuffer,"what the heck")
  633.     || NULL != strstr(LowerBuffer,"what the hell")
  634.     || NULL != strstr(LowerBuffer,"fucking sucks")
  635.     || NULL != strstr(LowerBuffer,"fuckin sucks")
  636.     || NULL != strstr(LowerBuffer,"wtf")
  637.      ) {
  638.       xchat_commandf(ph, "say Don't worry about it, go back to bed");
  639.     }
  640.   }  
  641. */
  642.  
  643.   if(!MyNickCmp(word[1], "root")) // Is Bitlbee trying to talk to us?
  644.   { // automatically accept friend requests
  645.     if(NULL != strstr(word[2],"wants to add you to his/her buddy list")
  646.     || NULL != strstr(word[2],"is not in your buddy list yet. Do you want to add him/her now")
  647.     || NULL != strstr(word[2],"Would you like to take over this session?"))
  648.       xchat_commandf(ph, "say yes");
  649.   }
  650.  
  651.   if(RecognizeCommand(LowerBuffer,BotPrefix, &MkLowPoke)){
  652.     if(!strcasecmp(MkLowPoke,"whatchannelisthis") && !already) {
  653.       sprintf(Temp,"NBBSAY umm, I think this is %s",xchat_get_info(ph,"channel"));
  654.       xchat_command(ph, Temp);
  655.       already=1;
  656.     }
  657.     if(!already)
  658.      ReactGlobalCommand(BackTo, word[1], word[2], "nbsay", word[3]);
  659.    }
  660.   if(RandomFunnyStuff) {
  661.     if(!strcasecmp(word[2],"!help") && !already) {
  662.       xchat_commandf(ph, "KICK %s 8==========D~~~~~~~~~~~~~~~~~", word[1]);
  663.       already=1;
  664.     }
  665.   }
  666.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  667. }
  668.  
  669. //  Whenever someone gets kicked from the channel, this code runs
  670. static int kick_cb(char *word[], void *userdata) {
  671.   static char Temp[512]; Prep();
  672.   sprintf(Temp,"NBBSAY \02%s\x0f has been kicked by \02%s\x0f (%s)", word[2],word[1],word[4]);
  673.   if(PrepOkay==1)
  674.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  675.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  676. }
  677.  
  678. //  Whenever someone changes their name, this code runs
  679. static int nick_cb(char *word[], void *userdata) {
  680.   static char Temp[512]; Prep();
  681.   sprintf(Temp,"NBBSAY \02%s\x0f is now known as \02%s\x0f", word[1],word[2]);
  682.   if(PrepOkay==1)
  683.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  684.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  685. }
  686.  
  687. //  Whenever someone quits, this code runs
  688. static int quit_cb(char *word[], void *userdata) {
  689.   static char Temp[512]; Prep();
  690.   if(-1 != IsBotOwner(word[1], xchat_get_context(ph)))
  691.     PowerTildeLock = 0;
  692.  
  693.   sprintf(Temp,"NBBSAY \02%s\x0f has disconnected from %s, (%s)", word[1],xchat_get_info(ph,"server"),word[2]);
  694.   if(PrepOkay==1)
  695.     AllOthers(Temp,xchat_get_info(ph,"channel"),xchat_get_info(ph,"server"));
  696.   return XCHAT_EAT_NONE;  /* don't eat this event, xchat needs to see it! */
  697. }
  698.  
  699. void xchat_plugin_get_info(char **name, char **desc, char **version, void **reserved) {
  700.   *name = PNAME;
  701.   *desc = PDESC;
  702.   *version = PVERSION;
  703. }
  704.  
  705. static int nb_config_cb(char *word[], char *word_eol[], void *userdata) {
  706.    if(word[2] == NULL || word_eol[3] == NULL) return(XCHAT_EAT_ALL);
  707.  
  708.    xchat_printf(ph,"Setting %s to %s ", word[2], word_eol[3]);
  709.    char *Msg = SetConfigByName(word[2], word_eol[3]);
  710.    if(Msg!=NULL)
  711.      xchat_printf(ph," - %s", Msg);
  712.    xchat_printf(ph,"\n");
  713.    return XCHAT_EAT_ALL;
  714. }
  715. static int nb_extcmd_cb(char *word[], char *word_eol[], void *userdata) {
  716.   char Temp[512];
  717.   char *ReplyCmd = word[2];
  718.   char *NBCmd = word[3];
  719.   char *Nick=word[4];
  720.  
  721.   int i;
  722.   int ArgPtrIndex = -1;
  723.   char *ArgPtr = NULL;
  724.   for(i=4;i<10 && (word[i]!=NULL);i++) {
  725.     if(!strcasecmp(word[i],"-A"))
  726.       if(word[++i]!=NULL)
  727.         if(strcasecmp(word[i],"")) {
  728.           ArgPtr = word_eol[i];
  729.           ArgPtrIndex = i;
  730.           break;
  731.         }
  732.   }
  733.  
  734.   if(!strcasecmp(NBCmd,"nickfix") && AllowNickFix) {
  735.     xchat_commandf(ph, "nick %s", BotNick);
  736.     return XCHAT_EAT_ALL;
  737.   }
  738.   if(!strcasecmp(NBCmd,"help")) {
  739.     xchat_commandf(ph, "%s Check out %s", ReplyCmd, HelpSite);
  740.     return XCHAT_EAT_ALL;
  741.   }
  742.   if(!strcasecmp(NBCmd,"version")) {
  743.     xchat_commandf(ph,"%s Currently running NovaBot version %s",ReplyCmd,PVERSION);
  744.     return XCHAT_EAT_ALL;
  745.   }
  746.  
  747.   if(!strcasecmp(NBCmd,"spawnmsg")) { // nb.spawnmsg Time Unit Message
  748.     char *Message = word_eol[ArgPtrIndex+2];
  749.     char *Ptr;
  750.     int Time = SpawnTimeCalc(word[ArgPtrIndex], word[ArgPtrIndex+1]);
  751.     if(RecognizeCommand(Message, "to ", &Ptr))
  752.       sprintf(Temp, "nbsay \2%s\2, time %s", Nick, Message);
  753.     else
  754.       sprintf(Temp, "nbsay \2%s\2, time for %s", Nick, Message);    
  755.  
  756.     struct SpawnInfo *UserSpawn = CreateSpawn(Time, Temp);
  757.     if(UserSpawn == NULL) {
  758.       xchat_commandf(ph,"%s Unable to create spawn (Maybe the list is maxed out)", ReplyCmd);
  759.       return XCHAT_EAT_ALL;
  760.     }
  761.     strcpy(UserSpawn->User, Nick);
  762.     xchat_commandf(ph,"%s Timer set to go off in %is/%fm/%fh",ReplyCmd, Time/1000,(float)Time/1000/60,(float)Time/1000/60/60);
  763.     return XCHAT_EAT_ALL;
  764.   }
  765.  
  766.   if(!strcasecmp(NBCmd,"spawnclear")) {
  767.     xchat_commandf(ph, "%s Cleared %i spawn slots", ReplyCmd, ClearSpawns(Nick));
  768.     return XCHAT_EAT_ALL;  
  769.   }
  770.  
  771.  
  772.   xchat_printf(ph, "Unhandled ExtCmd: %s\n", word_eol[1]);
  773.   if(ErrorOnBadCommand)
  774.     if(NULL != word[2])
  775.       xchat_commandf(ph, "%s Doesn't seem to be a valid command. Check %s", ReplyCmd, HelpSite);
  776.   return XCHAT_EAT_ALL;
  777. }
  778.  
  779. static int dangerous_cb(char *word[], char *word_eol[], void *userdata) {
  780.   if(BlockExec)
  781.     return XCHAT_EAT_ALL;
  782.   else
  783.     return XCHAT_EAT_NONE;
  784. }
  785. void *GetFuncByName(char *Name) {
  786.   if(!strcasecmp(Name,"SpawnHookList"))    return SpawnHook;
  787.   if(!strcasecmp(Name,"SpawnInfoList"))    return SpawnInfos;
  788.   if(!strcasecmp(Name,"HelpSite"))         return HelpSite;
  789.   if(!strcasecmp(Name,"ph"))               return ph;
  790.   if(!strcasecmp(Name,"SetConfigByName"))  return SetConfigByName;
  791.   if(!strcasecmp(Name,"GetConfigByName"))  return GetConfigByName;
  792.   if(!strcasecmp(Name,"CreateDataPath2"))  return CreateDataPath2;
  793.   if(!strcasecmp(Name,"RecognizeCommand")) return RecognizeCommand;
  794.   if(!strcasecmp(Name,"MyNickCmp"))        return MyNickCmp;
  795.   if(!strcasecmp(Name,"IsBotOwner"))       return IsBotOwner;
  796.   if(!strcasecmp(Name,"ClearSpawns"))      return ClearSpawns;
  797.   if(!strcasecmp(Name,"SpawnTimeCalc"))    return SpawnTimeCalc;
  798.   if(!strcasecmp(Name,"CreateSpawn"))      return CreateSpawn;
  799.   return NULL;
  800. }
  801. static int nb_mrequest_cb(char *word[], char *word_eol[], void *userdata) {
  802.   int Type = (int)userdata;
  803.   int Int;
  804.   char *Str;
  805.  
  806.   if(!strcasecmp(word[2],PLUGIN_IPC_NAME)) { // It's a message for NovaBot! :P
  807.     switch(Type) {
  808.       case 1: // ping
  809.         xchat_commandf(ph, "nb_mPong %s %s", PLUGIN_IPC_NAME, word[3]);      
  810.         break;
  811.       case 2: // ptr
  812.         xchat_commandf(ph, "nb_mSayPtr %s %s %p", PLUGIN_IPC_NAME, word[3], GetFuncByName(word[3]));
  813.         break;
  814.       case 3: // inf
  815.        switch(GetConfigByName(word[3], &Str, &Int)) {
  816.          case 0: // fail
  817.            xchat_commandf(ph, "nb_mSayInf %s %s fail", PLUGIN_IPC_NAME, word[3]);
  818.            break;
  819.          case 1: // string
  820.            xchat_commandf(ph, "nb_mSayInf %s %s %s", PLUGIN_IPC_NAME, word[3], Str);
  821.            break;
  822.          case 2: // int
  823.            xchat_commandf(ph, "nb_mSayInf %s %s %i", PLUGIN_IPC_NAME, word[3], Int);
  824.            break;
  825.          case 3: // bool
  826.            xchat_commandf(ph, "nb_mSayInf %s %s %i", PLUGIN_IPC_NAME, word[3], Int);
  827.            break;
  828.        }
  829.        break;
  830.     }
  831.   }
  832.   if(ShowPluginIPC)
  833.     xchat_printf(ph, "NBIPC (%i) %s\n", Type, word_eol[1]);
  834.   return XCHAT_EAT_ALL;
  835. }
  836. static int nb_manswer_cb(char *word[], char *word_eol[], void *userdata) {
  837.   int Type = (int)userdata;
  838.   if(ShowPluginIPC)
  839.     xchat_printf(ph, "NBIPC (%i) %s\n", Type, word_eol[1]);
  840.   return XCHAT_EAT_ALL;
  841. }
  842.  
  843. int xchat_plugin_deinit() {
  844.   ClearSpawns(NULL);
  845.   return 1;
  846. }
  847. int xchat_plugin_init(xchat_plugin *plugin_handle, char **plugin_name,
  848.                       char **plugin_desc, char **plugin_version, char *arg) {
  849.    /* we need to save this for use with any xchat_* functions */
  850.    ph = plugin_handle;
  851.    
  852.    /* tell xchat our info */
  853.    *plugin_name = PNAME;
  854.    *plugin_desc = PDESC;
  855.    *plugin_version = PVERSION;
  856.  
  857.    /* If I didn't insist on keeping NovaBot's bridge features I could eliminate a lot of these */
  858.    xchat_hook_print(ph, "Join", XCHAT_PRI_NORM, join_cb, 0);
  859.    xchat_hook_print(ph, "Part", XCHAT_PRI_NORM, part_cb, 0);
  860.    xchat_hook_print(ph, "Part with reason", XCHAT_PRI_NORM, partr_cb, 0);
  861.    xchat_hook_print(ph, "Channel Action", XCHAT_PRI_NORM, emote_cb, 0);
  862.    xchat_hook_print(ph, "Channel Action Highlight", XCHAT_PRI_NORM, emote_cb, 0);
  863.    xchat_hook_print(ph, "Channel Message", XCHAT_PRI_NORM, message_cb, 0);
  864.    xchat_hook_print(ph, "Channel Message Hilight", XCHAT_PRI_NORM, message_cb, 0);
  865.    xchat_hook_print(ph, "Channel Msg Hilight", XCHAT_PRI_NORM, message_cb, 0);
  866.    xchat_hook_print(ph, "Kick", XCHAT_PRI_NORM, kick_cb, 0);
  867.    xchat_hook_print(ph, "Quit", XCHAT_PRI_NORM, quit_cb, 0);
  868.    xchat_hook_print(ph, "Notice", XCHAT_PRI_NORM, notice_cb, 0);
  869.    xchat_hook_print(ph, "Private Message", XCHAT_PRI_NORM, private_cb, 0);
  870.    xchat_hook_print(ph, "Private Message to Dialog", XCHAT_PRI_NORM, private_cb, 0);
  871.    xchat_hook_print(ph, "Change Nick", XCHAT_PRI_NORM, nick_cb, 0);
  872.    xchat_hook_print(ph, "You Kicked", XCHAT_PRI_NORM, kicked_cb, 0);
  873.    xchat_hook_print(ph, "You Join", XCHAT_PRI_NORM, ijoin_cb, 0);
  874.    xchat_hook_print(ph, "You Message", XCHAT_PRI_LOWEST, imessage_cb, 0);
  875.    xchat_hook_print(ph, "You Action", XCHAT_PRI_LOWEST, iaction_cb, 0);
  876.    xchat_hook_print(ph, "Your Message", XCHAT_PRI_LOWEST, imessage_cb, 0);
  877.    xchat_hook_print(ph, "Your Action", XCHAT_PRI_LOWEST, iaction_cb, 0);
  878.    xchat_hook_print(ph, "Invited", XCHAT_PRI_NORM, invited_cb, 0);  
  879.    xchat_hook_command(ph, "exec", XCHAT_PRI_HIGH, dangerous_cb, "dangerous", 0);
  880.    xchat_hook_command(ph, "NB_ExtCmd", XCHAT_PRI_LOWEST, nb_extcmd_cb, NULL, 0);
  881.    xchat_hook_command(ph, "NB_Config", XCHAT_PRI_NORM, nb_config_cb, NULL, 0);
  882.  
  883.    xchat_hook_command(ph, "NB_mPing",   XCHAT_PRI_LOWEST, nb_mrequest_cb, NULL, (void*)1);
  884.    xchat_hook_command(ph, "NB_mAskPtr", XCHAT_PRI_LOWEST, nb_mrequest_cb, NULL, (void*)2);
  885.    xchat_hook_command(ph, "NB_mAskInf", XCHAT_PRI_LOWEST, nb_mrequest_cb, NULL, (void*)3);
  886.  
  887.    xchat_hook_command(ph, "NB_mPong",   XCHAT_PRI_LOWEST, nb_manswer_cb,  NULL, (void*)1);
  888.    xchat_hook_command(ph, "NB_mSayPtr", XCHAT_PRI_LOWEST, nb_manswer_cb,  NULL, (void*)2);
  889.    xchat_hook_command(ph, "NB_mSayInf", XCHAT_PRI_LOWEST, nb_manswer_cb,  NULL, (void*)3);
  890.    xchat_hook_command(ph, "NB_mLoaded", XCHAT_PRI_LOWEST, nb_manswer_cb,  NULL, (void*)4);
  891.    xchat_hook_command(ph, "NB_mUnload", XCHAT_PRI_LOWEST, nb_manswer_cb,  NULL, (void*)5);
  892.  
  893.    xchat_commandf(ph, "NB_mLoaded %s", PLUGIN_IPC_NAME);
  894.    
  895.    FILE *Script;
  896.    char Buffer[512];
  897.    sprintf(Buffer, "%s/NovaBot/autoexec.txt", xchat_get_info(ph, "xchatdirfs"));
  898.  
  899.    int i,j,k;
  900.    Script = fopen(Buffer,"r");
  901.    if(Script != NULL) {
  902.      xchat_print(ph, "Auto-exec script was found");
  903.      for(k=0;!k;i=0) {
  904.        i=0;
  905.        while(1) {
  906.          j = fgetc(Script);
  907.          Buffer[i++]=j;
  908.          if(j == '\n' || j==EOF) {
  909.            Buffer[i-1] = 0;
  910.            if(j==EOF) k=1;
  911.              break;
  912.          }
  913.        }
  914.        xchat_commandf(ph, "%s", Buffer);
  915.      }
  916.      fclose(Script);
  917.    }
  918.  
  919.    xchat_printf(ph, "Hello from NovaBot %s\n", PVERSION);
  920.    return 1;       /* return 1 for success */
  921. }
Add Comment
Please, Sign In to add comment