Advertisement
Kar

BlueG IRC Bot (Updated) v0.2

Kar
Feb 27th, 2015
304
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 13.33 KB | None | 0 0
  1. #include <a_samp>
  2. #include <socket>
  3.  
  4. #define MAX_NICK_LEN 30
  5. #define MAX_CHANNEL_LEN 32
  6. #define MAX_CHANNEL_KEY_LEN 12
  7. #define MAX_BOTS 5
  8. #define COMMAND_PREFIX '!'
  9.  
  10. forward IRC_onBotConnect(botid);
  11. forward IRC_onBotDisonnect(botid);
  12. forward IRC_onCTCPRequest(botid, user[], request_msg[], user_ident[]);
  13. forward IRC_onChannelMessage(botid, user[], channel[], message[], user_ident[]);
  14. forward IRC_onCommand(botid, user[], channel[], command[], user_ident[]);
  15. forward IRC_onPrivateMessage(botid, user[], message[], user_ident[]);
  16. forward IRC_onChannelJoin(botid, user[], channel[], user_ident[]);
  17. forward IRC_onChannelPart(botid, user[], channel[], part_msg[], user_ident[]);
  18. forward IRC_onBotNotice(botid, source[], message[], user_ident);
  19. forward IRC_onUserQuit(botid, user[], leaving_msg[], user_ident[]);
  20. forward IRC_onNicknameChange(botid, user[], new_name[], user_ident[]);
  21. forward IRC_onChannelKick(botid, user[], victim[], channel[], reason[], user_ident[]);
  22. forward IRC_onBotInvite(botid, user[], channel[], user_ident[]);
  23. forward IRC_onRawCommand(botid, raw_code, raw_data[]);
  24. forward IRC_onChannelMode(botid, user[], channel[], mode[], option[], user_ident[]);
  25. forward IRC_onTopicChange(botid, user[], channel[], topic[], user_ident[]);
  26.  
  27.  
  28. enum botInfo {
  29.     Socket:ircsocket,
  30.     ircServer[80],
  31.     ircPort,
  32.     ircNickname[MAX_NICK_LEN],
  33.     ircUsername[MAX_NICK_LEN],
  34.     ircRealName[MAX_NICK_LEN*2],
  35.     bool:ircConnected
  36.    
  37. };
  38.  
  39. new g_aIRCBot[MAX_BOTS][botInfo],
  40.     g_iBots = -1;
  41.  
  42. stock ircbot_isconnected(botid)
  43. {
  44.     return g_aIRCBot[botid][ircConnected];
  45. }
  46.  
  47. stock ircbot_connect(server[], port, nickname[], username[], realname[])
  48. {
  49.     new sData[256];
  50.     g_aIRCBot[++g_iBots][ircsocket] = socket_create(TCP);
  51.     if(is_socket_valid(g_aIRCBot[g_iBots][ircsocket])) {
  52.         g_aIRCBot[g_iBots][ircConnected] = false;
  53.         format(g_aIRCBot[g_iBots][ircServer], 80, server);
  54.         g_aIRCBot[g_iBots][ircPort] = port;
  55.         format(g_aIRCBot[g_iBots][ircNickname], MAX_NICK_LEN, nickname);
  56.         format(g_aIRCBot[g_iBots][ircUsername], MAX_NICK_LEN, username);
  57.         format(g_aIRCBot[g_iBots][ircRealName], MAX_NICK_LEN*2, realname);
  58.         socket_cIRC_onNect(g_aIRCBot[g_iBots][ircsocket], g_aIRCBot[g_iBots][ircServer], g_aIRCBot[g_iBots][ircPort]);
  59.         format(sData, sizeof sData, "NICK %s\r\nUSER %s - - :%s\r\nMODE %s +B\r\n", g_aIRCBot[g_iBots][ircNickname], g_aIRCBot[g_iBots][ircUsername], g_aIRCBot[g_iBots][ircRealName], g_aIRCBot[g_iBots][ircNickname]);
  60.         socket_send(g_aIRCBot[g_iBots][ircsocket], sData, sizeof sData);
  61.         return g_iBots;
  62.     }
  63.     g_iBots--;
  64.     return (-1);
  65. }
  66.  
  67. stock ircbot_reconnect(botid)
  68. {
  69.     new sData[80];
  70.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && !g_aIRCBot[botid][ircConnected]) {
  71.         g_aIRCBot[botid][ircsocket] = socket_create(TCP);
  72.         socket_cIRC_onNect(g_aIRCBot[botid][ircsocket], g_aIRCBot[botid][server], g_aIRCBot[botid][port]);
  73.         format(sData, sizeof sData, "NICK %s\r\nUSER %s - - :%s\r\nMODE %s +B\r\n", g_aIRCBot[botid][ircNickname], g_aIRCBot[botid][ircUsername], g_aIRCBot[botid][ircRealName], g_aIRCBot[botid][ircNickname]);
  74.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  75.         return 1;
  76.     }
  77.     return 0;
  78. }
  79.  
  80. stock ircbot_say(botid, receiver[], message[])
  81. {
  82.     new sMessage[256];
  83.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  84.         format(sMessage, sizeof sMessage, "PRIVMSG %s :%s\r\n", receiver, message);
  85.         socket_send(g_aIRCBot[botid][ircsocket], sMessage, sizeof(sMessage));
  86.         return 1;
  87.     }
  88.     return 0;
  89. }
  90.  
  91. // /me command
  92. stock ircbot_action(botid, receiver[], message[])
  93. {
  94.     new sMessage[256];
  95.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  96.         format(sMessage, sizeof sMessage, "PRIVMSG %s :\001ACTION %s\001\r\n", receiver, message);
  97.         socket_send(g_aIRCBot[botid][ircsocket], sMessage, sizeof(sMessage));
  98.         return 1;
  99.     }
  100.     return 0;
  101. }
  102.  
  103. stock ircbot_kick(botid, channel[], user[], reason[])
  104. {
  105.     new sMessage[256];
  106.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  107.         format(sMessage, sizeof sMessage, "KICK %s %s %s", channel, user, reason);
  108.         socket_send(g_aIRCBot[botid][ircsocket], sMessage, sizeof(sMessage));
  109.         return 1;
  110.     }
  111.     return 0;
  112. }
  113.  
  114. stock ircbot_notice(botid, receiver[], message[])
  115. {
  116.     new sMessage[256];
  117.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  118.         format(sMessage, sizeof sMessage, "NOTICE %s %s", receiver, message);
  119.         socket_send(g_aIRCBot[botid][ircsocket], sMessage, sizeof(sMessage));
  120.         return 1;
  121.     }
  122.     return 0;
  123. }
  124.  
  125. stock ircbot_join(botid, channel[], key[])
  126. {
  127.     new sData[MAX_CHANNEL_LEN + MAX_CHANNEL_KEY_LEN + 9];
  128.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  129.         switch(strlen(key))
  130.         {
  131.             case 0: format(sData, sizeof sData, "JOIN %s\r\n", channel);
  132.             default: format(sData, sizeof sData, "JOIN %s %s\r\n", channel, key);
  133.         }
  134.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  135.         return 1;
  136.     }
  137.     return 0;
  138. }
  139.  
  140. stock ircbot_part(botid, channel[], message[])
  141. {
  142.     new sData[256];
  143.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  144.         format(sData, sizeof sData, "PART %s :%s\r\n", channel, msg);
  145.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  146.         return 1;
  147.     }
  148.     return 0;
  149. }
  150.  
  151. stock ircbot_quit(botid, message[])
  152. {
  153.     new sData[256];
  154.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  155.         format(sData, sizeof sData, "QUIT :%s\r\n", message);
  156.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  157.         return 1;
  158.     }
  159.     return 0;
  160. }
  161.  
  162. stock ircbot_raw(botid, raw_cmd[])
  163. {
  164.     new sData[256];
  165.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  166.         format(sData, sizeof sData, "%s\r\n", raw_cmd);
  167.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  168.         return 1;
  169.     }
  170.     return 0;
  171. }
  172.  
  173. stock ircbot_setmode(botid, channel[], mode[])
  174. {
  175.     new sData[64];
  176.     if(is_socket_valid(g_aIRCBot[botid][ircsocket]) && g_aIRCBot[botid][ircConnected]) {
  177.         format(sData, sizeof sData, "MODE %s %s\r\n", channel, mode);
  178.         socket_send(g_aIRCBot[botid][ircsocket], sData, sizeof sData);
  179.         return 1;
  180.     }
  181.     return 0;
  182. }
  183.  
  184. public onSocketAnswer(Socket:id, data[], data_len)
  185. {
  186.     for(new i = 0; i < MAX_BOTS; ++i) {
  187.         if(g_aIRCBot[i][ircsocket] == id) {
  188.             // :server 376 nickname :End of /MOTD command.
  189.             if(!g_aIRCBot[g_iBots][ircConnected]) {
  190.                 if(strfind(data, ":End of /MOTD command.") != -1) {
  191.                     g_aIRCBot[g_iBots][ircConnected] = true;
  192.                     // IRC_onBotConnect(botid);
  193.                     CallRemoteFunction("IRC_onBotConnect", "i", i);
  194.                     return 0;
  195.                 }
  196.             }
  197.             if(!g_aIRCBot[g_iBots][ircConnected] || !Ping(id, data)) return 0;
  198.             new strParts[5][128];
  199.             split(data, strParts, 5, ' ');
  200.             if(!isNumeric(strParts[1])) {
  201.                 new sUser[MAX_NICK_LEN], sIdent[60];
  202.                 substr(sIdent, strParts[0], 1);
  203.                 FilterNickname(strParts[0], sUser);
  204.                 // lets parse all incoming events
  205.                 if(!strcmp(strParts[1], "PRIVMSG")) {
  206.                     new sMessage[256];
  207.                     trim(array_slice(data, 3), sMessage);
  208.                     if(sMessage[0] == COMMAND_PREFIX && sMessage[1] != ' ')
  209.                         CallRemoteFunction("IRC_onCommand", "issss", i, sUser, strParts[2], sMessage, sIdent);
  210.                     if(sMessage[0] == '\001') {
  211.                         strmid(sMessage, sMessage, 1, strlen(sMessage)-1);
  212.                         // IRC_onCTCPRequest(botid, user[], request_msg[], user_ident[]);
  213.                         CallRemoteFunction("IRC_onCTCPRequest", "isss", i, sUser, sMessage, sIdent);
  214.                     } else if(strParts[2][0] == '#') {
  215.                         // IRC_onChannelMessage(botid, user[], channel[], message[], user_ident[]);
  216.                         CallRemoteFunction("IRC_onChannelMessage", "issss", i, sUser, strParts[2], sMessage, sIdent);
  217.                     } else {
  218.                         // IRC_onPrivateMessage(botid, user[], message[], user_ident[]);
  219.                         CallRemoteFunction("IRC_onPrivateMessage", "isss", i, sUser, sMessage, sIdent);
  220.                     }
  221.                 } else if(!strcmp(strParts[1], "JOIN")) {
  222.                     new sChannel[MAX_CHANNEL_LEN];
  223.                     strmid(sChannel, strParts[2], 1, strlen(strParts[2])-1);
  224.                     trim(sChannel, sChannel);
  225.                     // IRC_onChannelJoin(botid, user[], channel[], user_ident[]);
  226.                     CallRemoteFunction("IRC_onChannelJoin", "isss", i, sUser, sChannel, sIdent);
  227.                 } else if(!strcmp(strParts[1], "PART")) {
  228.                     new sMessage[128];
  229.                     if(strlen(strParts[3]) > 0)
  230.                         trim(array_slice(data, 3), sMessage);
  231.                     else
  232.                         format(sMessage, sizeof sMessage, "None");
  233.                     // IRC_onChannelPart(botid, user[], channel[], part_msg[], user_ident[]);
  234.                     CallRemoteFunction("IRC_onChannelPart", "issss", i, sUser, strParts[2], sMessage, sIdent);
  235.                 } else if(!strcmp(strParts[1], "NOTICE")) {
  236.                     new sMessage[128];
  237.                     trim(array_slice(data, 3), sMessage);
  238.                     // IRC_onBotNotice(botid, source[], message[], user_ident);
  239.                     CallRemoteFunction("IRC_onBotNotice", "issss", i, strParts[2], sMessage, sIdent);
  240.                 } else if(!strcmp(strParts[1], "QUIT")) {
  241.                     new sMessage[128];
  242.                     trim(array_slice(data, 2), sMessage);
  243.                     // IRC_onUserQuit(botid, user[], leaving_msg[], user_ident[]);
  244.                     CallRemoteFunction("IRC_onUserQuit", "isss", i, sUser, sMessage, sIdent);
  245.                 } else if(!strcmp(strParts[1], "NICK")) {
  246.                     new sNew[128];
  247.                     substr(sNew, strParts[2], 1);
  248.                     // IRC_onNicknameChange(botid, user[], new_name[], user_ident[]);
  249.                     CallRemoteFunction("IRC_onNicknameChange", "isss", i, sUser, sNew, sIdent);
  250.                 } else if(!strcmp(strParts[1], "KICK")) {
  251.                     new sMessage[128];
  252.                     trim(array_slice(data, 4), sMessage);
  253.                     // IRC_onChannelKick(botid, user[], victim[], channel[], reason[], user_ident[]);
  254.                     CallRemoteFunction("IRC_onChannelKick", "isssss", i, sUser, strParts[3], strParts[2], sMessage, sIdent);
  255.                 } else if(!strcmp(strParts[1], "INVITE")) {
  256.                     new sChannel[MAX_CHANNEL_LEN];
  257.                     substr(sChannel, strParts[3], 1);
  258.                     // IRC_onBotInvite(botid, user[], channel[], user_ident[]);
  259.                     CallRemoteFunction("IRC_onBotInvite", "iss", i, sUser, sChannel, sIdent);
  260.                 } else if(!strcmp(strParts[1], "MODE")) {
  261.                     new sOption[256];
  262.                     if(strlen(strParts[4]) > 0)
  263.                         trim(array_slice(data, 4, 1), sOption);
  264.                     // IRC_onChannelMode(botid, user[], channel[], mode[], option[], user_ident[]);
  265.                     CallRemoteFunction("IRC_onChannelMode", "isssss", i, sUser, strParts[2], strParts[3], sOption, sIdent);
  266.                 } else if(!strcmp(strParts[1], "TOPIC")) {
  267.                     new sTopic[256];
  268.                     trim(array_slice(data, 3), sTopic);
  269.                     // IRC_onTopicChange(botid, user[], channel[], topic[], user_ident[]);
  270.                     CallRemoteFunction("IRC_onTopicChange", "issss", i, sUser, strParts[2], sTopic, sIdent);
  271.                 }
  272.             } else {
  273.                 CallRemoteFunction("IRC_onRawCommand", "iis", i, strval(strParts[1]), array_slice(data, 2, 1));
  274.             }
  275.         }
  276.         break;
  277.     }
  278.     return 1;
  279. }
  280.  
  281. public onSocketClose(Socket:id)
  282. {
  283.     for(new i = 0; i < MAX_BOTS; ++i) {
  284.         if(g_aIRCBot[i][ircsocket] == id) {
  285.             if(g_aIRCBot[i][ircConnected]) {
  286.                 CallRemoteFunction("IRC_onBotDisonnect", "i", i);
  287.                 g_aIRCBot[i][ircConnected] = false;
  288.             }
  289.         }
  290.     }
  291.     return 1;
  292. }
  293.  
  294. stock substr(dest[], source[], pos, max_len = sizeof(dest))
  295. {
  296.     return strmid(dest, source, pos, strlen(source), max_len);
  297. }
  298.  
  299. stock trim(string_data[], dest[])
  300. {
  301.     for(new i, a = strlen(string_data);i < a;i++)
  302.     {
  303.         if(string_data[i] != '\r' && string_data[i] != '\n'/* string_data[i] != '\001'*/)
  304.             dest[i] = string_data[i];
  305.     }
  306. }
  307.  
  308. stock FilterNickname(const ident[], dest[])
  309. {
  310.     // :nick!user@hostname
  311.     new pos = strfind(ident, "!");
  312.     return strmid(dest, ident, 1, pos, MAX_NICK_LEN);
  313. }
  314.  
  315. // php like behaviour
  316. stock array_slice(array[], offset, start_pos = 2)
  317. {
  318.     new pCount = 0, final[1024];
  319.     for(new i, a = strlen(array);i < a;i++)
  320.     {
  321.         if(array[i] == ' ') {
  322.             pCount++;
  323.             if(pCount == offset) {
  324.                 // skip :msg
  325.                 strmid(final, array, i+start_pos, a);
  326.                 break;
  327.             }
  328.         }
  329.     }
  330.     return final;
  331. }
  332.  
  333. stock Ping(Socket:id, raw_data[])
  334. {
  335.     // handle ping pong
  336.     new idx, string[256];
  337.     string = strtok(raw_data, idx);
  338.     if(!strcmp(string, "PING")) {
  339.         new pong[64];
  340.         string = strtok(raw_data, idx);
  341.         format(pong, sizeof pong, "PONG :%s\r\n", string);
  342.         socket_send(id, pong, sizeof(pong));
  343.         return 0;
  344.     }
  345.     return 1;
  346. }
  347.  
  348. stock isNumeric(const string[])
  349. {
  350.     new len = strlen(string);
  351.     if(!len) return 0;
  352.     for (new i = 0; i < len; i++) {
  353.         if(string[i] < '0' || string[i] > '9') return 0;
  354.     }
  355.     return 1;
  356. }
  357.  
  358. strtok(const string[], &index)
  359. {
  360.     new length = strlen(string);
  361.     while ((index < length) && (string[index] <= ' '))
  362.     {
  363.         index++;
  364.     }
  365.  
  366.     new offset = index;
  367.     new result[256];
  368.     while ((index < length) && (string[index] > ' ') && ((index - offset) < (sizeof(result) - 1)))
  369.     {
  370.         result[index - offset] = string[index];
  371.         index++;
  372.     }
  373.     result[index - offset] = EOS;
  374.     return result;
  375. }
  376.  
  377. // (c) to whoever made this function
  378. stock split(const strsrc[], strdest[][], limit, delimiter = '|')
  379. {
  380.     new i, li, aNum, len, srclen = strlen(strsrc);
  381.     while(i <= srclen && aNum < limit)
  382.     {
  383.         if (strsrc[i] == delimiter || i == srclen)
  384.         {
  385.             len = strmid(strdest[aNum], strsrc, li, i, 128);
  386.             strdest[aNum][len] = 0;
  387.             li = i + 1;
  388.             aNum++;
  389.         }
  390.         i++;
  391.     }
  392.     return 1;
  393. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement