/* speech.c */ /* $Id: speech.c,v 1.21 1993/09/18 19:03:46 nils Exp $ */ /* Commands which involve speaking */ #include <ctype.h> #include <sys/types.h> #include "db.h" #include "interface.h" #include "net.h" #include "match.h" #include "config.h" #include "externs.h" /* generate name for object to be used when spoken */ /* for spoof protection player names always capitalized, object names */ /* always lower case */ char *spname(thing) dbref thing; { /* ack! this is evil to do. -shkoo static char buff[1024]; strcpy(buff,db[thing].name); if (Typeof(thing)==TYPE_PLAYER) buff[0]=to_upper(buff[0]); else buff[0]=to_lower(buff[0]); return(buff); */ return db[thing].name; } /* this function is a kludge for regenerating messages split by '=' */ char *reconstruct_message(arg1,arg2) char *arg1; char *arg2; { static char buf[BUFFER_LEN]; if ( arg2 ) if ( *arg2 ) { strcpy(buf, arg1?arg1:""); strcat(buf, " = "); strcat(buf, arg2); return buf; } return arg1?arg1:""; } int sp_ok(player) dbref player; { /* if ( ! Robot(player) && ! controls(player,db[player].location, TYPE_ADMIN)) { notify(player,"Sorry robots may not speak in public"); return(0); } */ return(1); } void do_say(player,arg1,arg2) dbref player; char *arg1; char *arg2; { dbref loc; char *message; char buf[BUFFER_LEN],*bf; if((loc = getloc(player)) == NOTHING) return; if (!sp_ok(player)) return; if(IS(loc,TYPE_ROOM,ROOM_AUDITORIUM) && !could_doit(player, loc, A_SLOCK)) { did_it(player, loc, A_SFAIL, "Shh.", A_OSFAIL, NULL, A_ASFAIL); return; } message = reconstruct_message(arg1, arg2); pronoun_substitute(buf,player,message,player); bf=buf+strlen(db[player].name)+1; /* notify everybody */ notify(player, tprintf("You say \"%s\"",bf)); notify_in(loc,player, tprintf("%s says \"%s\"", spname(player), bf)); } void do_whisper(player,arg1,arg2) dbref player; char *arg1; char *arg2; { dbref who; char buf[BUFFER_LEN],*bf; pronoun_substitute(buf, player, arg2, player); bf = buf + strlen(db[player].name) + 1; init_match(player, arg1, TYPE_PLAYER); match_neighbor(); match_me(); if(power(player, POW_REMOTE)) { match_absolute(); match_player(); } switch(who = match_result()) { case NOTHING: notify(player, "Whisper to whom?"); break; case AMBIGUOUS: notify(player, "I don't know who you mean!"); break; default: if ( *bf == ':' ) { notify(player, tprintf("You whisper-posed %s with \"%s %s\".", db[who].name, spname(player), bf+1)); notify(who, tprintf("%s whisper-poses: %s %s", spname(player), spname(player), bf+1)); /* wptr[0]=bf; */ /* Don't pass %0 */ did_it(player, who, NULL, 0, NULL, 0, A_AWHISPER); break; } notify(player, tprintf( "You whisper \"%s\" to %s.", bf, db[who].name)); notify(who, tprintf( "%s whispers \"%s\"", spname(player), bf)); /* wptr[0]=bf; */ /* Don't pass %0 */ did_it(player, who, NULL, 0, NULL, 0, A_AWHISPER); break; } } void do_pose(player,arg1,arg2,possessive) dbref player; char *arg1; char *arg2; int possessive; { dbref loc; char lastchar, *format; char *message; char buf[BUFFER_LEN], *bf; if((loc = getloc(player)) == NOTHING) return; if (!sp_ok(player)) return; if(IS(loc,TYPE_ROOM,ROOM_AUDITORIUM) && !could_doit(player, loc, A_SLOCK)) { did_it(player, loc, A_SFAIL, "Shhh.", A_OSFAIL, NULL, A_ASFAIL); return; } if ( possessive ) { /* get last character of player's name */ lastchar = to_lower(db[player].name[strlen(db[player].name)-1]); format = (lastchar == 's') ? "%s' %s" : "%s's %s"; } else format = "%s %s"; message = reconstruct_message(arg1, arg2); pronoun_substitute(buf,player,message,player); bf=strlen(db[player].name)+buf+1; /* notify everybody */ notify_in(loc,NOTHING, tprintf(format, spname(player), bf)); } void do_echo(player,arg1,arg2,type) dbref player; char *arg1, *arg2; int type; { char *message = reconstruct_message(arg1,arg2); char buf[1024]; if (type == 0) { pronoun_substitute(buf, player, message, player); message = buf+strlen(db[player].name) +1; } notify (player, message); } void do_emit(player,arg1,arg2,type) dbref player; char *arg1; char *arg2; int type; { dbref loc; char *message; char buf[BUFFER_LEN], *bf=buf; if ((loc = getloc(player)) == NOTHING) return; if (IS(loc, TYPE_ROOM, ROOM_AUDITORIUM) && !controls(player,loc,POW_SPOOF) && !could_doit(player, loc, A_SLOCK)) { did_it(player, loc,A_SFAIL,"Shh.",A_OSFAIL,NULL, A_ASFAIL); return; } message = reconstruct_message(arg1,arg2); if ( type == 0 ) { pronoun_substitute(buf, player, message, player); bf = buf + strlen(db[player].name) + 1; } if ( type == 1) { strcpy(buf, message); bf = buf; } if (power(player, POW_SPOOF)) { notify_in(loc,NOTHING,tprintf("%s",bf)); return; } if (can_emit_msg(player, db[player].location, bf)) notify_in(loc,NOTHING,tprintf("%s", bf)); else notify(player, "Permission denied."); } static void notify_in_zone P((dbref, char *)); void notify_in_zone (zone, msg) dbref zone; char *msg; { dbref thing; static int depth=0; if (depth > 10) return; depth++; for (thing = 0; thing < db_top; thing++) { if (db[thing].zone == zone) { notify_in_zone(thing, msg); notify_in(thing, NOTHING, msg); } } depth--; } void do_general_emit(player,arg1,arg2, emittype) dbref player; char *arg1; char *arg2; int emittype; { dbref who; char buf[BUFFER_LEN], *bf=buf; if ( emittype != 4 ) { pronoun_substitute(buf, player, arg2, player); bf = buf + strlen(db[player].name) + 1; } if ( emittype == 4 ) { bf = arg2; while ( *bf && !(bf[0]=='=') ) bf++; if (*bf) bf++; emittype=0; } init_match(player, arg1, TYPE_PLAYER); match_absolute(); match_player(); match_neighbor(); match_possession(); match_me(); match_here(); who = noisy_match_result(); if(get_room(who) != get_room(player) && !controls(player,get_room(who),POW_REMOTE) && !controls_a_zone(player, who, POW_REMOTE)) { notify(player,"Permission denied."); return; } if (IS(db[who].location,TYPE_ROOM, ROOM_AUDITORIUM) && !controls(player,db[who].location,POW_SPOOF) && !could_doit(player, db[who].location, A_SLOCK)) { did_it(player, db[who].location,A_SFAIL,"Shhh.",A_OSFAIL,NULL, A_ASFAIL); return; } switch( who ) { case NOTHING: break; default: if (emittype == 0) /* pemit */ if (can_emit_msg(player, db[who].location, bf) || controls (player, who, POW_SPOOF)) { notify(who, bf); /* wptr[0]=bf; */ /* Do not pass %0 */ did_it(player, who, NULL, 0, NULL, 0, A_APEMIT); if(!(db[player].flags&QUIET)) notify(player, tprintf("%s just saw \"%s\".", unparse_object(player, who), bf)); } else notify(player, "Permission denied"); else if (emittype == 1) { /* room. */ if (((controls(player, who, POW_REMOTE) && controls(player, who, POW_SPOOF)) || db[player].location == who) && can_emit_msg(player,who,bf)) { notify_in(who, NOTHING, bf); if(!(db[player].flags&QUIET)) notify(player, tprintf("Everything in %s saw \"%s\".", unparse_object(player, who), bf)); } else { notify(player,"Permission denied."); return; } } else if (emittype == 2) { /* oemit */ if (can_emit_msg(player, db[who].location, bf)) { notify_in(db[who].location,who,bf); } else { notify(player,"Permission denied."); return; } } else if (emittype == 3) /* zone */ if (controls(player, who, POW_REMOTE) && controls(player, who, POW_SPOOF) && controls(player, who, POW_MODIFY) && can_emit_msg(player, (dbref) -1, bf)) { if (db[who].zone == NOTHING && !(db[player].flags&QUIET)) notify(player, tprintf("%s might not be a zone... but i'll do it anyways", unparse_object(player, who))); notify_in_zone (who, bf); if(!(db[player].flags&QUIET)) notify(player, tprintf("Everything in zone %s saw \"%s\".", unparse_object(player, who), bf)); } else notify(player, "Permission denied."); } } int can_emit_msg(player, loc, msg) dbref player; dbref loc; char *msg; { char mybuf[1000]; char *s; dbref thing, save_loc; strcpy(mybuf, msg); for (s = mybuf; *s && (*s != ' '); s++); if (*s) *s = '\0'; if ((thing = lookup_player(mybuf)) != NOTHING && !string_compare(db[thing].name, mybuf)) if (!controls(player, thing, POW_SPOOF)) return 0; if ((s-mybuf)>2 && !strcmp(s-2,"'s")) { *(s-2) = '\0'; if ((thing = lookup_player(mybuf)) != NOTHING && !string_compare(db[thing].name, mybuf)) if (!controls(player, thing, POW_SPOOF)) return 0; } /* yes, get ready, another awful kludge */ save_loc = db[player].location; db[player].location = loc; init_match (player, mybuf, NOTYPE); match_perfect(); db[player].location = save_loc; thing = match_result(); if (thing != NOTHING && !controls(player, thing, POW_SPOOF)) return 0; return 1; } void do_announce(player,arg1,arg2) dbref player; char *arg1; char *arg2; { char *message; char buf[2000]; #ifndef SYSV_IO struct descriptor_data *d; #endif if ( Guest(player) || (Typeof(player)!=TYPE_PLAYER && !power(player,POW_SPOOF))) { notify(player, "You can't do that."); return; } message = reconstruct_message(arg1, arg2); if ( power(player, POW_ANNOUNCE) || payfor(player,ANNOUNCE_COST)) sprintf(buf, "%s announces \"%s\"", unparse_object(player,player), message); else { notify(player,"sorry, you don't have any credits."); return; } log_io(tprintf("%s(#%d) [owner=%s(#%d)] executes: @announce %s", db[player].name, player, db[db[player].owner].name, db[player].owner, message)); /* for(i = 0; i < db_top; i++) if ( Typeof(i) == TYPE_PLAYER && ! (db[i].flags & NO_WALLS) ) notify(i, buf); */ #ifdef SYSV_IO wall_it(buf); #else strcat(buf,"\n"); for (d = descriptor_list; d; d = d->next) { if ( d->state != CONNECTED) continue; if ( db[d->player].flags & PLAYER_NO_WALLS ) continue; queue_string(d, buf); } #endif } void do_broadcast(player,arg1,arg2) dbref player; char *arg1; char *arg2; { char *message; #ifndef SYSV_IO struct descriptor_data *d; #endif char buf[2000]; if ( ! power(player, POW_BROADCAST) ) { notify(player, "You don't have the authority to do that."); return; } message = reconstruct_message(arg1, arg2); #ifdef SYSV_IO sprintf(buf, "Official broadcast from %s: \"%s\"", db[player].name, message); #else sprintf(buf, "Official broadcast from %s: \"%s\"\n", db[player].name, message); #endif log_important(tprintf("%s(#%d) executes: @broadcast %s", db[player].name, player, message)); #ifdef SYSV_IO for(i = 0; i < db_top; i++) if ( Typeof(i) == TYPE_PLAYER ) notify(i, buf); #else for (d = descriptor_list; d; d = d->next) { if ( d->state != CONNECTED ) continue; queue_string(d, buf); } #endif } void do_gripe(player,arg1,arg2) dbref player; char *arg1; char *arg2; { dbref loc; char *message; loc = db[player].location; message = reconstruct_message(arg1, arg2); log_gripe(tprintf("GRIPE from %s(%d) in %s(%d): %s", db[player].name, player, db[loc].name, loc, message)); notify(player, "Your complaint has been duly noted."); } /* doesn't really belong here, but I couldn't figure out where else */ void do_page(player,arg1,arg2) dbref player; char *arg1; char *arg2; { dbref *x; int k; x=lookup_players(player,arg1); if(x[0]==0) return; if(!payfor(player, PAGE_COST*(x[0]))) { notify(player,"You don't have enough Credits."); return; } for(k=1;k<=x[0];k++) { if((db[x[k]].owner==x[k]) ?(!(db[x[k]].flags & PLAYER_CONNECT)) :!(*atr_get(x[k],A_APAGE) || Hearer(x[k]))) { notify(player,tprintf("%s isn't connected.",db[x[k]].name)); if(*Away(x[k])) { notify(player, tprintf("Away message from %s: %s", spname(x[k]), atr_get(x[k],A_AWAY))); } } else if(!could_doit(player,x[k],A_LPAGE)) { notify(player, tprintf("%s is not accepting pages.",spname(x[k]))); if(*atr_get(x[k],A_HAVEN)) { notify(player,tprintf("Haven message from %s: %s", spname(x[k]), atr_get(x[k],A_HAVEN))); } } else { if(!*arg2) { notify(x[k], tprintf( "You sense that %s is looking for you in %s", spname(player), db[db[player].location].name)); notify(player, tprintf("You notified %s of your location.",spname(x[k]))); /* wptr[0]=arg2; */ /* Do not pass %0 */ did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE); } else if ( *arg2 == ':' ) { notify(x[k],tprintf("%s page-poses: %s %s",spname(player),spname(player),arg2+1)); notify(player, tprintf("You page-posed %s with \"%s %s\".", db[x[k]].name,spname(player),arg2+1)); if (db[x[k]].owner != x[k]) wptr[0]=arg2; did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE); } else { notify(x[k],tprintf("%s pages: %s",spname(player),arg2)); notify(player, tprintf("You paged %s with \"%s\".", spname(x[k]),arg2)); if (db[x[k]].owner != x[k]) wptr[0]=arg2; did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE); } if (*Idle(x[k])) { notify(player, tprintf("Idle message from %s: %s", spname(x[k]), atr_get(x[k],A_IDLE))); notify(x[k], tprintf("Your Idle message has been sent to %s.", spname(player))); } } } } void do_use(player,arg1) dbref player; char *arg1; { dbref thing; thing = match_thing(player,arg1); if (thing == NOTHING) return; did_it(player, thing, A_USE, "You don't know how to use that.", A_OUSE, NULL, A_AUSE); }