diff options
-rw-r--r-- | Changelog-Trunk.txt | 2 | ||||
-rw-r--r-- | src/map/irc.c | 362 |
2 files changed, 168 insertions, 196 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 3ac378a1e..355925b32 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,8 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2007/06/01 + * Fixed ircbot discarding all user levels when someone joins the channel 2007/05/29 * Hopefully fixed the vsnprintf incompatibility 2007/05/28 diff --git a/src/map/irc.c b/src/map/irc.c index de9edd87b..986efd51b 100644 --- a/src/map/irc.c +++ b/src/map/irc.c @@ -14,15 +14,15 @@ #include "map.h" #include "pc.h" -#include "intif.h" //For GM Broadcast [Zido] +#include "intif.h" //For GM Broadcast #include "irc.h" #include <stdio.h> #include <string.h> #include <stdlib.h> +// configuration short use_irc=0; - short irc_autojoin=0; short irc_announce_flag=1; @@ -30,11 +30,8 @@ short irc_announce_mvp_flag=1; short irc_announce_jobchange_flag=1; short irc_announce_shop_flag=1; -IRC_SI *irc_si=NULL; - char irc_nick[30]=""; char irc_password[32]=""; - char irc_channel[32]=""; char irc_channel_pass[32]=""; char irc_trade_channel[32]=""; @@ -42,8 +39,10 @@ char irc_trade_channel[32]=""; char irc_ip_str[128]=""; unsigned long irc_ip=0; unsigned short irc_port = 6667; -int irc_fd=0; +// variables +int irc_fd=0; +IRC_SI *irc_si=NULL; struct channel_data cd; int last_cd_user=0; @@ -66,7 +65,6 @@ int irc_connect_timer(int tid, unsigned int tick, int id, int data) void irc_announce(const char* buf) { char send_string[256]; - // memset(send_string,'\0',256); // NOT REQUIRED sprintf(send_string,"PRIVMSG %s :",irc_channel); strcat(send_string, buf); @@ -78,7 +76,6 @@ void irc_announce_jobchange(struct map_session_data *sd) char send_string[256]; nullpo_retv(sd); - memset(send_string,'\0',256); sprintf(send_string,"PRIVMSG %s :%s has changed into a %s.",irc_channel,sd->status.name,job_name(sd->status.class_)); irc_send(send_string); @@ -91,9 +88,6 @@ void irc_announce_shop(struct map_session_data *sd, int flag) int maplen = 0; nullpo_retv(sd); - memset(send_string,'\0',256); - memset(mapname,'\0',16); - if(flag){ strcpy(mapname, map[sd->bl.m].name); maplen = strcspn(mapname,"."); @@ -116,9 +110,6 @@ void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md) nullpo_retv(sd); nullpo_retv(md); - memset(send_string,'\0',256); - memset(mapname,'\0',16); - mapname[15]='\0'; // 15 is the final index, not 16 [Lance] strcpy(mapname, map[md->bl.m].name); maplen = strcspn(mapname,"."); mapname[maplen] = '\0'; @@ -130,27 +121,28 @@ void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md) int irc_parse(int fd) { - if (session[fd]->eof){ + if (session[fd]->eof) + { do_close(fd); irc_si = NULL; add_timer(gettick() + 15000, irc_connect_timer, 0, 0); return 0; } - if (session[fd]->session_data == NULL){ + + if (session[fd]->session_data == NULL) { irc_si = (struct IRC_Session_Info*)aMalloc(sizeof(struct IRC_Session_Info)); irc_si->fd = fd; irc_si->state = 0; session[fd]->session_data = irc_si; - } else if (!irc_si) { + } else if (!irc_si) { irc_si = (struct IRC_Session_Info*)session[fd]->session_data; irc_si->fd = fd; } - if(RFIFOREST(fd) > 0){ - char *incoming_string=aMalloc(RFIFOREST(fd)*sizeof(char)); - memcpy(incoming_string,RFIFOP(fd,0),RFIFOREST(fd)); - send_to_parser(fd,incoming_string,"\n"); + + if(RFIFOREST(fd) > 0) + { + send_to_parser(fd, (char*)RFIFOP(fd,0), "\n"); RFIFOSKIP(fd,RFIFOREST(fd)); - aFree(incoming_string); } return 0; } @@ -158,33 +150,24 @@ int irc_parse(int fd) int irc_keepalive_timer(int tid, unsigned int tick, int id, int data) { char send_string[128]; - memset(send_string,'\0',128); - sprintf(send_string,"PRIVMSG %s : ", irc_nick); irc_send(send_string); add_timer(gettick() + 30000, irc_keepalive_timer, 0, 0); return 0; } -void irc_send_sub(int fd, char transmit[4096]) -{ - sprintf(transmit,"%s%c",transmit,10); - WFIFOHEAD(fd,strlen(transmit)); - memcpy(WFIFOP(fd,0),transmit, strlen(transmit)); - WFIFOSET(fd,strlen(transmit)); -} - void irc_send(char *buf) { - char transmit[4096]; + int len; + int fd = irc_si->fd; - if(!irc_si || !session[irc_si->fd]) + if(!irc_si || !session[fd]) return; - memset(transmit,'\0',4096); - - sprintf(transmit,buf); - irc_send_sub(irc_si->fd,transmit); + len = strlen(buf) + 1; + WFIFOHEAD(fd, len); + sprintf((char*)WFIFOP(fd,0), "%s\n", buf); + WFIFOSET(fd, len); } void irc_parse_sub(int fd, char *incoming_string) @@ -199,12 +182,6 @@ void irc_parse_sub(int fd, char *incoming_string) char *source_host=NULL; char *state_mgr=NULL; - char cmd1[256]; - char cmd2[256]; - char cmdname[256]; - char cmdargs[256]; - - int users=0; int i=0; struct map_session_data **allsd; @@ -215,28 +192,30 @@ void irc_parse_sub(int fd, char *incoming_string) memset(message,'\0',8192); memset(send_string,'\0',8192); - memset(cmd1,'\0',256); - memset(cmd2,'\0',256); - memset(cmdname,'\0',256); - memset(cmdargs,'\0',256); - sscanf(incoming_string, ":%255s %255s %255s :%4095[^\r\n]", source, command, target, message); - if (source != NULL) { - if (strstr(source,"!") != NULL) { + if (source != NULL) + { + if (strstr(source,"!") != NULL) + { source_nick = strtok_r(source,"!",&state_mgr); source_ident = strtok_r(NULL,"@",&state_mgr); source_host = strtok_r(NULL,"%%",&state_mgr); } } - if (irc_si->state == 0){ + + switch (irc_si->state) + { + case 0: sprintf(send_string, "NICK %s", irc_nick); irc_send(send_string); sprintf(send_string, "USER eABot 8 * : eABot"); irc_send(send_string); irc_si->state = 1; - } - else if (irc_si->state == 1){ - if(!strcmp(command,"001")){ + break; + + case 1: + if(!strcmp(command,"001")) + { ShowStatus("IRC: Connected to IRC.\n"); sprintf(send_string, "PRIVMSG nickserv :identify %s", irc_password); irc_send(send_string); @@ -246,81 +225,99 @@ void irc_parse_sub(int fd, char *incoming_string) irc_send(send_string); irc_si->state = 2; } - else if(!strcmp(command,"433")){ - ShowError("IRC: Nickname %s is already taken, IRC Client unable to connect.\n", irc_nick); - sprintf(send_string, "QUIT"); + else + if(!strcmp(command,"433")) + { + ShowError("IRC: Nickname %s is already taken, IRC Client unable to connect.\n", irc_nick); + sprintf(send_string, "QUIT"); irc_send(send_string); if(session[fd]) set_eof(fd); } - } - else if (irc_si->state == 2){ - if(!strcmp(source, "PING")){ - sprintf(send_string, "PONG %s", command); + break; + + case 2: + if(!strcmp(source, "PING")) + { + sprintf(send_string, "PONG %s", command); irc_send(send_string); } - - else if((strcmpi(target,irc_channel)==0)||(strcmpi(target,irc_channel+1)==0)) { - - // Broadcast [Zido] (Work in Progress) - if((strcmpi(command,"privmsg")==0)&&(sscanf(message,"@%255s %255[^\r\n]",cmdname,cmdargs)>0)&&(target[0]=='#')) { - if(strcmpi(cmdname,"kami")==0) { - if(get_access(source_nick)<ACCESS_OP) + else // channel message + if( strcmpi(target,irc_channel)==0 || strcmpi(target,irc_channel+1)==0 || strcmpi(target+1,irc_channel)==0 ) + { //TODO: why not allow talking to the bot directly? (|| strcmpi(irc_nick,target) == 0) + + // issue a command (usage: say @command <params> into the channel) + char cmdname[256]; + char cmdargs[256] = ""; + if((strcmpi(command,"privmsg")==0)&&(sscanf(message,"@%255s %255[^\r\n]",cmdname,cmdargs)>0)&&(target[0]=='#')) + { + if(strcmpi(cmdname,"kami")==0) + { + if(get_access(source_nick) < ACCESS_OP) sprintf(send_string,"NOTICE %s :Access Denied",source_nick); - else { + else + { sprintf(send_string,"%s: %s",source_nick,cmdargs); intif_GMmessage(send_string,strlen(send_string)+1,0); sprintf(send_string,"NOTICE %s :Message Sent",source_nick); } irc_send(send_string); - // Number of users online [Zido] - } else if(strcmpi(cmdname,"users")==0) { + } + else // Number of users online + if(strcmpi(cmdname,"users")==0) + { + int users; map_getallusers(&users); - sprintf(send_string,"PRIVMSG %s :Users Online: %d",irc_channel,users); - irc_send(send_string); - // List all users online [Zido] - } else if(strcmpi(cmdname,"who")==0) { - allsd=map_getallusers(&users); - if(users>0) { - sprintf(send_string,"NOTICE %s :%d Users Online",source_nick,users); + sprintf(send_string, "PRIVMSG %s :Users Online: %d", irc_channel, users); irc_send(send_string); - for(i=0;i<users;i++) { + } + else // List all users online + if(strcmpi(cmdname,"who")==0) + { + int users; + allsd = map_getallusers(&users); + if(users > 0) + { + sprintf(send_string,"NOTICE %s :%d Users Online",source_nick,users); + irc_send(send_string); + for(i = 0; i < users; i++) + { sprintf(send_string,"NOTICE %s :Name: \"%s\"",source_nick,allsd[i]->status.name); irc_send(send_string); } - } else { + } + else + { sprintf(send_string,"NOTICE %s :No Users Online",source_nick); irc_send(send_string); } } } - - // Refresh Names [Zido] - else if((strcmpi(command,"join")==0)||(strcmpi(command,"part")==0)||(strcmpi(command,"mode")==0)||(strcmpi(command,"nick")==0)) { + else // Refresh Names + if((strcmpi(command,"join")==0)||(strcmpi(command,"part")==0)||(strcmpi(command,"mode")==0)||(strcmpi(command,"nick")==0)) + { ShowInfo("IRC: Refreshing User List"); irc_rmnames(); printf("..."); sprintf(send_string,"NAMES %s",irc_channel); - printf("..."); irc_send(send_string); printf("Done\n"); } - - // Autojoin on kick [Zido] - else if((strcmpi(command,"kick")==0)&&(irc_autojoin==1)) { + else // Autojoin on kick + if((strcmpi(command,"kick")==0)&&(irc_autojoin==1)) + { sprintf(send_string, "JOIN %s %s", target, irc_channel_pass); irc_send(send_string); } } - - // Names Reply [Zido] - else if((strcmpi(command,"353")==0)) { + else // Names Reply + if((strcmpi(command,"353")==0)) + { ShowInfo("IRC: NAMES received\n"); parse_names_packet(incoming_string); } + break; } - - return; } int send_to_parser(int fd, char *input,char key[2]) @@ -330,7 +327,8 @@ int send_to_parser(int fd, char *input,char key[2]) int total_loops=0; temp_string = strtok_r(input,key,&state_mgr); - while (temp_string != NULL){ + while (temp_string != NULL) + { total_loops = total_loops+1; irc_parse_sub(fd,temp_string); temp_string = strtok_r(NULL,key,&state_mgr); @@ -338,33 +336,7 @@ int send_to_parser(int fd, char *input,char key[2]) return total_loops; } -void do_final_irc(void) -{ - -} - -void do_init_irc(void) -{ - if(!use_irc) - return; - if (irc_ip_str[strlen(irc_ip_str)-1] == '\n') - irc_ip_str[strlen(irc_ip_str)-1] = '\0'; - irc_ip = host2ip(irc_ip_str); - if (!irc_ip) - { - ShowError("Unable to resolve %s! Cannot connect to IRC server, disabling irc_bot.\n", irc_ip_str); - use_irc = 0; - return; - } - - irc_connect_timer(0, 0, 0, 0); - - add_timer_func_list(irc_connect_timer, "irc_connect_timer"); - add_timer_func_list(irc_keepalive_timer, "irc_keepalive_timer"); - add_timer(gettick() + 30000, irc_keepalive_timer, 0, 0); -} - -//NAMES Packet(353) parser [Zido] +//NAMES Packet(353) parser int parse_names_packet(char *str) { char *tok; @@ -380,12 +352,14 @@ int parse_names_packet(char *str) memset(channel,'\0',256); memset(names,'\0',1024); + //TODO: fold this tok=strtok(str,"\r\n"); sscanf(tok,":%255s %10s %255s %*1[=@] %255s :%1023[^\r\n]",source,numeric,target,channel,names); if(strcmpi(numeric,"353")==0) parse_names(names); - while((tok=strtok(NULL,"\r\n"))!=NULL) { + while((tok=strtok(NULL,"\r\n"))!=NULL) + { sscanf(tok,":%255s %10s %255s %*1[=@] %255s :%1023[^\r\n]",source,numeric,target,channel,names); if(strcmpi(numeric,"353")==0) parse_names(names); @@ -394,104 +368,78 @@ int parse_names_packet(char *str) return 0; } -//User access level prefix parser [Zido] -int parse_names(char *str) +//User access level prefix parser +int parse_names(char* str) { - char *tok; - if (str == NULL) return 0; //Nothing to parse! - tok=strtok(str," "); - switch(tok[0]) { - case '~': - set_access(tok+1,ACCESS_OWNER); - break; - case '&': - set_access(tok+1,ACCESS_SOP); - break; - case '@': - set_access(tok+1,ACCESS_OP); - break; - case '%': - set_access(tok+1,ACCESS_HOP); - break; - case '+': - set_access(tok+1,ACCESS_VOICE); - break; - default: - set_access(tok,ACCESS_NORM); - break; + //TODO: fold this copy-pasted junk + char* tok; + if (str == NULL) return 0; //Nothing to parse! + tok = strtok(str, " "); + switch(tok[0]) + { + case '~': set_access(tok+1,ACCESS_OWNER); break; + case '&': set_access(tok+1,ACCESS_SOP); break; + case '@': set_access(tok+1,ACCESS_OP); break; + case '%': set_access(tok+1,ACCESS_HOP); break; + case '+': set_access(tok+1,ACCESS_VOICE); break; + default : set_access(tok,ACCESS_NORM); break; } - while((tok=strtok(NULL," "))!=NULL) { - switch(tok[0]) { - case '~': - set_access(tok+1,ACCESS_OWNER); - break; - case '&': - set_access(tok+1,ACCESS_SOP); - break; - case '@': - set_access(tok+1,ACCESS_OP); - break; - case '%': - set_access(tok+1,ACCESS_HOP); - break; - case '+': - set_access(tok+1,ACCESS_VOICE); - break; - default: - set_access(tok,ACCESS_NORM); - break; + while((tok = strtok(NULL, " ")) != NULL) + { + switch(tok[0]) + { + case '~': set_access(tok+1,ACCESS_OWNER); break; + case '&': set_access(tok+1,ACCESS_SOP); break; + case '@': set_access(tok+1,ACCESS_OP); break; + case '%': set_access(tok+1,ACCESS_HOP); break; + case '+': set_access(tok+1,ACCESS_VOICE); break; + default : set_access(tok,ACCESS_NORM); break; } } return 1; } -//Store user's access level [Zido] +//Store user's access level int set_access(char *nick,int newlevel) { - int i=0; + int i; - for(i=0;i<=MAX_CHANNEL_USERS;i++) { - if(strcmpi(cd.user[i].name,nick)==0) { - cd.user[i].level=newlevel; + for(i = 0; i <= MAX_CHANNEL_USERS; i++) { + if(strcmpi(cd.user[i].name, nick)==0) { + cd.user[i].level = newlevel; return 1; } } - strcpy(cd.user[last_cd_user].name,nick); - cd.user[last_cd_user].level=newlevel; + strcpy(cd.user[last_cd_user].name, nick); + cd.user[last_cd_user].level = newlevel; last_cd_user++; return 0; } -//Returns users access level [Zido] +//Returns users access level int get_access(char *nick) { - int i=0; + int i; - for(i=0;i<=MAX_CHANNEL_USERS;i++) { - if(strcmpi(cd.user[i].name,nick)==0) { + for(i = 0; i <= MAX_CHANNEL_USERS; i++) + if(strcmpi(cd.user[i].name, nick)==0) return (cd.user[i].level); - } - } return -1; } int irc_rmnames() { - int i=0; - - for(i=0;i<=MAX_CHANNEL_USERS;i++) { - //memset(cd.user[i].name,'\0',256); + int i; + //TODO: why not just set the max counter to 0? + for(i = 0; i <= MAX_CHANNEL_USERS; i++) cd.user[i].level=0; - } - - last_cd_user=0; - + last_cd_user = 0; return 0; } @@ -517,21 +465,18 @@ int irc_read_conf(char *file) while(fgets(row, sizeof(row), fp) != NULL) { - if(row[0]=='/'&&row[1]=='/') + if(row[0]=='/' && row[1]=='/') continue; + sscanf(row,"%[^:]: %255[^\r\n]",w1,w2); - if(strcmpi(w1,"use_irc")==0) { - if(strcmpi(w2,"on")==0) - use_irc=1; - else - use_irc=0; - } + if(strcmpi(w1,"use_irc")==0) + use_irc = config_switch(w2); else if(strcmpi(w1,"irc_server")==0) strcpy(irc_ip_str,w2); else if(strcmpi(w1,"irc_port")==0) - irc_port=atoi(w2); + irc_port = atoi(w2); else if(strcmpi(w1,"irc_autojoin")==0) - irc_autojoin=atoi(w2); + irc_autojoin = atoi(w2); else if(strcmpi(w1,"irc_channel")==0) strcpy(irc_channel,w2); else if(strcmpi(w1,"irc_channel_pass")==0) @@ -550,3 +495,28 @@ int irc_read_conf(char *file) return 1; } + +void do_init_irc(void) +{ + if(!use_irc) + return; + + irc_ip = host2ip(irc_ip_str); + if (!irc_ip) + { + ShowError("Unable to resolve %s! Cannot connect to IRC server, disabling irc_bot.\n", irc_ip_str); + use_irc = 0; + return; + } + + irc_connect_timer(0, 0, 0, 0); + + add_timer_func_list(irc_connect_timer, "irc_connect_timer"); + add_timer_func_list(irc_keepalive_timer, "irc_keepalive_timer"); + add_timer(gettick() + 30000, irc_keepalive_timer, 0, 0); +} + +void do_final_irc(void) +{ + +} |