# Patch name: NveidGoodies+TrivStuff # Patch version: 1.8 # Author's name: RLB # Author's email: nveid@deepfire.net # Version of PennMUSH: 1.7.2p30 # Date patch made: Wed Mar 29 03:09:22 2000 # Author is willing to support (yes/no): yes # Patch format: Context # # # This is a contributed PennMUSH patch. Its use is subject to the # same restrictions found in PennMUSH's hdrs/copyrite.h file. # # No warranty is given for this patch. It is not necessarily going # to work on your system, with any version of PennMUSH other than # the one above, etc. # # If the author given above was willing to support the patch, you # should write to the author if you have any questions or problems. Do # *NOT* send email messages to Javelin or any PennMUSH mailing list about # this patch! # # Below this line is the author's description of the patch, # followed by the patch itself. If the patch is in context diff # format, you'll probably apply it by typing: patch < patchfile # in your top-level MUSH directory, unless instructed otherwise below. # The upgrade from my last patch to this one is at(incase you have problems reverse patching the p29 one at p30) ftp://deepfire.net/pub/nveid/NveidGoodies+TrivStuff.fromlast.172p30.diff CHANGES: Changed the name of MySwitch() to ASwitch() more appriopriately named (for matching all occurences). Added MEdit() as suggested by Dave@Galactic Added in reply & @dpage Removed all of the unnecessary MEM_CHECK stuff i was doing, didn't notice mush_free handled it Brief Documentation ################### Clock() Clock is used just like lock() except for channels. So if you want to get the lock on a channel just clock(/) or just clock() will default to join lock. Adding a second argument to the clock function will work as a side effect. ASwitch() This is the same as switch(), except instead of breaking off returning just the first match. It evaluates all of teh matches it finds. Note: You need to #define GOODIES for Clock() & ASwitch() to be enabled. :) MEdit() This is like using alot of edit()'s on a string, Dave@Galactic complained about it, so i made this MEdit(,,,,,...) Force() Same as @force, but its a function, whee. force(,) Wait() Wait(,) Trigger() Trigger(/,,,...) Nesting iter()s This was written by trivian, though what David released of it had a bug in it so i fixed it. This patch was originally meant just to fix. However, since David nor Trivian were supporting any of this stuff, thought i should. We always need support. :) Anyhow, this works like normal iter except it comes with two functions to help with nested iterating. ir() & iv() ir() works as the place word its on in the iter, samething as '##' and iv() is the same as '#@'. Example: iter(1, iter(2 3 4,ir(0))) -> 2 3 4 compared to. iter(1, iter(2 3 4,##)) -> 1 1 1 the argument used with ir() & iv() represents which iter to refer.. 0 is the closest, 1 is the one above it 2 above that one.. etc.. Master Object: Alright, i'm gonna explain master objects. Some people get the wrong ideas abotu these things. First off, you declare your msater object in mush.cnf with the conf parameter 'master_object' sameway as master_room 'cept this one will represent your master object. All that carries down from this is the @verbs i guess(@attr @aattr & @oattr). So @desc, @adesc & @odesc will carry down to all objects that the master object has set. If you don't set your master object It'll just use #1's stuff. (Of course you don't have to use this, just don't define USE_MASTEROBJECT) COLNAME: And there is @cname, i see no reason to explain this. Its quite simple i believe. @cname me=[ansi(r,The Great Nveid)][ansi(hr,!)] And you need to #define USE_COLNAME to use this. Timezone stufff: time() convsecs() & convtime() can do timezone stuff alittle easier now. Basically. time() So how we usually recgonize GMT 0, whatever timezone the MUSH is in is 0, unless the MUSH is runnign off of GMT time. you can also set your &timezone me=. convsecs & convtime can be used with an how time() is as well. 'cept it'll be the 2nd arg on them instead of the first. Showzone: (this is enabled along with USE_COLNAME define) When this flag is set on a room, the name of the zone the room is in will be shown in brackets. Ex: Room without ShowZone. This is a Room! Room with ShowZone This is a Room [In a cool zone!] Note: (Nveid addition) If you define SHOWZONE_CUTZONE the 'ZONE' part of the name of a zone will be cut off. So somethin with a zone that is called somethin like 'House Zone', will just be displayed as RoomName [House] @DPAGE & REPLY: @DPAGE is sorta like what @CPAGE was on MUSE if anyone remembers. You could page a concid. Welp i did the same for penmush, 'cept called it @DPAGE as in descriptor page. And i'm allowing a reply command as well for the person at the connect screen to reply to you. @DPAGE Syntax: @DPAGE [] = The replysecs is how many secs your giving the person to reply to you. If you don't specify it, it defaults to 15. REPLY Syntax: reply [] The player slot is if multiple players have @dpage'd them. Otherwise it will just result to the last person that @dpage'd 'em. diff -c ../virgin/pennmush/src/bsd.c ./src/bsd.c *** ../virgin/pennmush/src/bsd.c Tue Mar 21 12:30:35 2000 --- ./src/bsd.c Wed Mar 29 03:08:46 2000 *************** *** 215,220 **** --- 215,223 ---- #ifdef USE_MAILER struct mail *mailp; #endif + #ifdef DPAGER + DPAGER_DATA *dpage_list; + #endif int pueblo; }; *************** *** 2189,2194 **** --- 2192,2200 ---- /* Go find where this player's messages start */ d->mailp = NULL; #endif + #ifdef DPAGER + d->dpage_list = NULL; + #endif strncpy(d->addr, addr, 100); d->addr[99] = '\0'; strncpy(d->ip, ip, 100); *************** *** 3133,3142 **** --- 3139,3203 ---- char *command; { int j; + #ifdef DPAGER + DPAGER_DATA *dp; + char *tbuf1, *tbuf2, *bp, *p, *t; + int found = 0; + dbref rplyr; + #endif + depth = 0; (d->cmds)++; + #ifdef DPAGER + if(strncasecmp(command, (char *)"REPLY", 5) == 0 && d->dpage_list != NULL ) { + tbuf1 = (char *) mush_malloc(BUFFER_LEN/2, "do_command.tbuf1"); + tbuf2 = (char *) mush_malloc(BUFFER_LEN/2, "do_command.tbuf2"); + if(!tbuf1 || !tbuf2) + panic("Out of memory"); + bp = tbuf1; + send_prefix(d); + safe_copy_str(command + 5, tbuf1, &bp,(BUFFER_LEN/2)-1); + *bp = '\0'; + for(p = tbuf1; p && *p == ' '; p++) + ; + for(t = tbuf2; p && *p != ' '; *t++ = *p++) + ; + *t = '\0'; + if(tbuf2) + /* ok.. now we're gonna see if this arg represents a name for them to reply to */ + for(dp = d->dpage_list; dp ; dp = dp->next) + if(!strcasecmp(tbuf2, Name(dp->reply_plyr))) { + found = 1; + break; + } + rplyr = (found == 1? dp->reply_plyr : d->dpage_list->reply_plyr); + /* modify tbuf2 to be the message now */ + mush_free((Malloc_t) tbuf2, "do_command.tbuf2"); + tbuf2 = (char *) mush_malloc(BUFFER_LEN/2, "do_command.tbuf2"); + bp = tbuf2; + for(p = tbuf1; p && *p == ' '; p++) + ; + if(!found) + safe_copy_str(p, tbuf2, &bp, (BUFFER_LEN/2)-1); + else { + for(; p && *p != ' '; p++) + ; + for(; p && *p == ' '; p++) + ; + safe_copy_str(p, tbuf2, &bp, (BUFFER_LEN/2)-1); + } + *bp = '\0'; + + notify(rplyr, tprintf("Descriptor %d replies with: %s", d->descriptor, tbuf2)); + queue_string(d, tprintf("You reply to %s with: %s\r\n", Name(rplyr), tbuf2)); + + mush_free((Malloc_t) tbuf2, "do_command.tbuf2"); + mush_free((Malloc_t) tbuf1, "do_command.tbuf1"); + send_suffix(d); + } else + #endif if (!strcmp(command, QUIT_COMMAND)) { return 0; } else if (!strcmp(command, LOGOUT_COMMAND)) { diff -c ../virgin/pennmush/src/cmdlocal.c ./src/cmdlocal.c *** ../virgin/pennmush/src/cmdlocal.c Wed Mar 29 02:31:07 2000 --- ./src/cmdlocal.c Fri Mar 3 00:20:54 2000 *************** *** 20,25 **** --- 20,28 ---- #include "htab.h" #include "command.h" #include "confmagic.h" + #ifdef DPAGER + #include "ddata.h" + #endif extern HASHTAB htab_reserved_aliases; void reserve_aliases _((void)); *************** *** 60,65 **** --- 63,143 ---- } #endif + #ifdef DPAGER + COMMAND(local_cmd_dpage) { /* syntax @dpage [] = */ + struct descriptor_data *d; + int pdesc, secs; + char *buf, *p, *t; + + if(do_wordcount(arg_left, ' ') > 1) { + buf = mush_malloc(BUFFER_LEN, "dpage.buf"); + t = buf; + for(p = arg_left; *p & *p == ' ' ; p++) /* may not need this, but just incase */ + ; + for(; *p && *p != ' '; *t++ = *p++) + ; + *t = '\0'; + secs = atoi(buf); + mush_free((Malloc_t) buf, "dpage.buf"); + buf = mush_malloc(BUFFER_LEN, "dpage.buf"); + t = buf; + for(; *p && *p == ' '; p++) + ; + for(; *p && *p != ' '; *t++ = *p++) + ; + *t = '\0'; + pdesc = atoi(buf); + mush_free((Malloc_t) buf, "dpage.buf"); + } else { + pdesc = atoi(arg_left); + secs = 15; + } + + for (d=descriptor_list; d; d=d->next) + if(d->descriptor == pdesc) { + if(!d->connected) + break; + else { + notify(player, "Use 'page' silly."); + return; + } + } + + if(!d) { + notify(player,"Can't find that descriptor. :P"); + return; + } + if(secs > 0) { + notify(player, tprintf("You page descriptor '%d' with(reply limit set to %d): %s", pdesc, secs, arg_right)); + queue_string(d, tprintf("Descriptor page from %s(%ds to reply): %s\r\n", Name(player), secs, arg_right)); + dpager_schedule(d, player, secs); + } else { + notify(player, tprintf("You page descriptor '%d' with: %s", pdesc, arg_right)); + queue_string(d, tprintf("Descriptor page from %s: %s\r\n", Name(player), arg_right)); + } + } + + COMMAND(local_cmd_cwho) { /* shows descriptors at connect screen */ + DESC *d; + char *buf, *bp; + time_t now; + + now = time((time_t *) 0); + + buf = (char *) mush_malloc(BUFFER_LEN,"local_cmd_cwho.buf"); + bp = buf; + + safe_str("Desc On For Idle Cmds Addr\r\n", buf, &bp); + for(d = descriptor_list; d ; d = d->next) + if(!d->connected) + safe_str(tprintf("%3d %9s %5s %4d %s\r\n", d->descriptor, time_format_1(now - d->connected_at), + time_format_2(now - d->last_time), d->cmds, d->addr), buf, &bp); + *bp = '\0'; + notify(player, buf); + mush_free((Malloc_t) buf, "local_cmd_cwho.buf"); + + } + #endif /* Called during the command init sequence. * This is where you'd put calls to add_command to insert a local *************** *** 69,74 **** --- 147,156 ---- void local_commands() { + #ifdef DPAGER + command_add("@DPAGE", CMD_T_PLAYER | CMD_T_EQSPLIT | CMD_T_NOGAGGED, WIZARD, 0, 0, NULL, local_cmd_dpage); + command_add("@CWHO", CMD_T_PLAYER, WIZARD, 0, 0, NULL, local_cmd_cwho); + #endif #ifdef EXAMPLE command_add("@SILLY", CMD_T_ANY, 0, 0, 0, switchmask("NOISY NOEVAL"), cmd_local_silly); #endif diff -c ../virgin/pennmush/src/command.c ./src/command.c *** ../virgin/pennmush/src/command.c Tue Mar 21 12:30:36 2000 --- ./src/command.c Wed Mar 29 02:37:49 2000 *************** *** 81,86 **** --- 81,89 ---- #ifdef CHAT_SYSTEM {"@CLOCK", "JOIN SPEAK MOD SEE HIDE", cmd_clock, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0, 0}, #endif + #ifdef USE_COLNAME + {"@CNAME", NULL, cmd_colname, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0, 0}, + #endif {"@DBCK", NULL, cmd_dbck, CMD_T_ANY, WIZARD, 0, 0}, {"@DECOMPILE", "DB TF FLAGS ATTRIBS", cmd_decompile, CMD_T_ANY, 0, 0, 0}, {"@DESTROY", "OVERRIDE", cmd_destroy, CMD_T_ANY, 0, 0, 0}, diff -c ../virgin/pennmush/src/conf.c ./src/conf.c *** ../virgin/pennmush/src/conf.c Tue Mar 21 12:30:38 2000 --- ./src/conf.c Wed Mar 29 02:37:49 2000 *************** *** 54,59 **** --- 54,62 ---- {"mud_name", cf_str, (int *) options.mud_name, 128, 0, "net"}, {"port", cf_int, &options.port, 32000, 0, "net"}, {"use_dns", cf_bool, &options.use_dns, 2, 0, "net"}, + #ifdef USE_MASTEROBJECT + {"master_object", cf_int, &options.master_object, 100000, 0, "cosmetic"}, + #endif {"ip_addr", cf_str, (int *) options.ip_addr, 64, 0, "net"}, {"input_database", cf_str, (int *) options.input_db, 256, 0, "files"}, {"output_database", cf_str, (int *) options.output_db, 256, 0, "files"}, *************** *** 488,493 **** --- 491,499 ---- options.warn_interval = 3600; #endif options.use_dns = 1; + #ifdef USE_MASTEROBJECT + options.master_object = 1; + #endif options.haspower_restricted = 0; options.safer_ufun = 1; strcpy(options.dump_warning_1min, "GAME: Database will be dumped in 1 minute."); diff -c ../virgin/pennmush/src/flags.c ./src/flags.c *** ../virgin/pennmush/src/flags.c Tue Mar 21 12:30:50 2000 --- ./src/flags.c Wed Mar 29 02:37:49 2000 *************** *** 163,168 **** --- 163,171 ---- {"MONITOR", 'M', TYPE_ROOM, ROOM_LISTEN, F_ANY, F_ANY}, {"Z_TEL", 'Z', TYPE_ROOM, ROOM_Z_TEL, F_ANY, F_ANY}, {"NO_TEL", 'N', TYPE_ROOM, ROOM_NO_TEL, F_ANY, F_ANY}, + #ifdef USE_COLNAME + {"SHOWZONE", 's', TYPE_ROOM, ROOM_SHOWZONE, F_ANY, F_ANY}, + #endif #ifdef UNINSPECTED_FLAG {"UNINSPECTED", 'u', TYPE_ROOM, ROOM_UNINSPECT, F_ROYAL, F_ROYAL}, #endif *************** *** 428,433 **** --- 431,441 ---- {"NO_T", "NO_TEL"}, {"Z_TE", "Z_TEL"}, {"Z_T", "Z_TEL"}, + #ifdef USE_COLNAME + {"SHOWZON", "SHOWZONE"}, + {"SHOWZO", "SHOWZONE"}, + {"SHOWZ", "SHOWZONE"}, + #endif #ifdef UNINSPECTED_FLAG {"UNINSPECT", "UNINSPECTED"}, {"UNINSPEC", "UNINSPECTED"}, diff -c ../virgin/pennmush/src/function.c ./src/function.c *** ../virgin/pennmush/src/function.c Tue Mar 21 12:30:51 2000 --- ./src/function.c Wed Mar 1 05:05:56 2000 *************** *** 134,141 **** {"CON", fun_con, 1, 1, FN_REG}, {"CONN", fun_conn, 1, 1, FN_REG}, {"CONTROLS", fun_controls, 2, 2, FN_REG}, ! {"CONVSECS", fun_convsecs, 1, 1, FN_REG}, ! {"CONVTIME", fun_convtime, 1, 1, FN_REG}, {"COR", fun_cor, 2, INT_MAX, FN_NOPARSE}, {"CREATE", fun_create, 1, 2, FN_REG}, #ifdef CREATION_TIMES --- 134,141 ---- {"CON", fun_con, 1, 1, FN_REG}, {"CONN", fun_conn, 1, 1, FN_REG}, {"CONTROLS", fun_controls, 2, 2, FN_REG}, ! {"CONVSECS", fun_convsecs, 1, 2, FN_REG}, ! {"CONVTIME", fun_convtime, 1, 2, FN_REG}, {"COR", fun_cor, 2, INT_MAX, FN_NOPARSE}, {"CREATE", fun_create, 1, 2, FN_REG}, #ifdef CREATION_TIMES *************** *** 208,213 **** --- 208,215 ---- {"ISNUM", fun_isnum, 1, 1, FN_REG}, {"ISWORD", fun_isword, 1, 1, FN_REG}, {"ITER", fun_iter, 2, 4, FN_NOPARSE}, + {"IR", fun_ir, 1, 1, FN_REG}, + {"IV", fun_iv, 1, 1, FN_REG}, {"ITEMS", fun_items, 2, 2, FN_REG}, {"LAST", fun_last, 1, 2, FN_REG}, {"LATTR", fun_lattr, 1, 1, FN_REG}, *************** *** 337,343 **** {"T", fun_t, 1, 1, FN_REG}, {"TABLE", fun_table, 1, 5, FN_REG}, {"TEL", fun_tel, 2, 2, FN_REG}, ! {"TIME", fun_time, 0, 0, FN_REG}, {"TIMESTRING", fun_timestring, 1, 2, FN_REG}, {"TRIM", fun_trim, 1, 3, FN_REG}, {"TRUNC", fun_trunc, 1, 1, FN_REG}, --- 339,345 ---- {"T", fun_t, 1, 1, FN_REG}, {"TABLE", fun_table, 1, 5, FN_REG}, {"TEL", fun_tel, 2, 2, FN_REG}, ! {"TIME", fun_time, 0, 1, FN_REG}, {"TIMESTRING", fun_timestring, 1, 2, FN_REG}, {"TRIM", fun_trim, 1, 3, FN_REG}, {"TRUNC", fun_trunc, 1, 1, FN_REG}, *************** *** 387,392 **** --- 389,397 ---- {"SQRT", fun_sqrt, 1, 1, FN_REG}, {"TAN", fun_tan, 1, 1, FN_REG}, #endif /* FLOATING_POINTS */ + {"FORCE", fun_force, 2, 2, FN_REG}, + {"TRIGGER", fun_trigger, 1, 11, FN_REG}, + {"WAIT", fun_wait, 2, 2, FN_REG}, {"HTML", fun_html, 1, 1, FN_REG}, {"TAG", fun_tag, 1, INT_MAX, FN_REG}, {"ENDTAG", fun_endtag, 1, 1, FN_REG}, diff -c ../virgin/pennmush/src/funlist.c ./src/funlist.c *** ../virgin/pennmush/src/funlist.c Tue Mar 21 12:30:52 2000 --- ./src/funlist.c Thu Mar 2 19:54:24 2000 *************** *** 1724,1729 **** --- 1724,1735 ---- } } + #define MAXITERS 2048 + + static char *iter_rep[MAXITERS]; + static int iter_place[MAXITERS]; + static int inum; + /* ARGSUSED */ FUNCTION(fun_iter) { *************** *** 1735,1741 **** char *outsep, *list; char *tbuf1, *tbuf2, *lp; char const *sp; ! int place; if (nargs >= 3) { /* We have a delimiter. We've got to parse the third arg in place */ --- 1741,1752 ---- char *outsep, *list; char *tbuf1, *tbuf2, *lp; char const *sp; ! int *place; ! ! if (inum >= MAXITERS) { ! safe_str("#-1 TOO MANY ITERS", buff, bp); ! return; ! } if (nargs >= 3) { /* We have a delimiter. We've got to parse the third arg in place */ *************** *** 1774,1796 **** mush_free((Malloc_t) list, "string"); return; } ! place = 0; while (lp) { ! if (place) safe_str(outsep, buff, bp); ! place++; ! tbuf1 = split_token(&lp, sep); tbuf2 = replace_string("##", tbuf1, args[1]); ! tbuf1 = replace_string("#@", unparse_integer(place), tbuf2); mush_free((Malloc_t) tbuf2, "replace_string.buff"); sp = tbuf1; process_expression(buff, bp, &sp, executor, caller, enactor, PE_DEFAULT, PT_DEFAULT, pe_info); mush_free((Malloc_t) tbuf1, "replace_string.buff"); } mush_free((Malloc_t) outsep, "string"); mush_free((Malloc_t) list, "string"); } /* ARGSUSED */ FUNCTION(fun_map) --- 1785,1850 ---- mush_free((Malloc_t) list, "string"); return; } ! ! inum++; ! place = &iter_place[inum]; ! *place = 0; while (lp) { ! if (*place) safe_str(outsep, buff, bp); ! (*place)++; ! iter_rep[inum] = tbuf1 = split_token(&lp, sep); tbuf2 = replace_string("##", tbuf1, args[1]); ! tbuf1 = replace_string("#@", unparse_integer(*place), tbuf2); mush_free((Malloc_t) tbuf2, "replace_string.buff"); sp = tbuf1; process_expression(buff, bp, &sp, executor, caller, enactor, PE_DEFAULT, PT_DEFAULT, pe_info); mush_free((Malloc_t) tbuf1, "replace_string.buff"); } + *place = 0; + iter_rep[inum] = NULL; + inum--; + mush_free((Malloc_t) outsep, "string"); mush_free((Malloc_t) list, "string"); } + + /* ARGSUSED */ + FUNCTION(fun_ir) + { + int i; + if (!is_integer(args[0])) { + safe_str("#-1 ARGUMENT MUST BE INTEGER", buff, bp); + return; + } + i = parse_integer(args[0]); + + if (i < 0 || i >= inum) { + safe_str("#-1 ARGUMENT OUT OF RANGE", buff, bp); + return; + } + safe_str(iter_rep[inum - i], buff, bp); + } + + /* ARGSUSED */ + FUNCTION(fun_iv) + { + int i; + + if (!is_integer(args[0])) { + safe_str("#-1 ARGUMENT MUST BE INTEGER", buff, bp); + return; + } + i = parse_integer(args[0]); + + if (i < 0 || i >= inum) { + safe_str("#-1 ARGUMENT OUT OF RANGE", buff, bp); + return; + } + safe_str(unparse_number(iter_place[inum - i]), buff, bp); + } + /* ARGSUSED */ FUNCTION(fun_map) diff -c ../virgin/pennmush/src/funlocal.c ./src/funlocal.c *** ../virgin/pennmush/src/funlocal.c Wed Mar 29 02:31:37 2000 --- ./src/funlocal.c Wed Mar 29 02:26:40 2000 *************** *** 31,36 **** --- 31,194 ---- * Example included :) */ + #ifdef GOODIES + FUNCTION(local_fun_myswitch) { + char *mbuf, *pstr, *mbp; + char const *map; + char *tbuf1; + int j; + + mbuf = mush_malloc(BUFFER_LEN, "local_fun_myswitch.mbuf"); + pstr = mush_malloc(BUFFER_LEN, "local_fun_myswitch.pstr"); + if(!pstr || !mbuf) + return; + mbp = mbuf; + map = args[0]; + process_expression(mbuf, &mbp, &map, executor, caller, enactor, + PE_DEFAULT, PT_DEFAULT, pe_info); + *mbp = '\0'; + + /* Match all */ + for(j = 1;j < (nargs - 1); j += 2) { + mbp = pstr; + map = args[j]; + process_expression(pstr, &mbp, &map, executor, caller, enactor, + PE_DEFAULT, PT_DEFAULT, pe_info); + + *mbp = '\0'; + + if(local_wild_match(pstr, mbuf)) { + tbuf1 = replace_string("#$", mbuf, args[j + 1]); + map = tbuf1; + process_expression(buff, bp, &map, executor, caller, enactor, + PE_DEFAULT, PT_DEFAULT, pe_info); + mush_free((Malloc_t) tbuf1, "replace_string.buff"); + } + } + mush_free((Malloc_t) mbuf, "local_fun_myswitch.mbuf"); + mush_free((Malloc_t) pstr, "local_fun_myswitch.pstr"); + } + + FUNCTION(local_fun_clock) { + CHAN *c = NULL; + char *p = NULL; + struct boolexp *lock_ptr = NULL; + int which_lock = 0; + + if((p = strchr(args[0], '/'))) { + *p++ = '\0'; + } else { + p = "JOIN"; + } + + switch(find_channel(args[0], &c)) { + case CMATCH_NONE: + safe_str("#-1 NO SUCH CHANNEL", buff, bp); + return; + case CMATCH_AMBIG: + safe_str("#-2 AMBIGUOUS CHANNEL MATCH", buff, bp); + return; + } + + if(!strcasecmp(p, "JOIN")) { + which_lock = CL_JOIN; + lock_ptr = ChanJoinLock(c); + } else if(!strcasecmp(p, "SPEAK")) { + which_lock = CL_SPEAK; + lock_ptr = ChanSpeakLock(c); + } else if(!strcasecmp(p, "MOD")) { + which_lock = CL_MOD; + lock_ptr = ChanModLock(c); + } else if(!strcasecmp(p, "SEE")) { + which_lock = CL_SEE; + lock_ptr = ChanSeeLock(c); + } else if(!strcasecmp(p, "HIDE")) { + which_lock = CL_HIDE; + lock_ptr = ChanHideLock(c); + } else { + safe_str("#-1 NO SUCH LOCK TYPE", buff, bp); + return; + } + + if(nargs == 2) { + #ifdef FUNCTION_SIDE_EFFECTS + if(!command_check_byname(executor, "@clock")) { + safe_str("#-1 PERMISSION DENIED", buff, bp); + return; + } + do_chan_lock(executor, args[0], args[1], which_lock); + #else + safe_str("#-1 SIDE EFFECTS DISABLED", buff, bp); + #endif + return; + } + + if(Chan_Can_Decomp(c, executor)) { + safe_str(unparse_boolexp(executor, lock_ptr, 1), buff, bp); + return; + } else { + safe_str("#-1 PERMISSION DENIED", buff, bp); + return; + } + } + + FUNCTION(fun_myedit) { + int len, j; + char *str, *f, *r, *mstr, *mbp; + + /* set first stuff */ + str = args[0]; + f = args[1]; + r = args[2]; + mstr = mush_malloc(BUFFER_LEN, "mstr"); + mbp = mstr; + + for(j = 1;j < nargs; j += 2) { + if(j != 1) { + strcpy(str, mstr); + mush_free((Malloc_t) mstr, "mstr"); + f = args[j]; + r = args[j+1]; + mstr = mush_malloc(BUFFER_LEN, "mstr"); + mbp = mstr; + } + if(!*f && !*r) { + mush_free((Malloc_t)mstr, "mstr"); + safe_str(str,buff,bp); + return; + } + if(!strcmp(f, "$")) { + /* append */ + safe_str(str, mstr, &mbp); + safe_str(r, mstr, &mbp); + } else if(!strcmp(f, "^")) { + safe_str(r, mstr, &mbp); + safe_str(str, mstr, &mbp); + } else { + len = strlen(f); + while(*str) { + if(!strncmp(str,f,len)) { + safe_str(r, mstr, &mbp); + if(len) + str += len; + else + safe_chr(*str++,mstr, &mbp); + } else safe_chr(*str++, mstr, &mbp); + } + if(!*f) + safe_str(r, str, &mbp); + } + *mbp = '\0'; + } + safe_str(mstr, buff, bp); + mush_free((Malloc_t) mstr, "mstr"); + } + + + #endif /* GOODIES */ + + + #ifdef EXAMPLE FUNCTION(local_fun_silly) { *************** *** 44,48 **** --- 202,211 ---- { #ifdef EXAMPLE function_add("SILLY", local_fun_silly, 1, 1, FN_REG); + #endif + #ifdef GOODIES + function_add("ASWITCH", local_fun_myswitch, 3, INT_MAX, FN_NOPARSE); + function_add("MEDIT", fun_myedit, 3, INT_MAX, FN_NOPARSE); + function_add("CLOCK", local_fun_clock, 1, 2, FN_REG); #endif } diff -c ../virgin/pennmush/src/funmisc.c ./src/funmisc.c *** ../virgin/pennmush/src/funmisc.c Tue Mar 21 12:30:54 2000 --- ./src/funmisc.c Wed Mar 1 05:05:56 2000 *************** *** 17,22 **** --- 17,23 ---- #include "command.h" #include "function.h" #include "confmagic.h" + #include "game.h" #ifdef WIN32 #pragma warning( disable : 4761) /* NJG: disable warning re conversion */ *************** *** 441,443 **** --- 442,481 ---- safe_str(ptrs[i], buff, bp); } } + + /* ARGSUSED */ + FUNCTION(fun_trigger) + { + char *arg[11]; + int i; + if (!command_check_byname(executor, "@trigger")) { + safe_str("#-1 PERMISSION DENIED", buff, bp); + return; + } + for(i=1;i<10;i++) { + arg[i]=args[i]; + } + arg[10]=NULL; + do_trigger(executor, args[0], arg); + } + + /* ARGSUSED */ + FUNCTION(fun_force) + { + if (!command_check_byname(executor, "@force")) { + safe_str("#-1 PERMISSION DENIED", buff, bp); + return; + } + do_force(executor, args[0], args[1]); + } + + /* ARGSUSED */ + FUNCTION(fun_wait) + { + if (!command_check_byname(executor, "@wait")) { + safe_str("#-1 PERMISSION DENIED", buff, bp); + return; + } + do_wait(executor, executor, args[0], args[1]); + } + diff -c ../virgin/pennmush/src/funtime.c ./src/funtime.c *** ../virgin/pennmush/src/funtime.c Tue Mar 21 12:30:55 2000 --- ./src/funtime.c Wed Mar 1 05:05:56 2000 *************** *** 15,26 **** extern time_t mudtime; int do_convtime _((char *str, struct tm * ttm)); /* ARGSUSED */ FUNCTION(fun_time) { char *s; ! s = (char *) ctime(&mudtime); s[strlen(s) - 1] = '\0'; if (s[8] == ' ') s[8] = '0'; --- 15,47 ---- extern time_t mudtime; int do_convtime _((char *str, struct tm * ttm)); + time_t tz_charadj(string) + char *string; + { + ATTR *a; + dbref who; + if (is_dbref(string)) { + who = parse_dbref(string); + a = atr_get(who, "TIMEZONE"); + if (a) { + return parse_integer(uncompress(a->value)) * 3600; + } + } else if (is_integer(string)) { + return parse_integer(string) * 3600; + } + return 0; + } + + /* ARGSUSED */ FUNCTION(fun_time) { char *s; + time_t tt; ! tt = mudtime + ((nargs == 1) ? tz_charadj(args[0]) : 0); ! ! s = (char *) ctime(&tt); s[strlen(s) - 1] = '\0'; if (s[8] == ' ') s[8] = '0'; *************** *** 45,51 **** safe_str(e_int, buff, bp); return; } ! tt = parse_integer(args[0]); if (tt < 0) { safe_str("#-1 ARGUMENT MUST BE POSITIVE", buff, bp); return; --- 66,72 ---- safe_str(e_int, buff, bp); return; } ! tt = parse_integer(args[0]) + ((nargs == 2) ? tz_charadj(args[1]) : 0); if (tt < 0) { safe_str("#-1 ARGUMENT MUST BE POSITIVE", buff, bp); return; *************** *** 199,207 **** if (do_convtime(args[0], &ttm)) { #ifdef SUN_OS ! safe_str(unparse_integer(timelocal(&ttm)), buff, bp); ! #else ! safe_str(unparse_integer(mktime(&ttm)), buff, bp); #endif /* SUN_OS */ } else { safe_str("-1", buff, bp); --- 220,228 ---- if (do_convtime(args[0], &ttm)) { #ifdef SUN_OS ! safe_str(unparse_integer(timelocal(&ttm) - ((nargs == 2) ? tz_charadj(args[1]) : 0)), buff, bp); ! #else ! safe_str(unparse_integer(mktime(&ttm) - ((nargs == 2) ? tz_charadj(args[1]) : 0)), buff, bp); #endif /* SUN_OS */ } else { safe_str("-1", buff, bp); diff -c ../virgin/pennmush/src/local.c ./src/local.c *** ../virgin/pennmush/src/local.c Wed Mar 29 02:31:47 2000 --- ./src/local.c Wed Mar 29 03:09:56 2000 *************** *** 21,33 **** --- 21,72 ---- #include "command.h" #include "confmagic.h" + #ifdef DPAGER + #include "ddata.h" + + void dpager_schedule(DESC *, dbref, int); + static int dpage_schedules; + void dpage_check(void); + #endif /* DPAGER */ + extern HASHTAB htab_reserved_aliases; + #ifdef DPAGER + void dpager_schedule(struct descriptor_data *d, dbref plyr, int wait) { + DPAGER_DATA *dp, *pdp; + time_t expire; + + expire = time((time_t *) 0); + expire += wait; + + for(dp = d->dpage_list; dp && dp->reply_plyr != plyr;pdp = dp, dp = dp->next) + ; + if(dp != NULL) { /* refresh expire & put 'em at the front */ + pdp->next = dp->next + dp->expire = expire; + dp->next = d->dpage_list + d->dpage_list = dp; + return; + } + + dp = (DPAGER_DATA *) malloc(sizeof(DPAGER_DATA)); + + if(!dp) + panic("Out of memory"); + dp->reply_plyr = plyr; + dp->expire = expire; + dp->next = d->dpage_list; + d->dpage_list = dp; + dpage_schedules++; + } + #endif + /* Called after all MUSH init is done. */ void local_startup() { + dpage_schedules = 0; } /* Called when the database will be saved *************** *** 56,61 **** --- 95,124 ---- void local_timer() { + #ifdef DPAGER + struct descriptor_data *d; + DPAGER_DATA *dp, *pd; + time_t now; + now = time((time_t *) 0); + + if(dpage_schedules > 0) /* No need to do all of this crapp if we have no one to check for */ + for(d = descriptor_list; d ; d = d->next) + if(d->dpage_list) { + if(d->dpage_list->expire == now) { + dp = d->dpage_list->next; + free(d->dpage_list); + d->dpage_list = dp; + dpage_schedules--; + } else { + for(dp = d->dpage_list, pd = d->dpage_list; dp; pd = dp, dp = dp->next) + if(dp->expire == now) { + pd->next = dp->next; + free(dp); + dpage_schedules--; + } + } + } + #endif } #ifdef LOCAL_DATA diff -c ../virgin/pennmush/src/look.c ./src/look.c *** ../virgin/pennmush/src/look.c Tue Mar 21 12:31:00 2000 --- ./src/look.c Wed Mar 29 02:37:50 2000 *************** *** 178,184 **** for (; thing != NOTHING; thing = Next(thing)) { if (Name(thing) && !DarkLegal(thing) && (!Dark(loc) || Light(thing))) { ! strcpy(pbuff, Name(thing)); if ((p = strchr(pbuff, ';'))) *p = '\0'; p = nbuf; --- 178,184 ---- for (; thing != NOTHING; thing = Next(thing)) { if (Name(thing) && !DarkLegal(thing) && (!Dark(loc) || Light(thing))) { ! strcpy(pbuff, colname(thing, 0)); if ((p = strchr(pbuff, ';'))) *p = '\0'; p = nbuf; *************** *** 204,210 **** else { safe_str(" leads to ", tbuf1, &s1); if (Name(Location(thing))) ! safe_str(Name(Location(thing)), tbuf1, &s1); safe_chr('.', tbuf1, &s1); } *s1 = '\0'; --- 204,210 ---- else { safe_str(" leads to ", tbuf1, &s1); if (Name(Location(thing))) ! safe_str(colname(Location(thing), 0), tbuf1, &s1); safe_chr('.', tbuf1, &s1); } *s1 = '\0'; diff -c ../virgin/pennmush/src/predicat.c ./src/predicat.c *** ../virgin/pennmush/src/predicat.c Tue Mar 21 12:31:07 2000 --- ./src/predicat.c Wed Mar 1 05:05:56 2000 *************** *** 178,183 **** --- 178,187 ---- int j; char *preserve[10]; int need_pres = 0; + #ifdef USE_MASTEROBJECT + char tbuf[BUFFER_LEN]; + int oldhalt; + #endif loc = (loc == NOTHING) ? Location(player) : loc; *************** *** 199,204 **** --- 203,228 ---- PE_DEFAULT, PT_DEFAULT, NULL); *bp = '\0'; notify_by(thing, player, buff); + #ifdef USE_MASTEROBJECT + d = atr_get(MASTER_OBJECT, what); + if (d) { + oldhalt = Halted(thing); + Flags(thing) &= ~HALT; + if (!need_pres) { + need_pres = 1; + save_global_regs("did_it_save", preserve); + } + asave = safe_uncompress(d->value); + ap = asave; + bp = buff; + process_expression(buff, &bp, &ap, thing, player, player, + PE_DEFAULT, PT_DEFAULT, NULL); + *bp = '\0'; + notify_by(thing, player, buff); + free((Malloc_t) asave); + Flags(thing) |= oldhalt; + } + #endif free((Malloc_t) asave); } else if (def && *def) notify_by(thing, player, def); *************** *** 230,235 **** --- 254,283 ---- tprintf("%s %s", Name(player), odef)); } } + #ifdef USE_MASTEROBJECT + d = atr_get(MASTER_OBJECT, owhat); + if (d) { + oldhalt = Halted(thing); + Flags(thing) &= ~HALT; + if (!need_pres) { + need_pres = 1; + save_global_regs("did_it_save", preserve); + } + asave = safe_uncompress(d->value); + ap = asave; + bp = buff; + safe_str(Name(player), buff, &bp); + safe_chr(' ', buff, &bp); + sp = bp; + process_expression(buff, &bp, &ap, thing, player, player, + PE_DEFAULT, PT_DEFAULT, NULL); + *bp = '\0'; + if (bp != sp) + notify_except2(Contents(loc), player, thing, buff); + free((Malloc_t) asave); + Flags(thing) |= oldhalt; + } + #endif } } } *************** *** 240,245 **** --- 288,301 ---- rnxt[j] = NULL; } charge_action(player, thing, awhat); + #ifdef USE_MASTEROBJECT + if ((d = atr_get(MASTER_OBJECT, awhat))) { + if (!Halted(thing)) { + strcpy(tbuf, uncompress(d->value)); + parse_que(thing, tbuf, player); + } + } + #endif } dbref diff -c ../virgin/pennmush/src/set.c ./src/set.c *** ../virgin/pennmush/src/set.c Tue Mar 21 12:31:11 2000 --- ./src/set.c Wed Mar 1 05:05:56 2000 *************** *** 150,155 **** --- 150,159 ---- } delete_player(thing, NULL); SET(Name(thing), newname); + #ifdef USE_COLNAME + /* Make sure the COLNAME attr is deleted. */ + atr_clr(thing, "COLNAME", thing); + #endif add_player(thing, NULL); if (USE_RWHO) rwhocli_userlogin(tbuf1, newname, time((time_t *) 0)); *************** *** 164,169 **** --- 168,177 ---- /* everything ok, change the name */ SET(Name(thing), newname); + #ifdef USE_COLNAME + /* Make sure the COLNAME attr is deleted. */ + atr_clr(thing, "COLNAME", thing); + #endif notify(player, "Name set."); } } diff -c ../virgin/pennmush/src/unparse.c ./src/unparse.c *** ../virgin/pennmush/src/unparse.c Tue Mar 21 12:31:17 2000 --- ./src/unparse.c Wed Mar 1 05:05:56 2000 *************** *** 85,91 **** return "*HOME*"; default: Access(loc); ! strcpy(tbuf1, Name(loc)); if (IsExit(loc) && obey_myopic) { if ((p = strchr(tbuf1, ';'))) *p = '\0'; --- 85,91 ---- return "*HOME*"; default: Access(loc); ! strcpy(tbuf1, colname(loc,1)); if (IsExit(loc) && obey_myopic) { if ((p = strchr(tbuf1, ';'))) *p = '\0'; diff -c ../virgin/pennmush/src/utils.c ./src/utils.c *** ../virgin/pennmush/src/utils.c Tue Mar 21 12:31:18 2000 --- ./src/utils.c Fri Mar 3 00:22:00 2000 *************** *** 1,4 **** ! /* utils.c */ #include "copyrite.h" #include "config.h" --- 1,4 ---- ! #include "copyrite.h" #include "config.h" *************** *** 29,35 **** #include "mushdb.h" #include "mymalloc.h" #include "confmagic.h" ! extern ATTR *atr_get _((dbref thing, const char *atr)); extern char *upcasestr _((char *s)); --- 29,36 ---- #include "mushdb.h" #include "mymalloc.h" #include "confmagic.h" ! #include "command.h" ! #include "ansi.h" extern ATTR *atr_get _((dbref thing, const char *atr)); extern char *upcasestr _((char *s)); *************** *** 294,296 **** --- 295,420 ---- } return n; } + + #ifdef USE_COLNAME + const char * + colname(thing, showzone) + dbref thing; + int showzone; + { + ATTR *a; + static char buf[BUFFER_LEN]; + #ifdef SHOWZONE_CUTZONE + char *buf2, *bp; + char *q, *t, *r; + #endif + char *p; + + memset(buf, '\0', BUFFER_LEN); + #ifdef SHOWZONE_CUTZONE + buf2 = (char *) mush_malloc(BUFFER_LEN/2,"colname_buf2"); + if(!buf2) + panic("Out of memory"); + bp = buf2; + #endif + a = atr_get_noparent(thing, "COLNAME"); + if (!a) + sprintf(buf, "%s%s%s", ANSI_HILITE, Name(thing), ANSI_NORMAL); + else + strcpy(buf, uncompress(a->value)); + if (showzone && IS(thing, TYPE_ROOM, ROOM_SHOWZONE) && GoodObject(Zone(thing))) { + p=buf+strlen(buf); + a = atr_get_noparent(Zone(thing), "COLNAME"); + if (!a) { + #ifdef SHOWZONE_CUTZONE + if(4 < strlen(Name(Zone(thing)))) { + safe_str(ANSI_HILITE, buf2, &bp); + safe_chr('[', buf2, &bp); + safe_str(Name(Zone(thing)), buf2, &bp); + q = NULL; + t = buf2 + strlen(buf2) - 4; + r = buf2; + do { + if(strncasecmp(r, "ZONE", 4) == 0) { + q = r; + break; + } + r++; + } while(r <= t); + while(*q && (*(q - 1) == ' ')) + q--; + if(*q) + bp = q; + safe_chr(']', buf2, &bp); + safe_str(ANSI_NORMAL, buf2, &bp); + *bp = '\0'; + sprintf(p," %s", buf2); + } else + #endif + sprintf(p, " [%s%s%s]", ANSI_HILITE, Name(Zone(thing)), ANSI_NORMAL); + } else + sprintf(p, " [%s]", uncompress(a->value)); + } + + #ifdef SHOWZONE_CUTZONE + mush_free((Malloc_t) buf2, "colname_buf2"); + #endif + return buf; + } + + COMMAND(cmd_colname) { + dbref target; + char *p; + char *buff; + char *nbuff; + char *t; + + + target=noisy_match_result(player, arg_left, NOTYPE, MAT_EVERYTHING | MAT_ME | MAT_HERE); + if (target == NOTHING) + return; + + if (!controls(player, target)) { + notify(player, "Permission denied."); + return; + } + + buff = (char *) mush_malloc(BUFFER_LEN, "cmd_colname_buff"); + nbuff = (char *) mush_malloc(BUFFER_LEN, "cmd_colname_nbuff"); + if(!buff || !nbuff) + return; + + if (!arg_right || !*arg_right) { + atr_clr(target, "COLNAME", GOD); + notify(player, "Colname cleared."); + } else { + t=buff; + p=arg_right; + while (*p) { + if (*p == ESC_CHAR) + while (*p && *p++ != 'm') ; + else + *t++=*p++; + } + *t='\0'; + strcpy(nbuff, Name(target)); + if (Typeof(target) == TYPE_EXIT) { + t=index(nbuff, ';'); + if (t) + *t='\0'; + } + if (!strstr(buff, nbuff)) + notify(player, tprintf("New name \"%s\" doesn't contain old name \"%s\".",buff,Name(target))); + else { + atr_add(target, "COLNAME", arg_right, GOD, AF_NOPROG | AF_MDARK | AF_WIZARD | AF_PRIVATE); + notify(player, "Colname set."); + } + } + + mush_free((Malloc_t)buff, "cmd_colname_buff"); + mush_free((Malloc_t)nbuff, "cmd_colname_nbuff"); + return; + } + + #endif + diff -c ../virgin/pennmush/hdrs/atr_tab.h ./hdrs/atr_tab.h *** ../virgin/pennmush/hdrs/atr_tab.h Tue Mar 21 12:30:12 2000 --- ./hdrs/atr_tab.h Wed Mar 1 05:05:56 2000 *************** *** 36,41 **** --- 36,44 ---- {(char *) "AUSE", AF_NOPROG, NULL, 0}, {(char *) "AWAY", AF_NOPROG, NULL, 0}, {(char *) "CHARGES", AF_NOPROG, NULL, 0}, + #ifdef USE_COLNAME + {(char *) "COLNAME", AF_NOPROG | AF_MDARK | AF_WIZARD | AF_PRIVATE, NULL, 0}, + #endif {(char *) "COMMENT", AF_NOPROG | AF_MDARK | AF_WIZARD, NULL, 0}, {(char *) "CONFORMAT", AF_NOPROG, NULL, 0}, {(char *) "COST", AF_NOPROG, NULL, 0}, diff -c ../virgin/pennmush/hdrs/conf.h ./hdrs/conf.h *** ../virgin/pennmush/hdrs/conf.h Tue Mar 21 12:30:16 2000 --- ./hdrs/conf.h Wed Mar 29 02:37:49 2000 *************** *** 182,187 **** --- 182,190 ---- #endif int base_room; int use_dns; + #ifdef USE_MASTEROBJECT + int master_object; + #endif int haspower_restricted; int safer_ufun; char dump_warning_1min[256]; *************** *** 282,287 **** --- 285,293 ---- (Wizard(p) && (g->viewperms & CGP_WIZARD)) || \ (Hasprivs(p) && (g->viewperms & CGP_ADMIN))) + #ifdef USE_MASTEROBJECT + #define MASTER_OBJECT (options.master_object) + #endif #define DUMP_INTERVAL (options.dump_interval) #define DUMP_NOFORK_MESSAGE (options.dump_message) diff -c ../virgin/pennmush/hdrs/externs.h ./hdrs/externs.h *** ../virgin/pennmush/hdrs/externs.h Tue Mar 21 12:30:18 2000 --- ./hdrs/externs.h Wed Mar 1 20:23:24 2000 *************** *** 410,415 **** --- 410,423 ---- void local_data_clone _((dbref clone, dbref source)); void local_data_free _((dbref object)); #endif + #ifdef DPAGER + typedef struct dpage_reply_data_t { + dbref reply_plyr; + time_t expire; + struct dpage_reply_data_t *next; + } DPAGER_DATA; + #endif + /* rwho.c */ int rwhocli_setup _((const char *server, const char *serverpw, const char *myname, const char *comment)); *************** *** 421,426 **** --- 429,440 ---- /* funlist.c */ void do_gensort _((char **s, int n, int sort_type)); + + #ifdef USE_COLNAME + const char *colname _((dbref thing, int showzone)); + #else + #define colname(x,y) Name(x) + #endif /* This is from sig.c, but put at the end because it confuses indent */ typedef diff -c ../virgin/pennmush/hdrs/flags.h ./hdrs/flags.h *** ../virgin/pennmush/hdrs/flags.h Tue Mar 21 12:30:19 2000 --- ./hdrs/flags.h Wed Mar 1 05:05:56 2000 *************** *** 162,167 **** --- 162,172 ---- #endif + #ifdef USE_COLNAME + #define ROOM_SHOWZONE 0x4000000 + #endif + + /*-------------------------------------------------------------------------- * Exit flags */ *** /dev/null Sat Nov 27 07:16:32 1999 --- ./hdrs/ddata.h Wed Mar 1 21:57:40 2000 *************** *** 0 **** --- 1,46 ---- + struct text_block { + int nchars; + struct text_block *nxt; + char *start; + char *buf; + }; + struct text_queue { + struct text_block *head; + struct text_block **tail; + }; + struct descriptor_data { + int descriptor; + int connected; + char addr[101]; + char ip[101]; + dbref player; + char *output_prefix; + char *output_suffix; + int output_size; + struct text_queue output; + struct text_queue input; + char *raw_input; + char *raw_input_at; + long connected_at; + long last_time; + int quota; + int cmds; + int hide; + char doing[DOING_LEN]; + struct descriptor_data *next; + struct descriptor_data *prev; + #ifdef USE_MAILER + struct mail *mailp; + #endif + #ifdef DPAGER + DPAGER_DATA *dpage_list; + #endif + int pueblo; + }; + extern struct descriptor_data *descriptor_list; + + #define DESC_ITER_CONN(d) \ + for(d = descriptor_list;(d);d=(d)->next) \ + if((d)->connected) + #define Hidden(d) ((d->hide == 1) && Can_Hide(d->player)) +