浏览代码

Fixed ircbot not processing new users

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10657 54d463be-8e91-2dee-dedb-b68131a5f0ec
ultramage 18 年之前
父节点
当前提交
c45404429f
共有 2 个文件被更改,包括 168 次插入196 次删除
  1. 2 0
      Changelog-Trunk.txt
  2. 166 196
      src/map/irc.c

+ 2 - 0
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

+ 166 - 196
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)
+{
+
+}