=== conf/irc_athena.conf ================================================================== --- conf/irc_athena.conf (revision 14212) +++ conf/irc_athena.conf (local) @@ -0,0 +1,42 @@ +// ______ __ __ +// /\ _ \/\ \__/\ \ +// __\ \ \L\ \ \ ,_\ \ \___ __ ___ __ +// /'__`\ \ __ \ \ \/\ \ _ `\ /'__`\/' _ `\ /'__`\ +///\ __/\ \ \/\ \ \ \_\ \ \ \ \/\ __//\ \/\ \/\ \L\.\_ +//\ \____\\ \_\ \_\ \__\\ \_\ \_\ \____\ \_\ \_\ \__/.\_\ +// \/____/ \/_/\/_/\/__/ \/_/\/_/\/____/\/_/\/_/\/__/\/_/ +// _ _ _ _ _ _ _ _ _ _ _ _ _ +// / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ +//( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) +// \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ +// +//-------------------------------------------------------- +// eAthena IRC Bot Configuration File +//-------------------------------------------------------- + +//Turn the IRC Bot 'on' or 'off' +use_irc: off + +//IRC Server Address +irc_server: irc.deltaanime.net + +//IRC Server Port +irc_port: 6667 + +//Autojoin channel when kicked (on=1,off=0) +irc_autojoin: 0 + +//IRC Channel +irc_channel: # + +//IRC Channel password (set if required) +//irc_channel_pass: + +//IRC Trade Channel +irc_trade_channel: # + +//IRC Nickname +irc_nick: + +//IRC Password ("0" for no pass) +irc_pass: 0 Property changes on: conf/irc_athena.conf ___________________________________________________________________ Name: svn:eol-style +native === src/map/Makefile.in ================================================================== --- src/map/Makefile.in (revision 14212) +++ src/map/Makefile.in (local) @@ -17,7 +17,7 @@ npc_chat.o chat.o path.o itemdb.o mob.o script.o \ storage.o skill.o atcommand.o battle.o battleground.o \ intif.o trade.o party.o vending.o guild.o pet.o \ - log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o + log.o mail.o date.o irc.o unit.o homunculus.o mercenary.o quest.o instance.o MAP_TXT_OBJ = $(MAP_OBJ:%=obj_txt/%) \ obj_txt/mapreg_txt.o MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \ @@ -26,7 +26,7 @@ chat.h itemdb.h mob.h script.h path.h \ storage.h skill.h atcommand.h battle.h battleground.h \ intif.h trade.h party.h vending.h guild.h pet.h \ - log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h + log.h mail.h date.h irc.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h HAVE_MYSQL=@HAVE_MYSQL@ ifeq ($(HAVE_MYSQL),yes) === src/map/clif.c ================================================================== --- src/map/clif.c (revision 14212) +++ src/map/clif.c (local) @@ -36,6 +36,7 @@ #include "instance.h" #include "mercenary.h" #include "log.h" +#include "irc.h" #include "clif.h" #include "mail.h" #include "quest.h" @@ -4784,6 +4785,9 @@ if (buf) aFree(buf); + if(use_irc && irc_announce_flag && target == ALL_CLIENT) + irc_announce(mes); + return 0; } === src/map/map.c ================================================================== --- src/map/map.c (revision 14212) +++ src/map/map.c (local) @@ -42,6 +42,7 @@ #include "mercenary.h" #include "atcommand.h" #include "log.h" +#include "irc.h" #ifndef TXT_ONLY #include "mail.h" #endif @@ -3394,6 +3395,8 @@ do_final_status(); do_final_unit(); do_final_battleground(); + if(use_irc) + do_final_irc(); map_db->destroy(map_db, map_db_final); @@ -3554,6 +3557,7 @@ } map_config_read(MAP_CONF_NAME); + irc_read_conf(IRC_CONF); // [Zido] chrif_checkdefaultlogin(); if (!map_ip_set || !char_ip_set) { @@ -3610,6 +3614,8 @@ add_timer_func_list(map_removemobs_timer, "map_removemobs_timer"); add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000); + if(use_irc) + do_init_irc(); do_init_atcommand(); do_init_battle(); do_init_instance(); === src/map/mob.c ================================================================== --- src/map/mob.c (revision 14212) +++ src/map/mob.c (local) @@ -32,6 +32,7 @@ #include "script.h" #include "atcommand.h" #include "date.h" +#include "irc.h" #include "quest.h" #include @@ -2318,6 +2319,9 @@ mexp = (unsigned int)cap_value(exp, 1, UINT_MAX); + if(use_irc && irc_announce_mvp_flag) + irc_announce_mvp(mvp_sd,md); + clif_mvp_effect(mvp_sd); clif_mvp_exp(mvp_sd,mexp); pc_gainexp(mvp_sd, &md->bl, mexp,0); === src/map/script.c ================================================================== --- src/map/script.c (revision 14212) +++ src/map/script.c (local) @@ -43,6 +43,7 @@ #include "atcommand.h" #include "log.h" #include "unit.h" +#include "irc.h" #include "pet.h" #include "mail.h" #include "script.h" @@ -4463,6 +4464,8 @@ return 0; pc_jobchange(sd, job, upper); + if(use_irc && irc_announce_jobchange_flag) + irc_announce_jobchange(sd); } return 0; === src/map/vending.c ================================================================== --- src/map/vending.c (revision 14212) +++ src/map/vending.c (local) @@ -16,6 +16,8 @@ #include "battle.h" #include "log.h" +#include "irc.h" + #include #include @@ -29,6 +31,9 @@ sd->vender_id = 0; clif_closevendingboard(&sd->bl,0); + + if( use_irc && irc_announce_shop_flag ) + irc_announce_shop(sd,0); } /*========================================== @@ -293,4 +298,7 @@ pc_stop_walking(sd,1); clif_openvending(sd,sd->vender_id,sd->vending); clif_showvendingboard(&sd->bl,message,0); + + if( use_irc && irc_announce_shop_flag ) + irc_announce_shop(sd,1); } === src/map/irc.c ================================================================== --- src/map/irc.c (revision 14212) +++ src/map/irc.c (local) @@ -0,0 +1,535 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#include "../common/core.h" +#include "../common/socket.h" +#include "../common/malloc.h" +#include "../common/db.h" +#include "../common/timer.h" +#include "../common/strlib.h" +#include "../common/mmo.h" +#include "../common/showmsg.h" +#include "../common/version.h" +#include "../common/nullpo.h" + +#include "map.h" +#include "mob.h" +#include "pc.h" +#include "intif.h" //For GM Broadcast +#include "irc.h" + +#include +#include +#include + +// configuration +short use_irc=0; +short irc_autojoin=0; + +short irc_announce_flag=1; +short irc_announce_mvp_flag=1; +short irc_announce_jobchange_flag=1; +short irc_announce_shop_flag=1; + +char irc_nick[30]=""; +char irc_password[32]=""; +char irc_channel[32]=""; +char irc_channel_pass[32]=""; +char irc_trade_channel[32]=""; + +char irc_ip_str[128]=""; +unsigned long irc_ip=0; +unsigned short irc_port = 6667; + +// variables +int irc_fd=0; +IRC_SI *irc_si=NULL; +struct channel_data cd; +int last_cd_user=0; + +int irc_connect_timer(int tid, unsigned int tick, int id, intptr data) +{ + if(irc_si && session[irc_si->fd]) + return 0; + //Ok, this ShowInfo and printf are a little ugly, but they are meant to + //debug just how long the code freezes here. [Skotlex] + ShowInfo("(IRC) Connecting to %s... ", irc_ip_str); + irc_fd = make_connection(irc_ip,irc_port); + if(irc_fd > 0){ + ShowMessage("ok\n"); + session[irc_fd]->func_parse = irc_parse; + } else + ShowMessage("failed\n"); + return 0; +} + +void irc_announce(const char* buf) +{ + char send_string[256]; + + sprintf(send_string,"PRIVMSG %s :",irc_channel); + strcat(send_string, buf); + irc_send(send_string); +} + +void irc_announce_jobchange(struct map_session_data *sd) +{ + char send_string[256]; + + nullpo_retv(sd); + + 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); +} + +void irc_announce_shop(struct map_session_data *sd, int flag) +{ + char send_string[256]; + char mapname[16]; + int maplen = 0; + nullpo_retv(sd); + + if(flag){ + strcpy(mapname, map[sd->bl.m].name); + maplen = strcspn(mapname,"."); + mapname[maplen] = '\0'; + mapname[0]=TOUPPER(mapname[0]); + + sprintf(send_string,"PRIVMSG %s :%s has opened a shop, %s, at <%d,%d> in %s.",irc_trade_channel,sd->status.name,sd->message,sd->bl.x,sd->bl.y,mapname); + } else + sprintf(send_string,"PRIVMSG %s :%s has closed their shop.",irc_trade_channel,sd->status.name); + + irc_send(send_string); +} + +void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md) +{ + char send_string[256]; + char mapname[16]; + int maplen = 0; + + nullpo_retv(sd); + nullpo_retv(md); + + strcpy(mapname, map[md->bl.m].name); + maplen = strcspn(mapname,"."); + mapname[maplen] = '\0'; + mapname[0]=TOUPPER(mapname[0]); + + sprintf(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); + irc_send(send_string); +} + +int irc_parse(int fd) +{ + if (session[fd]->flag.eof) + { + do_close(fd); + irc_si = NULL; + add_timer(gettick() + 15000, irc_connect_timer, 0, 0); + return 0; + } + + 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) { + irc_si = (struct IRC_Session_Info*)session[fd]->session_data; + irc_si->fd = fd; + } + + if(RFIFOREST(fd) > 0) + { + send_to_parser(fd, (char*)RFIFOP(fd,0), "\n"); + RFIFOSKIP(fd,RFIFOREST(fd)); + } + return 0; +} + +int irc_keepalive_timer(int tid, unsigned int tick, int id, intptr data) +{ + char send_string[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(char *buf) +{ + int len; + int fd; + + if(!irc_si || !(fd = irc_si->fd) || !session[fd]) + return; + + 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) +{ + char source[256]; + char command[256]; + char target[256]; + char message[8192]; + char send_string[8192]; + char *source_nick=NULL; + char *source_ident=NULL; + char *source_host=NULL; + char *state_mgr=NULL; + + memset(source,'\0',256); + memset(command,'\0',256); + memset(target,'\0',256); + memset(message,'\0',8192); + memset(send_string,'\0',8192); + + sscanf(incoming_string, ":%255s %255s %255s :%4095[^\r\n]", source, command, target, message); + 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); + } + } + + 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; + 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); + sprintf(send_string, "JOIN %s %s", irc_channel, irc_channel_pass); + irc_send(send_string); + sprintf(send_string,"NAMES %s",irc_channel); + 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"); + irc_send(send_string); + if(session[fd]) + set_eof(fd); + } + break; + + case 2: + if(!strcmp(source, "PING")) + { + sprintf(send_string, "PONG %s", command); + irc_send(send_string); + } + 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 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 + { + sprintf(send_string,"%s: %s",source_nick,cmdargs); + intif_broadcast(send_string,strlen(send_string)+1,0); + sprintf(send_string,"NOTICE %s :Message Sent",source_nick); + } + irc_send(send_string); + } + else // Number of users online + if(strcmpi(cmdname,"users")==0) + { + int users = 0; + struct s_mapiterator* iter; + + iter = mapit_getallusers(); + for( mapit_first(iter); mapit_exists(iter); mapit_next(iter) ) + users++; + mapit_free(iter); + + sprintf(send_string, "PRIVMSG %s :Users Online: %d", irc_channel, users); + irc_send(send_string); + } + else // List all users online + if(strcmpi(cmdname,"who")==0) + { + int users = 0; + struct s_mapiterator* iter; + struct map_session_data* sd; + + iter = mapit_getallusers(); + for( mapit_first(iter); mapit_exists(iter); mapit_next(iter) ) + users++; + mapit_free(iter); + + if(users > 0) + { + sprintf(send_string,"NOTICE %s :%d Users Online",source_nick,users); + irc_send(send_string); + + iter = mapit_getallusers(); + for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) + { + sprintf(send_string,"NOTICE %s :Name: \"%s\"",source_nick,sd->status.name); + irc_send(send_string); + } + mapit_free(iter); + } + else + { + sprintf(send_string,"NOTICE %s :No Users Online",source_nick); + irc_send(send_string); + } + } + } + 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(); + ShowMessage("..."); + sprintf(send_string,"NAMES %s",irc_channel); + irc_send(send_string); + ShowMessage("Done\n"); + } + 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); + } + } + else // Names Reply + if((strcmpi(command,"353")==0)) + { + ShowInfo("IRC: NAMES received\n"); + parse_names_packet(incoming_string); + } + break; + } +} + +int send_to_parser(int fd, char *input,char key[2]) +{ + char *temp_string=NULL; + char *state_mgr=NULL; + int total_loops=0; + + temp_string = strtok_r(input,key,&state_mgr); + while (temp_string != NULL) + { + total_loops = total_loops+1; + irc_parse_sub(fd,temp_string); + temp_string = strtok_r(NULL,key,&state_mgr); + } + return total_loops; +} + +//NAMES Packet(353) parser +int parse_names_packet(char *str) +{ + char *tok; + char source[256]; + char numeric[10]; + char target[256]; + char channel[256]; + char names[1024]; + + memset(source,'\0',256); + memset(numeric,'\0',10); + memset(target,'\0',256); + 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) + { + sscanf(tok,":%255s %10s %255s %*1[=@] %255s :%1023[^\r\n]",source,numeric,target,channel,names); + if(strcmpi(numeric,"353")==0) + parse_names(names); + } + + return 0; +} + +//User access level prefix parser +int parse_names(char* str) +{ + //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; + } + } + + return 1; +} + +//Store user's access level +int set_access(char *nick,int newlevel) +{ + int i; + + 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; + last_cd_user++; + + return 0; +} + +//Returns users access level +int get_access(char *nick) +{ + int i; + + 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; + //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; + return 0; +} + +int irc_read_conf(char *file) +{ + FILE *fp=NULL; + char w1[256]; + char w2[256]; + char path[256]; + char row[1024]; + + memset(w1,'\0',256); + memset(w2,'\0',256); + memset(path,'\0',256); + memset(row,'\0',256); + + sprintf(path,"conf/%s",file); + + if(!(fp=fopen(path,"r"))) { + ShowError("Cannot find file: %s\n",path); + return 0; + } + + while(fgets(row, sizeof(row), fp) != NULL) + { + if(row[0]=='/' && row[1]=='/') + continue; + + sscanf(row,"%[^:]: %255[^\r\n]",w1,w2); + 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); + else if(strcmpi(w1,"irc_autojoin")==0) + irc_autojoin = atoi(w2); + else if(strcmpi(w1,"irc_channel")==0) + strcpy(irc_channel,w2); + else if(strcmpi(w1,"irc_channel_pass")==0) + strcpy(irc_channel_pass,w2); + else if(strcmpi(w1,"irc_trade_channel")==0) + strcpy(irc_trade_channel,w2); + else if(strcmpi(w1,"irc_nick")==0) + strcpy(irc_nick,w2); + else if(strcmpi(w1,"irc_pass")==0) { + if(strcmpi(w2,"0")!=0) + strcpy(irc_password,w2); + } + } + + ShowInfo("IRC Config read successfully\n"); + + 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) +{ + +} Property changes on: src/map/irc.c ___________________________________________________________________ Name: svn:eol-style +native === src/map/irc.h ================================================================== --- src/map/irc.h (revision 14212) +++ src/map/irc.h (local) @@ -0,0 +1,64 @@ +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL +// For more information, see LICENCE in the main folder + +#ifndef _IRC_H_ +#define _IRC_H_ + +//#include "map.h" +struct map_session_data; + +// IRC .conf file [Zido] +#define IRC_CONF "irc_athena.conf" + +// IRC Access levels [Zido] +#define ACCESS_OWNER 5 +#define ACCESS_SOP 4 +#define ACCESS_OP 3 +#define ACCESS_HOP 2 +#define ACCESS_VOICE 1 +#define ACCESS_NORM 0 + +#define MAX_CHANNEL_USERS 500 + +extern short use_irc; + +extern short irc_announce_flag; +extern short irc_announce_mvp_flag; +extern short irc_announce_shop_flag; +extern short irc_announce_jobchange_flag; + +void irc_announce(const char* buf); +void irc_announce_jobchange(struct map_session_data *sd); +void irc_announce_shop(struct map_session_data *sd,int flag); +void irc_announce_mvp(struct map_session_data *sd, struct mob_data *md); + +int irc_parse(int fd); +void do_final_irc(void); +void do_init_irc(void); +void irc_send(char *buf); +void irc_parse_sub(int fd, char *incoming_string); +int send_to_parser(int fd, char *input,char key[2]); +struct IRC_Session_Info { + int state; + int fd; + char username[30]; + char password[33]; +}; + +typedef struct IRC_Session_Info IRC_SI; + +struct channel_data { + struct { + char name[256]; + int level; + }user[MAX_CHANNEL_USERS]; +}; + +int parse_names_packet(char *str); // [Zido] +int parse_names(char *str); // [Zido] +int set_access(char *nick,int level); // [Zido] +int get_access(char *nick); // [Zido] +int irc_rmnames(void); // [Zido] +int irc_read_conf(char *file); // [Zido] + +#endif /* _IRC_H_ */ Property changes on: src/map/irc.h ___________________________________________________________________ Name: svn:eol-style +native === vcproj-6/map-server_sql.dsp ================================================================== --- vcproj-6/map-server_sql.dsp (revision 14212) +++ vcproj-6/map-server_sql.dsp (local) @@ -279,6 +279,14 @@ # End Source File # Begin Source File +SOURCE=..\src\map\irc.c +# End Source File +# Begin Source File + +SOURCE=..\src\map\irc.h +# End Source File +# Begin Source File + SOURCE=..\src\map\itemdb.c # End Source File # Begin Source File === vcproj-6/map-server_txt.dsp ================================================================== --- vcproj-6/map-server_txt.dsp (revision 14212) +++ vcproj-6/map-server_txt.dsp (local) @@ -235,6 +235,10 @@ # End Source File # Begin Source File +SOURCE=..\src\map\irc.c +# End Source File +# Begin Source File + SOURCE=..\src\map\itemdb.c # End Source File # Begin Source File @@ -359,6 +363,10 @@ # End Source File # Begin Source File +SOURCE=..\src\map\irc.h +# End Source File +# Begin Source File + SOURCE=..\src\map\itemdb.h # End Source File # Begin Source File === vcproj-7.1/map-server_sql.vcproj ================================================================== --- vcproj-7.1/map-server_sql.vcproj (revision 14212) +++ vcproj-7.1/map-server_sql.vcproj (local) @@ -203,6 +203,12 @@ RelativePath="..\src\map\intif.h"> + + + + + + + + + + + + === vcproj-8/map-server_txt.vcproj ================================================================== --- vcproj-8/map-server_txt.vcproj (revision 14212) +++ vcproj-8/map-server_txt.vcproj (local) @@ -291,6 +291,14 @@ > + + + + === vcproj-9/map-server_sql.vcproj ================================================================== --- vcproj-9/map-server_sql.vcproj (revision 14212) +++ vcproj-9/map-server_sql.vcproj (local) @@ -423,6 +423,14 @@ > + + + + === vcproj-9/map-server_txt.vcproj ================================================================== --- vcproj-9/map-server_txt.vcproj (revision 14212) +++ vcproj-9/map-server_txt.vcproj (local) @@ -290,6 +290,14 @@ > + + + +