diff --git a/src/sbbs3/baja.c b/src/sbbs3/baja.c index 3bfc72f538fc4a867c5580422c711787b8a7781a..fcee9a1e9665f02e06f8bfe5af8d90e3d025659f 100644 --- a/src/sbbs3/baja.c +++ b/src/sbbs3/baja.c @@ -3058,6 +3058,23 @@ void compile(char *src) fprintf(out,"%c",CS_PRIVATE_MESSAGE); continue; } + if(!stricmp(p,"MULTINODE_CHAT")) { + if(!(*arg)) + ch=1; + else { + if((l=isvar(arg))!=0) { + fputc(CS_USE_INT_VAR,out); + fwrite(&l,4,1,out); // variable + fputc(1,out); // int offset + fputc(1,out); // int length + ch=0; } // place holder + else + ch=val(src,arg); + } + + fprintf(out,"%c%c",CS_MULTINODE_CHAT,ch); + continue; } + if(!stricmp(p,"MAIL_READ")) { fprintf(out,"%c",CS_MAIL_READ); continue; } diff --git a/src/sbbs3/chat.cpp b/src/sbbs3/chat.cpp index 7758058f4c685199c6aaf88ecc105d500f64d1cd..676c024c0cd214f84ebe0807f2444efb73d777a7 100644 --- a/src/sbbs3/chat.cpp +++ b/src/sbbs3/chat.cpp @@ -44,13 +44,10 @@ const char *weekday[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Frida const char *month[]={"January","February","March","April","May","June" ,"July","August","September","October","November","December"}; -/****************************************************************************/ -/* The chat section */ -/****************************************************************************/ -void sbbs_t::chatsection() +void sbbs_t::multinodechat(int channel) { - char line[256],str[256],ch,done,no_rip_menu - ,usrs,preusrs,qusrs,*gurubuf=NULL,channel,savch,*p + char line[256],str[256],ch,done + ,usrs,preusrs,qusrs,*gurubuf=NULL,savch,*p ,pgraph[400],buf[400] ,usr[MAX_NODES],preusr[MAX_NODES],qusr[MAX_NODES]; char tmp[512]; @@ -58,6 +55,487 @@ void sbbs_t::chatsection() long i,j,k,n; node_t node; + if(channel<1 || channel>cfg.total_chans) + channel=1; + + if(!chan_access(channel-1)) + return; + if(useron.misc&(RIP|WIP) ||!(useron.misc&EXPERT)) + menu("multchat"); + getnodedat(cfg.node_num,&thisnode,1); + bputs(text[WelcomeToMultiChat]); + thisnode.aux=channel; + putnodedat(cfg.node_num,&thisnode); + bprintf(text[WelcomeToChannelN],channel,cfg.chan[channel-1]->name); + if(gurubuf) { + FREE(gurubuf); + gurubuf=NULL; } + if(cfg.chan[channel-1]->misc&CHAN_GURU && cfg.chan[channel-1]->guru<cfg.total_gurus + && chk_ar(cfg.guru[cfg.chan[channel-1]->guru]->ar,&useron)) { + sprintf(str,"%s%s.dat",cfg.ctrl_dir,cfg.guru[cfg.chan[channel-1]->guru]->code); + if((file=nopen(str,O_RDONLY))==-1) { + errormsg(WHERE,ERR_OPEN,str,O_RDONLY); + return; } + if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { + close(file); + errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1); + return; } + read(file,gurubuf,filelength(file)); + gurubuf[filelength(file)]=0; + close(file); } + usrs=0; + for(i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) { + if(i==cfg.node_num) + continue; + getnodedat(i,&node,0); + if(node.action!=NODE_MCHT || node.status!=NODE_INUSE) + continue; + if(node.aux && (node.aux&0xff)!=channel) + continue; + printnodedat(i,&node); + preusr[usrs]=usr[usrs++]=(char)i; } + preusrs=usrs; + if(gurubuf) + bprintf(text[NodeInMultiChatLocally] + ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name,channel); + bputs(text[YoureOnTheAir]); + done=0; + while(online && !done) { + checkline(); + gettimeleft(); + action=NODE_MCHT; + qusrs=usrs=0; + for(i=1;i<=cfg.sys_nodes;i++) { + if(i==cfg.node_num) + continue; + getnodedat(i,&node,0); + if(node.action!=NODE_MCHT + || (node.aux && channel && (node.aux&0xff)!=channel)) + continue; + if(node.status==NODE_QUIET) + qusr[qusrs++]=(char)i; + else if(node.status==NODE_INUSE) + usr[usrs++]=(char)i; } + if(preusrs>usrs) { + if(!usrs && channel && cfg.chan[channel-1]->misc&CHAN_GURU + && cfg.chan[channel-1]->guru<cfg.total_gurus) + bprintf(text[NodeJoinedMultiChat] + ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name + ,channel); + outchar(BEL); + for(i=0;i<preusrs;i++) { + for(j=0;j<usrs;j++) + if(preusr[i]==usr[j]) + break; + if(j==usrs) { + getnodedat(preusr[i],&node,0); + if(node.misc&NODE_ANON) + sprintf(str,"%.80s",text[UNKNOWN_USER]); + else + username(&cfg,node.useron,str); + bprintf(text[NodeLeftMultiChat] + ,preusr[i],str,channel); } } } + else if(preusrs<usrs) { + if(!preusrs && channel && cfg.chan[channel-1]->misc&CHAN_GURU + && cfg.chan[channel-1]->guru<cfg.total_gurus) + bprintf(text[NodeLeftMultiChat] + ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name + ,channel); + outchar(BEL); + for(i=0;i<usrs;i++) { + for(j=0;j<preusrs;j++) + if(usr[i]==preusr[j]) + break; + if(j==preusrs) { + getnodedat(usr[i],&node,0); + if(node.misc&NODE_ANON) + sprintf(str,"%.80s",text[UNKNOWN_USER]); + else + username(&cfg,node.useron,str); + bprintf(text[NodeJoinedMultiChat] + ,usr[i],str,channel); } } } + preusrs=usrs; + for(i=0;i<usrs;i++) + preusr[i]=usr[i]; + attr(cfg.color[clr_multichat]); + SYNC; + sys_status&=~SS_ABORT; + if((ch=inkey(0))!=0 || wordwrap[0]) { + if(ch=='/') { + bputs(text[MultiChatCommandPrompt]); + strcpy(str,"ACELWQ?*"); + if(SYSOP) + strcat(str,"0"); + i=getkeys(str,cfg.total_chans); + if(i&0x80000000L) { /* change channel */ + savch=(char)(i&~0x80000000L); + if(savch==channel) + continue; + if(!chan_access(savch-1)) + continue; + bprintf(text[WelcomeToChannelN] + ,savch,cfg.chan[savch-1]->name); + + usrs=0; + for(i=1;i<=cfg.sys_nodes;i++) { + if(i==cfg.node_num) + continue; + getnodedat(i,&node,0); + if(node.action!=NODE_MCHT + || node.status!=NODE_INUSE) + continue; + if(node.aux && (node.aux&0xff)!=savch) + continue; + printnodedat(i,&node); + if(node.aux&0x1f00) { /* password */ + bprintf(text[PasswordProtected] + ,node.misc&NODE_ANON + ? text[UNKNOWN_USER] + : username(&cfg,node.useron,tmp)); + if(!getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) + break; + if(strcmp(str,unpackchatpass(tmp,&node))) + break; + bputs(text[CorrectPassword]); } + preusr[usrs]=usr[usrs++]=(char)i; } + if(i<=cfg.sys_nodes) { /* failed password */ + bputs(text[WrongPassword]); + continue; } + if(gurubuf) { + FREE(gurubuf); + gurubuf=NULL; } + if(cfg.chan[savch-1]->misc&CHAN_GURU + && cfg.chan[savch-1]->guru<cfg.total_gurus + && chk_ar(cfg.guru[cfg.chan[savch-1]->guru]->ar,&useron + )) { + sprintf(str,"%s%s.dat",cfg.ctrl_dir + ,cfg.guru[cfg.chan[savch-1]->guru]->code); + if((file=nopen(str,O_RDONLY))==-1) { + errormsg(WHERE,ERR_OPEN,str,O_RDONLY); + break; } + if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { + close(file); + errormsg(WHERE,ERR_ALLOC,str + ,filelength(file)+1); + break; } + read(file,gurubuf,filelength(file)); + gurubuf[filelength(file)]=0; + close(file); } + preusrs=usrs; + if(gurubuf) + bprintf(text[NodeInMultiChatLocally] + ,cfg.sys_nodes+1 + ,cfg.guru[cfg.chan[savch-1]->guru]->name + ,savch); + channel=savch; + if(!usrs && cfg.chan[savch-1]->misc&CHAN_PW + && !noyes(text[PasswordProtectChanQ])) { + bputs(text[PasswordPrompt]); + if(getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) { + getnodedat(cfg.node_num,&thisnode,1); + thisnode.aux=channel; + packchatpass(str,&thisnode); } + else { + getnodedat(cfg.node_num,&thisnode,1); + thisnode.aux=channel; } } + else { + getnodedat(cfg.node_num,&thisnode,1); + thisnode.aux=channel; } + putnodedat(cfg.node_num,&thisnode); + bputs(text[YoureOnTheAir]); + if(cfg.chan[channel-1]->cost + && !(useron.exempt&FLAG('J'))) + subtract_cdt(&cfg,&useron,cfg.chan[channel-1]->cost); } + else switch(i) { /* other command */ + case '0': /* Global channel */ + if(!SYSOP) + break; + usrs=0; + for(i=1;i<=cfg.sys_nodes;i++) { + if(i==cfg.node_num) + continue; + getnodedat(i,&node,0); + if(node.action!=NODE_MCHT + || node.status!=NODE_INUSE) + continue; + printnodedat(i,&node); + preusr[usrs]=usr[usrs++]=(char)i; } + preusrs=usrs; + getnodedat(cfg.node_num,&thisnode,1); + thisnode.aux=channel=0; + putnodedat(cfg.node_num,&thisnode); + break; + case 'A': /* Action commands */ + useron.chat^=CHAT_ACTION; + bprintf("\r\nAction commands are now %s\r\n" + ,useron.chat&CHAT_ACTION + ? text[ON]:text[OFF]); + putuserrec(&cfg,useron.number,U_CHAT,8 + ,ultoa(useron.chat,str,16)); + break; + case 'C': /* List of action commands */ + CRLF; + for(i=0;i<cfg.total_chatacts;i++) { + if(cfg.chatact[i]->actset + !=cfg.chan[channel-1]->actset) + continue; + bprintf("%-*.*s",LEN_CHATACTCMD + ,LEN_CHATACTCMD,cfg.chatact[i]->cmd); + if(!((i+1)%8)) { + CRLF; } + else + bputs(" "); } + CRLF; + break; + case 'E': /* Toggle echo */ + useron.chat^=CHAT_ECHO; + bprintf(text[EchoIsNow] + ,useron.chat&CHAT_ECHO + ? text[ON]:text[OFF]); + putuserrec(&cfg,useron.number,U_CHAT,8 + ,ultoa(useron.chat,str,16)); + break; + case 'L': /* list nodes */ + CRLF; + for(i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) { + getnodedat(i,&node,0); + printnodedat(i,&node); } + CRLF; + break; + case 'W': /* page node(s) */ + j=getnodetopage(0,0); + if(!j) + break; + for(i=0;i<usrs;i++) + if(usr[i]==j) + break; + if(i>=usrs) { + bputs(text[UserNotFound]); + break; } + + bputs(text[NodeMsgPrompt]); + if(!getstr(line,66,K_LINE|K_MSG)) + break; + + sprintf(buf,text[ChatLineFmt] + ,thisnode.misc&NODE_ANON + ? text[AnonUserChatHandle] + : useron.handle + ,cfg.node_num,'*',line); + strcat(buf,crlf); + if(useron.chat&CHAT_ECHO) + bputs(buf); + putnmsg(j,buf); + break; + case 'Q': /* quit */ + done=1; + break; + case '*': + sprintf(str,"%smenu/chan.*",cfg.text_dir); + if(fexist(str)) + menu("chan"); + else { + bputs(text[ChatChanLstHdr]); + bputs(text[ChatChanLstTitles]); + if(cfg.total_chans>=10) { + bputs(" "); + bputs(text[ChatChanLstTitles]); } + CRLF; + bputs(text[ChatChanLstUnderline]); + if(cfg.total_chans>=10) { + bputs(" "); + bputs(text[ChatChanLstUnderline]); } + CRLF; + if(cfg.total_chans>=10) + j=(cfg.total_chans/2)+(cfg.total_chans&1); + else + j=cfg.total_chans; + for(i=0;i<j && !msgabort();i++) { + bprintf(text[ChatChanLstFmt],i+1 + ,cfg.chan[i]->name + ,cfg.chan[i]->cost); + if(cfg.total_chans>=10) { + k=(cfg.total_chans/2) + +i+(cfg.total_chans&1); + if(k<cfg.total_chans) { + bputs(" "); + bprintf(text[ChatChanLstFmt] + ,k+1 + ,cfg.chan[k]->name + ,cfg.chan[k]->cost); } } + CRLF; } + CRLF; } + break; + case '?': /* menu */ + menu("multchat"); + break; } } + else { + ungetkey(ch); + j=0; + pgraph[0]=0; + while(j<5) { + if(!getstr(line,66,K_WRAP|K_MSG|K_CHAT)) + break; + if(j) { + sprintf(str,text[ChatLineFmt] + ,thisnode.misc&NODE_ANON + ? text[AnonUserChatHandle] + : useron.handle + ,cfg.node_num,':',nulstr); + sprintf(tmp,"%*s",bstrlen(str),nulstr); + strcat(pgraph,tmp); } + strcat(pgraph,line); + strcat(pgraph,crlf); + if(!wordwrap[0]) + break; + j++; } + if(pgraph[0]) { + if(useron.chat&CHAT_ACTION) { + for(i=0;i<cfg.total_chatacts;i++) { + if(cfg.chatact[i]->actset + !=cfg.chan[channel-1]->actset) + continue; + sprintf(str,"%s ",cfg.chatact[i]->cmd); + if(!strnicmp(str,pgraph,strlen(str))) + break; + sprintf(str,"%.*s" + ,LEN_CHATACTCMD+2,pgraph); + str[strlen(str)-2]=0; + if(!stricmp(cfg.chatact[i]->cmd,str)) + break; } + + if(i<cfg.total_chatacts) { + p=pgraph+strlen(str); + n=atoi(p); + for(j=0;j<usrs;j++) { + getnodedat(usr[j],&node,0); + if(usrs==1) /* no need to search */ + break; + if(n) { + if(usr[j]==n) + break; + continue; } + username(&cfg,node.useron,str); + if(!strnicmp(str,p,strlen(str))) + break; + getuserrec(&cfg,node.useron,U_HANDLE + ,LEN_HANDLE,str); + if(!strnicmp(str,p,strlen(str))) + break; } + if(!usrs + && cfg.chan[channel-1]->guru<cfg.total_gurus) + strcpy(str + ,cfg.guru[cfg.chan[channel-1]->guru]->name); + else if(j>=usrs) + strcpy(str,"everyone"); + else if(node.misc&NODE_ANON) + strcpy(str,text[UNKNOWN_USER]); + else + username(&cfg,node.useron,str); + + /* Display on same node */ + bprintf(cfg.chatact[i]->out + ,thisnode.misc&NODE_ANON + ? text[UNKNOWN_USER] : useron.alias + ,str); + CRLF; + + if(usrs && j<usrs) { + /* Display to dest user */ + sprintf(buf,cfg.chatact[i]->out + ,thisnode.misc&NODE_ANON + ? text[UNKNOWN_USER] : useron.alias + ,"you"); + strcat(buf,crlf); + putnmsg(usr[j],buf); } + + + /* Display to all other users */ + sprintf(buf,cfg.chatact[i]->out + ,thisnode.misc&NODE_ANON + ? text[UNKNOWN_USER] : useron.alias + ,str); + strcat(buf,crlf); + + for(i=0;i<usrs;i++) { + if(i==j) + continue; + getnodedat(usr[i],&node,0); + putnmsg(usr[i],buf); } + for(i=0;i<qusrs;i++) { + getnodedat(qusr[i],&node,0); + putnmsg(qusr[i],buf); } + continue; } } + + sprintf(buf,text[ChatLineFmt] + ,thisnode.misc&NODE_ANON + ? text[AnonUserChatHandle] + : useron.handle + ,cfg.node_num,':',pgraph); + if(useron.chat&CHAT_ECHO) + bputs(buf); + for(i=0;i<usrs;i++) { + getnodedat(usr[i],&node,0); + putnmsg(usr[i],buf); } + for(i=0;i<qusrs;i++) { + getnodedat(qusr[i],&node,0); + putnmsg(qusr[i],buf); } + if(!usrs && channel && gurubuf + && cfg.chan[channel-1]->misc&CHAN_GURU) + guruchat(pgraph,gurubuf,cfg.chan[channel-1]->guru); + } } } + else + mswait(1); + if(sys_status&SS_ABORT) + break; } + lncntr=0; +} + +bool sbbs_t::guru_page(void) +{ + char path[MAX_PATH+1]; + char* gurubuf; + int file; + long i; + + if(!cfg.total_gurus) { + bprintf(text[SysopIsNotAvailable],"The Guru"); + return(false); + } + if(cfg.total_gurus==1 && chk_ar(cfg.guru[0]->ar,&useron)) + i=0; + else { + for(i=0;i<cfg.total_gurus;i++) + uselect(1,i,nulstr,cfg.guru[i]->name,cfg.guru[i]->ar); + i=uselect(0,0,0,0,0); + if(i<0) + return(false); + } + sprintf(path,"%s%s.dat",cfg.ctrl_dir,cfg.guru[i]->code); + if((file=nopen(path,O_RDONLY))==-1) { + errormsg(WHERE,ERR_OPEN,path,O_RDONLY); + return(false); + } + if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { + close(file); + errormsg(WHERE,ERR_ALLOC,path,filelength(file)+1); + return(false); + } + read(file,gurubuf,filelength(file)); + gurubuf[filelength(file)]=0; + close(file); + localguru(gurubuf,i); + FREE(gurubuf); + return(true); +} + +/****************************************************************************/ +/* The chat section */ +/****************************************************************************/ +void sbbs_t::chatsection() +{ + char str[256],ch,no_rip_menu; + action=NODE_CHAT; if(useron.misc&(RIP|WIP) || !(useron.misc&EXPERT)) menu("chat"); @@ -99,485 +577,25 @@ void sbbs_t::chatsection() no_rip_menu=true; break; case 'J': - if(!chan_access(0)) - break; - if(useron.misc&(RIP|WIP) ||!(useron.misc&EXPERT)) - menu("multchat"); - getnodedat(cfg.node_num,&thisnode,1); - bputs(text[WelcomeToMultiChat]); - channel=1; - thisnode.aux=1; /* default channel 1 */ - putnodedat(cfg.node_num,&thisnode); - bprintf(text[WelcomeToChannelN],channel,cfg.chan[0]->name); - if(gurubuf) { - FREE(gurubuf); - gurubuf=NULL; } - if(cfg.chan[0]->misc&CHAN_GURU && cfg.chan[0]->guru<cfg.total_gurus - && chk_ar(cfg.guru[cfg.chan[0]->guru]->ar,&useron)) { - sprintf(str,"%s%s.dat",cfg.ctrl_dir,cfg.guru[cfg.chan[0]->guru]->code); - if((file=nopen(str,O_RDONLY))==-1) { - errormsg(WHERE,ERR_OPEN,str,O_RDONLY); - break; } - if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { - close(file); - errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1); - break; } - read(file,gurubuf,filelength(file)); - gurubuf[filelength(file)]=0; - close(file); } - usrs=0; - for(i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) { - if(i==cfg.node_num) - continue; - getnodedat(i,&node,0); - if(node.action!=NODE_MCHT || node.status!=NODE_INUSE) - continue; - if(node.aux && (node.aux&0xff)!=channel) - continue; - printnodedat(i,&node); - preusr[usrs]=usr[usrs++]=(char)i; } - preusrs=usrs; - if(gurubuf) - bprintf(text[NodeInMultiChatLocally] - ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name,channel); - bputs(text[YoureOnTheAir]); - done=0; - while(online && !done) { - checkline(); - gettimeleft(); - action=NODE_MCHT; - qusrs=usrs=0; - for(i=1;i<=cfg.sys_nodes;i++) { - if(i==cfg.node_num) - continue; - getnodedat(i,&node,0); - if(node.action!=NODE_MCHT - || (node.aux && channel && (node.aux&0xff)!=channel)) - continue; - if(node.status==NODE_QUIET) - qusr[qusrs++]=(char)i; - else if(node.status==NODE_INUSE) - usr[usrs++]=(char)i; } - if(preusrs>usrs) { - if(!usrs && channel && cfg.chan[channel-1]->misc&CHAN_GURU - && cfg.chan[channel-1]->guru<cfg.total_gurus) - bprintf(text[NodeJoinedMultiChat] - ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name - ,channel); - outchar(BEL); - for(i=0;i<preusrs;i++) { - for(j=0;j<usrs;j++) - if(preusr[i]==usr[j]) - break; - if(j==usrs) { - getnodedat(preusr[i],&node,0); - if(node.misc&NODE_ANON) - sprintf(str,"%.80s",text[UNKNOWN_USER]); - else - username(&cfg,node.useron,str); - bprintf(text[NodeLeftMultiChat] - ,preusr[i],str,channel); } } } - else if(preusrs<usrs) { - if(!preusrs && channel && cfg.chan[channel-1]->misc&CHAN_GURU - && cfg.chan[channel-1]->guru<cfg.total_gurus) - bprintf(text[NodeLeftMultiChat] - ,cfg.sys_nodes+1,cfg.guru[cfg.chan[channel-1]->guru]->name - ,channel); - outchar(BEL); - for(i=0;i<usrs;i++) { - for(j=0;j<preusrs;j++) - if(usr[i]==preusr[j]) - break; - if(j==preusrs) { - getnodedat(usr[i],&node,0); - if(node.misc&NODE_ANON) - sprintf(str,"%.80s",text[UNKNOWN_USER]); - else - username(&cfg,node.useron,str); - bprintf(text[NodeJoinedMultiChat] - ,usr[i],str,channel); } } } - preusrs=usrs; - for(i=0;i<usrs;i++) - preusr[i]=usr[i]; - attr(cfg.color[clr_multichat]); - SYNC; - sys_status&=~SS_ABORT; - if((ch=inkey(0))!=0 || wordwrap[0]) { - if(ch=='/') { - bputs(text[MultiChatCommandPrompt]); - strcpy(str,"ACELWQ?*"); - if(SYSOP) - strcat(str,"0"); - i=getkeys(str,cfg.total_chans); - if(i&0x80000000L) { /* change channel */ - savch=(char)(i&~0x80000000L); - if(savch==channel) - continue; - if(!chan_access(savch-1)) - continue; - bprintf(text[WelcomeToChannelN] - ,savch,cfg.chan[savch-1]->name); - - usrs=0; - for(i=1;i<=cfg.sys_nodes;i++) { - if(i==cfg.node_num) - continue; - getnodedat(i,&node,0); - if(node.action!=NODE_MCHT - || node.status!=NODE_INUSE) - continue; - if(node.aux && (node.aux&0xff)!=savch) - continue; - printnodedat(i,&node); - if(node.aux&0x1f00) { /* password */ - bprintf(text[PasswordProtected] - ,node.misc&NODE_ANON - ? text[UNKNOWN_USER] - : username(&cfg,node.useron,tmp)); - if(!getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) - break; - if(strcmp(str,unpackchatpass(tmp,&node))) - break; - bputs(text[CorrectPassword]); } - preusr[usrs]=usr[usrs++]=(char)i; } - if(i<=cfg.sys_nodes) { /* failed password */ - bputs(text[WrongPassword]); - continue; } - if(gurubuf) { - FREE(gurubuf); - gurubuf=NULL; } - if(cfg.chan[savch-1]->misc&CHAN_GURU - && cfg.chan[savch-1]->guru<cfg.total_gurus - && chk_ar(cfg.guru[cfg.chan[savch-1]->guru]->ar,&useron - )) { - sprintf(str,"%s%s.dat",cfg.ctrl_dir - ,cfg.guru[cfg.chan[savch-1]->guru]->code); - if((file=nopen(str,O_RDONLY))==-1) { - errormsg(WHERE,ERR_OPEN,str,O_RDONLY); - break; } - if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { - close(file); - errormsg(WHERE,ERR_ALLOC,str - ,filelength(file)+1); - break; } - read(file,gurubuf,filelength(file)); - gurubuf[filelength(file)]=0; - close(file); } - preusrs=usrs; - if(gurubuf) - bprintf(text[NodeInMultiChatLocally] - ,cfg.sys_nodes+1 - ,cfg.guru[cfg.chan[savch-1]->guru]->name - ,savch); - channel=savch; - if(!usrs && cfg.chan[savch-1]->misc&CHAN_PW - && !noyes(text[PasswordProtectChanQ])) { - bputs(text[PasswordPrompt]); - if(getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) { - getnodedat(cfg.node_num,&thisnode,1); - thisnode.aux=channel; - packchatpass(str,&thisnode); } - else { - getnodedat(cfg.node_num,&thisnode,1); - thisnode.aux=channel; } } - else { - getnodedat(cfg.node_num,&thisnode,1); - thisnode.aux=channel; } - putnodedat(cfg.node_num,&thisnode); - bputs(text[YoureOnTheAir]); - if(cfg.chan[channel-1]->cost - && !(useron.exempt&FLAG('J'))) - subtract_cdt(&cfg,&useron,cfg.chan[channel-1]->cost); } - else switch(i) { /* other command */ - case '0': /* Global channel */ - if(!SYSOP) - break; - usrs=0; - for(i=1;i<=cfg.sys_nodes;i++) { - if(i==cfg.node_num) - continue; - getnodedat(i,&node,0); - if(node.action!=NODE_MCHT - || node.status!=NODE_INUSE) - continue; - printnodedat(i,&node); - preusr[usrs]=usr[usrs++]=(char)i; } - preusrs=usrs; - getnodedat(cfg.node_num,&thisnode,1); - thisnode.aux=channel=0; - putnodedat(cfg.node_num,&thisnode); - break; - case 'A': /* Action commands */ - useron.chat^=CHAT_ACTION; - bprintf("\r\nAction commands are now %s\r\n" - ,useron.chat&CHAT_ACTION - ? text[ON]:text[OFF]); - putuserrec(&cfg,useron.number,U_CHAT,8 - ,ultoa(useron.chat,str,16)); - break; - case 'C': /* List of action commands */ - CRLF; - for(i=0;i<cfg.total_chatacts;i++) { - if(cfg.chatact[i]->actset - !=cfg.chan[channel-1]->actset) - continue; - bprintf("%-*.*s",LEN_CHATACTCMD - ,LEN_CHATACTCMD,cfg.chatact[i]->cmd); - if(!((i+1)%8)) { - CRLF; } - else - bputs(" "); } - CRLF; - break; - case 'E': /* Toggle echo */ - useron.chat^=CHAT_ECHO; - bprintf(text[EchoIsNow] - ,useron.chat&CHAT_ECHO - ? text[ON]:text[OFF]); - putuserrec(&cfg,useron.number,U_CHAT,8 - ,ultoa(useron.chat,str,16)); - break; - case 'L': /* list nodes */ - CRLF; - for(i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) { - getnodedat(i,&node,0); - printnodedat(i,&node); } - CRLF; - break; - case 'W': /* page node(s) */ - j=getnodetopage(0,0); - if(!j) - break; - for(i=0;i<usrs;i++) - if(usr[i]==j) - break; - if(i>=usrs) { - bputs(text[UserNotFound]); - break; } - - bputs(text[NodeMsgPrompt]); - if(!getstr(line,66,K_LINE|K_MSG)) - break; - - sprintf(buf,text[ChatLineFmt] - ,thisnode.misc&NODE_ANON - ? text[AnonUserChatHandle] - : useron.handle - ,cfg.node_num,'*',line); - strcat(buf,crlf); - if(useron.chat&CHAT_ECHO) - bputs(buf); - putnmsg(j,buf); - break; - case 'Q': /* quit */ - done=1; - break; - case '*': - sprintf(str,"%smenu/chan.*",cfg.text_dir); - if(fexist(str)) - menu("chan"); - else { - bputs(text[ChatChanLstHdr]); - bputs(text[ChatChanLstTitles]); - if(cfg.total_chans>=10) { - bputs(" "); - bputs(text[ChatChanLstTitles]); } - CRLF; - bputs(text[ChatChanLstUnderline]); - if(cfg.total_chans>=10) { - bputs(" "); - bputs(text[ChatChanLstUnderline]); } - CRLF; - if(cfg.total_chans>=10) - j=(cfg.total_chans/2)+(cfg.total_chans&1); - else - j=cfg.total_chans; - for(i=0;i<j && !msgabort();i++) { - bprintf(text[ChatChanLstFmt],i+1 - ,cfg.chan[i]->name - ,cfg.chan[i]->cost); - if(cfg.total_chans>=10) { - k=(cfg.total_chans/2) - +i+(cfg.total_chans&1); - if(k<cfg.total_chans) { - bputs(" "); - bprintf(text[ChatChanLstFmt] - ,k+1 - ,cfg.chan[k]->name - ,cfg.chan[k]->cost); } } - CRLF; } - CRLF; } - break; - case '?': /* menu */ - menu("multchat"); - break; } } - else { - ungetkey(ch); - j=0; - pgraph[0]=0; - while(j<5) { - if(!getstr(line,66,K_WRAP|K_MSG|K_CHAT)) - break; - if(j) { - sprintf(str,text[ChatLineFmt] - ,thisnode.misc&NODE_ANON - ? text[AnonUserChatHandle] - : useron.handle - ,cfg.node_num,':',nulstr); - sprintf(tmp,"%*s",bstrlen(str),nulstr); - strcat(pgraph,tmp); } - strcat(pgraph,line); - strcat(pgraph,crlf); - if(!wordwrap[0]) - break; - j++; } - if(pgraph[0]) { - if(useron.chat&CHAT_ACTION) { - for(i=0;i<cfg.total_chatacts;i++) { - if(cfg.chatact[i]->actset - !=cfg.chan[channel-1]->actset) - continue; - sprintf(str,"%s ",cfg.chatact[i]->cmd); - if(!strnicmp(str,pgraph,strlen(str))) - break; - sprintf(str,"%.*s" - ,LEN_CHATACTCMD+2,pgraph); - str[strlen(str)-2]=0; - if(!stricmp(cfg.chatact[i]->cmd,str)) - break; } - - if(i<cfg.total_chatacts) { - p=pgraph+strlen(str); - n=atoi(p); - for(j=0;j<usrs;j++) { - getnodedat(usr[j],&node,0); - if(usrs==1) /* no need to search */ - break; - if(n) { - if(usr[j]==n) - break; - continue; } - username(&cfg,node.useron,str); - if(!strnicmp(str,p,strlen(str))) - break; - getuserrec(&cfg,node.useron,U_HANDLE - ,LEN_HANDLE,str); - if(!strnicmp(str,p,strlen(str))) - break; } - if(!usrs - && cfg.chan[channel-1]->guru<cfg.total_gurus) - strcpy(str - ,cfg.guru[cfg.chan[channel-1]->guru]->name); - else if(j>=usrs) - strcpy(str,"everyone"); - else if(node.misc&NODE_ANON) - strcpy(str,text[UNKNOWN_USER]); - else - username(&cfg,node.useron,str); - - /* Display on same node */ - bprintf(cfg.chatact[i]->out - ,thisnode.misc&NODE_ANON - ? text[UNKNOWN_USER] : useron.alias - ,str); - CRLF; - - if(usrs && j<usrs) { - /* Display to dest user */ - sprintf(buf,cfg.chatact[i]->out - ,thisnode.misc&NODE_ANON - ? text[UNKNOWN_USER] : useron.alias - ,"you"); - strcat(buf,crlf); - putnmsg(usr[j],buf); } - - - /* Display to all other users */ - sprintf(buf,cfg.chatact[i]->out - ,thisnode.misc&NODE_ANON - ? text[UNKNOWN_USER] : useron.alias - ,str); - strcat(buf,crlf); - - for(i=0;i<usrs;i++) { - if(i==j) - continue; - getnodedat(usr[i],&node,0); - putnmsg(usr[i],buf); } - for(i=0;i<qusrs;i++) { - getnodedat(qusr[i],&node,0); - putnmsg(qusr[i],buf); } - continue; } } - - sprintf(buf,text[ChatLineFmt] - ,thisnode.misc&NODE_ANON - ? text[AnonUserChatHandle] - : useron.handle - ,cfg.node_num,':',pgraph); - if(useron.chat&CHAT_ECHO) - bputs(buf); - for(i=0;i<usrs;i++) { - getnodedat(usr[i],&node,0); - putnmsg(usr[i],buf); } - for(i=0;i<qusrs;i++) { - getnodedat(qusr[i],&node,0); - putnmsg(qusr[i],buf); } - if(!usrs && channel && gurubuf - && cfg.chan[channel-1]->misc&CHAN_GURU) - guruchat(pgraph,gurubuf,cfg.chan[channel-1]->guru); - } } } - else - mswait(1); - if(sys_status&SS_ABORT) - break; } - lncntr=0; + multinodechat(); break; case 'P': /* private node-to-node chat */ privchat(); break; case 'C': no_rip_menu=1; - if(startup->options&BBS_OPT_SYSOP_AVAILABLE - || (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron)) - || useron.exempt&FLAG('C')) { - sysop_page(); - break; } - bprintf(text[SysopIsNotAvailable],cfg.sys_op); + if(sysop_page()) + break; if(cfg.total_gurus && chk_ar(cfg.guru[0]->ar,&useron)) { sprintf(str,text[ChatWithGuruInsteadQ],cfg.guru[0]->name); if(!yesno(str)) break; } else break; + /* FALL-THROUGH */ case 'T': - if(!cfg.total_gurus) { - bprintf(text[SysopIsNotAvailable],"The Guru"); - break; } - if(cfg.total_gurus==1 && chk_ar(cfg.guru[0]->ar,&useron)) - i=0; - else { - for(i=0;i<cfg.total_gurus;i++) - uselect(1,i,nulstr,cfg.guru[i]->name,cfg.guru[i]->ar); - i=uselect(0,0,0,0,0); - if(i<0) - break; } - if(gurubuf) - FREE(gurubuf); - sprintf(str,"%s%s.dat",cfg.ctrl_dir,cfg.guru[i]->code); - if((file=nopen(str,O_RDONLY))==-1) { - errormsg(WHERE,ERR_OPEN,str,O_RDONLY); - return; } - if((gurubuf=(char *)MALLOC(filelength(file)+1))==NULL) { - close(file); - errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1); - return; } - read(file,gurubuf,filelength(file)); - gurubuf[filelength(file)]=0; - close(file); - localguru(gurubuf,i); + guru_page(); no_rip_menu=1; - FREE(gurubuf); - gurubuf=NULL; break; case '?': if(useron.misc&EXPERT) @@ -585,8 +603,8 @@ void sbbs_t::chatsection() break; default: /* 'Q' or <CR> */ lncntr=0; - if(gurubuf) - FREE(gurubuf); +// if(gurubuf) +// FREE(gurubuf); return; } action=NODE_CHAT; if(!(useron.misc&EXPERT) || useron.misc&WIP @@ -595,34 +613,46 @@ void sbbs_t::chatsection() } ASYNC; bputs(text[ChatPrompt]); } - if(gurubuf) - FREE(gurubuf); +// if(gurubuf) +// FREE(gurubuf); } -void sbbs_t::sysop_page(void) +bool sbbs_t::sysop_page(void) { int i; - for(i=0;i<cfg.total_pages;i++) - if(chk_ar(cfg.page[i]->ar,&useron)) - break; - if(i<cfg.total_pages) { - bprintf(text[PagingGuru],cfg.sys_op); - external(cmdstr(cfg.page[i]->cmd,nulstr,nulstr,NULL) - ,cfg.page[i]->misc&IO_INTS ? EX_OUTL|EX_OUTR|EX_INR - : EX_OUTL); } - else if(cfg.sys_misc&SM_SHRTPAGE) { - bprintf(text[PagingGuru],cfg.sys_op); - for(i=0;i<10 && !lkbrd(1);i++) { - sbbs_beep(1000,200); - mswait(200); - outchar('.'); } - CRLF; } - else { - sys_status^=SS_SYSPAGE; - bprintf(text[SysopPageIsNow] - ,sys_status&SS_SYSPAGE ? text[ON] : text[OFF]); - nosound(); } + if(startup->options&BBS_OPT_SYSOP_AVAILABLE + || (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron)) + || useron.exempt&FLAG('C')) { + + for(i=0;i<cfg.total_pages;i++) + if(chk_ar(cfg.page[i]->ar,&useron)) + break; + if(i<cfg.total_pages) { + bprintf(text[PagingGuru],cfg.sys_op); + external(cmdstr(cfg.page[i]->cmd,nulstr,nulstr,NULL) + ,cfg.page[i]->misc&IO_INTS ? EX_OUTL|EX_OUTR|EX_INR + : EX_OUTL); } + else if(cfg.sys_misc&SM_SHRTPAGE) { + bprintf(text[PagingGuru],cfg.sys_op); + for(i=0;i<10 && !lkbrd(1);i++) { + sbbs_beep(1000,200); + mswait(200); + outchar('.'); } + CRLF; } + else { + sys_status^=SS_SYSPAGE; + bprintf(text[SysopPageIsNow] + ,sys_status&SS_SYSPAGE ? text[ON] : text[OFF]); + nosound(); + } + + return(true); + } + + bprintf(text[SysopIsNotAvailable],cfg.sys_op); + + return(false); } /****************************************************************************/ diff --git a/src/sbbs3/cmdshell.h b/src/sbbs3/cmdshell.h index e1086fa0e608cfb83c122b8dee0cdfb340306492..c20ac77c3abd198b3b19ca7ece17e5cb0df64945 100644 --- a/src/sbbs3/cmdshell.h +++ b/src/sbbs3/cmdshell.h @@ -112,6 +112,7 @@ enum { ,CS_NODE_STATUS ,CS_CMDCHAR ,CS_COMPARE_CHAR + ,CS_MULTINODE_CHAT ,CS_TWO_MORE_BYTES=0x3f /* Three byte instructions */ diff --git a/src/sbbs3/exec.cpp b/src/sbbs3/exec.cpp index f07cf8ddd38b7a12cd34a858a9d2a6fb2df350a4..fc6e8bc7693f02c02bb86064fba9ecaf8d3f3f1e 100644 --- a/src/sbbs3/exec.cpp +++ b/src/sbbs3/exec.cpp @@ -1278,6 +1278,9 @@ int sbbs_t::exec(csi_t *csi) thisnode.status=*csi->ip++; putnodedat(cfg.node_num,&thisnode); return(0); + case CS_MULTINODE_CHAT: + multinodechat(*csi->ip++); + return(0); case CS_GETSTR: csi->logic=LOGIC_TRUE; getstr(csi->str,*csi->ip++,0); diff --git a/src/sbbs3/sbbs.h b/src/sbbs3/sbbs.h index a487b04b07774b6491ef6ac69519860cbd9435bc..c9d6194be15e0dd84c6d92dc9f0ed1492ec28950 100644 --- a/src/sbbs3/sbbs.h +++ b/src/sbbs3/sbbs.h @@ -505,6 +505,7 @@ public: /* chat.cpp */ void chatsection(void); + void multinodechat(int channel=1); void nodepage(void); void nodemsg(void); int nodemsg_inside; @@ -513,7 +514,8 @@ public: void guruchat(char *line, char *guru, int gurunum); bool guruexp(char **ptrptr, char *line); void localguru(char *guru, int gurunum); - void sysop_page(void); + bool sysop_page(void); + bool guru_page(void); void privchat(bool local=false); bool chan_access(uint cnum); int getnodetopage(int all, int telegram);