Guest User

Untitled

a guest
May 27th, 2018
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 32.51 KB | None | 0 0
  1. Index: conf/irc_athena.conf
  2.  
  3. ===================================================================
  4.  
  5. --- conf/irc_athena.conf    (revision 0)
  6.  
  7. +++ conf/irc_athena.conf    (working copy)
  8.  
  9. @@ -0,0 +1,34 @@
  10.  
  11. +//--------------------------------------------------------
  12.  
  13. +// RAthena IRC Bot Configuration File
  14.  
  15. +//--------------------------------------------------------
  16.  
  17. +
  18.  
  19. +//Turn the IRC Bot 'on' or 'off'
  20.  
  21. +irc_enable: 1
  22.  
  23. +
  24.  
  25. +//IRC Server Address
  26.  
  27. +irc_server: irc.rizon.net
  28.  
  29. +
  30.  
  31. +//IRC Server Port
  32.  
  33. +irc_port: 6667
  34.  
  35. +
  36.  
  37. +//Autojoin channel when kicked (on=1,off=0)
  38.  
  39. +irc_autojoin: 0
  40.  
  41. +
  42.  
  43. +//IRC Channel with # infront
  44.  
  45. +irc_channel: #iHeartRO
  46.  
  47. +
  48.  
  49. +//IRC Channel password (set if required)
  50.  
  51. +//irc_channel_pass:
  52.  
  53. +
  54.  
  55. +//IRC Nickname
  56.  
  57. +irc_nick: ihroBot
  58.  
  59. +
  60.  
  61. +//IRC Password ("0" for no pass)
  62.  
  63. +irc_pass: kooyeene
  64.  
  65. +
  66.  
  67. +irc_announce_flag: 1           // Display Announcements in IRC?
  68.  
  69. +irc_announce_jobchange_flag: 1 // Display Job Changes in IRC?
  70.  
  71. +irc_announce_main_auto: 1      // Display everything said in IRC automatically in @main?
  72.  
  73. +irc_announce_main_flag: 1      // Display @main in IRC?
  74.  
  75. +irc_announce_mvp_flag: 0       // Display MVP kills in IRC?
  76.  
  77. +irc_announce_shop_flag: 1      // Display shop status in IRC?
  78.  
  79. Index: src/map/atcommand.c
  80.  
  81. ===================================================================
  82.  
  83. --- src/map/atcommand.c (revision 15490)
  84.  
  85. +++ src/map/atcommand.c (working copy)
  86.  
  87. @@ -20,6 +20,7 @@
  88.  
  89.  #include "chrif.h"
  90.  #include "duel.h"
  91.  #include "intif.h"
  92. +#include "irc.h"
  93.  #include "itemdb.h"
  94.  #include "log.h"
  95.  #include "map.h"
  96. @@ -8366,7 +8367,9 @@
  97.  
  98.             // main chat message. 0xFE000000 is invalid color, same using
  99.             // 0xFF000000 for simple (not colored) GM messages. [LuzZza]
  100.             intif_broadcast2(atcmd_output, strlen(atcmd_output) + 1, 0xFE000000, 0, 0, 0, 0);
  101. -
  102. +            if(irc.enabled && irc.main_flag)
  103. +               irc_announce(atcmd_output);
  104. +          
  105.             // Chat logging type 'M' / Main Chat
  106.             log_chat(LOG_CHAT_MAINCHAT, 0, sd->status.char_id, sd->status.account_id, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y, NULL, message);
  107.         }
  108. Index: src/map/clif.c
  109.  
  110. ===================================================================
  111.  
  112. --- src/map/clif.c  (revision 15490)
  113.  
  114. +++ src/map/clif.c  (working copy)
  115.  
  116. @@ -38,6 +38,7 @@
  117.  
  118.  #include "instance.h"
  119.  #include "mercenary.h"
  120.  #include "log.h"
  121. +#include "irc.h"
  122.  #include "clif.h"
  123.  #include "mail.h"
  124.  #include "quest.h"
  125. @@ -5273,6 +5274,9 @@
  126.  
  127.    
  128.     if (buf)
  129.         aFree(buf);
  130. +
  131. +   if(irc.enabled && irc.announce_flag && target == ALL_CLIENT)
  132. +       irc_announce(mes);
  133.  }
  134.  
  135.  
  136. Index: src/map/irc.c
  137.  
  138. ===================================================================
  139.  
  140. --- src/map/irc.c   (revision 0)
  141.  
  142. +++ src/map/irc.c   (working copy)
  143.  
  144. @@ -0,0 +1,611 @@
  145.  
  146. +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  147. +// For more information, see LICENCE in the main folder
  148. +
  149. +#include "../common/core.h"
  150. +#include "../common/socket.h"
  151. +#include "../common/malloc.h"
  152. +#include "../common/db.h"
  153. +#include "../common/timer.h"
  154. +#include "../common/strlib.h"
  155. +#include "../common/mmo.h"
  156. +#include "../common/showmsg.h"
  157. +#include "../common/version.h"
  158. +#include "../common/nullpo.h"
  159. +
  160. +#include "map.h"
  161. +#include "mob.h"
  162. +#include "pc.h"
  163. +#include "intif.h" //For GM Broadcast
  164. +#include "irc.h"
  165. +
  166. +#include <stdio.h>
  167. +#include <string.h>
  168. +#include <stdlib.h>
  169. +
  170. +char irc_channel[32] = "";
  171. +char irc_channel_pass[32] = "";
  172. +char irc_ip_str[128] = "";
  173. +char irc_nick[30] = "";
  174. +char irc_password[32] = "";
  175. +
  176. +unsigned long  irc_ip = 0;
  177. +unsigned short irc_port = 6667;
  178. +
  179. +// configuration
  180. +struct e_irc_config irc;
  181. +
  182. +// variables
  183. +int irc_fd = 0;
  184. +int last_cd_user = 0;
  185. +struct e_irc_session* irc_session_info = NULL;
  186. +struct e_channel_data cd;
  187. +
  188. +//======================================================
  189. +// Read Config File (irc_athena.conf)
  190. +//======================================================
  191. +int irc_read_conf(char *file)
  192. +{
  193. +   FILE* fp;
  194. +   char w1[256], w2[256];
  195. +   char path[256];
  196. +   char row[1024];
  197. +
  198. +   memset( w1, '\0', sizeof(w1) );
  199. +   memset( w2, '\0', sizeof(w2) );
  200. +   memset( path, '\0', sizeof(path) );
  201. +   memset( row, '\0', sizeof(row) );
  202. +
  203. +   snprintf( path, sizeof(path), "conf/%s", file );
  204. +
  205. +   if( !(fp = fopen(path,"r")) )
  206. +   {// failed to open the configuration file
  207. +       ShowError( "Cannot find file: %s\n", path );
  208. +       return 0;
  209. +   }
  210. +
  211. +   while( fgets(row, sizeof(row), fp) )
  212. +   {
  213. +       if( row[0] == '/' && row[1] == '/' )
  214. +           continue;
  215. +
  216. +       sscanf( row, "%[^:]: %255[^\r\n]", w1, w2 );
  217. +
  218. +       if(strcmpi(w1,"irc.enabled")==0)
  219. +           irc.enabled = (unsigned char)config_switch(w2);
  220. +       else if(strcmpi(w1,"irc_server")==0)
  221. +           safestrncpy(irc_ip_str,w2,sizeof(irc_ip_str));
  222. +       else if(strcmpi(w1,"irc_port")==0)
  223. +           irc_port = atoi(w2);
  224. +       else if(strcmpi(w1,"irc.autojoin")==0)
  225. +           irc.autojoin = (unsigned char)atoi(w2);
  226. +       else if(strcmpi(w1,"irc_channel")==0)
  227. +           safestrncpy(irc_channel,w2,sizeof(irc_channel));
  228. +       else if(strcmpi(w1,"irc_channel_pass")==0)
  229. +           safestrncpy(irc_channel_pass,w2,sizeof(irc_channel_pass));
  230. +       else if(strcmpi(w1,"irc_nick")==0)
  231. +           safestrncpy(irc_nick,w2,sizeof(irc_nick));
  232. +       else if(strcmpi(w1,"irc_pass")==0) {
  233. +           if(strcmpi(w2,"0")!=0)
  234. +               safestrncpy(irc_password,w2,sizeof(irc_password));
  235. +       }
  236. +       else if(strcmpi(w1,"irc.announce_flag")==0)
  237. +           irc.announce_flag = (unsigned char)config_switch(w2);
  238. +       else if(strcmpi(w1,"irc.job_change_flag")==0)
  239. +           irc.job_change_flag = (unsigned char)config_switch(w2);
  240. +       else if(strcmpi(w1,"irc.main_auto")==0)
  241. +           irc.main_auto = (unsigned char)config_switch(w2);
  242. +       else if(strcmpi(w1,"irc.main_flag")==0)
  243. +           irc.main_flag = (unsigned char)config_switch(w2);
  244. +       else if(strcmpi(w1,"irc.mvp_flag")==0)
  245. +           irc.mvp_flag = (unsigned char)config_switch(w2);
  246. +       else if(strcmpi(w1,"irc.shop_flag")==0)
  247. +           irc.shop_flag = (unsigned char)config_switch(w2);
  248. +   }
  249. +
  250. +   ShowInfo("IRC configuration has been read successfully.\n");
  251. +   fclose(fp);
  252. +   return 1;
  253. +}
  254. +
  255. +
  256. +int irc_connect_timer(int tid, unsigned int tick, int id, intptr data)
  257. +{
  258. +   if(irc_session_info && session[irc_session_info->fd])
  259. +       return 0;
  260. +   //Ok, this ShowInfo and printf are a little ugly, but they are meant to
  261. +   //debug just how long the code freezes here. [Skotlex]
  262. +   ShowInfo("(IRC) Connecting to %s... \n", irc_ip_str);
  263. +   irc_fd = make_connection(irc_ip,irc_port);
  264. +   if(irc_fd > 0){
  265. +       ShowMessage("ok\n");
  266. +       session[irc_fd]->func_parse = irc_parse;
  267. +   } else
  268. +       ShowMessage("failed\n");
  269. +   return 0;
  270. +}
  271. +
  272. +//======================================================
  273. +// Displays announcements in IRC
  274. +//======================================================
  275. +void irc_announce(const char* buf)
  276. +{
  277. +   char send_string[MAX_SEND_LENGTH];
  278. +
  279. +   // print the message into the buffer and send to the IRC server
  280. +   snprintf( send_string, sizeof(send_string), "PRIVMSG %s :<SERVER BROADCAST> %s", irc_channel, buf );
  281. +   irc_send( send_string );
  282. +}
  283. +
  284. +
  285. +//======================================================
  286. +// Displays Job Changes in IRC
  287. +// Note: only shows job changes from npc jobchange
  288. +//      function.
  289. +//======================================================
  290. +void irc_announce_jobchange(struct map_session_data *sd)
  291. +{
  292. +   char send_string[256];
  293. +  
  294. +   // ensure the parses session_data is valid
  295. +   nullpo_retv( sd );
  296. +
  297. +   // print the job change message into the output buffer and send to the IRC server
  298. +   snprintf( send_string, sizeof(send_string), "PRIVMSG %s :%s has changed into a %s.", irc_channel, sd->status.name, job_name(sd->status.class_) );
  299. +   irc_send( send_string );
  300. +}
  301. +
  302. +//======================================================
  303. +// Displays shop open/closing in IRC.
  304. +//======================================================
  305. +void irc_announce_shop(struct map_session_data *sd, int flag)
  306. +{
  307. +   char send_string[MAX_SEND_LENGTH];
  308. +   char mapname[MAP_NAME_LENGTH_EXT], *mapext;
  309. +   int maplen = 0;
  310. +   nullpo_retv(sd);
  311. +
  312. +   if( flag )
  313. +   {// player opened a shop
  314. +       safestrncpy(mapname, map[sd->bl.m].name, sizeof(mapname));
  315. +      
  316. +       if( mapext = strchr(mapname, '.') )
  317. +       {// remove the extension from the map name
  318. +           *mapext = '\0';
  319. +       }
  320. +
  321. +       // capitalize the name of the map
  322. +       mapname[0] = TOUPPER( mapname[0] );
  323. +
  324. +       // print the open shop message into the output buffer
  325. +       snprintf( send_string, sizeof(send_string), "PRIVMSG %s :%s has opened a shop, [%s], in %s (%d, %d).", irc_channel, sd->status.name, sd->message, mapname, sd->bl.x, sd->bl.y );
  326. +   }
  327. +   else
  328. +   {// print a shop closed message into the output buffer
  329. +       snprintf( send_string, sizeof(send_string), "PRIVMSG %s :%s has closed %s shop.", irc_channel, sd->status.name, sd->status.sex ? "his" : "her" );
  330. +   }
  331. +
  332. +   // send the message to the IRC server
  333. +   irc_send(send_string);
  334. +}
  335. +
  336. +//======================================================
  337. +// Displays MVP kills in IRC
  338. +//======================================================
  339. +void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md)
  340. +{
  341. +   char send_string[MAX_SEND_LENGTH];
  342. +   char mapname[MAP_NAME_LENGTH_EXT], *mapext;
  343. +   int maplen = 0;
  344. +
  345. +   // ensure both session_data and mob_data both exist before attempting to access them
  346. +   nullpo_retv(sd);
  347. +   nullpo_retv(md);
  348. +
  349. +   // copy the name of the map for map name extension removal
  350. +   safestrncpy( mapname, map[md->bl.m].name, sizeof(map[md->bl.m].name) );
  351. +
  352. +   if( mapext = strchr(mapname, '.') )
  353. +   {// remove the extension from the map name
  354. +       *mapext = '\0';
  355. +   }
  356. +
  357. +   // capitalize the name of the map
  358. +   mapname[0] = TOUPPER( mapname[0] );
  359. +
  360. +   // print the mvp kill message into the output buffer and send to the IRC server
  361. +   snprintf( send_string, sizeof(send_string), "PRIVMSG %s :%s the %s has MVP'd %s in %s.", irc_channel, sd->status.name, job_name(sd->status.class_), md->name, mapname );
  362. +   irc_send( send_string );
  363. +}
  364. +
  365. +//======================================================
  366. +// Parses content in IRC channel
  367. +//======================================================
  368. +int irc_parse(int fd)
  369. +{
  370. +   if( session[fd]->flag.eof )
  371. +   {// closing IRC session so release any of the allocated memory
  372. +       do_close( fd );
  373. +       irc_session_info = NULL;
  374. +       add_timer(gettick() + 15000, irc_connect_timer, 0, 0);
  375. +       return 0;
  376. +   }
  377. +
  378. +   if( session[fd]->session_data == NULL )
  379. +   {// ensure that the session information is constructed
  380. +       irc_session_info = (struct e_irc_session*)aMalloc(sizeof(struct e_irc_session));
  381. +       irc_session_info->fd = fd;
  382. +       irc_session_info->state = 0;
  383. +       session[fd]->session_data = irc_session_info;
  384. +   }
  385. +  
  386. +   if( !irc_session_info )
  387. +   {// copy the same session information from the socket
  388. +       irc_session_info = (struct e_irc_session*)session[fd]->session_data;
  389. +       irc_session_info->fd = fd;
  390. +   }
  391. +
  392. +   if( RFIFOREST(fd) > 0 )
  393. +   {// remaining packets exist so process the packet and continue
  394. +       send_to_parser( fd, (char*)RFIFOP(fd,0), "\n" );
  395. +       RFIFOSKIP( fd, RFIFOREST(fd) );
  396. +   }
  397. +
  398. +   return 0;
  399. +}
  400. +//======================================================
  401. +// Sends keepalive when necessary
  402. +//======================================================
  403. +int irc_keepalive_timer(int tid, unsigned int tick, int id, intptr data)
  404. +{
  405. +   char send_string[MAX_SEND_LENGTH];
  406. +
  407. +   // send a singular packet with no data to ensure that the connection lives
  408. +   snprintf(send_string,sizeof(send_string),"PRIVMSG %s : ", irc_nick);
  409. +   irc_send(send_string);
  410. +
  411. +   // ensure that this function is called again to ensure survival
  412. +   add_timer(gettick() + 30000, irc_keepalive_timer, 0, 0);
  413. +
  414. +   return 0;
  415. +}
  416. +
  417. +//======================================================
  418. +// Function to send message to IRC channel
  419. +//======================================================
  420. +void irc_send(char *buf)
  421. +{
  422. +   int len;
  423. +   int fd;
  424. +  
  425. +   if( !irc_session_info || !(fd = irc_session_info->fd) || !session[fd] )
  426. +   {// no connection available or socket non-existant
  427. +       return;
  428. +   }
  429. +
  430. +   len = strlen(buf) + 1;
  431. +   WFIFOHEAD(fd, len);
  432. +   sprintf((char*)WFIFOP(fd,0), "%s\n", buf);
  433. +   WFIFOSET(fd, len);
  434. +}
  435. +
  436. +//======================================================
  437. +// Parses content in IRC channel
  438. +//======================================================
  439. +void irc_parse_sub(int fd, char *incoming_string)
  440. +{
  441. +   char source[256];
  442. +   char command[256];
  443. +   char target[256];
  444. +   char message[1024];
  445. +   char send_string[1024];
  446. +   char ping_message[256];
  447. +   char ssource[256];
  448. +   char *source_nick=NULL;
  449. +   char *source_ident=NULL;
  450. +   char *source_host=NULL;
  451. +   char *state_mgr=NULL;
  452. +
  453. +   memset( source, 0, sizeof(source) );
  454. +   memset( command, 0, sizeof(command) );
  455. +   memset( target, 0, sizeof(target) );
  456. +   memset( message, 0, sizeof(message) );
  457. +   memset( send_string, 0, sizeof(send_string) );
  458. +  
  459. +   sscanf( incoming_string, ":%255s %255s %255s :%1023[^\r\n]", source, command, target, message );
  460. +   sscanf( incoming_string, "%255s %255s[^\r\n]", ssource, ping_message );
  461. +
  462. +   if( source != NULL )
  463. +   {// received source name from the packet so store the credentials
  464. +       if( strchr(source, '!') ) {
  465. +           source_nick =  strtok_r( source, "!", &state_mgr );
  466. +           source_ident = strtok_r( NULL,   "@", &state_mgr );
  467. +           source_host =  strtok_r( NULL,   "%%",&state_mgr );
  468. +       }
  469. +   }
  470. +
  471. +   switch( irc_session_info->state )
  472. +   {
  473. +       case 0:
  474. +       {// not yet identified so send identification credentials
  475. +           snprintf(send_string, sizeof(send_string), "USER eABot 8 * :eABot");
  476. +           irc_send(send_string);
  477. +           snprintf(send_string, sizeof(send_string), "NICK %s", irc_nick);
  478. +           irc_send(send_string);
  479. +           irc_session_info->state = 1;
  480. +       }
  481. +       break;
  482. +
  483. +       case 1:
  484. +       {// identified but awaiting confirmation from the IRC server
  485. +           if( !strcmp(ssource, "PING") )
  486. +           {// reply to a PING message with a PONG message
  487. +               snprintf( send_string, sizeof(send_string), "PONG %s", ping_message );
  488. +               irc_send( send_string );
  489. +           }
  490. +           else if( !strcmp(command,"001") )
  491. +           {// received confirmation from the IRC server that the connection was successful.
  492. +               ShowStatus("IRC: Connected to IRC.\n");
  493. +
  494. +               if( irc_password[0] != '\0' )
  495. +               {// send password identification associated with this nickname
  496. +                   snprintf( send_string, sizeof(send_string), "PRIVMSG nickserv :identify %s", irc_password );
  497. +                   irc_send( send_string );
  498. +               }
  499. +
  500. +               // join the appropriate channels and retrieve a list of all participants
  501. +               snprintf( send_string, sizeof(send_string), "JOIN %s %s", irc_channel, irc_channel_pass );
  502. +               irc_send( send_string );
  503. +               snprintf( send_string, sizeof(send_string), "NAMES %s",irc_channel );
  504. +               irc_send( send_string );
  505. +               irc_session_info->state = 2;
  506. +           }
  507. +           else if( !strcmp(command,"433") )
  508. +           {// nickname is already in use so enforce an error and cancel
  509. +               ShowError( "IRC: Nickname %s is already taken, IRC Client unable to connect.\n", irc_nick );
  510. +               snprintf( send_string, sizeof(send_string), "QUIT" );
  511. +               irc_send( send_string );
  512. +               if( session[fd] )
  513. +                   set_eof( fd );
  514. +           }
  515. +       }
  516. +       break;
  517. +
  518. +       case 2:
  519. +       {// identified and connected to the IRC server successfully so process other messages
  520. +           if( !strcmp(source, "PING") )
  521. +           {// reply to a PING message with a PONG message
  522. +               snprintf( send_string, sizeof(send_string), "PONG %s", command );
  523. +               irc_send( send_string );
  524. +           }
  525. +           else if ( strcmpi(target,irc_channel) == 0 || strcmpi( target, irc_channel + 1 ) == 0 || strcmpi( target + 1, irc_channel ) == 0 )
  526. +           {// message was received from the channel exclusively
  527. +               char cmdname[256];
  528. +               char cmdargs[256] = "";
  529. +
  530. +               if( !strcmpi(command,"privmsg") && target[0] == '#')
  531. +               {// private message (public really) from the channel
  532. +                   if( irc.main_auto )
  533. +                   {// messages spoken in the IRC channel should be relayed as @main messages
  534. +                       snprintf( send_string, sizeof(send_string), ">> (IRC)%s : %s", source_nick, message );
  535. +                       intif_broadcast2( send_string, strlen(send_string) + 1, 0xFE000000, 0, 0, 0, 0 );
  536. +                   }
  537. +
  538. +                   if( sscanf(message, "@%255s %255[^\r\n]", cmdname, cmdargs) )
  539. +                   {// at-command used in the IRC channel so perform any commands here
  540. +                       if( !strcmpi(cmdname, "users") || !strcmpi(cmdname, "who") )
  541. +                       {// @users, @who
  542. +                           snprintf( send_string, sizeof(send_string), "PRIVMSG %s :Users online: %d", irc_channel, map_getusers() );
  543. +                           irc_send( send_string );
  544. +                       }
  545. +                       else if( !strcmpi(cmdname, "main") && !irc.main_auto )
  546. +                       {// @main
  547. +                           snprintf( send_string, sizeof(send_string), ">> (IRC)%s : %s", source_nick, cmdargs );
  548. +                           intif_broadcast2( send_string, strlen(send_string) + 1, 0xFE000000, 0, 0, 0, 0 );
  549. +                       }
  550. +                   }
  551. +                   //else if( strstr(message, "ACTION rubs RaijeBot's tummy") )
  552. +                   //{// someone use /me rubs RaijeBot's tummy
  553. +                   //  sprintf( send_string, "PRIVMSG %s :*purr*", irc_channel );
  554. +                   //  irc_send( send_string );
  555. +                   //}
  556. +               }
  557. +               else if ( !strcmpi(command, "join") || !strcmpi(command, "part") || !strcmpi(command, "mode") || !strcmpi(command, "nick") )
  558. +               {// retrieve the list of channel names again
  559. +                   ShowInfo( "IRC: Refreshing user list" );
  560. +                   irc_rmnames();
  561. +                   ShowMessage( "..." );
  562. +                   snprintf( send_string, sizeof(send_string), "NAMES %s", irc_channel );
  563. +                   irc_send( send_string );
  564. +                   ShowMessage( "complete.\n" );
  565. +               }
  566. +               else if( !strcmpi(command, "kick") && irc.autojoin )
  567. +               {// auto-join when kicked
  568. +                   snprintf( send_string, sizeof(send_string), "JOIN %s %s", target, irc_channel_pass );
  569. +                   irc_send( send_string );
  570. +               }
  571. +           }
  572. +           else if( !strcmpi(command, "353") )
  573. +           {// reply to the names packet
  574. +               ShowInfo( "IRC: NAMES received\n" );
  575. +               parse_names_packet( incoming_string );
  576. +           }
  577. +       }
  578. +       break;
  579. +   }
  580. +}
  581. +
  582. +int send_to_parser(int fd, char* input, char key[2])
  583. +{
  584. +   char* temp_string = NULL;
  585. +   char* state_mgr = NULL;
  586. +   int total_loops = 0;
  587. +
  588. +   // process the line until the next delimiter
  589. +   temp_string = strtok_r( input, key, &state_mgr );
  590. +
  591. +   // while a line exists in the buffer
  592. +   while( temp_string )
  593. +   {
  594. +       total_loops++;
  595. +       irc_parse_sub( fd, temp_string );
  596. +       temp_string = strtok_r( NULL, key, &state_mgr );
  597. +   }
  598. +
  599. +   return total_loops;
  600. +}
  601. +
  602. +//======================================================
  603. +// NAMES Packet(353) parser
  604. +//======================================================
  605. +int parse_names_packet(char *str)
  606. +{
  607. +   char* tok;
  608. +   char source[256];
  609. +   char numeric[10];
  610. +   char target[256];
  611. +   char channel[256];
  612. +   char names[1024];
  613. +
  614. +   memset(source,'\0',256);
  615. +   memset(numeric,'\0',10);
  616. +   memset(target,'\0',256);
  617. +   memset(channel,'\0',256);
  618. +   memset(names,'\0',1024);
  619. +
  620. +   //TODO: fold this
  621. +   tok=strtok(str,"\r\n");
  622. +   sscanf(tok,":%255s %10s %255s %*1[=@] %255s :%1023[^\r\n]",source,numeric,target,channel,names);
  623. +   if(strcmpi(numeric,"353")==0)
  624. +       parse_names(names);
  625. +
  626. +   while((tok=strtok(NULL,"\r\n"))!=NULL)
  627. +   {
  628. +       sscanf(tok,":%255s %10s %255s %*1[=@] %255s :%1023[^\r\n]",source,numeric,target,channel,names);
  629. +       if(strcmpi(numeric,"353")==0)
  630. +           parse_names(names);
  631. +   }
  632. +
  633. +   return 0;
  634. +}
  635. +
  636. +//======================================================
  637. +// User access level prefix parser
  638. +//======================================================
  639. +int parse_names(char* str)
  640. +{
  641. +   char* tok;
  642. +
  643. +   if( !str )
  644. +   {// no usernames received to parse
  645. +       return 0;
  646. +   }
  647. +
  648. +   tok = strtok( str, " " );
  649. +
  650. +   switch(tok[0])
  651. +   {
  652. +       case '~': set_access(tok+1,ACCESS_OWNER); break;
  653. +       case '&': set_access(tok+1,ACCESS_SOP); break;
  654. +       case '@': set_access(tok+1,ACCESS_OP); break;
  655. +       case '%': set_access(tok+1,ACCESS_HOP); break;
  656. +       case '+': set_access(tok+1,ACCESS_VOICE); break;
  657. +       default : set_access(tok,ACCESS_NORM); break;  
  658. +   }
  659. +
  660. +   while((tok = strtok(NULL, " ")) != NULL)
  661. +   {
  662. +       switch(tok[0])
  663. +       {
  664. +           case '~': set_access(tok+1,ACCESS_OWNER); break;
  665. +           case '&': set_access(tok+1,ACCESS_SOP); break;
  666. +           case '@': set_access(tok+1,ACCESS_OP); break;
  667. +           case '%': set_access(tok+1,ACCESS_HOP); break;
  668. +           case '+': set_access(tok+1,ACCESS_VOICE); break;
  669. +           default : set_access(tok,ACCESS_NORM); break;  
  670. +       }
  671. +   }
  672. +  
  673. +   return 1;
  674. +}
  675. +
  676. +//======================================================
  677. +// Store user's access level
  678. +//======================================================
  679. +int set_access(char* nick, int newlevel )
  680. +{
  681. +   int i;
  682. +
  683. +   // find the entry matching this nickname
  684. +   ARR_FIND( 0, MAX_CHANNEL_USERS + 1, i, !strcmpi(cd.user[i].name, nick) );
  685. +  
  686. +   if( i < MAX_CHANNEL_USERS + 1 )
  687. +   {// update the level of the existing entry
  688. +       cd.user[i].level = (unsigned char)newlevel;
  689. +       return 1;
  690. +   }
  691. +  
  692. +   // copy the nickname into the user list for future reference
  693. +   safestrncpy( cd.user[last_cd_user].name, nick, sizeof(cd.user[last_cd_user].name) );
  694. +
  695. +   // copy the new level of this nickname
  696. +   cd.user[last_cd_user++].level = (unsigned char)newlevel;
  697. +
  698. +   return 0;
  699. +}
  700. +
  701. +//======================================================
  702. +// Returns users access level
  703. +//======================================================
  704. +int get_access(char *nick)
  705. +{
  706. +   int i;
  707. +
  708. +   // find the entry matching this nickname
  709. +   ARR_FIND( 0, MAX_CHANNEL_USERS + 1, i, !strcmpi(cd.user[i].name, nick) );
  710. +
  711. +   // push the level of the person or -1 from the method
  712. +   return ( i == MAX_CHANNEL_USERS + 1 ) ? -1 : cd.user[i].level;
  713. +}
  714. +
  715. +int irc_rmnames()
  716. +{
  717. +   int i;
  718. +
  719. +   // reset the entire user block
  720. +   memset( cd.user, 0, sizeof(cd.user) );
  721. +  
  722. +   // reset the user block counter to nothing
  723. +   last_cd_user = 0;
  724. +
  725. +   return 0;
  726. +}
  727. +
  728. +void do_init_irc(void)
  729. +{
  730. +   if( !irc.enabled )
  731. +   {// do not process the IRC server at all
  732. +       return;
  733. +   }
  734. +
  735. +   // retrieve the long IP from the string value
  736. +   irc_ip = host2ip(irc_ip_str);
  737. +
  738. +   if( !irc_ip )
  739. +   {// cannot resolve the IP address
  740. +       ShowError("Unable to resolve %s! Cannot connect to IRC server, disabling irc_bot.\n", irc_ip_str);
  741. +       irc.enabled = 0;
  742. +       return;
  743. +   }
  744. +
  745. +   // perform the first connection attempt to the IRC server
  746. +   irc_connect_timer( 0, 0, 0, 0 );
  747. +
  748. +   // register important timers for automated removal
  749. +   add_timer_func_list( irc_connect_timer, "irc_connect_timer" );
  750. +   add_timer_func_list( irc_keepalive_timer, "irc_keepalive_timer" );
  751. +   add_timer(gettick() + 30000, irc_keepalive_timer, 0, 0);
  752. +}
  753. +
  754. +void do_final_irc(void)
  755. +{
  756. +}
  757. Index: src/map/irc.c
  758.  
  759. ===================================================================
  760.  
  761. --- src/map/irc.c   (revision 0)
  762.  
  763. +++ src/map/irc.c   (working copy)
  764.  
  765.  
  766.  
  767. Property changes on: src/map/irc.c
  768.  
  769. ___________________________________________________________________
  770.  
  771. Added: svn:eol-style
  772.  
  773. ## -0,0 +1 ##
  774.  
  775. +native
  776.  
  777. Index: src/map/irc.h
  778.  
  779. ===================================================================
  780.  
  781. --- src/map/irc.h   (revision 0)
  782.  
  783. +++ src/map/irc.h   (working copy)
  784.  
  785. @@ -0,0 +1,80 @@
  786.  
  787. +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  788. +// For more information, see LICENCE in the main folder
  789. +
  790. +#ifndef _IRC_H_
  791. +#define _IRC_H_
  792. +
  793. +//#include "map.h"
  794. +struct map_session_data;
  795. +
  796. +// IRC .conf file [Zido]
  797. +#define IRC_CONF   "irc_athena.conf"
  798. +
  799. +// IRC Access levels [Zido]
  800. +#define    ACCESS_OWNER    5
  801. +#define    ACCESS_SOP      4
  802. +#define    ACCESS_OP       3
  803. +#define    ACCESS_HOP      2
  804. +#define    ACCESS_VOICE    1
  805. +#define ACCESS_NORM        0
  806. +
  807. +// maximum number of users available in a channel
  808. +#define MAX_CHANNEL_USERS  500
  809. +
  810. +// maximum length for a received message, adjust accordingly for a busy channel
  811. +#define MAX_MESSAGE_LENGTH 2048
  812. +
  813. +// maximum length for a message being sent to the IRC server, adjust accordingly if necessary
  814. +#define MAX_SEND_LENGTH 256
  815. +
  816. +// structure to store irc configuration
  817. +struct e_irc_config {
  818. +   unsigned char enabled;
  819. +   unsigned char autojoin;
  820. +   unsigned char announce_flag;
  821. +   unsigned char job_change_flag;
  822. +   unsigned char main_auto;
  823. +   unsigned char main_flag;
  824. +   unsigned char mvp_flag;
  825. +   unsigned char shop_flag;
  826. +};
  827. +
  828. +// Config Variables
  829. +extern struct e_irc_config irc;
  830. +
  831. +void irc_announce(const char* buf);
  832. +void irc_announce_jobchange(struct map_session_data *sd);
  833. +void irc_announce_shop(struct map_session_data *sd,int flag);
  834. +void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md);
  835. +
  836. +int irc_parse(int fd);
  837. +void do_final_irc(void);
  838. +void do_init_irc(void);
  839. +void irc_send(char *buf);
  840. +void irc_parse_sub(int fd, char *incoming_string);
  841. +int send_to_parser(int fd, char *input,char key[2]);
  842. +
  843. +struct e_irc_session {
  844. +    int state;
  845. +    int fd;
  846. +    char username[30];
  847. +    char password[33];
  848. +};
  849. +
  850. +typedef struct e_irc_session irc_session;
  851. +
  852. +struct e_channel_data {
  853. +   struct {
  854. +       char name[256];
  855. +       unsigned char level;
  856. +   } user[MAX_CHANNEL_USERS];
  857. +};
  858. +
  859. +int parse_names_packet(char *str); // [Zido]
  860. +int parse_names(char *str); // [Zido]
  861. +int set_access(char *nick,int level); // [Zido]
  862. +int get_access(char *nick); // [Zido]
  863. +int irc_rmnames(void); // [Zido]
  864. +int irc_read_conf(char *file); // [Zido]
  865. +
  866. +#endif /* _IRC_H_ */
  867. Index: src/map/irc.h
  868.  
  869. ===================================================================
  870.  
  871. --- src/map/irc.h   (revision 0)
  872.  
  873. +++ src/map/irc.h   (working copy)
  874.  
  875.  
  876.  
  877. Property changes on: src/map/irc.h
  878.  
  879. ___________________________________________________________________
  880.  
  881. Added: svn:keywords
  882.  
  883. ## -0,0 +1 ##
  884.  
  885. +Author Date Id Rev URL
  886.  
  887. Added: svn:eol-style
  888.  
  889. ## -0,0 +1 ##
  890.  
  891. +native
  892.  
  893. Index: src/map/map.c
  894.  
  895. ===================================================================
  896.  
  897. --- src/map/map.c   (revision 15490)
  898.  
  899. +++ src/map/map.c   (working copy)
  900.  
  901. @@ -44,6 +44,7 @@
  902.  
  903.  #include "mercenary.h"
  904.  #include "atcommand.h"
  905.  #include "log.h"
  906. +#include "irc.h"
  907.  #ifndef TXT_ONLY
  908.  #include "mail.h"
  909.  #endif
  910. @@ -3472,6 +3473,8 @@
  911.  
  912.     do_final_unit();
  913.     do_final_battleground();
  914.     do_final_duel();
  915. +   if(irc.enabled)
  916. +       do_final_irc();
  917.    
  918.     map_db->destroy(map_db, map_db_final);
  919.    
  920. @@ -3724,6 +3727,7 @@
  921.  
  922.      **/
  923.     map_config_read("npc/scripts_renewal.conf");
  924.  #endif
  925. +   irc_read_conf(IRC_CONF); // [Zido]
  926.     chrif_checkdefaultlogin();
  927.  
  928.     if (!map_ip_set || !char_ip_set) {
  929. @@ -3779,6 +3783,8 @@
  930.  
  931.     add_timer_func_list(map_removemobs_timer, "map_removemobs_timer");
  932.     add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000);
  933.  
  934. +   if(irc.enabled)
  935. +       do_init_irc();
  936.     do_init_atcommand();
  937.     do_init_battle();
  938.     do_init_instance();
  939. Index: src/map/mob.c
  940.  
  941. ===================================================================
  942.  
  943. --- src/map/mob.c   (revision 15490)
  944.  
  945. +++ src/map/mob.c   (working copy)
  946.  
  947. @@ -33,6 +33,7 @@
  948.  
  949.  #include "script.h"
  950.  #include "atcommand.h"
  951.  #include "date.h"
  952. +#include "irc.h"
  953.  #include "quest.h"
  954.  
  955.  #include <stdio.h>
  956. @@ -2362,6 +2363,9 @@
  957.  
  958.         }
  959.        
  960.         mexp = (unsigned int)cap_value(exp, 1, UINT_MAX);
  961. +      
  962. +       if(irc.enabled && irc.mvp_flag)
  963. +           irc_announce_mvp(mvp_sd,md);
  964.  
  965.         clif_mvp_effect(mvp_sd);
  966.         clif_mvp_exp(mvp_sd,mexp);
  967. Index: src/map/script.c
  968.  
  969. ===================================================================
  970.  
  971. --- src/map/script.c    (revision 15490)
  972.  
  973. +++ src/map/script.c    (working copy)
  974.  
  975. @@ -44,6 +44,7 @@
  976.  
  977.  #include "atcommand.h"
  978.  #include "log.h"
  979.  #include "unit.h"
  980. +#include "irc.h"
  981.  #include "pet.h"
  982.  #include "mail.h"
  983.  #include "script.h"
  984. @@ -4829,6 +4830,8 @@
  985.  
  986.             return 0;
  987.  
  988.         pc_jobchange(sd, job, upper);
  989. +       if(irc.enabled && irc.job_change_flag)
  990. +           irc_announce_jobchange(sd);
  991.     }
  992.  
  993.     return 0;
  994. Index: src/map/vending.c
  995.  
  996. ===================================================================
  997.  
  998. --- src/map/vending.c   (revision 15490)
  999.  
  1000. +++ src/map/vending.c   (working copy)
  1001.  
  1002. @@ -15,6 +15,7 @@
  1003.  
  1004.  #include "skill.h"
  1005.  #include "battle.h"
  1006.  #include "log.h"
  1007. +#include "irc.h"
  1008.  
  1009.  #include <stdio.h>
  1010.  #include <string.h>
  1011. @@ -38,6 +39,9 @@
  1012.  
  1013.     {
  1014.         sd->state.vending = false;
  1015.         clif_closevendingboard(&sd->bl, 0);
  1016. +
  1017. +        if(irc.enabled && irc.shop_flag )
  1018. +              irc_announce_shop(sd,0);
  1019.     }
  1020.  }
  1021.  
  1022. @@ -308,6 +312,9 @@
  1023.  
  1024.     pc_stop_walking(sd,1);
  1025.     clif_openvending(sd,sd->bl.id,sd->vending);
  1026.     clif_showvendingboard(&sd->bl,message,0);
  1027. +  
  1028. +   if(irc.enabled && irc.shop_flag )
  1029. +       irc_announce_shop(sd,1);
  1030.  }
  1031.  
  1032.  
  1033. Index: vcproj-10/map-server_sql.vcxproj
  1034.  
  1035. ===================================================================
  1036.  
  1037. --- vcproj-10/map-server_sql.vcxproj    (revision 15490)
  1038.  
  1039. +++ vcproj-10/map-server_sql.vcxproj    (working copy)
  1040.  
  1041. @@ -159,6 +159,7 @@
  1042.  
  1043.      <ClInclude Include="..\src\map\duel.h" />
  1044.      <ClInclude Include="..\src\map\guild.h" />
  1045.      <ClInclude Include="..\src\map\intif.h" />
  1046. +    <ClInclude Include="..\src\map\irc.h" />
  1047.      <ClInclude Include="..\src\map\itemdb.h" />
  1048.      <ClInclude Include="..\src\map\log.h" />
  1049.      <ClInclude Include="..\src\map\mail.h" />
  1050. @@ -220,6 +221,7 @@
  1051.  
  1052.      <ClCompile Include="..\src\map\duel.c" />
  1053.      <ClCompile Include="..\src\map\guild.c" />
  1054.      <ClCompile Include="..\src\map\intif.c" />
  1055. +    <ClCompile Include="..\src\map\irc.c" />
  1056.      <ClCompile Include="..\src\map\itemdb.c" />
  1057.      <ClCompile Include="..\src\map\log.c" />
  1058.      <ClCompile Include="..\src\map\mail.c" />
  1059. Index: vcproj-10/map-server_sql.vcxproj.filters
  1060.  
  1061. ===================================================================
  1062.  
  1063. --- vcproj-10/map-server_sql.vcxproj.filters    (revision 15490)
  1064.  
  1065. +++ vcproj-10/map-server_sql.vcxproj.filters    (working copy)
  1066.  
  1067. @@ -40,6 +40,9 @@
  1068.  
  1069.      <ClCompile Include="..\src\map\intif.c">
  1070.        <Filter>map_sql</Filter>
  1071.      </ClCompile>
  1072. +   <ClCompile Include="..\src\map\irc.c">
  1073. +      <Filter>map_sql</Filter>
  1074. +    </ClCompile>
  1075.      <ClCompile Include="..\src\map\itemdb.c">
  1076.        <Filter>map_sql</Filter>
  1077.      </ClCompile>
  1078. @@ -201,6 +204,9 @@
  1079.  
  1080.      <ClInclude Include="..\src\map\intif.h">
  1081.        <Filter>map_sql</Filter>
  1082.      </ClInclude>
  1083. +   <ClInclude Include="..\src\map\irc.h">
  1084. +      <Filter>map_sql</Filter>
  1085. +    </ClInclude>
  1086.      <ClInclude Include="..\src\map\itemdb.h">
  1087.        <Filter>map_sql</Filter>
  1088.      </ClInclude>
  1089. Index: vcproj-10/map-server_txt.vcxproj
  1090.  
  1091. ===================================================================
  1092.  
  1093. --- vcproj-10/map-server_txt.vcxproj    (revision 15490)
  1094.  
  1095. +++ vcproj-10/map-server_txt.vcxproj    (working copy)
  1096.  
  1097. @@ -138,6 +138,7 @@
  1098.  
  1099.      <ClCompile Include="..\src\map\homunculus.c" />
  1100.      <ClCompile Include="..\src\map\instance.c" />
  1101.      <ClCompile Include="..\src\map\intif.c" />
  1102. +    <ClCompile Include="..\src\map\irc.c" />
  1103.      <ClCompile Include="..\src\map\itemdb.c" />
  1104.      <ClCompile Include="..\src\map\log.c" />
  1105.      <ClCompile Include="..\src\map\mail.c" />
  1106. @@ -193,6 +194,7 @@
  1107.  
  1108.      <ClInclude Include="..\src\map\homunculus.h" />
  1109.      <ClInclude Include="..\src\map\instance.h" />
  1110.      <ClInclude Include="..\src\map\intif.h" />
  1111. +    <ClCompile Include="..\src\map\irc.h" />
  1112.      <ClInclude Include="..\src\map\itemdb.h" />
  1113.      <ClInclude Include="..\src\map\log.h" />
  1114.      <ClInclude Include="..\src\map\mail.h" />
  1115. Index: vcproj-10/map-server_txt.vcxproj.filters
  1116.  
  1117. ===================================================================
  1118.  
  1119. --- vcproj-10/map-server_txt.vcxproj.filters    (revision 15490)
  1120.  
  1121. +++ vcproj-10/map-server_txt.vcxproj.filters    (working copy)
  1122.  
  1123. @@ -58,6 +58,9 @@
  1124.  
  1125.      <ClCompile Include="..\src\map\intif.c">
  1126.        <Filter>map_txt</Filter>
  1127.      </ClCompile>
  1128. +    <ClCompile Include="..\src\map\irc.c">
  1129. +      <Filter>map_txt</Filter>
  1130. +    </ClCompile>
  1131.      <ClCompile Include="..\src\map\itemdb.c">
  1132.        <Filter>map_txt</Filter>
  1133.      </ClCompile>
  1134. @@ -225,6 +228,9 @@
  1135.  
  1136.      <ClInclude Include="..\src\map\intif.h">
  1137.        <Filter>map_txt</Filter>
  1138.      </ClInclude>
  1139. +    <ClInclude Include="..\src\map\irc.h">
  1140. +      <Filter>map_txt</Filter>
  1141. +    </ClInclude>
  1142.      <ClInclude Include="..\src\map\itemdb.h">
  1143.        <Filter>map_txt</Filter>
  1144.      </ClInclude>
  1145. Index: vcproj-9/map-server_sql.vcproj
  1146.  
  1147. ===================================================================
  1148.  
  1149. --- vcproj-9/map-server_sql.vcproj  (revision 15490)
  1150.  
  1151. +++ vcproj-9/map-server_sql.vcproj  (working copy)
  1152.  
  1153. @@ -484,6 +484,14 @@
  1154.  
  1155.                 >
  1156.             </File>
  1157.             <File
  1158. +               RelativePath="..\src\map\irc.c"
  1159. +               >
  1160. +           </File>
  1161. +           <File
  1162. +               RelativePath="..\src\map\irc.h"
  1163. +               >
  1164. +           </File>
  1165. +           <File
  1166.                 RelativePath="..\src\map\itemdb.c"
  1167.                 >
  1168.             </File>
  1169. Index: vcproj-9/map-server_txt.vcproj
  1170.  
  1171. ===================================================================
  1172.  
  1173. --- vcproj-9/map-server_txt.vcproj  (revision 15490)
  1174.  
  1175. +++ vcproj-9/map-server_txt.vcproj  (working copy)
  1176.  
  1177. @@ -307,10 +307,17 @@
  1178.  
  1179.                 >
  1180.             </File>
  1181.             <File
  1182. -               RelativePath="..\src\map\itemdb.c"
  1183. +               RelativePath="..\src\map\irc.c"
  1184.                 >
  1185.             </File>
  1186.             <File
  1187. +               RelativePath="..\src\map\irc.h"
  1188. +               >
  1189. +           </File>
  1190. +           <File
  1191. +               RelativePath="..\src\map\itemdb.c"
  1192. +               >
  1193. +           <File
  1194.                 RelativePath="..\src\map\itemdb.h"
  1195.                 >
  1196.             </File>
Add Comment
Please, Sign In to add comment