Guest User

Untitled

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