[PENNMUSH-ANNOUNCE] 1.7.7-patch21
dunemush at tala.mede.uic.edu
dunemush at tala.mede.uic.edu
Mon Sep 29 16:56:18 CDT 2003
This is patch21 to PennMUSH 1.7.7. After applying this patch, you will
have version 1.7.7p21
To apply this patch, save it to a file in your top-level MUSH directory,
and do the following:
patch -p1 < 1.7.7-patch21
make install
If you use GNU patch 2.2, you probably want the above to be 'patch -b -p1',
not just 'patch -p1'.
Unix (or cygwin) users need not worry about failed hunks in src/switchinc.c,
hdrs/switches.h, hdrs/cmds.h, or hdrs/funs.h. These files are automatically
rebuilt on compile. On the off chance they appear not to be, simply
rm them and re-run make.
Then @shutdown and restart your MUSH.
- Alan/Javelin
In this patch:
Major Changes:
* Attribute trees. Attributes may now be organized hierarchically
like files and directories in a filesystem, using the backtick (`)
character as the branch separator. Attribute access restrictions
propagate down trees. New wildcard ** is introduced to match
all attributes at all tree levels. Suggested by Tabbifli. [TAP]
Locks:
* New framework for performing lock failure activities in hardcode.
As a proof-of-concept, the attributes FOLLOW_LOCK`FAILURE,
FOLLOW_LOCK`OFAILURE, FOLLOW_LOCK`AFAILURE do what you'd expect
when set on a potential leader. Suggested by Sholevi at M*U*S*H.
Channels:
* New per-channel flags NoTitles, NoNames, and NoCemit do what you'd
expect. Set them with @chan/privs. Based on suggestion by
Saturn at M3.
* @chan/recall/quiet omits timestamps. Suggested by Vadiv at M*U*S*H.
Commands:
* 'help <wildcard-pattern>' now lists all help topics that match that
pattern. By popular request. [MUX,SW]
* @flag/letter can be used to change or clear the one-letter alias for a
flag. Suggested by Nymeria at M*U*S*H. [SW]
* @flag/list by God notes disabled flags. Suggested by Nymeria at M*U*S*H. [SW]
Functions:
* rand() now comes in a two-argument (low,high) flavor, and randword()
selects a random word from a list. The latter is aliased to
pickrand() to match Mux's name. Patch by Luke at M*U*S*H.
Minor Changes:
* Although we're Pueblo 2.50 compliant, go back to sending Pueblo 1.10
as the server version until everyone upgrades their clients so
they can handle the 2.50 string. Suggested by Shirow.
* The locate() function is no longer noisy (no longer notifies
the executor in addition to returning a value). Suggested by
Mystery8 at ST:AW.
* @lock/interact now has a higher priority than other interaction
checks, so it will work for Wizards. Suggested by Viila at M*U*S*H.
* Tweaks to facilitate a Debian package of PennMUSH. [EEH]
Fixes:
* max descriptor could get stomped in some cases. [SW]
* Removed extra struct def in hdrs/mushtype.h. Suggested by Kyle.
* Help tweak by Kevin at M*U*S*H.
* Fix to locks on players messing up their connection failure counts.
Reported by Luke at M*U*S*H.
* Fix to @entrances by Luke at M*U*S*H.
* Fix to Win32 not handling a missing minimal.db by Luke at M*U*S*H.
* The confirmation message for setting/clearing attribute flags would use
the flag name given as an argument, not neccessarily the the full name of
the flag. Reported by Vadiv at M*U*S*H. [SW]
* Fix a potential memory leak in ident.c [SW]
Prereq: 1.7.7p20
*** 1_7_7.624/Patchlevel Thu, 04 Sep 2003 17:36:31 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.22 600)
--- 1_7_7.664(w)/Patchlevel Tue, 23 Sep 2003 12:12:35 -0500 dunemush (pennmush/5_Patchlevel 1.17.1.11.1.23 600)
***************
*** 1,2 ****
Do not edit this file. It is maintained by the official PennMUSH patches.
! This is PennMUSH 1.7.7p20
--- 1,2 ----
Do not edit this file. It is maintained by the official PennMUSH patches.
! This is PennMUSH 1.7.7p21
*** 1_7_7.624/CHANGES.176 Thu, 14 Aug 2003 09:59:50 -0500 dunemush (pennmush/g/17_CHANGES 1.10.1.6.1.2.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.9.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.2 600)
--- 1_7_7.664(w)/CHANGES.176 Wed, 24 Sep 2003 11:53:01 -0500 dunemush (pennmush/g/17_CHANGES 1.10.1.6.1.2.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.9.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.1.1.2 600)
***************
*** 13,18 ****
--- 13,29 ----
==========================================================================
+ Version 1.7.6 patchlevel 14 September 23, 2003
+
+ Fixes:
+ * Fix to help @search2 by LeeLaLimaLLama at M*U*S*H.
+ * The max file descriptor could get stomped in some cases. [SW]
+ * Powers and toggles on destroyed objects are reset, as they
+ caused anomalous lsearch/haspower behavior. Report by Mordie at M*U*S*H.
+ * Changing channel privs and loading channels with objects no longer
+ permitted could cause crashes. Report by Septimus at SW RP Forum.
+
+
Version 1.7.6 patchlevel 13 August 11, 2003
Fixes:
*** 1_7_7.624/CHANGES.177 Fri, 05 Sep 2003 20:59:37 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.165 600)
--- 1_7_7.664(w)/CHANGES.177 Mon, 29 Sep 2003 16:35:25 -0500 dunemush (pennmush/g/23_CHANGES 1.48.1.184 600)
***************
*** 18,23 ****
--- 18,74 ----
==========================================================================
+ Version 1.7.7 patchlevel 21 September 23, 2003
+
+ Major Changes:
+ * Attribute trees. Attributes may now be organized hierarchically
+ like files and directories in a filesystem, using the backtick (`)
+ character as the branch separator. Attribute access restrictions
+ propagate down trees. New wildcard ** is introduced to match
+ all attributes at all tree levels. Suggested by Tabbifli. [TAP]
+ Locks:
+ * New framework for performing lock failure activities in hardcode.
+ As a proof-of-concept, the attributes FOLLOW_LOCK`FAILURE,
+ FOLLOW_LOCK`OFAILURE, FOLLOW_LOCK`AFAILURE do what you'd expect
+ when set on a potential leader. Suggested by Sholevi at M*U*S*H.
+ Channels:
+ * New per-channel flags NoTitles, NoNames, and NoCemit do what you'd
+ expect. Set them with @chan/privs. Based on suggestion by
+ Saturn at M3.
+ * @chan/recall/quiet omits timestamps. Suggested by Vadiv at M*U*S*H.
+ Commands:
+ * 'help <wildcard-pattern>' now lists all help topics that match that
+ pattern. By popular request. [MUX,SW]
+ * @flag/letter can be used to change or clear the one-letter alias for a
+ flag. Suggested by Nymeria at M*U*S*H. [SW]
+ * @flag/list by God notes disabled flags. Suggested by Nymeria at M*U*S*H. [SW]
+ Functions:
+ * rand() now comes in a two-argument (low,high) flavor, and randword()
+ selects a random word from a list. The latter is aliased to
+ pickrand() to match Mux's name. Patch by Luke at M*U*S*H.
+ Minor Changes:
+ * Although we're Pueblo 2.50 compliant, go back to sending Pueblo 1.10
+ as the server version until everyone upgrades their clients so
+ they can handle the 2.50 string. Suggested by Shirow.
+ * The locate() function is no longer noisy (no longer notifies
+ the executor in addition to returning a value). Suggested by
+ Mystery8 at ST:AW.
+ * @lock/interact now has a higher priority than other interaction
+ checks, so it will work for Wizards. Suggested by Viila at M*U*S*H.
+ * Tweaks to facilitate a Debian package of PennMUSH. [EEH]
+ Fixes:
+ * max descriptor could get stomped in some cases. [SW]
+ * Removed extra struct def in hdrs/mushtype.h. Suggested by Kyle.
+ * Help tweak by Kevin at M*U*S*H.
+ * Fix to locks on players messing up their connection failure counts.
+ Reported by Luke at M*U*S*H.
+ * Fix to @entrances by Luke at M*U*S*H.
+ * Fix to Win32 not handling a missing minimal.db by Luke at M*U*S*H.
+ * The confirmation message for setting/clearing attribute flags would use
+ the flag name given as an argument, not neccessarily the the full name of
+ the flag. Reported by Vadiv at M*U*S*H. [SW]
+ * Fix a potential memory leak in ident.c [SW]
+
Version 1.7.7 patchlevel 20 September 4, 2003
Major Changes:
*** 1_7_7.624/game/txt/hlp/penntop.hlp Sat, 31 May 2003 16:32:59 -0500 dunemush (pennmush/13_penntop.hl 1.2.1.27.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.12.1.1.1.1.1.2 600)
--- 1_7_7.664(w)/game/txt/hlp/penntop.hlp Mon, 15 Sep 2003 11:38:53 -0500 dunemush (pennmush/13_penntop.hl 1.2.1.27.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.12.1.1.1.1.1.4 600)
***************
*** 6,11 ****
--- 6,12 ----
For the list of MUSH commands, type: help commands
For the list of MUSH topics, type: help topics
For an alphabetical list of all help entries: help entries
+ For a list of entries that match a pattern: help <wildcard>
For information about PennMUSH: help code
For a list of flags: help flag list
***************
*** 227,236 ****
would.
To see the attributes that are set on you or on any of the objects you own,
! you should use the "examine" command. This will list all of the attributes
! and their contents. As this can get very spammy for any large object, you
! can also examine specific attributes by using this format:
! examine <object>/<attribute>
(continued in help attributes4)
& ATTRIBUTES4
--- 228,234 ----
would.
To see the attributes that are set on you or on any of the objects you own,
! you should use the "examine" command. See 'help examine'.
(continued in help attributes4)
& ATTRIBUTES4
***************
*** 250,256 ****
to examine and work on objects.
See also: ATTRIB-OWNERSHIP, @set, examine, @atrchown, @atrlock, hasattr()
! get(), v(), NON-STANDARD ATTRIBUTES, SETTING-ATTRIBUTES
& BEING KILLED
Getting killed is no big deal. If you are killed, you return to
--- 248,255 ----
to examine and work on objects.
See also: ATTRIB-OWNERSHIP, @set, examine, @atrchown, @atrlock, hasattr()
! get(), v(), NON-STANDARD ATTRIBUTES, SETTING-ATTRIBUTES, ATTRIBUTE TREES
!
& BEING KILLED
Getting killed is no big deal. If you are killed, you return to
***************
*** 866,872 ****
All attributes can be used in attribute locks and can be 'owned'
independent of object ownership.
! See also: ATTRIBUTES, ATTRIB-OWNERSHIP, Attribute Functions
& PARENT
& PARENTS
& OBJECT PARENTS
--- 865,872 ----
All attributes can be used in attribute locks and can be 'owned'
independent of object ownership.
! See also: ATTRIBUTES, ATTRIB-OWNERSHIP, Attribute Functions,
! ATTRIBUTE TREES
& PARENT
& PARENTS
& OBJECT PARENTS
*** 1_7_7.624/game/txt/hlp/pennfunc.hlp Fri, 05 Sep 2003 20:59:37 -0500 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.10 600)
--- 1_7_7.664(w)/game/txt/hlp/pennfunc.hlp Tue, 23 Sep 2003 11:10:53 -0500 dunemush (pennmush/16_pennfunc.h 1.2.1.50.1.1.1.1.1.2.1.7.1.8.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.9.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.13 600)
***************
*** 1359,1365 ****
These functions return a list of attributes on <object> containing
<pattern> (or matching <regexp>). <attrs> is a wildcard pattern for
! attribute names to search; if you want to search all attributes, use "*".
The list returned is similar to that returned by @grep/list
<object>/<attrs>=<pattern>
--- 1359,1365 ----
These functions return a list of attributes on <object> containing
<pattern> (or matching <regexp>). <attrs> is a wildcard pattern for
! attribute names to search.
The list returned is similar to that returned by @grep/list
<object>/<attrs>=<pattern>
***************
*** 1690,1698 ****
function on the object.
If a wildcarded attribute pattern is provided, only attribute names
! matching that pattern will be returned.
! See also: nattr()
& NATTR()
& ATTRCNT()
nattr(<object>)
--- 1690,1699 ----
function on the object.
If a wildcarded attribute pattern is provided, only attribute names
! matching that pattern will be returned. lattr() uses the same
! wildcards as examine (?, *, **).
! See also: nattr(), examine
& NATTR()
& ATTRCNT()
nattr(<object>)
***************
*** 2632,2641 ****
See "help SETQ()" for details about registers.
& RAND()
rand(<num>)
- Rand returns an integer between 0 and num-1, inclusive.
If called with an invalid argument, rand() returns an error message
beginning with #-1.
& REGEDIT()
& REGEDITALL()
& REGEDITI()
--- 2633,2655 ----
See "help SETQ()" for details about registers.
& RAND()
rand(<num>)
+ rand(<min>, <max>)
+
+ Return a random number.
+
+ The first form returns an integer between 0 and <num>-1, inclusive.
+ The second returns an integer between <min> and <max>, inclusive.
If called with an invalid argument, rand() returns an error message
beginning with #-1.
+ & RANDWORD()
+ & PICKRAND()
+ randword(<list>[, <delim>])
+
+ Returns a randomly selected element from <list>. <delim> is the list
+ delimiter: if not specified, whitespace delimits the list.
+
+ pickrand() may be an alias for randword() on some servers.
& REGEDIT()
& REGEDITALL()
& REGEDITI()
*** 1_7_7.624/game/txt/hlp/penncmd.hlp Tue, 02 Sep 2003 10:07:23 -0500 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.10.1.1.1.1.1.1.1.1.1.11 600)
--- 1_7_7.664(w)/game/txt/hlp/penncmd.hlp Thu, 18 Sep 2003 09:00:30 -0500 dunemush (pennmush/18_penncmd.hl 1.2.1.1.1.47.1.1.1.1.1.3.1.4.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.2.1.10.1.1.1.1.1.1.1.1.1.1.1.3 600)
***************
*** 1291,1296 ****
--- 1291,1297 ----
@flag/add <flag name>=[<letter>], [<type(s)>], [<setperms>], [<unsetperms>]
@flag/delete <flag name>
@flag/alias <flag name>=<alias>
+ @flag/letter <flag name>[=<letter>]
@flag/restrict <flag name>=[<setperms>], [<unsetperms>]
@flag/enable <flag name>
@flag/disable <flagname>
***************
*** 1305,1310 ****
--- 1306,1312 ----
/disable disables a flag, making it invisible and unusable
/enable re-enables a disabled flag
/alias adds a new alias for an existing flag
+ /letter changes or removes a single-letter alias for an existing flag.
/restrict changes flag permissions (see help @flag2)
/delete deletes a flag completely, removing it from all objects
in the database and the removing it permanently from the
***************
*** 2764,2769 ****
--- 2766,2772 ----
prefixmatch When a user attempts to set an attribute using @<attrib>,
this attribute will be matched down to its unique
prefixes. This flag is primarily used internally.
+ ` This attribute is a branch. See: help ATTRIBUTE TREES
& @sex
@sex <player> = <gender>
***************
*** 3456,3464 ****
you do not own the object, or it is not visible, you will just see the
name of the object's owner. May be abbreviated 'ex <object>'. If the
attribute parameter is given, you will only see that attribute (good
! for looking at code). You can also wild-card match on attributes. For
! example. to see all the attributes that began with a 'v' you could do
! ex <object>/v*
The /brief switch is equivalent to the 'brief' command.
The /debug switch is wizard-only and shows raw values for certa
--- 3459,3470 ----
you do not own the object, or it is not visible, you will just see the
name of the object's owner. May be abbreviated 'ex <object>'. If the
attribute parameter is given, you will only see that attribute (good
! for looking at code). You can also wild-card match on attributes.
! The * wildcard matches any number of characters except a backtick (`).
! The ? wildcard matches a single character except a backtick (`).
! The ** wildcard matches any number of characters, including backticks.
! For example. to see all the attributes that began with a 'v' you could do
! ex <object>/v**
The /brief switch is equivalent to the 'brief' command.
The /debug switch is wizard-only and shows raw values for certa
***************
*** 3467,3472 ****
--- 3473,3480 ----
the object's owner and is primarily useful to admins. This switch
ignores the object's VISUAL flag (but not its attribute flags)
The /all switch shows the values of VEILED attributes.
+
+ See also: ATTRIBUTE TREES
& follow
follow <object>
*** 1_7_7.624/game/txt/hlp/pennchat.hlp Sun, 16 Mar 2003 16:55:02 -0600 dunemush (pennmush/19_pennchat.h 1.2.1.4.1.5 600)
--- 1_7_7.664(w)/game/txt/hlp/pennchat.hlp Mon, 15 Sep 2003 23:31:51 -0500 dunemush (pennmush/19_pennchat.h 1.2.1.4.1.6 600)
***************
*** 126,131 ****
--- 126,134 ----
* "quiet" - channel will not show connection messages
* "open" - you may speak even if you aren't listening to the channel
* "hide_ok" - you may hide from the channel who list.
+ * "notitles" - chantitles are not displayed in channel messages.
+ * "nonames" - player names are not displayed in channel messages.
+ * "nocemit" - @cemit is prohibited on the channel.
Specifications may be combined, space-separated. Default is "player"
@channel/delete removes a channel. You must own it or be Wizard.
***************
*** 142,148 ****
@channel/decompile[/brief] <channel>
@channel/chown <channel> = <new owner>
! The "priv" switch changes the channel's access privileges.
The "quiet" switch turns the quiet status of a channel on and off.
The "wipe" switch clears a channel of players without deleting it.
The "buffer" switch sets the maximum number of full-length lines that
--- 145,152 ----
@channel/decompile[/brief] <channel>
@channel/chown <channel> = <new owner>
! The "priv" switch changes the channel's access privileges. Use !<priv>
! to reset a privilege.
The "quiet" switch turns the quiet status of a channel on and off.
The "wipe" switch clears a channel of players without deleting it.
The "buffer" switch sets the maximum number of full-length lines that
*** 1_7_7.624/game/txt/index-files.pl Sat, 31 May 2003 16:07:52 -0500 dunemush (pennmush/28_index-file 1.9 600)
--- 1_7_7.664(w)/game/txt/index-files.pl Mon, 15 Sep 2003 11:35:05 -0500 dunemush (pennmush/28_index-file 1.10 600)
***************
*** 1,4 ****
! #!/usr/local/bin/perl
#
# index-files.pl - make an & index topic for events/news/help
#
--- 1,4 ----
! #!/usr/bin/perl
#
# index-files.pl - make an & index topic for events/news/help
#
*** 1_7_7.624/game/txt/compose.sh.SH Sat, 19 Jul 2003 09:31:25 -0500 dunemush (pennmush/33_compose.sh 1.5 700)
--- 1_7_7.664(w)/game/txt/compose.sh.SH Mon, 15 Sep 2003 11:35:05 -0500 dunemush (pennmush/33_compose.sh 1.5.1.1 700)
***************
*** 1,3 ****
--- 1,4 ----
+ #!/bin/sh
case $CONFIG in
'')
if test -f config.sh; then TOP=.;
*** 1_7_7.624/game/restart Tue, 02 Sep 2003 21:18:49 -0500 dunemush (pennmush/39_restart 1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.2.2.1.2.2.1.1 700)
--- 1_7_7.664(w)/game/restart Mon, 15 Sep 2003 11:35:05 -0500 dunemush (pennmush/39_restart 1.1.1.1.1.1.1.2.1.1.1.1.1.2.1.2.2.1.2.2.1.1.1.1 700)
***************
*** 26,31 ****
--- 26,32 ----
if [ ! -f $CONF_FILE ]; then
echo "CONF_FILE doesn't exist. It's: $CONF_FILE"
+ echo "Create $CONF_FILE from $GAMEDIR/mushcnf.dst"
exit 1
fi
*** 1_7_7.624/game/mushcnf.dst Sun, 17 Aug 2003 08:30:54 -0500 dunemush (pennmush/41_mushcnf.ds 1.1.1.19.1.1.1.2.1.1.1.8.1.1.1.1.1.17 600)
--- 1_7_7.664(w)/game/mushcnf.dst Mon, 15 Sep 2003 22:20:00 -0500 dunemush (pennmush/41_mushcnf.ds 1.1.1.19.1.1.1.2.1.1.1.8.1.1.1.1.1.18 600)
***************
*** 76,84 ****
#uncompress_program bunzip2
#compress_suffix .bz2
#
! compress_program compress
! uncompress_program uncompress
! compress_suffix .Z
# Room where new players are created.
player_start 0
--- 76,84 ----
#uncompress_program bunzip2
#compress_suffix .bz2
#
! compress_program gzip
! uncompress_program gunzip
! compress_suffix .gz
# Room where new players are created.
player_start 0
*** 1_7_7.624/utils/mkcmds.sh.SH Wed, 02 Jul 2003 14:19:13 -0500 dunemush (pennmush/g/16_mkcmds.sh. 1.3.1.2 750)
--- 1_7_7.664(w)/utils/mkcmds.sh.SH Tue, 23 Sep 2003 12:07:40 -0500 dunemush (pennmush/g/16_mkcmds.sh. 1.3.1.3 750)
***************
*** 118,124 ****
$echo "Rebuilding command prototype file"
$echo "/* AUTOGENERATED FILE. DO NOT EDIT */" > ../hdrs/temp.h
! for c in `grep "^COMMAND *(" ../src/*.c | cut -f2 -d\( | cut -f1 -d\) | sort | uniq`; do
$echo >>../hdrs/temp.h "COMMAND_PROTO($c);"
$echo $n "."
done
--- 118,124 ----
$echo "Rebuilding command prototype file"
$echo "/* AUTOGENERATED FILE. DO NOT EDIT */" > ../hdrs/temp.h
! for c in `grep "^COMMAND *(" ../src/*.c | grep -v cmd_local_silly | cut -f2 -d\( | cut -f1 -d\) | sort | uniq`; do
$echo >>../hdrs/temp.h "COMMAND_PROTO($c);"
$echo $n "."
done
***************
*** 140,146 ****
$echo "Rebuilding function prototype file"
$echo "/* AUTOGENERATED FILE. DO NOT EDIT */" > ../hdrs/temp.h
! for c in `grep "^FUNCTION *(" ../src/*.c | cut -f2 -d\( | cut -f1 -d\) | sort | uniq`; do
$echo >>../hdrs/temp.h "FUNCTION_PROTO($c);"
$echo $n "."
done
--- 140,146 ----
$echo "Rebuilding function prototype file"
$echo "/* AUTOGENERATED FILE. DO NOT EDIT */" > ../hdrs/temp.h
! for c in `grep "^FUNCTION *(" ../src/*.c | grep -v local_fun_silly | cut -f2 -d\( | cut -f1 -d\) | sort | uniq`; do
$echo >>../hdrs/temp.h "FUNCTION_PROTO($c);"
$echo $n "."
done
*** 1_7_7.624/src/SWITCHES Mon, 01 Sep 2003 18:39:12 -0500 dunemush (pennmush/b/22_SWITCHES 1.12.1.3.1.7 600)
--- 1_7_7.664(w)/src/SWITCHES Mon, 29 Sep 2003 16:42:36 -0500 dunemush (pennmush/b/22_SWITCHES 1.12.1.3.1.8 600)
***************
*** 59,64 ****
--- 59,65 ----
INVENTORY
IPRINT
JOIN
+ LETTER
LIST
LOWERCASE
ME
*** 1_7_7.624/src/wiz.c Thu, 04 Sep 2003 17:27:46 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.17.1.1 660)
--- 1_7_7.664(w)/src/wiz.c Mon, 29 Sep 2003 16:42:35 -0500 dunemush (pennmush/b/23_wiz.c 1.44.1.1.1.1.1.2.1.7.1.1.1.1.1.1.1.1.1.1.1.8.1.2.2.2.1.2.1.1.1.1.1.1.1.2.1.1.1.2.2.17.1.2 660)
***************
*** 529,536 ****
return;
}
/* we can't do it */
! did_it(player, destination, "EFAIL", T("Permission denied."),
! "OEFAIL", NULL, "AEFAIL", Location(player));
return;
} else {
/* attempted teleport to an exit */
--- 529,536 ----
return;
}
/* we can't do it */
! fail_lock(player, destination, Enter_Lock, T("Permission denied."),
! Location(player));
return;
} else {
/* attempted teleport to an exit */
*** 1_7_7.624/src/wild.c Mon, 14 Jul 2003 09:12:36 -0500 dunemush (pennmush/b/24_wild.c 1.11.1.1.1.8.1.1.1.4.1.2.1.4 660)
--- 1_7_7.664(w)/src/wild.c Mon, 29 Sep 2003 16:42:34 -0500 dunemush (pennmush/b/24_wild.c 1.11.1.1.1.8.1.1.1.4.1.2.1.5 660)
***************
*** 153,158 ****
--- 153,262 ----
return 0;
}
+ /** Do an attribute name wildcard match.
+ *
+ * This probably crashes if fed NULLs instead of strings, too.
+ * The special thing about this one is that ` doesn't match normal
+ * wildcards; you have to use ** to match embedded `. Also, patterns
+ * ending in ` are treated as patterns ending in `*, and empty patterns
+ * are treated as *.
+ *
+ * \param tstr pattern to match against.
+ * \param dstr string to check.
+ * \retval 1 dstr matches the tstr pattern.
+ * \retval 0 dstr does not match the tstr pattern.
+ */
+ int
+ atr_wild(const char *RESTRICT tstr, const char *RESTRICT dstr)
+ {
+ int starcount;
+
+ if (!*tstr)
+ return !strchr(dstr, '`');
+
+ while (*tstr != '*') {
+ switch (*tstr) {
+ case '?':
+ /* Single character match. Return false if at
+ * end of data.
+ */
+ if (!*dstr || *dstr == '`')
+ return 0;
+ break;
+ case '`':
+ /* Delimiter match. Special handling if at end of pattern. */
+ if (*dstr != '`')
+ return 0;
+ if (!tstr[1])
+ return !strchr(dstr + 1, '`');
+ break;
+ case '\\':
+ /* Escape character. Move up, and force literal
+ * match of next character.
+ */
+ tstr++;
+ /* FALL THROUGH */
+ default:
+ /* Literal character. Check for a match.
+ * If matching end of data, return true.
+ */
+ if (NOTEQUAL(0, *dstr, *tstr))
+ return 0;
+ if (!*dstr)
+ return 1;
+ }
+ tstr++;
+ dstr++;
+ }
+
+ /* Skip over '*'. */
+ tstr++;
+ starcount = 1;
+
+ /* Skip over wildcards. */
+ while (starcount < 2 && ((*tstr == '?') || (*tstr == '*'))) {
+ if (*tstr == '?') {
+ if (!*dstr || *dstr == '`')
+ return 0;
+ dstr++;
+ starcount = 0;
+ } else
+ starcount++;
+ tstr++;
+ }
+
+ /* Skip over long strings of '*'. */
+ while (*tstr == '*')
+ tstr++;
+
+ /* Return true on trailing '**'. */
+ if (!*tstr)
+ return starcount == 2 || !strchr(dstr, '`');
+
+ if (*tstr == '?') {
+ /* Scan for possible matches. */
+ while (*dstr) {
+ if (*dstr != '`' && atr_wild(tstr + 1, dstr + 1))
+ return 1;
+ dstr++;
+ }
+ } else {
+ /* Skip over a backslash in the pattern string if it is there. */
+ if (*tstr == '\\')
+ tstr++;
+
+ /* Scan for possible matches. */
+ while (*dstr) {
+ if (EQUAL(0, *dstr, *tstr) && atr_wild(tstr + 1, dstr + 1))
+ return 1;
+ if (starcount < 2 && *dstr == '`')
+ return 0;
+ dstr++;
+ }
+ }
+ return 0;
+ }
+
/* ---------------------------------------------------------------------------
* wild1: INTERNAL: do a wildcard match, remembering the wild data.
*
*** 1_7_7.624/src/utils.c Mon, 01 Sep 2003 15:56:43 -0500 dunemush (pennmush/b/27_utils.c 1.30.1.1.1.14 660)
--- 1_7_7.664(w)/src/utils.c Mon, 29 Sep 2003 16:42:34 -0500 dunemush (pennmush/b/27_utils.c 1.30.1.1.1.15 660)
***************
*** 572,577 ****
--- 572,584 ----
/* Standard checks */
+ /* If it's an audible message, it must pass your Interact_Lock
+ * (or be from a privileged speaker)
+ */
+ if ((type == INTERACT_HEAR) && !Pemit_All(from)
+ && !eval_lock(from, to, Interact_Lock))
+ return 0;
+
/* You can interact with the object you are in or any objects
* you're holding.
* You can interact with objects you control, but not
***************
*** 580,592 ****
if ((from == Location(to)) || (to == Location(from)) || controls(to, from))
return 1;
- /* If it's an audible message, it must pass your Interact_Lock
- * (or be from a privileged speaker)
- */
- if ((type == INTERACT_HEAR) && !Pemit_All(from)
- && !eval_lock(from, to, Interact_Lock))
- return 0;
-
lci = local_can_interact_last(from, to, type);
if (lci != NOTHING)
--- 587,592 ----
*** 1_7_7.624/src/help.c Sun, 10 Aug 2003 11:13:00 -0500 dunemush (pennmush/f/32_help.c 1.4.1.2.1.1.1.3.2.2.1.1.2.1.1.2.1.2.1.2.1.3.1.15 660)
--- 1_7_7.664(w)/src/help.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/f/32_help.c 1.4.1.2.1.1.1.3.2.2.1.1.2.1.1.2.1.2.1.2.1.3.1.17 660)
***************
*** 32,41 ****
static int help_init = 0;
! static void do_new_spitfile(dbref player, char *arg1,
! help_file *help_dat, int restricted);
static const char *string_spitfile(help_file *help_dat, char *arg1);
static help_indx *help_find_entry(help_file *help_dat, const char *the_topic);
static void help_build_index(help_file *h, int restricted);
--- 32,41 ----
static int help_init = 0;
! static void do_new_spitfile(dbref player, char *arg1, help_file *help_dat);
static const char *string_spitfile(help_file *help_dat, char *arg1);
static help_indx *help_find_entry(help_file *help_dat, const char *the_topic);
+ static char *list_matching_entries(const char *pattern, help_file *help_dat);
static void help_build_index(help_file *h, int restricted);
***************
*** 66,72 ****
return;
}
! do_new_spitfile(player, arg_left, h, h->admin);
}
/** Initialize the helpfile hashtable, which contains the names of the
--- 66,81 ----
return;
}
! if (h->admin && !Hasprivs(player)) {
! notify(player, T("You don't look like an admin to me."));
! return;
! }
!
! if (wildcard(arg_left))
! notify_format(player, T("Here are the entries which match '%s':\n%s"),
! arg_left, list_matching_entries(arg_left, h));
! else
! do_new_spitfile(player, arg_left, h);
}
/** Initialize the helpfile hashtable, which contains the names of the
***************
*** 159,165 ****
}
static void
! do_new_spitfile(dbref player, char *arg1, help_file *help_dat, int restricted)
{
help_indx *entry = NULL;
FILE *fp;
--- 168,174 ----
}
static void
! do_new_spitfile(dbref player, char *arg1, help_file *help_dat)
{
help_indx *entry = NULL;
FILE *fp;
***************
*** 178,188 ****
if (strlen(arg1) > LINE_SIZE)
*(arg1 + LINE_SIZE) = '\0';
! if (restricted) {
! if (!Hasprivs(player)) {
! notify(player, T("You don't look like an admin to me."));
! return;
! }
sprintf(the_topic, "&%s", arg1);
} else
strcpy(the_topic, arg1);
--- 187,193 ----
if (strlen(arg1) > LINE_SIZE)
*(arg1 + LINE_SIZE) = '\0';
! if (help_dat->admin) {
sprintf(the_topic, "&%s", arg1);
} else
strcpy(the_topic, arg1);
***************
*** 195,201 ****
entry = help_find_entry(help_dat, the_topic);
if (!entry && default_topic)
! entry = help_find_entry(help_dat, (restricted ? "&help" : "help"));
if (!entry) {
notify_format(player, T("No entry for '%s'."), arg1);
--- 200,206 ----
entry = help_find_entry(help_dat, the_topic);
if (!entry && default_topic)
! entry = help_find_entry(help_dat, (help_dat->admin ? "&help" : "help"));
if (!entry) {
notify_format(player, T("No entry for '%s'."), arg1);
***************
*** 458,464 ****
safe_str(T(e_perm), buff, bp);
return;
}
! safe_str(string_spitfile(h, args[1]), buff, bp);
}
--- 463,473 ----
safe_str(T(e_perm), buff, bp);
return;
}
!
! if (wildcard(args[1]))
! safe_str(list_matching_entries(args[1], h), buff, bp);
! else
! safe_str(string_spitfile(h, args[1]), buff, bp);
}
***************
*** 488,537 ****
if (!help_dat->indx || help_dat->entries == 0)
return T("#-1 NO INDEX FOR FILE");
! if (help_dat->entries < 10) { /* Just do a linear search for small files */
! for (n = 0; n < help_dat->entries; n++) {
! if (string_prefix(help_dat->indx[n].topic, the_topic)) {
! entry = &help_dat->indx[n];
! break;
! }
! }
! } else { /* Binary search of the index */
! int left = 0;
! int cmp;
! int right = help_dat->entries - 1;
!
! while (1) {
! n = (left + right) / 2;
!
! if (left > right)
! break;
!
! cmp = strcasecmp(the_topic, help_dat->indx[n].topic);
!
! if (cmp == 0) {
! entry = &help_dat->indx[n];
! break;
! } else if (cmp < 0) {
! /* We need to catch the first prefix */
! if (string_prefix(help_dat->indx[n].topic, the_topic)) {
! int m;
! for (m = n - 1; m >= 0; m--) {
! if (!string_prefix(help_dat->indx[m].topic, the_topic))
! break;
! }
! entry = &help_dat->indx[m + 1];
! break;
! }
! if (left == right)
! break;
! right = n - 1;
! } else { /* cmp > 0 */
! if (left == right)
! break;
! left = n + 1;
! }
! }
! }
if (!entry) {
return T("#-1 NO ENTRY");
--- 497,503 ----
if (!help_dat->indx || help_dat->entries == 0)
return T("#-1 NO INDEX FOR FILE");
! entry = help_find_entry(help_dat, the_topic);
if (!entry) {
return T("#-1 NO ENTRY");
***************
*** 555,557 ****
--- 521,555 ----
fclose(fp);
return buff;
}
+
+ /** Return a string with all help entries that match a pattern */
+ static char *
+ list_matching_entries(const char *pattern, help_file *help_dat)
+ {
+ static char buff[BUFFER_LEN];
+ int offset;
+ char *bp;
+ size_t n;
+
+ bp = buff;
+
+ if (help_dat->admin)
+ offset = 1; /* To skip the leading & */
+ else
+ offset = 0;
+
+ for (n = 0; n < help_dat->entries; n++)
+ if (quick_wild(pattern, help_dat->indx[n].topic + offset)) {
+ safe_str(help_dat->indx[n].topic + offset, buff, &bp);
+ safe_strl(", ", 2, buff, &bp);
+ }
+
+ if (bp > buff)
+ *(bp - 2) = '\0';
+ else {
+ safe_str(T("No matching help topics."), buff, &bp);
+ *bp = '\0';
+ }
+
+ return buff;
+ }
*** 1_7_7.624/src/switchinc.c Mon, 01 Sep 2003 18:39:12 -0500 dunemush (pennmush/b/32_switchinc. 1.3.1.2.1.6.1.18.1.2.1.2.2.5.1.4.2.4.1.1.1.2.1.5.1.2.1.5.2.1.1.31.3.4.1.5.1.4.1.1.1.1.1.1.1.7.1.1 660)
--- 1_7_7.664(w)/src/switchinc.c Mon, 29 Sep 2003 16:42:41 -0500 dunemush (pennmush/b/32_switchinc. 1.3.1.2.1.6.1.18.1.2.1.2.2.5.1.4.2.4.1.1.1.2.1.5.1.2.1.5.2.1.1.31.3.4.1.5.1.4.1.1.1.1.1.1.1.7.1.1.1.1 660)
***************
*** 61,66 ****
--- 61,67 ----
{"INVENTORY", SWITCH_INVENTORY},
{"IPRINT", SWITCH_IPRINT},
{"JOIN", SWITCH_JOIN},
+ {"LETTER", SWITCH_LETTER},
{"LIST", SWITCH_LIST},
{"LOWERCASE", SWITCH_LOWERCASE},
{"ME", SWITCH_ME},
*** 1_7_7.624/src/set.c Wed, 03 Sep 2003 22:39:22 -0500 dunemush (pennmush/b/38_set.c 1.26.1.5.1.1.2.1.1.1.1.1.1.11.1.1.1.1.1.1.1.1.1.1.1.1.1.9 660)
--- 1_7_7.664(w)/src/set.c Mon, 29 Sep 2003 16:42:34 -0500 dunemush (pennmush/b/38_set.c 1.26.1.5.1.1.2.1.1.1.1.1.1.11.1.1.1.1.1.1.1.1.1.1.1.1.1.12 660)
***************
*** 538,546 ****
notify(player, T("Unrecognized attribute flag."));
return;
}
! af.flag = flag;
! if (!atr_iter_get(player, thing, atrname, af_helper, &af))
notify(player, T("No attribute found to change."));
}
--- 538,547 ----
notify(player, T("Unrecognized attribute flag."));
return;
}
! af.flag = mush_strdup(atrflag_to_string(af.f), "af_flag list");
! if (!atr_iter_get(player, thing, atrname, 0, af_helper, &af))
notify(player, T("No attribute found to change."));
+ mush_free(af.flag, "af_flag list");
}
***************
*** 869,875 ****
notify(player, T("Nothing to do."));
return;
}
! if (!atr_iter_get(player, thing, q, gedit_helper, argv))
notify(player, T("No matching attributes."));
}
--- 870,876 ----
notify(player, T("Nothing to do."));
return;
}
! if (!atr_iter_get(player, thing, q, 0, gedit_helper, argv))
notify(player, T("No matching attributes."));
}
***************
*** 939,946 ****
noisy_match_result(player, what, TYPE_THING,
MAT_NEAR_THINGS)) != NOTHING) {
if (!eval_lock(player, thing, Use_Lock)) {
! did_it(player, thing, "UFAIL", T("Pemission denied."), "OUFAIL", NULL,
! "AUFAIL", NOTHING);
return;
} else
did_it(player, thing, "USE", "Used.", "OUSE", NULL, "AUSE", NOTHING);
--- 940,946 ----
noisy_match_result(player, what, TYPE_THING,
MAT_NEAR_THINGS)) != NOTHING) {
if (!eval_lock(player, thing, Use_Lock)) {
! fail_lock(player, thing, Use_Lock, T("Permission denied."), NOTHING);
return;
} else
did_it(player, thing, "USE", "Used.", "OUSE", NULL, "AUSE", NOTHING);
***************
*** 1058,1065 ****
notify(player, T("That object is protected."));
return;
}
! if (!atr_iter_get(player, thing, pattern, wipe_helper, NULL))
notify(player, T("No matching attributes."));
else
notify(player, T("Attributes wiped."));
}
--- 1058,1070 ----
notify(player, T("That object is protected."));
return;
}
!
! we_are_wiping = 1;
!
! if (!atr_iter_get(player, thing, pattern, 0, wipe_helper, NULL))
notify(player, T("No matching attributes."));
else
notify(player, T("Attributes wiped."));
+
+ we_are_wiping = 0;
}
*** 1_7_7.624/src/predicat.c Wed, 03 Sep 2003 22:39:22 -0500 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.4.2.27 660)
--- 1_7_7.664(w)/src/predicat.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/b/44_predicat.c 1.1.1.34.1.1.1.3.1.4.2.28 660)
***************
*** 1105,1111 ****
guh.lookfor = lookfor;
guh.len = len;
guh.insensitive = insensitive;
! (void) atr_iter_get(player, thing, pattern, grep_util_helper, &guh);
*guh.bp = '\0';
return guh.buff;
}
--- 1105,1111 ----
guh.lookfor = lookfor;
guh.len = len;
guh.insensitive = insensitive;
! (void) atr_iter_get(player, thing, pattern, 0, grep_util_helper, &guh);
*guh.bp = '\0';
return guh.buff;
}
***************
*** 1201,1207 ****
gh.lookfor = lookfor;
gh.len = len;
gh.insensitive = insensitive;
! if (!atr_iter_get(player, thing, pattern, grep_helper, &gh))
notify(player, T("No matching attributes."));
} else {
tp = grep_util(player, thing, pattern, lookfor, len, insensitive);
--- 1201,1207 ----
gh.lookfor = lookfor;
gh.len = len;
gh.insensitive = insensitive;
! if (!atr_iter_get(player, thing, pattern, 0, grep_helper, &gh))
notify(player, T("No matching attributes."));
} else {
tp = grep_util(player, thing, pattern, lookfor, len, insensitive);
*** 1_7_7.624/src/move.c Tue, 06 May 2003 17:31:42 -0500 dunemush (pennmush/b/51_move.c 1.1.1.18.1.5.1.13.1.3.1.9.1.1.1.1.1.2.1.1.1.1.1.21 660)
--- 1_7_7.664(w)/src/move.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/b/51_move.c 1.1.1.18.1.5.1.13.1.3.1.9.1.1.1.1.1.2.1.1.1.1.1.22 660)
***************
*** 467,474 ****
break;
}
} else
! did_it(player, exit_m, "FAILURE", T("You can't go that way."),
! "OFAILURE", NULL, "AFAILURE", NOTHING);
break;
}
}
--- 467,474 ----
break;
}
} else
! fail_lock(player, exit_m, Basic_Lock, T("You can't go that way."),
! NOTHING);
break;
}
}
***************
*** 562,569 ****
"ARECEIVE", NOTHING, myenv, NA_INTER_SEE);
mush_free(myenv[0], "dbref");
} else
! did_it(player, thing, "FAILURE", T("You can't take that from there."),
! "OFAILURE", NULL, "AFAILURE", NOTHING);
} else {
notify(player, T("I don't see that here."));
}
--- 562,569 ----
"ARECEIVE", NOTHING, myenv, NA_INTER_SEE);
mush_free(myenv[0], "dbref");
} else
! fail_lock(player, thing, Basic_Lock,
! T("You can't take that from there."), NOTHING);
} else {
notify(player, T("I don't see that here."));
}
***************
*** 609,616 ****
"ARECEIVE", NOTHING, myenv, NA_INTER_SEE);
mush_free(myenv[0], "dbref");
} else
! did_it(player, thing, "FAILURE", T("You can't pick that up."),
! "OFAILURE", NULL, "AFAILURE", NOTHING);
break;
case TYPE_EXIT:
notify(player, T("You can't pick up exits."));
--- 609,616 ----
"ARECEIVE", NOTHING, myenv, NA_INTER_SEE);
mush_free(myenv[0], "dbref");
} else
! fail_lock(player, thing, Basic_Lock, T("You can't pick that up."),
! NOTHING);
break;
case TYPE_EXIT:
notify(player, T("You can't pick up exits."));
***************
*** 715,722 ****
if (!((EnterOk(thing) || controls(player, thing)) &&
(eval_lock(player, thing, Enter_Lock))
)) {
! did_it(player, thing, "EFAIL", T("Permission denied."), "OEFAIL",
! NULL, "AEFAIL", NOTHING);
return;
}
if (thing == player) {
--- 715,721 ----
if (!((EnterOk(thing) || controls(player, thing)) &&
(eval_lock(player, thing, Enter_Lock))
)) {
! fail_lock(player, thing, Enter_Lock, T("Permission denied."), NOTHING);
return;
}
if (thing == player) {
***************
*** 744,751 ****
|| NoLeave(loc)
|| !eval_lock(player, loc, Leave_Lock)
) {
! did_it(player, loc, "LFAIL", T("You can't leave."), "OLFAIL",
! NULL, "ALFAIL", NOTHING);
return;
}
enter_room(player, Location(loc), 0);
--- 743,749 ----
|| NoLeave(loc)
|| !eval_lock(player, loc, Leave_Lock)
) {
! fail_lock(player, loc, Leave_Lock, T("You can't leave."), NOTHING);
return;
}
enter_room(player, Location(loc), 0);
***************
*** 849,856 ****
}
/* Ok, are we allowed to follow them? */
if (!eval_lock(player, leader, Follow_Lock)) {
! notify_format(player,
! T("You're not allowed to follow %s."), Name(leader));
return;
}
/* Ok, looks good */
--- 847,854 ----
}
/* Ok, are we allowed to follow them? */
if (!eval_lock(player, leader, Follow_Lock)) {
! fail_lock(player, leader, Follow_Lock,
! T("You're not alllowed to follow."), Location(player));
return;
}
/* Ok, looks good */
*** 1_7_7.624/src/look.c Mon, 25 Aug 2003 12:05:33 -0500 dunemush (pennmush/c/4_look.c 1.21.1.2.1.9.1.1.1.1.1.12 660)
--- 1_7_7.664(w)/src/look.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/c/4_look.c 1.21.1.2.1.9.1.1.1.1.1.17 660)
***************
*** 308,319 ****
__attribute__ ((__unused__)))
{
char fbuf[BUFFER_LEN];
! char *r;
if (EX_PUBLIC_ATTRIBS &&
!strcmp(AL_NAME(atr), "DESCRIBE") && !strcmp(pattern, "*"))
return 0;
strcpy(fbuf, privs_to_letters(attr_privs, AL_FLAGS(atr)));
if (AL_FLAGS(atr) & AF_VEILED) {
if (ShowAnsi(player))
notify_format(player,
--- 308,321 ----
__attribute__ ((__unused__)))
{
char fbuf[BUFFER_LEN];
! char const *r;
if (EX_PUBLIC_ATTRIBS &&
!strcmp(AL_NAME(atr), "DESCRIBE") && !strcmp(pattern, "*"))
return 0;
strcpy(fbuf, privs_to_letters(attr_privs, AL_FLAGS(atr)));
+ if (atr_sub_branch(atr))
+ strcat(fbuf, "`");
if (AL_FLAGS(atr) & AF_VEILED) {
if (ShowAnsi(player))
notify_format(player,
***************
*** 343,354 ****
__attribute__ ((__unused__)))
{
char fbuf[BUFFER_LEN];
! char *r;
if (EX_PUBLIC_ATTRIBS &&
!strcmp(AL_NAME(atr), "DESCRIBE") && !strcmp(pattern, "*"))
return 0;
strcpy(fbuf, privs_to_letters(attr_privs, AL_FLAGS(atr)));
r = safe_atr_value(atr);
if (ShowAnsi(player))
notify_format(player,
--- 345,358 ----
__attribute__ ((__unused__)))
{
char fbuf[BUFFER_LEN];
! char const *r;
if (EX_PUBLIC_ATTRIBS &&
!strcmp(AL_NAME(atr), "DESCRIBE") && !strcmp(pattern, "*"))
return 0;
strcpy(fbuf, privs_to_letters(attr_privs, AL_FLAGS(atr)));
+ if (atr_sub_branch(atr))
+ strcat(fbuf, "`");
r = safe_atr_value(atr);
if (ShowAnsi(player))
notify_format(player,
***************
*** 365,374 ****
look_atrs(dbref player, dbref thing, const char *mstr, int all)
{
if (all || (mstr && *mstr && !wildcard(mstr))) {
! if (!atr_iter_get(player, thing, mstr, look_helper, NULL) && mstr)
notify(player, T("No matching attributes."));
} else {
! if (!atr_iter_get(player, thing, mstr, look_helper_veiled, NULL) && mstr)
notify(player, T("No matching attributes."));
}
}
--- 369,378 ----
look_atrs(dbref player, dbref thing, const char *mstr, int all)
{
if (all || (mstr && *mstr && !wildcard(mstr))) {
! if (!atr_iter_get(player, thing, mstr, 0, look_helper, NULL) && mstr)
notify(player, T("No matching attributes."));
} else {
! if (!atr_iter_get(player, thing, mstr, 0, look_helper_veiled, NULL) && mstr)
notify(player, T("No matching attributes."));
}
}
***************
*** 377,386 ****
mortal_look_atrs(dbref player, dbref thing, const char *mstr, int all)
{
if (all || (mstr && *mstr && !wildcard(mstr))) {
! if (!atr_iter_get_visible(player, thing, mstr, look_helper, NULL) && mstr)
notify(player, T("No matching attributes."));
} else {
! if (!atr_iter_get_visible(player, thing, mstr, look_helper_veiled, NULL)
&& mstr)
notify(player, T("No matching attributes."));
}
--- 381,390 ----
mortal_look_atrs(dbref player, dbref thing, const char *mstr, int all)
{
if (all || (mstr && *mstr && !wildcard(mstr))) {
! if (!atr_iter_get(player, thing, mstr, 1, look_helper, NULL) && mstr)
notify(player, T("No matching attributes."));
} else {
! if (!atr_iter_get(player, thing, mstr, 1, look_helper_veiled, NULL)
&& mstr)
notify(player, T("No matching attributes."));
}
***************
*** 485,492 ****
did_it(player, loc, "SUCCESS", NULL, "OSUCCESS", NULL, "ASUCCESS",
NOTHING);
else
! did_it(player, loc, "FAILURE", NULL, "OFAILURE", NULL, "AFAILURE",
! NOTHING);
}
/* tell him the contents */
if (style != LOOK_CLOUDYTRANS)
--- 489,495 ----
did_it(player, loc, "SUCCESS", NULL, "OSUCCESS", NULL, "ASUCCESS",
NOTHING);
else
! fail_lock(player, loc, Basic_Lock, NULL, NOTHING);
}
/* tell him the contents */
if (style != LOOK_CLOUDYTRANS)
***************
*** 1315,1321 ****
dh.name = name;
dh.skipdef = skipdef;
/* Comment complaints if none are found */
! if (!atr_iter_get(player, thing, pattern, decompile_helper, &dh))
notify(player, T("@@ No attributes found. @@"));
}
--- 1318,1324 ----
dh.name = name;
dh.skipdef = skipdef;
/* Comment complaints if none are found */
! if (!atr_iter_get(player, thing, pattern, 0, decompile_helper, &dh))
notify(player, T("@@ No attributes found. @@"));
}
***************
*** 1483,1488 ****
decompile_powers(player, thing, object);
}
if (dbflag != DEC_FLAG) {
! decompile_atrs(player, thing, object, "*", "", skipdef);
}
}
--- 1486,1491 ----
decompile_powers(player, thing, object);
}
if (dbflag != DEC_FLAG) {
! decompile_atrs(player, thing, object, "**", "", skipdef);
}
}
*** 1_7_7.624/src/lock.c Mon, 01 Sep 2003 15:52:02 -0500 dunemush (pennmush/c/6_lock.c 1.17.1.13.1.1.1.1.1.7 660)
--- 1_7_7.664(w)/src/lock.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/c/6_lock.c 1.17.1.13.1.1.1.1.1.11 660)
***************
*** 111,116 ****
--- 111,129 ----
{NULL, TRUE_BOOLEXP, GOD, 0, NULL}
};
+ /** Table of base attributes associated with success and failure of
+ * locks. These are the historical ones; we automatically generate
+ * such attribute names for those that aren't in this table using
+ * <lock>_LOCK`<message>
+ */
+ const LOCKMSGINFO lock_msgs[] = {
+ {"Basic", "SUCCESS", "FAILURE"},
+ {"Enter", "ENTER", "EFAIL"},
+ {"Use", "USE", "UFAIL"},
+ {"Leave", "LEAVE", "LFAIL"},
+ {NULL, NULL, NULL}
+ };
+
/** Table of lock permissions */
PRIV lock_privs[] = {
{"visual", 'v', LF_VISUAL, LF_VISUAL},
***************
*** 618,624 ****
if (!AreQuiet(player, thing))
notify_format(player, T("%s(%s) - %s unlocked."), Name(thing),
unparse_dbref(thing), real_type);
! ModTime(thing) = mudtime;
} else
notify(player, T("Permission denied."));
}
--- 631,638 ----
if (!AreQuiet(player, thing))
notify_format(player, T("%s(%s) - %s unlocked."), Name(thing),
unparse_dbref(thing), real_type);
! if (!IsPlayer(thing))
! ModTime(thing) = mudtime;
} else
notify(player, T("Permission denied."));
}
***************
*** 683,689 ****
if (!AreQuiet(player, thing))
notify_format(player, T("%s(%s) - %s locked."), Name(thing),
unparse_dbref(thing), real_type);
! ModTime(thing) = mudtime;
} else
notify(player, T("Permission denied."));
}
--- 697,704 ----
if (!AreQuiet(player, thing))
notify_format(player, T("%s(%s) - %s locked."), Name(thing),
unparse_dbref(thing), real_type);
! if (!IsPlayer(thing))
! ModTime(thing) = mudtime;
} else
notify(player, T("Permission denied."));
}
***************
*** 720,725 ****
--- 735,791 ----
return eval_boolexp(player, getlock(thing, ltype), thing);
}
+ /** Active a lock's failure attributes.
+ * \param player dbref failing to pass the lock.
+ * \param thing object containing the lock.
+ * \param ltype type of lock failed.
+ * \param def default message if there is no appropriate failure attribute.
+ * \param loc location in which action is taking place.
+ */
+ void
+ fail_lock(dbref player, dbref thing, lock_type ltype, const char *def,
+ dbref loc)
+ {
+ const LOCKMSGINFO *lm;
+ char atr[BUFFER_LEN];
+ char oatr[BUFFER_LEN];
+ char aatr[BUFFER_LEN];
+ char *bp;
+
+ /* Find the lock's failure attribute, if it's there */
+ for (lm = lock_msgs; lm->type; lm++) {
+ if (!strcmp(lm->type, ltype))
+ break;
+ }
+ if (lm->type) {
+ strcpy(atr, lm->failbase);
+ bp = oatr;
+ safe_format(oatr, &bp, "O%s", lm->failbase);
+ *bp = '\0';
+ strcpy(aatr, oatr);
+ aatr[0] = 'A';
+ } else {
+ /* Oops, it's not in the table. So we construct them on these lines:
+ * <LOCKNAME>_LOCK`<type>FAILURE
+ */
+ bp = atr;
+ safe_format(atr, &bp, "%s_LOCK`FAILURE", ltype);
+ *bp = '\0';
+ bp = oatr;
+ safe_format(oatr, &bp, "%s_LOCK`OFAILURE", ltype);
+ *bp = '\0';
+ bp = aatr;
+ safe_format(aatr, &bp, "%s_LOCK`AFAILURE", ltype);
+ *bp = '\0';
+ }
+ /* Now do the work */
+ upcasestr(atr);
+ upcasestr(oatr);
+ upcasestr(aatr);
+ did_it(player, thing, atr, def, oatr, NULL, aatr, loc);
+ }
+
+
/** Determine if a lock is visual.
* \param thing object containing the lock.
* \param ltype type of lock to check.
***************
*** 791,795 ****
if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
notify_format(player, "%s/%s - %s.", Name(thing), L_TYPE(l),
unset ? T("lock flags unset") : T("lock flags set"));
! ModTime(thing) = mudtime;
}
--- 857,862 ----
if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
notify_format(player, "%s/%s - %s.", Name(thing), L_TYPE(l),
unset ? T("lock flags unset") : T("lock flags set"));
! if (!IsPlayer(thing))
! ModTime(thing) = mudtime;
}
*** 1_7_7.624/src/ident.c Sat, 01 Mar 2003 23:51:32 -0600 dunemush (pennmush/c/8_ident.c 1.19.1.4.1.13 660)
--- 1_7_7.664(w)/src/ident.c Mon, 29 Sep 2003 16:42:32 -0500 dunemush (pennmush/c/8_ident.c 1.19.1.4.1.14 660)
***************
*** 228,235 ****
memset(id, 0, sizeof(ident_t));
if (getnameinfo(faddr, flen, host, sizeof(host), NULL, 0,
! NI_NUMERICHOST | NI_NUMERICSERV) != 0)
return 0;
/* Make sure we connect from the right interface. Changing the pointer
directly doesn't seem to work. So... */
--- 228,237 ----
memset(id, 0, sizeof(ident_t));
if (getnameinfo(faddr, flen, host, sizeof(host), NULL, 0,
! NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
! free(id);
return 0;
+ }
/* Make sure we connect from the right interface. Changing the pointer
directly doesn't seem to work. So... */
*** 1_7_7.624/src/funmisc.c Wed, 03 Sep 2003 22:39:22 -0500 dunemush (pennmush/c/14_funmisc.c 1.30.1.1.1.22 660)
--- 1_7_7.664(w)/src/funmisc.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/14_funmisc.c 1.30.1.1.1.25 660)
***************
*** 181,193 ****
* Uses Sh'dow's random number generator, found in utils.c. Better
* distribution than original, w/ minimal speed losses.
*/
! int i;
if (!is_integer(args[0])) {
safe_str(T(e_int), buff, bp);
return;
}
! i = get_random_long(0, parse_integer(args[0]) - 1);
! safe_integer(i, buff, bp);
}
/* ARGSUSED */
--- 181,209 ----
* Uses Sh'dow's random number generator, found in utils.c. Better
* distribution than original, w/ minimal speed losses.
*/
! int low, high;
if (!is_integer(args[0])) {
safe_str(T(e_int), buff, bp);
return;
}
! if (nargs == 1) {
! low = 0;
! high = parse_integer(args[0]) - 1;
! } else {
! if (!is_integer(args[1])) {
! safe_str(T(e_ints), buff, bp);
! return;
! }
! low = parse_integer(args[0]);
! high = parse_integer(args[1]);
! }
!
! if (low > high) {
! safe_str(T(e_range), buff, bp);
! return;
! }
!
! safe_integer(get_random_long(low, high), buff, bp);
}
/* ARGSUSED */
*** 1_7_7.624/src/funlist.c Mon, 14 Jul 2003 09:07:25 -0500 dunemush (pennmush/c/16_funlist.c 1.3.1.1.1.5.1.2.1.1.1.1.1.4.1.2.1.2.1.19.1.2.1.1.1.2.1.5.1.1.1.1.1.1.1.1.1.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.1.1.12.1.14 660)
--- 1_7_7.664(w)/src/funlist.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/16_funlist.c 1.3.1.1.1.5.1.2.1.1.1.1.1.4.1.2.1.2.1.19.1.2.1.1.1.2.1.5.1.1.1.1.1.1.1.1.1.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.1.1.12.1.14.1.2 660)
***************
*** 1481,1486 ****
--- 1481,1519 ----
}
/* ARGSUSED */
+ FUNCTION(fun_randword)
+ {
+ char *s, *r;
+ char sep;
+ int word_count, word_index;
+
+ if (!*args[0])
+ return;
+
+ if (!delim_check(buff, bp, nargs, args, 2, &sep))
+ return;
+
+ s = trim_space_sep(args[0], sep);
+ word_count = do_wordcount(s, sep);
+ word_index = get_random_long(0, word_count - 1);
+
+ /* Go to the start of the token we're interested in. */
+ while (word_index && s) {
+ s = next_token(s, sep);
+ word_index--;
+ }
+
+ if (!s || !*s) /* ran off the end of the string */
+ return;
+
+ /* Chop off the end, and copy. No length checking needed. */
+ r = s;
+ if (s && *s)
+ (void) split_token(&s, sep);
+ safe_str(r, buff, bp);
+ }
+
+ /* ARGSUSED */
FUNCTION(fun_rest)
{
char *p;
***************
*** 2859,2865 ****
reharg.buff = buff;
reharg.bp = bp;
! atr_iter_get(executor, it, args[1], regrep_helper, (void *) &reharg);
mush_free(reharg.re, "pcre");
if (reharg.study)
mush_free(reharg.study, "pcre.extra");
--- 2892,2898 ----
reharg.buff = buff;
reharg.bp = bp;
! atr_iter_get(executor, it, args[1], 0, regrep_helper, (void *) &reharg);
mush_free(reharg.re, "pcre");
if (reharg.study)
mush_free(reharg.study, "pcre.extra");
*** 1_7_7.624/src/fundb.c Fri, 05 Sep 2003 20:59:37 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.19 660)
--- 1_7_7.664(w)/src/fundb.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/17_fundb.c 1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.7.1.3.1.3.1.3.1.2.1.2.1.3.2.1.2.1.2.1.1.1.1.4.1.1.1.1.1.1.1.1.1.1.1.3.1.1.2.2.2.1.1.1.1.1.1.22 660)
***************
*** 125,131 ****
lh.first = 1;
lh.buff = buff;
lh.bp = bp;
! (void) atr_iter_get(executor, thing, pattern, lattr_helper, &lh);
}
/* ARGSUSED */
--- 125,131 ----
lh.first = 1;
lh.buff = buff;
lh.bp = bp;
! (void) atr_iter_get(executor, thing, pattern, 0, lattr_helper, &lh);
}
/* ARGSUSED */
***************
*** 437,442 ****
--- 437,444 ----
return;
}
safe_str(privs_to_letters(attr_privs, AL_FLAGS(a)), buff, bp);
+ if (atr_sub_branch(a))
+ safe_chr('`', buff, bp);
} else {
/* Object flags, visible to all */
safe_str(unparse_flags(thing, executor), buff, bp);
***************
*** 1501,1512 ****
/* find out what we're matching in relation to */
looker = match_thing(executor, args[0]);
if (!GoodObject(looker)) {
- notify(executor, T("I don't see that here."));
safe_str("#-1", buff, bp);
return;
}
if (!See_All(executor) && !controls(executor, looker)) {
- notify(executor, T("Permission denied."));
safe_str("#-1", buff, bp);
return;
}
--- 1503,1512 ----
***************
*** 1587,1596 ****
else
item = last_match_result(looker, args[1], pref_type, match_flags);
- if (item == NOTHING)
- notify(executor, T("Nothing found."));
- else if (item == AMBIGUOUS)
- notify(executor, T("More than one match found."));
if (GoodObject(item) && (force_type && pref_type != NOTYPE
&& !(Typeof(item) == pref_type)))
safe_dbref(NOTHING, buff, bp);
--- 1587,1592 ----
*** 1_7_7.624/src/function.c Mon, 11 Aug 2003 16:30:36 -0500 dunemush (pennmush/c/18_function.c 1.29.1.14.1.3.1.6.1.1.1.1.1.14.1.2.1.1.1.7.1.22 660)
--- 1_7_7.664(w)/src/function.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/18_function.c 1.29.1.14.1.3.1.6.1.1.1.1.1.14.1.2.1.1.1.7.1.22.1.1 660)
***************
*** 409,415 ****
{"QUOTA", fun_quota, 1, 1, FN_REG},
#endif
{"R", fun_r, 1, 1, FN_REG},
! {"RAND", fun_rand, 1, 1, FN_REG},
{"REGEDIT", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
{"REGEDITALL", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
{"REGEDITALLI", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
--- 409,416 ----
{"QUOTA", fun_quota, 1, 1, FN_REG},
#endif
{"R", fun_r, 1, 1, FN_REG},
! {"RAND", fun_rand, 1, 2, FN_REG},
! {"RANDWORD", fun_randword, 1, 2, FN_REG},
{"REGEDIT", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
{"REGEDITALL", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
{"REGEDITALLI", fun_regreplace, 3, INT_MAX, FN_NOPARSE},
*** 1_7_7.624/src/flags.c Wed, 27 Aug 2003 23:03:24 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.56 660)
--- 1_7_7.664(w)/src/flags.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/20_flags.c 1.1.1.1.1.1.1.1.1.1.1.1.1.6.1.2.1.1.1.1.1.2.2.2.2.1.2.1.1.3.1.2.1.1.1.1.1.1.1.1.1.3.1.9.1.2.2.1.1.2.1.56.1.2 660)
***************
*** 1911,1916 ****
--- 1911,1961 ----
notify(player, T("Unknown failure adding alias."));
}
+ /** Change a flag's alias.
+ * \param player the enactor.
+ * \param name name of the flag.
+ * \param letter The new alias, or an empty string to remove the alias.
+ */
+ void
+ do_flag_letter(dbref player, const char *name, const char *letter)
+ {
+ FLAG *f;
+ FLAGSPACE *n;
+
+ if (!God(player)) {
+ notify(player, T("You don't look like God."));
+ return;
+ }
+ Flagspace_Lookup(n, "FLAG");
+ f = match_flag_ns(n, name);
+ if (!f) {
+ notify(player, T("I don't know that flag."));
+ return;
+ }
+ if (letter && *letter) {
+ FLAG *other;
+
+ if (strlen(letter) > 1) {
+ notify(player, T("Flag characters must be single characters."));
+ return;
+ }
+
+ if ((other = letter_to_flagptr(n, *letter, NOTYPE))) {
+ notify_format(player, T("Letter conflicts with the %s flag."),
+ other->name);
+ return;
+ }
+
+ f->letter = *letter;
+ notify_format(player, T("Letter for flag %s set to '%c'."),
+ f->name, *letter);
+ } else { /* Clear a flag */
+ f->letter = '\0';
+ notify_format(player, T("Letter for flag %s cleared."), f->name);
+ }
+ }
+
+
/** Disable a flag.
* \verbatim
* This function implements @flag/disable.
***************
*** 2065,2071 ****
/** Return a list of all flags.
* \param name wildcard to match against flag names, or NULL for all.
* \param privs the looker, for permission checking.
! * \param which a bitmask of 0x1 (flag chars) and 0x2 (flag names)u
*/
char *
list_all_flags(const char *ns, const char *name, dbref privs, int which)
--- 2110,2116 ----
/** Return a list of all flags.
* \param name wildcard to match against flag names, or NULL for all.
* \param privs the looker, for permission checking.
! * \param which a bitmask of 0x1 (flag chars) and 0x2 (flag names).
*/
char *
list_all_flags(const char *ns, const char *name, dbref privs, int which)
***************
*** 2093,2103 ****
switch (which) {
case 0x3:
if (i)
! safe_chr(' ', buf, &bp);
safe_str(ptrs[i], buf, &bp);
f = match_flag_ns(n, ptrs[i]);
! if (f && (f->letter != '\0'))
safe_format(buf, &bp, " (%c)", f->letter);
break;
case 0x2:
if (i)
--- 2138,2152 ----
switch (which) {
case 0x3:
if (i)
! safe_strl(", ", 2, buf, &bp);
safe_str(ptrs[i], buf, &bp);
f = match_flag_ns(n, ptrs[i]);
! if (!f)
! break;
! if (f->letter != '\0')
safe_format(buf, &bp, " (%c)", f->letter);
+ if (f->perms & F_DISABLED)
+ safe_str(T(" (disabled)"), buf, &bp);
break;
case 0x2:
if (i)
*** 1_7_7.624/src/filecopy.c Thu, 28 Aug 2003 11:10:52 -0500 dunemush (pennmush/c/21_filecopy.c 1.80 660)
--- 1_7_7.664(w)/src/filecopy.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/21_filecopy.c 1.81 660)
***************
*** 256,262 ****
if (panicdb_OK) { /* panicdb */
ConcatenateFiles(options.crash_db, options.input_db);
} else { /* NOTHING */
!
exit(-1);
}
}
}
--- 256,262 ----
if (panicdb_OK) { /* panicdb */
ConcatenateFiles(options.crash_db, options.input_db);
} else { /* NOTHING */
!
return;
}
}
}
*** 1_7_7.624/src/extchat.c Mon, 01 Sep 2003 15:54:38 -0500 dunemush (pennmush/c/23_extchat.c 1.1.1.1.1.1.1.1.1.2.1.1.1.3.1.1.1.5.1.1.1.1.1.5.1.2.1.3.1.3.1.1.1.4.1.2.1.6.1.2.1.1.2.4.2.9.1.2.1.2.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.2.1.1.2.1.1.2.1.1.1.1.1.37.1.2 660)
--- 1_7_7.664(w)/src/extchat.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/23_extchat.c 1.1.1.1.1.1.1.1.1.2.1.1.1.3.1.1.1.5.1.1.1.1.1.5.1.2.1.3.1.3.1.1.1.4.1.2.1.6.1.2.1.1.2.4.2.9.1.2.1.2.1.3.1.2.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.2.1.1.2.1.1.2.1.1.1.1.1.1.1.3 660)
***************
*** 80,85 ****
--- 80,88 ----
static void channel_push_buffer(CHAN *c, char *tbuf1);
static void channel_shift_buffer(CHAN *c, int space_needed);
static int channel_buffer_lines(CHAN *c);
+ static void format_channel_broadcast(CHAN *chan, CHANUSER *u, dbref victim,
+ int flags, const char *msg,
+ const char *extra);
const char *chan_speak_lock = "ChanSpeakLock"; /**< Name of speak lock */
const char *chan_join_lock = "ChanJoinLock"; /**< Name of join lock */
***************
*** 111,116 ****
--- 114,122 ----
{"Quiet", 'Q', CHANNEL_QUIET, CHANNEL_QUIET},
{"Open", 'o', CHANNEL_OPEN, CHANNEL_OPEN},
{"Hide_Ok", 'H', CHANNEL_CANHIDE, CHANNEL_CANHIDE},
+ {"NoTitles", 'T', CHANNEL_NOTITLES, CHANNEL_NOTITLES},
+ {"NoNames", 'N', CHANNEL_NONAMES, CHANNEL_NONAMES},
+ {"NoCemit", 'C', CHANNEL_NOCEMIT, CHANNEL_NOCEMIT},
{NULL, '\0', 0, 0}
};
***************
*** 287,292 ****
--- 293,299 ----
static int
load_channel(FILE * fp, CHAN *ch)
{
+ int ret = 1;
strcpy(ChanName(ch), getstring_noalloc(fp));
if (feof(fp))
return 0;
***************
*** 303,310 ****
ChanNumUsers(ch) = getref(fp);
ChanMaxUsers(ch) = ChanNumUsers(ch);
ChanUsers(ch) = NULL;
! if (ChanNumUsers(ch) > 0)
! return (ChanNumUsers(ch) = load_chanusers(fp, ch));
return 1;
}
--- 310,321 ----
ChanNumUsers(ch) = getref(fp);
ChanMaxUsers(ch) = ChanNumUsers(ch);
ChanUsers(ch) = NULL;
! if (ChanNumUsers(ch) > 0) {
! ret = load_chanusers(fp, ch);
! if (ret < 0)
! return 0;
! ChanNumUsers(ch) = ret;
! }
return 1;
}
***************
*** 321,327 ****
if (GoodObject(player) && Chan_Ok_Type(ch, player)) {
user = new_user(player);
if (!user)
! return 0;
CUtype(user) = getref(fp);
strcpy(CUtitle(user), getstring_noalloc(fp));
CUnext(user) = NULL;
--- 332,338 ----
if (GoodObject(player) && Chan_Ok_Type(ch, player)) {
user = new_user(player);
if (!user)
! return -1;
CUtype(user) = getref(fp);
strcpy(CUtitle(user), getstring_noalloc(fp));
CUnext(user) = NULL;
***************
*** 876,881 ****
--- 887,893 ----
do_channel(dbref player, const char *name, const char *target, const char *com)
{
CHAN *chan = NULL;
+ CHANUSER *u;
dbref victim;
if (!name && !*name) {
***************
*** 973,990 ****
notify_format(player,
T("CHAT: You join %s to channel <%s>."), Name(victim),
ChanName(chan));
! if (!Channel_Quiet(chan) && !DarkLegal(victim))
! channel_broadcast(chan, victim, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has joined this channel."), ChanName(chan),
! Name(victim));
! ChanNumUsers(chan)++;
! } else {
! notify_format(player,
! T("%s is already on channel <%s>."), Name(victim),
! ChanName(chan));
}
- return;
} else if (!strcasecmp("off", com) || !strcasecmp("leave", com)) {
/* You must control either the victim or the channel */
if (!controls(player, victim) && !Chan_Can_Modify(chan, player)) {
notify(player, T("Invalid target."));
--- 985,1004 ----
notify_format(player,
T("CHAT: You join %s to channel <%s>."), Name(victim),
ChanName(chan));
! u = onchannel(victim, chan);
! if (!Channel_Quiet(chan) && !DarkLegal(victim)) {
! format_channel_broadcast(chan, u, victim, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has joined this channel."), NULL);
! ChanNumUsers(chan)++;
! } else {
! notify_format(player,
! T("%s is already on channel <%s>."), Name(victim),
! ChanName(chan));
! }
! return;
}
} else if (!strcasecmp("off", com) || !strcasecmp("leave", com)) {
+ char title[CU_TITLE_LEN];
/* You must control either the victim or the channel */
if (!controls(player, victim) && !Chan_Can_Modify(chan, player)) {
notify(player, T("Invalid target."));
***************
*** 994,1004 ****
notify(player, T("Guests may not leave channels."));
return;
}
! if (remove_user_by_dbref(victim, chan)) {
! if (!Channel_Quiet(chan) && !DarkLegal(victim))
! channel_broadcast(chan, victim, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has left this channel."), ChanName(chan),
! Name(victim));
notify_format(victim,
T("CHAT: %s removes you from channel <%s>."),
Name(player), ChanName(chan));
--- 1008,1021 ----
notify(player, T("Guests may not leave channels."));
return;
}
! u = onchannel(victim, chan);
! strcpy(title, (u &&CUtitle(u)) ? CUtitle(u) : "");
! if (remove_user(u, chan)) {
! if (!Channel_Quiet(chan) && !DarkLegal(victim)) {
! format_channel_broadcast(chan, NULL, victim,
! CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has left this channel."), title);
! }
notify_format(victim,
T("CHAT: %s removes you from channel <%s>."),
Name(player), ChanName(chan));
***************
*** 1020,1031 ****
channel_join_self(dbref player, const char *name)
{
CHAN *chan = NULL;
if (Guest(player)) {
notify(player, T("Guests are not allowed to join channels."));
return;
}
-
switch (find_channel_partial_off(name, &chan, player)) {
case CMATCH_NONE:
if (find_channel_partial_on(name, &chan, player))
--- 1037,1049 ----
channel_join_self(dbref player, const char *name)
{
CHAN *chan = NULL;
+ CHANUSER *u;
+
if (Guest(player)) {
notify(player, T("Guests are not allowed to join channels."));
return;
}
switch (find_channel_partial_off(name, &chan, player)) {
case CMATCH_NONE:
if (find_channel_partial_on(name, &chan, player))
***************
*** 1062,1071 ****
}
if (insert_user_by_dbref(player, chan)) {
notify_format(player, T("CHAT: You join channel <%s>."), ChanName(chan));
if (!Channel_Quiet(chan) && !DarkLegal(player))
! channel_broadcast(chan, player, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has joined this channel."), ChanName(chan),
! Name(player));
ChanNumUsers(chan)++;
} else {
/* Should never happen */
--- 1080,1089 ----
}
if (insert_user_by_dbref(player, chan)) {
notify_format(player, T("CHAT: You join channel <%s>."), ChanName(chan));
+ u = onchannel(player, chan);
if (!Channel_Quiet(chan) && !DarkLegal(player))
! format_channel_broadcast(chan, u, player, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has joined this channel."), NULL);
ChanNumUsers(chan)++;
} else {
/* Should never happen */
***************
*** 1079,1084 ****
--- 1097,1105 ----
channel_leave_self(dbref player, const char *name)
{
CHAN *chan = NULL;
+ CHANUSER *u;
+ char title[CU_TITLE_LEN];
+
if (Guest(player)) {
notify(player, T("Guests are not allowed to leave channels."));
return;
***************
*** 1096,1106 ****
notify(player, T("CHAT: I don't know which channel you mean."));
return;
}
! if (remove_user_by_dbref(player, chan)) {
if (!Channel_Quiet(chan) && !DarkLegal(player))
! channel_broadcast(chan, player, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has left this channel."), ChanName(chan),
! Name(player));
notify_format(player, T("CHAT: You leave channel <%s>."), ChanName(chan));
} else {
/* Should never happen */
--- 1117,1128 ----
notify(player, T("CHAT: I don't know which channel you mean."));
return;
}
! u = onchannel(player, chan);
! strcpy(title, (u &&CUtitle(u)) ? CUtitle(u) : "");
! if (remove_user(u, chan)) {
if (!Channel_Quiet(chan) && !DarkLegal(player))
! format_channel_broadcast(chan, NULL, player, CB_CHECKQUIET | CB_PRESENCE,
! T("<%s> %s has left this channel."), title);
notify_format(player, T("CHAT: You leave channel <%s>."), ChanName(chan));
} else {
/* Should never happen */
***************
*** 1196,1207 ****
{
CHANUSER *u;
const char *gap;
char *title;
int canhear;
if (!Chan_Ok_Type(chan, player)) {
notify_format(player,
! T("Sorry, you're not the right type to be on channel <%s>."),
ChanName(chan));
return;
}
--- 1218,1232 ----
{
CHANUSER *u;
const char *gap;
+ const char *someone = "Someone";
char *title;
+ const char *name;
int canhear;
if (!Chan_Ok_Type(chan, player)) {
notify_format(player,
! T
! ("Sorry, you're not the right type to be on channel <%s>."),
ChanName(chan));
return;
}
***************
*** 1232,1241 ****
return;
}
! if (u &&CUtitle(u) && *CUtitle(u))
title = CUtitle(u);
else
title = NULL;
/* figure out what kind of message we have */
gap = " ";
--- 1257,1272 ----
return;
}
! if (!Channel_NoTitles(chan) && u &&CUtitle(u) && *CUtitle(u))
title = CUtitle(u);
else
title = NULL;
+ if (Channel_NoNames(chan))
+ name = NULL;
+ else
+ name = accented_name(player);
+ if (!title && !name)
+ name = someone;
/* figure out what kind of message we have */
gap = " ";
***************
*** 1247,1268 ****
arg1 = arg1 + 1;
channel_broadcast(chan, player, 0, "<%s> %s%s%s%s%s%s", ChanName(chan),
title ? title : "", title ? ANSI_NORMAL : "",
! title ? " " : "", accented_name(player), gap, arg1);
if (!canhear)
! notify_format(player, T("To channel %s: %s%s%s"), ChanName(chan),
! accented_name(player), gap, arg1);
break;
default:
if (CHAT_STRIP_QUOTE && (*arg1 == SAY_TOKEN))
arg1 = arg1 + 1;
channel_broadcast(chan, player, 0, T("<%s> %s%s%s%s says, \"%s\""),
ChanName(chan), title ? title : "",
! title ? ANSI_NORMAL : "", title ? " " : "",
! accented_name(player), arg1);
if (!canhear)
notify_format(player,
! T("To channel %s: %s says, \"%s\""), ChanName(chan),
! accented_name(player), arg1);
break;
}
--- 1278,1302 ----
arg1 = arg1 + 1;
channel_broadcast(chan, player, 0, "<%s> %s%s%s%s%s%s", ChanName(chan),
title ? title : "", title ? ANSI_NORMAL : "",
! (title && name) ? " " : "", name ? name : "", gap, arg1);
if (!canhear)
! notify_format(player, T("To channel %s: %s%s%s%s%s%s"), ChanName(chan),
! title ? title : "", title ? ANSI_NORMAL : "",
! (title && name) ? " " : "", name ? name : "", gap, arg1);
break;
default:
if (CHAT_STRIP_QUOTE && (*arg1 == SAY_TOKEN))
arg1 = arg1 + 1;
channel_broadcast(chan, player, 0, T("<%s> %s%s%s%s says, \"%s\""),
ChanName(chan), title ? title : "",
! title ? ANSI_NORMAL : "", (title && name) ? " " : "",
! name ? name : "", arg1);
if (!canhear)
notify_format(player,
! T("To channel %s: %s%s%s%s says, \"%s\""),
! ChanName(chan), title ? title : "",
! title ? ANSI_NORMAL : "", (title && name) ? " " : "",
! name ? name : "", arg1);
break;
}
***************
*** 1303,1315 ****
}
if (!Chan_Ok_Type(chan, player)) {
notify_format(player,
! T("Sorry, you're not the right type to be on channel <%s>."),
ChanName(chan));
return;
}
! if (!Chan_Can_Speak(chan, player)) {
notify_format(player,
! T("Sorry, you're not allowed to speak on channel <%s>."),
ChanName(chan));
return;
}
--- 1337,1350 ----
}
if (!Chan_Ok_Type(chan, player)) {
notify_format(player,
! T
! ("Sorry, you're not the right type to be on channel <%s>."),
ChanName(chan));
return;
}
! if (!Chan_Can_Cemit(chan, player)) {
notify_format(player,
! T("Sorry, you're not allowed to @cemit on channel <%s>."),
ChanName(chan));
return;
}
***************
*** 1343,1354 ****
/** Administrative channel commands.
* \verbatim
* This is one of top-level functions for @channel. This one handles
! * the /add, /delete, /rename, /priv, and /quiet switches.
* \endverbatim
* \param player the enactor.
* \param name the name of the channel.
* \param perms the permissions to set on an added/priv'd channel, the newname for a renamed channel, or on/off for a quieted channel.
! * \param flag switch indicator: 0=add, 1=delete, 2=rename, 3=priv, 4=quiet
*/
void
do_chan_admin(dbref player, char *name, const char *perms, int flag)
--- 1378,1389 ----
/** Administrative channel commands.
* \verbatim
* This is one of top-level functions for @channel. This one handles
! * the /add, /delete, /rename, and /priv switches.
* \endverbatim
* \param player the enactor.
* \param name the name of the channel.
* \param perms the permissions to set on an added/priv'd channel, the newname for a renamed channel, or on/off for a quieted channel.
! * \param flag switch indicator: 0=add, 1=delete, 2=rename, 3=priv
*/
void
do_chan_admin(dbref player, char *name, const char *perms, int flag)
***************
*** 1509,1527 ****
T("Permissions on channel <%s> changed."), ChanName(chan));
}
break;
- case 4:
- /* Quiet a channel */
- if (!Chan_Can_Modify(chan, player)) {
- notify(player, T("Permission denied. Use @channel/mute <chan>=<y/n>"));
- return;
- }
- if (abs(yesno(perms)))
- ChanType(chan) |= CHANNEL_QUIET;
- else
- ChanType(chan) &= ~CHANNEL_QUIET;
- notify_format(player,
- T("Quiet status on channel <%s> changed."), ChanName(chan));
- break;
}
}
--- 1544,1549 ----
***************
*** 1653,1659 ****
CUtype(u) |= CU_HIDE;
if (!silent)
notify_format(player,
! T("You no longer appear on channel <%s>'s who list."),
ChanName(c));
}
} else {
--- 1675,1682 ----
CUtype(u) |= CU_HIDE;
if (!silent)
notify_format(player,
! T
! ("You no longer appear on channel <%s>'s who list."),
ChanName(c));
}
} else {
***************
*** 1670,1676 ****
CUtype(u) |= CU_GAG;
if (!silent)
notify_format(player,
! T("You will no longer hear messages on channel <%s>."),
ChanName(c));
} else {
CUtype(u) &= ~CU_GAG;
--- 1693,1700 ----
CUtype(u) |= CU_GAG;
if (!silent)
notify_format(player,
! T
! ("You will no longer hear messages on channel <%s>."),
ChanName(c));
} else {
CUtype(u) &= ~CU_GAG;
***************
*** 2447,2460 ****
{
CHAN *c;
CHANUSER *u;
for (c = channels; c; c = c->next) {
u = onchannel(player, c);
if (u) {
if (!Channel_Quiet(c) && (Channel_Admin(c) || Channel_Wizard(c)
! || (!Chanuser_Hide(u) && !Dark(player))))
! channel_broadcast(c, player, CB_CHECKQUIET | CB_PRESENCE, "<%s> %s",
! ChanName(c), msg);
CUtype(u) &= ~CU_GAG;
}
}
--- 2471,2490 ----
{
CHAN *c;
CHANUSER *u;
+ char buff[BUFFER_LEN], *bp;
for (c = channels; c; c = c->next) {
u = onchannel(player, c);
if (u) {
if (!Channel_Quiet(c) && (Channel_Admin(c) || Channel_Wizard(c)
! || (!Chanuser_Hide(u) && !Dark(player)))) {
! bp = buff;
!
! safe_format(buff, &bp, "<%s> %s", "%s", msg);
! *bp = '\0';
! format_channel_broadcast(c, u, player, CB_CHECKQUIET | CB_PRESENCE,
! buff, NULL);
! }
CUtype(u) &= ~CU_GAG;
}
}
***************
*** 2639,2648 ****
do_chan_admin(player, arg_left, arg_right, 2);
else if (SW_ISSET(sw, SWITCH_PRIVS))
do_chan_admin(player, arg_left, arg_right, 3);
else if (SW_ISSET(sw, SWITCH_QUIET))
! do_chan_admin(player, arg_left, arg_right, 4);
else if (SW_ISSET(sw, SWITCH_NOISY))
! do_chan_admin(player, arg_left, "n", 4);
else if (SW_ISSET(sw, SWITCH_DECOMPILE))
do_chan_decompile(player, arg_left, SW_ISSET(sw, SWITCH_BRIEF));
else if (SW_ISSET(sw, SWITCH_DESCRIBE))
--- 2669,2680 ----
do_chan_admin(player, arg_left, arg_right, 2);
else if (SW_ISSET(sw, SWITCH_PRIVS))
do_chan_admin(player, arg_left, arg_right, 3);
+ else if (SW_ISSET(sw, SWITCH_RECALL))
+ do_chan_recall(player, arg_left, arg_right, SW_ISSET(sw, SWITCH_QUIET));
else if (SW_ISSET(sw, SWITCH_QUIET))
! do_chan_admin(player, arg_left, "quiet", 3);
else if (SW_ISSET(sw, SWITCH_NOISY))
! do_chan_admin(player, arg_left, "!quiet", 3);
else if (SW_ISSET(sw, SWITCH_DECOMPILE))
do_chan_decompile(player, arg_left, SW_ISSET(sw, SWITCH_BRIEF));
else if (SW_ISSET(sw, SWITCH_DESCRIBE))
***************
*** 2667,2674 ****
do_chan_user_flags(player, arg_left, "n", 2, 0);
else if (SW_ISSET(sw, SWITCH_WHAT))
do_chan_what(player, arg_left);
- else if (SW_ISSET(sw, SWITCH_RECALL))
- do_chan_recall(player, arg_left, arg_right);
else if (SW_ISSET(sw, SWITCH_BUFFER))
do_chan_buffer(player, arg_left, arg_right);
else
--- 2699,2704 ----
***************
*** 2896,2904 ****
* \param player the enactor.
* \param name the name of the channel.
* \param lines a string given the number of lines to recall (default all).
*/
void
! do_chan_recall(dbref player, const char *name, const char *lines)
{
CHAN *chan;
CHANUSER *u;
--- 2926,2935 ----
* \param player the enactor.
* \param name the name of the channel.
* \param lines a string given the number of lines to recall (default all).
+ * \param quiet if true, don't show timestamps.
*/
void
! do_chan_recall(dbref player, const char *name, const char *lines, int quiet)
{
CHAN *chan;
CHANUSER *u;
***************
*** 2967,2982 ****
memcpy(&size, p, sizeof size);
p += sizeof size;
memcpy(×tamp, p, sizeof timestamp);
- stamp = show_time(timestamp, 0);
p += sizeof timestamp;
memcpy(tbuf1, p, size + 1);
! notify_format(player, "[%s] %s", stamp, tbuf1);
p += size + 1;
}
notify(player, T("CHAT: End recall"));
if (!lines || !*lines)
notify_format(player,
! T("CHAT: To recall the entire buffer, use @chan/recall %s=0"),
ChanName(chan));
}
--- 2998,3018 ----
memcpy(&size, p, sizeof size);
p += sizeof size;
memcpy(×tamp, p, sizeof timestamp);
p += sizeof timestamp;
memcpy(tbuf1, p, size + 1);
! if (quiet) {
! notify(player, tbuf1);
! } else {
! stamp = show_time(timestamp, 0);
! notify_format(player, "[%s] %s", stamp, tbuf1);
! }
p += size + 1;
}
notify(player, T("CHAT: End recall"));
if (!lines || !*lines)
notify_format(player,
! T
! ("CHAT: To recall the entire buffer, use @chan/recall %s=0"),
ChanName(chan));
}
***************
*** 3041,3046 ****
--- 3077,3100 ----
}
}
+ static void
+ format_channel_broadcast(CHAN *chan, CHANUSER *u, dbref victim, int flags,
+ const char *msg, const char *extra)
+ {
+ const char *title = NULL;
+ if (extra && *extra)
+ title = extra;
+ else if (u &&CUtitle(u))
+ title = CUtitle(u);
+
+ if (Channel_NoNames(chan)) {
+ if (Channel_NoTitles(chan) || !title)
+ channel_broadcast(chan, victim, flags, msg, ChanName(chan), "Someone");
+ else
+ channel_broadcast(chan, victim, flags, msg, ChanName(chan), title);
+ } else
+ channel_broadcast(chan, victim, flags, msg, ChanName(chan), Name(victim));
+ }
#endif /* CHAT_SYSTEM */
*** 1_7_7.624/src/destroy.c Tue, 13 May 2003 12:53:40 -0500 dunemush (pennmush/c/24_destroy.c 1.24.2.2.1.3.1.1.1.1.1.1.1.4.1.1.1.2 660)
--- 1_7_7.664(w)/src/destroy.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/24_destroy.c 1.24.2.2.1.3.1.1.1.1.1.1.1.4.1.1.1.1.1.3 660)
***************
*** 726,731 ****
--- 726,732 ----
Type(thing) = TYPE_GARBAGE;
destroy_flag_bitmask(Flags(thing));
Flags(thing) = NULL;
+ Powers(thing) = 0;
Location(thing) = NOTHING;
set_name(thing, "Garbage");
Exits(thing) = NOTHING;
***************
*** 1112,1118 ****
* an invalid dbref, change its ownership to God.
*/
if (!IsGarbage(thing))
! atr_iter_get(GOD, thing, NULL, attribute_owner_helper, NULL);
}
}
}
--- 1113,1119 ----
* an invalid dbref, change its ownership to God.
*/
if (!IsGarbage(thing))
! atr_iter_get(GOD, thing, "**", 0, attribute_owner_helper, NULL);
}
}
}
*** 1_7_7.624/src/cque.c Mon, 28 Apr 2003 22:37:00 -0500 dunemush (pennmush/c/28_cque.c 1.36.1.5.1.1.1.1.1.1.1.2.1.6.1.9 660)
--- 1_7_7.664(w)/src/cque.c Mon, 29 Sep 2003 16:42:31 -0500 dunemush (pennmush/c/28_cque.c 1.36.1.5.1.1.1.1.1.1.1.2.1.6.1.10 660)
***************
*** 667,673 ****
if (aname)
(void) atr_clr(thing, aname, GOD);
else
! atr_iter_get(GOD, thing, "*", drain_helper, NULL);
}
/* If @notify and count was higher than the number of queue entries,
--- 667,673 ----
if (aname)
(void) atr_clr(thing, aname, GOD);
else
! atr_iter_get(GOD, thing, "**", 0, drain_helper, NULL);
}
/* If @notify and count was higher than the number of queue entries,
*** 1_7_7.624/src/command.c Mon, 01 Sep 2003 23:41:11 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.20 660)
--- 1_7_7.664(w)/src/command.c Mon, 29 Sep 2003 16:42:30 -0500 dunemush (pennmush/c/36_command.c 1.56.1.1.1.1.1.1.1.2.1.1.1.1.1.5.1.2.1.1.1.1.1.2.1.3.1.10.1.1.3.22 660)
***************
*** 79,85 ****
{"@CEMIT", "NOEVAL NOISY", cmd_cemit,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
{"@CHANNEL",
! "LIST ADD DELETE RENAME NAME PRIVS QUIET NOISY DECOMPILE DESCRIBE CHOWN WIPE MUTE UNMUTE GAG UNGAG HIDE UNHIDE WHAT TITLE BRIEF RECALL BUFFER",
cmd_channel,
CMD_T_ANY | CMD_T_SWITCHES | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
{"@CHAT", NULL, cmd_chat, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
--- 79,85 ----
{"@CEMIT", "NOEVAL NOISY", cmd_cemit,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
{"@CHANNEL",
! "LIST ADD DELETE RENAME NAME PRIVS QUIET NOISY DECOMPILE DESCRIBE CHOWN WIPE MUTE UNMUTE GAG UNGAG HIDE UNHIDE WHAT TITLE BRIEF RECALL BUFFER SET",
cmd_channel,
CMD_T_ANY | CMD_T_SWITCHES | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
{"@CHAT", NULL, cmd_chat, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
***************
*** 139,145 ****
{"@FIND", NULL, cmd_find,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
{"@FIRSTEXIT", NULL, cmd_firstexit, CMD_T_ANY, 0, 0},
! {"@FLAG", "ADD LIST RESTRICT DELETE ALIAS DISABLE ENABLE", cmd_flag,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
{"@FORCE", "NOEVAL", cmd_force, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
--- 139,145 ----
{"@FIND", NULL, cmd_find,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
{"@FIRSTEXIT", NULL, cmd_firstexit, CMD_T_ANY, 0, 0},
! {"@FLAG", "ADD LETTER LIST RESTRICT DELETE ALIAS DISABLE ENABLE", cmd_flag,
CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
{"@FORCE", "NOEVAL", cmd_force, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
*** 1_7_7.624/src/cmds.c Mon, 01 Sep 2003 22:38:06 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.20.1.3 660)
--- 1_7_7.664(w)/src/cmds.c Mon, 29 Sep 2003 16:42:30 -0500 dunemush (pennmush/c/37_cmds.c 1.33.1.1.1.2.1.2.2.3.1.1.1.2.1.1.1.3.1.8.1.1.2.2.2.20.1.3.1.2 660)
***************
*** 249,263 ****
COMMAND (cmd_entrances) {
if (SW_ISSET(sw, SWITCH_EXITS))
! do_entrances(player, arg_left, args_right, 1);
else if (SW_ISSET(sw, SWITCH_THINGS))
! do_entrances(player, arg_left, args_right, 2);
else if (SW_ISSET(sw, SWITCH_PLAYERS))
! do_entrances(player, arg_left, args_right, 3);
else if (SW_ISSET(sw, SWITCH_ROOMS))
! do_entrances(player, arg_left, args_right, 4);
else
! do_entrances(player, arg_left, args_right, 0);
}
COMMAND (cmd_eunlock) {
--- 249,263 ----
COMMAND (cmd_entrances) {
if (SW_ISSET(sw, SWITCH_EXITS))
! do_entrances(player, arg_left, args_right, ENT_EXITS);
else if (SW_ISSET(sw, SWITCH_THINGS))
! do_entrances(player, arg_left, args_right, ENT_THINGS);
else if (SW_ISSET(sw, SWITCH_PLAYERS))
! do_entrances(player, arg_left, args_right, ENT_PLAYERS);
else if (SW_ISSET(sw, SWITCH_ROOMS))
! do_entrances(player, arg_left, args_right, ENT_ROOMS);
else
! do_entrances(player, arg_left, args_right, ENT_ALL);
}
COMMAND (cmd_eunlock) {
***************
*** 287,292 ****
--- 287,294 ----
do_flag_disable(player, arg_left);
else if (SW_ISSET(sw, SWITCH_ENABLE))
do_flag_enable(player, arg_left);
+ else if (SW_ISSET(sw, SWITCH_LETTER))
+ do_flag_letter(player, arg_left, args_right[1]);
else
do_flag_info("FLAG", player, arg_left);
}
*** 1_7_7.624/src/bsd.c Thu, 04 Sep 2003 17:27:46 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.24.1.8.1.2 660)
--- 1_7_7.664(w)/src/bsd.c Mon, 29 Sep 2003 16:42:30 -0500 dunemush (pennmush/c/38_bsd.c 1.58.1.11.1.2.1.5.1.7.1.14.1.13.1.9.1.4.1.2.1.12.1.1.1.1.1.2.1.1.1.13.1.1.1.1.1.1.1.1.1.1.1.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.3.1.8.2.1.1.1.1.1.1.1.1.2.1.1.1.1.1.1.1.1.1.1.1.1.1.2 660)
***************
*** 1014,1025 ****
#endif
if (!restarting) {
sock = make_socket(port, NULL, NULL, MUSH_IP_ADDR);
! maxd = sock + 1;
#ifdef HAS_OPENSSL
if (sslport) {
sslsock = make_socket(sslport, NULL, NULL, MUSH_IP_ADDR);
ssl_master_socket = ssl_setup_socket(sslsock);
! maxd = sslsock + 1;
}
#endif
}
--- 1014,1027 ----
#endif
if (!restarting) {
sock = make_socket(port, NULL, NULL, MUSH_IP_ADDR);
! if (sock >= maxd)
! maxd = sock + 1;
#ifdef HAS_OPENSSL
if (sslport) {
sslsock = make_socket(sslport, NULL, NULL, MUSH_IP_ADDR);
ssl_master_socket = ssl_setup_socket(sslsock);
! if (sslsock >= maxd)
! maxd = sslsock + 1;
}
#endif
}
***************
*** 4697,4703 ****
}
sock = getref(f);
! maxd = getref(f);
while ((val = getref(f)) != 0) {
ndescriptors++;
d = (DESC *) mush_malloc(sizeof(DESC), "descriptor");
--- 4699,4708 ----
}
sock = getref(f);
! val = getref(f);
! if (val > maxd)
! maxd = val;
!
while ((val = getref(f)) != 0) {
ndescriptors++;
d = (DESC *) mush_malloc(sizeof(DESC), "descriptor");
*** 1_7_7.624/src/attrib.c Wed, 03 Sep 2003 22:39:22 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.29 660)
--- 1_7_7.664(w)/src/attrib.c Mon, 29 Sep 2003 16:42:30 -0500 dunemush (pennmush/c/40_attrib.c 1.15.1.2.1.5.1.1.1.3.1.3.1.2.1.2.1.2.2.1.1.2.1.2.1.2.1.1.1.3.1.1.1.1.1.1.3.36 660)
***************
*** 46,51 ****
--- 46,64 ----
/** Table of attribute flags. */
extern PRIV attr_privs[];
+ /** A flag to show if we're in the middle of a @wipe (this changes
+ * behaviour for atr_clr()). Yes, this is gross and ugly, but it
+ * seemed like a better idea than propogating a signature changes
+ * for atr_clr() and do_set_atr() through the entire codebase. If
+ * you come up with a better way, PLEASE fix this...
+ */
+ int we_are_wiping;
+
+ /** A string to hold the name of a missing prefix branch, set by
+ * can_write_attr_internal. Again, gross and ugly. Please fix.
+ */
+ static char missing_name[ATTRIBUTE_NAME_LIMIT + 1];
+
/*======================================================================*/
/** How many attributes go in a "page" of attribute memory? */
***************
*** 79,85 ****
/** Decide if a name is valid for an attribute.
* A good attribute name is at least one character long, no more than
* ATTRIBUTE_NAME_LIMIT characters long, and every character is a
! * valid character.
* \param s a string to test for validity as an attribute name.
*/
int
--- 92,99 ----
/** Decide if a name is valid for an attribute.
* A good attribute name is at least one character long, no more than
* ATTRIBUTE_NAME_LIMIT characters long, and every character is a
! * valid character. An attribute name may not start or end with a backtick.
! * An attribute name may not contain multiple consecutive backticks.
* \param s a string to test for validity as an attribute name.
*/
int
***************
*** 89,97 ****
--- 103,117 ----
int len = 0;
if (!s || !*s)
return 0;
+ if (*s == '`')
+ return 0;
+ if (strstr(s, "``"))
+ return 0;
for (a = (const unsigned char *) s; *a; a++, len++)
if (!atr_name_table[*a])
return 0;
+ if (*(s + len - 1) == '`')
+ return 0;
return len <= ATTRIBUTE_NAME_LIMIT;
}
***************
*** 105,110 ****
--- 125,155 ----
return aname_hash_lookup(string);
}
+ /** Find the first attribute branching off the specified attribute.
+ * \param branch the attribute to look under
+ */
+ ATTR *
+ atr_sub_branch(ATTR *branch)
+ {
+ char const *name, *n2;
+ size_t len;
+
+ name = AL_NAME(branch);
+ len = strlen(name);
+ for (branch = AL_NEXT(branch); branch; branch = AL_NEXT(branch)) {
+ n2 = AL_NAME(branch);
+ if (strlen(n2) <= len)
+ return NULL;
+ if (n2[len] == '`') {
+ if (!strncmp(n2, name, len))
+ return branch;
+ else
+ return NULL;
+ }
+ }
+ return NULL;
+ }
+
/** Convert a string of attribute flags to a bitmask.
* Given a space-separated string of attribute flags, look them up
* and return a bitmask of them if player is permitted to use
***************
*** 127,132 ****
--- 172,188 ----
return f;
}
+ /** Convert an attribute flag bitmask into a list of the full
+ * names of the flags.
+ * \param flags the attribute flags to display.
+ * \return a pointer to a static buffer with the full names of the flags.
+ */
+ const char *
+ atrflag_to_string(int mask)
+ {
+ return privs_to_string(attr_privs, mask);
+ }
+
/** Add an attribute to an object, dangerously.
* This is a stripped down version of atr_add, without duplicate checking,
* permissions checking, attribute count checking, or auto-ODARKing.
***************
*** 333,338 ****
--- 389,395 ----
/** Remove an attribute from an object.
* This function clears an attribute from an object.
+ * Permission is denied if the attribute is a branch, not a leaf.
* \param thing object to clear attribute from.
* \param atr name of attribute to remove.
* \param player enactor attempting to remove attribute.
***************
*** 340,347 ****
int
atr_clr(dbref thing, char const *atr, dbref player)
{
! ATTR *ptr, **prev;
int comp = 0;
prev = &List(thing);
ptr = *prev;
--- 397,405 ----
int
atr_clr(dbref thing, char const *atr, dbref player)
{
! ATTR *ptr, **prev, *sub;
int comp = 0;
+ size_t len;
prev = &List(thing);
ptr = *prev;
***************
*** 358,363 ****
--- 416,426 ----
if (!Can_Write_Attr(player, thing, ptr))
return -1;
+ len = strlen(AL_NAME(ptr));
+ sub = atr_sub_branch(ptr);
+ if (!we_are_wiping && sub)
+ return -1;
+
if (!IsPlayer(thing) && !(AL_FLAGS(ptr) & AF_NODUMP))
ModTime(thing) = mudtime;
***************
*** 371,376 ****
--- 434,459 ----
AL_FLAGS(ptr) = 0;
atr_free_list = ptr;
AttrCount(thing)--;
+
+ if (we_are_wiping && sub) {
+ while (*prev != sub)
+ prev = &AL_NEXT(*prev);
+ ptr = *prev;
+ while (ptr && strlen(AL_NAME(ptr)) > len && AL_NAME(ptr)[len] == '`') {
+ *prev = AL_NEXT(ptr);
+
+ if (ptr->data)
+ chunk_delete(ptr->data);
+ st_delete(AL_NAME(ptr), &atr_names);
+
+ AL_NEXT(ptr) = atr_free_list;
+ AL_FLAGS(ptr) = 0;
+ atr_free_list = ptr;
+ AttrCount(thing)--;
+
+ ptr = *prev;
+ }
+ }
return 1;
}
***************
*** 380,479 ****
* matches or NULL. This is a pointer to an attribute structure, not
* to the value of the attribute, so the value is usually accessed
* through atr_value() or safe_atr_value().
! * \param thing the object containing the attribute.
! * \param atr the name of the attribute.
* \return pointer to the attribute structure retrieved, or NULL.
*/
ATTR *
! atr_get(dbref thing, char const *atr)
{
! ATTR *ptr;
int parent_depth;
! dbref temp;
dbref ancestor;
int comp;
! if (thing == NOTHING || !good_atr_name(atr))
return NULL;
! ancestor = Ancestor_Parent(thing);
! for (parent_depth = 0, temp = thing;
! parent_depth < MAX_PARENTS && temp != NOTHING;
! parent_depth++, temp = Parent(temp)) {
! /* If the ancestor of the object is in its explict parent chain,
! * we use it there, and don't check the ancestor later
! */
! if (temp == ancestor)
! ancestor = NOTHING;
! for (ptr = List(temp); ptr; ptr = AL_NEXT(ptr)) {
! comp = strcoll(atr, AL_NAME(ptr));
! if (comp < 0)
! break;
! if (comp == 0) {
! if (temp == thing || !(AL_FLAGS(ptr) & AF_PRIVATE))
! return ptr;
! else
! break;
! }
! }
! }
! /* If we have a valid ancestor, search it as well */
! if (GoodObject(ancestor)) {
! for (parent_depth = 0, temp = ancestor;
! parent_depth < MAX_PARENTS && temp != NOTHING;
! parent_depth++, temp = Parent(temp)) {
! for (ptr = List(temp); ptr; ptr = AL_NEXT(ptr)) {
! comp = strcoll(atr, AL_NAME(ptr));
! if (comp < 0)
! break;
! if (comp == 0) {
! if (temp == thing || !(AL_FLAGS(ptr) & AF_PRIVATE))
! return ptr;
! else
! break;
}
}
- }
- }
! /* Perhaps we should try the alias */
! ptr = atr_match(atr);
! if (!ptr || !strcmp(atr, AL_NAME(ptr)))
! return NULL;
! atr = AL_NAME(ptr);
!
! for (parent_depth = 0, temp = thing;
! parent_depth < MAX_PARENTS && temp != NOTHING;
! parent_depth++, temp = Parent(temp)) {
! for (ptr = List(temp); ptr; ptr = AL_NEXT(ptr)) {
! comp = strcoll(atr, AL_NAME(ptr));
! if (comp < 0)
! break;
! if (comp == 0) {
! if (temp == thing || !(AL_FLAGS(ptr) & AF_PRIVATE))
! return ptr;
! else
! break;
! }
! }
! }
! /* If we have a valid ancestor, search it as well */
! if (GoodObject(ancestor)) {
! for (parent_depth = 0, temp = ancestor;
! parent_depth < MAX_PARENTS && temp != NOTHING;
! parent_depth++, temp = Parent(temp)) {
! for (ptr = List(temp); ptr; ptr = AL_NEXT(ptr)) {
! comp = strcoll(atr, AL_NAME(ptr));
if (comp < 0)
break;
if (comp == 0) {
! if (temp == thing || !(AL_FLAGS(ptr) & AF_PRIVATE))
! return ptr;
else
break;
}
}
}
}
return NULL;
--- 463,553 ----
* matches or NULL. This is a pointer to an attribute structure, not
* to the value of the attribute, so the value is usually accessed
* through atr_value() or safe_atr_value().
! * \param obj the object containing the attribute.
! * \param atrname the name of the attribute.
* \return pointer to the attribute structure retrieved, or NULL.
*/
ATTR *
! atr_get(dbref obj, char const *atrname)
{
! static char name[ATTRIBUTE_NAME_LIMIT + 1];
! char *p;
! ATTR *atr;
int parent_depth;
! dbref target;
dbref ancestor;
int comp;
! if (obj == NOTHING || !good_atr_name(atrname))
return NULL;
! /* First try given name, then try alias match. */
! strcpy(name, atrname);
! for (;;) {
! /* Hunt through the parents/ancestor chain... */
! ancestor = Ancestor_Parent(obj);
! target = obj;
! parent_depth = 0;
! while (parent_depth < MAX_PARENTS && GoodObject(target)) {
! /* If the ancestor of the object is in its explict parent chain,
! * we use it there, and don't check the ancestor later.
! */
! if (target == ancestor)
! ancestor = NOTHING;
! atr = List(target);
!
! /* If we're looking at a parent/ancestor, then we
! * need to check the branch path for privacy... */
! if (target != obj) {
! for (p = strchr(name, '`'); p; p = strchr(p + 1, '`')) {
! *p = '\0';
! while (atr) {
! comp = strcoll(name, AL_NAME(atr));
! if (comp < 0) {
! *p = '`';
! goto continue_target;
! }
! if (comp == 0)
! break;
! atr = AL_NEXT(atr);
! }
! if (!atr || (AL_FLAGS(atr) & AF_PRIVATE)) {
! *p = '`';
! goto continue_target;
! }
! *p = '`';
}
}
! /* Now actually find the attribute. */
! while (atr) {
! comp = strcoll(name, AL_NAME(atr));
if (comp < 0)
break;
if (comp == 0) {
! if (target == obj || !(AL_FLAGS(atr) & AF_PRIVATE))
! return atr;
else
break;
}
+ atr = AL_NEXT(atr);
+ }
+
+ continue_target:
+ /* Attribute wasn't on this object. Check a parent or ancestor. */
+ parent_depth++;
+ target = Parent(target);
+ if (!GoodObject(target)) {
+ parent_depth = 0;
+ target = ancestor;
}
}
+
+ /* Try the alias, too... */
+ atr = atr_match(atrname);
+ if (!atr || !strcmp(name, AL_NAME(atr)))
+ break;
+ strcpy(name, AL_NAME(atr));
}
return NULL;
***************
*** 533,616 ****
* \param player the enactor.
* \param thing the object containing the attribute.
* \param name the pattern to match against the attribute name.
* \param func the function to call for each matching attribute.
* \param args additional arguments to pass to the function.
* \return the sum of the return values of the functions called.
*/
int
! atr_iter_get(dbref player, dbref thing, const char *name, aig_func func,
! void *args)
! {
! ATTR *ptr, *next;
! int result;
!
! result = 0;
! if (!name || !*name)
! name = "*";
!
! if (!wildcard(name)) {
! ptr = atr_get_noparent(thing, strupper(name));
! if (ptr && Can_Read_Attr(player, thing, ptr))
! result = func(player, thing, name, ptr, args);
! } else {
! for (ptr = List(thing); ptr; ptr = next) {
! next = AL_NEXT(ptr);
! if (Can_Read_Attr(player, thing, ptr) &&
! local_wild_match(name, AL_NAME(ptr)))
! result += func(player, thing, name, ptr, args);
! }
! }
!
! return result;
! }
!
! /** Apply a function to a set of visual attributes.
! * This function applies another function to a set of attributes on an
! * object specified by a (wildcarded) pattern to match against the
! * attribute name.
! * \param player the enactor.
! * \param thing the object containing the attribute.
! * \param name the pattern to match against the attribute name.
! * \param func the function to call for each matching attribute.
! * \param args additional arguments to pass to the function.
! * \return the sum of the return values of the functions called.
! */
! int
! atr_iter_get_visible(dbref player, dbref thing, const char *name, aig_func func,
! void *args)
{
! ATTR *ptr, *next;
int result;
! int object_visual;
result = 0;
if (!name || !*name)
name = "*";
! object_visual = (Visual(thing) &&
! (getlock(thing, Examine_Lock) == TRUE_BOOLEXP ||
! (eval_lock(PLAYER_START, thing, Examine_Lock) &&
! eval_lock(MASTER_ROOM, thing, Examine_Lock))));
!
! if (!wildcard(name)) {
ptr = atr_get_noparent(thing, strupper(name));
! if (ptr && (object_visual ? Can_Read_Attr(player, thing, ptr)
! : Is_Visible_Attr(thing, ptr)))
result = func(player, thing, name, ptr, args);
} else {
! for (ptr = List(thing); ptr; ptr = next) {
! next = AL_NEXT(ptr);
! if ((object_visual ? Can_Read_Attr(player, thing, ptr)
! : Is_Visible_Attr(thing, ptr))
! && local_wild_match(name, AL_NAME(ptr)))
result += func(player, thing, name, ptr, args);
}
}
return result;
}
-
/** Free the memory associated with all attributes of an object.
* This function frees all of an object's attribute memory.
* This includes the memory allocated to hold the attribute's value,
--- 607,650 ----
* \param player the enactor.
* \param thing the object containing the attribute.
* \param name the pattern to match against the attribute name.
+ * \param mortal only fetch mortal-visible attributes?
* \param func the function to call for each matching attribute.
* \param args additional arguments to pass to the function.
* \return the sum of the return values of the functions called.
*/
int
! atr_iter_get(dbref player, dbref thing, const char *name, int mortal,
! aig_func func, void *args)
{
! ATTR *ptr, **indirect;
int result;
! int len;
result = 0;
if (!name || !*name)
name = "*";
+ len = strlen(name);
! if (!wildcard(name) && name[len - 1] != '`') {
ptr = atr_get_noparent(thing, strupper(name));
! if (ptr && (mortal ? Is_Visible_Attr(thing, ptr)
! : Can_Read_Attr(player, thing, ptr)))
result = func(player, thing, name, ptr, args);
} else {
! indirect = &List(thing);
! while (*indirect) {
! ptr = *indirect;
! if ((mortal ? Is_Visible_Attr(thing, ptr)
! : Can_Read_Attr(player, thing, ptr)) && atr_wild(name, AL_NAME(ptr)))
result += func(player, thing, name, ptr, args);
+ if (ptr == *indirect)
+ indirect = &AL_NEXT(ptr);
}
}
return result;
}
/** Free the memory associated with all attributes of an object.
* This function frees all of an object's attribute memory.
* This includes the memory allocated to hold the attribute's value,
***************
*** 664,669 ****
--- 698,771 ----
}
}
+ /** Structure for keeping track of which attributes have appeared
+ * on children when doing command matching. */
+ typedef struct used_attr {
+ struct used_attr *next; /**< Next attribute in list */
+ char const *name; /**< The name of the attribute */
+ int no_prog; /**< Was it AF_NOPROG */
+ } UsedAttr;
+
+ /** Find an attribute in the list of seen attributes.
+ * Since attributes are checked in collation order, the pointer to the
+ * list is updated to reflect the current search position.
+ * For efficiency of insertions, the pointer used is a trailing pointer,
+ * pointing at the pointer to the next used struct.
+ * To allow a useful return code, the pointer used is actually a pointer
+ * to the pointer mentioned above. Yes, I know three-star coding is bad,
+ * but I have good reason, here.
+ * \param prev the pointer to the pointer to the pointer to the next
+ * used attribute.
+ * \param name the name of the attribute to look for.
+ * \retval 0 the attribute was not in the list,
+ * **prev now points to the next atfer.
+ * \retval 1 the attribute was in the list,
+ * **prev now points to the entry for it.
+ */
+ static int
+ find_attr(UsedAttr *** prev, char const *name)
+ {
+ int comp;
+
+ comp = 1;
+ while (**prev) {
+ comp = strcoll(name, prev[0][0]->name);
+ if (comp <= 0)
+ break;
+ *prev = &prev[0][0]->next;
+ }
+ return comp == 0;
+ }
+
+ /** Insert an attribute in the list of seen attributes.
+ * Since attributes are inserted in collation order, an updated insertion
+ * point is returned (so subsequent calls don't have to go hunting as far).
+ * \param prev the pointer to the pointer to the attribute list.
+ * \param name the name of the attribute to insert.
+ * \param no_prog the AF_NOPROG value from the attribute.
+ * \return the pointer to the pointer to the next attribute after
+ * the one inserted.
+ */
+ static UsedAttr **
+ use_attr(UsedAttr ** prev, char const *name, int no_prog)
+ {
+ int found;
+ UsedAttr *used;
+
+ found = find_attr(&prev, name);
+ if (!found) {
+ used = mush_malloc(sizeof *used, "used_attr");
+ used->next = *prev;
+ used->name = name;
+ used->no_prog = 0;
+ *prev = used;
+ }
+ prev[0]->no_prog |= no_prog;
+ /* do_rawlog(LT_TRACE, "Recorded %s: %d -> %d", name,
+ no_prog, prev[0]->no_prog); */
+ return &prev[0]->next;
+ }
+
/** Match input against a $command or ^listen attribute.
* This function attempts to match a string against either the $commands
* or ^listens on an object. Matches may be glob or regex matches,
***************
*** 694,699 ****
--- 796,804 ----
char *s;
int match, match_found;
dbref parent;
+ UsedAttr *used_list, **prev;
+ ATTR *skip[ATTRIBUTE_NAME_LIMIT / 2];
+ int skipcount;
/* check for lots of easy ways out */
if ((type != '$' && type != '^') || !GoodObject(thing) || Halted(thing)
***************
*** 713,724 ****
}
match = 0;
! st_init(&temp_attrib);
for (ptr = List(thing); ptr; ptr = AL_NEXT(ptr)) {
if (parent_depth)
! st_insert(AL_NAME(ptr), &temp_attrib);
! if (AL_FLAGS(ptr) & AF_NOPROG || !(AL_FLAGS(ptr) & flag_mask))
continue;
strcpy(tbuf1, atr_value(ptr));
s = tbuf1;
--- 818,848 ----
}
match = 0;
! used_list = NULL;
! prev = &used_list;
+ skipcount = 0;
+ /* do_rawlog(LT_TRACE, "Searching %s:", Name(thing)); */
for (ptr = List(thing); ptr; ptr = AL_NEXT(ptr)) {
+ if (skipcount && ptr == skip[skipcount - 1]) {
+ size_t len = strrchr(AL_NAME(ptr), '`') - AL_NAME(ptr);
+ while (AL_NEXT(ptr) && strlen(AL_NAME(AL_NEXT(ptr))) > len &&
+ AL_NAME(AL_NEXT(ptr))[len] == '`') {
+ ptr = AL_NEXT(ptr);
+ /* do_rawlog(LT_TRACE, " Skipping %s", AL_NAME(ptr)); */
+ }
+ skipcount--;
+ continue;
+ }
if (parent_depth)
! prev = use_attr(prev, AL_NAME(ptr), AL_FLAGS(ptr) & AF_NOPROG);
! if (AL_FLAGS(ptr) & AF_NOPROG) {
! skip[skipcount] = atr_sub_branch(ptr);
! if (skip[skipcount])
! skipcount++;
! continue;
! }
! if (!(AL_FLAGS(ptr) & flag_mask))
continue;
strcpy(tbuf1, atr_value(ptr));
s = tbuf1;
***************
*** 777,789 ****
for (parent_depth = MAX_PARENTS, parent = Parent(thing);
parent_depth-- && parent != NOTHING; parent = Parent(parent)) {
for (ptr = List(parent); ptr; ptr = AL_NEXT(ptr)) {
! if (st_find(AL_NAME(ptr), &temp_attrib))
continue;
! if (Parent(parent) != NOTHING)
! st_insert(AL_NAME(ptr), &temp_attrib);
! if (AL_FLAGS(ptr) & (AF_NOPROG | AF_PRIVATE)
! || !(AL_FLAGS(ptr) & flag_mask))
continue;
strcpy(tbuf1, atr_value(ptr));
s = tbuf1;
--- 901,947 ----
for (parent_depth = MAX_PARENTS, parent = Parent(thing);
parent_depth-- && parent != NOTHING; parent = Parent(parent)) {
+ /* do_rawlog(LT_TRACE, "Searching %s:", Name(parent)); */
+ skipcount = 0;
+ prev = &used_list;
for (ptr = List(parent); ptr; ptr = AL_NEXT(ptr)) {
! if (skipcount && ptr == skip[skipcount - 1]) {
! size_t len = strrchr(AL_NAME(ptr), '`') - AL_NAME(ptr);
! while (AL_NEXT(ptr) && strlen(AL_NAME(AL_NEXT(ptr))) > len &&
! AL_NAME(AL_NEXT(ptr))[len] == '`') {
! ptr = AL_NEXT(ptr);
! /* do_rawlog(LT_TRACE, " Skipping %s", AL_NAME(ptr)); */
! }
! skipcount--;
! continue;
! }
! if (AL_FLAGS(ptr) & AF_PRIVATE) {
! /* do_rawlog(LT_TRACE, "Private %s:", AL_NAME(ptr)); */
! skip[skipcount] = atr_sub_branch(ptr);
! if (skip[skipcount])
! skipcount++;
continue;
! }
! if (find_attr(&prev, AL_NAME(ptr))) {
! /* do_rawlog(LT_TRACE, "Found %s:", AL_NAME(ptr)); */
! if (prev[0]->no_prog || (AL_FLAGS(ptr) & AF_NOPROG)) {
! skip[skipcount] = atr_sub_branch(ptr);
! if (skip[skipcount])
! skipcount++;
! prev[0]->no_prog = AF_NOPROG;
! }
! continue;
! }
! if (GoodObject(Parent(parent)))
! prev = use_attr(prev, AL_NAME(ptr), AL_FLAGS(ptr) & AF_NOPROG);
! if (AL_FLAGS(ptr) & AF_NOPROG) {
! /* do_rawlog(LT_TRACE, "NoProg %s:", AL_NAME(ptr)); */
! skip[skipcount] = atr_sub_branch(ptr);
! if (skip[skipcount])
! skipcount++;
! continue;
! }
! if (!(AL_FLAGS(ptr) & flag_mask))
continue;
strcpy(tbuf1, atr_value(ptr));
s = tbuf1;
***************
*** 832,843 ****
safe_chr('/', atrname, abp);
safe_str(AL_NAME(ptr), atrname, abp);
}
! if (!just_match)
parse_que(thing, s, player);
}
}
}
! st_flush(&temp_attrib);
return match;
}
--- 990,1007 ----
safe_chr('/', atrname, abp);
safe_str(AL_NAME(ptr), atrname, abp);
}
! if (!just_match) {
! /* do_rawlog(LT_TRACE, "MATCHED %s:", AL_NAME(ptr)); */
parse_que(thing, s, player);
+ }
}
}
}
! while (used_list) {
! UsedAttr *temp = used_list->next;
! mush_free(used_list, "used_attr");
! used_list = temp;
! }
return match;
}
***************
*** 1005,1011 ****
notify(player, T("That's not a very good name for an attribute."));
return 0;
} else if (res == AE_ERROR) {
! notify(player, T("That attribute cannot be changed by you."));
return 0;
} else if (!res) {
notify(player, T("No such attribute to reset."));
--- 1169,1178 ----
notify(player, T("That's not a very good name for an attribute."));
return 0;
} else if (res == AE_ERROR) {
! if (*missing_name)
! notify_format(player, T("You must set %s first."), missing_name);
! else
! notify(player, T("That attribute cannot be changed by you."));
return 0;
} else if (!res) {
notify(player, T("No such attribute to reset."));
***************
*** 1208,1213 ****
--- 1375,1545 ----
return atr_free_list;
}
+ /** Traversal routine for Can_Read_Attr.
+ * This function determines if an attribute can be read by examining
+ * the tree path to the attribute. This is not the full Can_Read_Attr
+ * check; only the stuff after See_All (just to avoid function calls
+ * when the answer is trivialized by special powers). If the specified
+ * player is NOTHING, then we're doing a generic mortal visibility check.
+ * \param player the player trying to do the read.
+ * \param obj the object targetted for the read (may be a child of a parent!).
+ * \param attr the attribute being interrogated.
+ * \retval 0 if the player cannot read the attribute.
+ * \retval 1 if the player can read the attribute.
+ */
+ int
+ can_read_attr_internal(dbref player, dbref obj, ATTR *atr)
+ {
+ static char name[ATTRIBUTE_NAME_LIMIT + 1];
+ char *p;
+ int control;
+ int exam;
+ int comp;
+ dbref target;
+ dbref ancestor;
+ int visible;
+ int parent_depth;
+
+ visible = (player == NOTHING);
+ if (visible) {
+ control = 0;
+ exam = (Visual(obj) &&
+ eval_lock(PLAYER_START, obj, Examine_Lock) &&
+ eval_lock(MASTER_ROOM, obj, Examine_Lock));
+ } else {
+ control = controls(player, obj);
+ exam = (Visual(obj) && eval_lock(player, obj, Examine_Lock));
+ }
+
+ /* Take an easy out if there is one... */
+ /* If we can't see the attribute itself, then that's easy. */
+ if ((AL_FLAGS(atr) & AF_MDARK) ||
+ !((AL_FLAGS(atr) & AF_VISUAL) || control || exam ||
+ (!visible && !Mistrust(player) &&
+ (Owner(AL_CREATOR(atr)) == Owner(player)))))
+ return 0;
+
+ /* If the attribute isn't on a branch, then that's also easy. */
+ if (!strchr(AL_NAME(atr), '`'))
+ return 1;
+
+ /* Nope, we actually have to go looking for the attribute in a tree. */
+ strcpy(name, AL_NAME(atr));
+ ancestor = Ancestor_Parent(obj);
+ target = obj;
+ parent_depth = 0;
+ while (parent_depth < MAX_PARENTS && GoodObject(target)) {
+ /* If the ancestor of the object is in its explict parent chain,
+ * we use it there, and don't check the ancestor later.
+ */
+ if (target == ancestor)
+ ancestor = NOTHING;
+ atr = List(target);
+
+ /* Check along the branch for permissions... */
+ for (p = strchr(name, '`'); p; p = strchr(p + 1, '`')) {
+ *p = '\0';
+ while (atr) {
+ comp = strcoll(name, AL_NAME(atr));
+ if (comp < 0)
+ goto continue_target;
+ if (comp == 0)
+ break;
+ atr = AL_NEXT(atr);
+ }
+ if (!atr || (target != obj && (AL_FLAGS(atr) & AF_PRIVATE)))
+ goto continue_target;
+ if ((AL_FLAGS(atr) & AF_INTERNAL) || (AL_FLAGS(atr) & AF_MDARK) ||
+ !((AL_FLAGS(atr) & AF_VISUAL) || control || exam ||
+ (!visible && !Mistrust(player) &&
+ (Owner(AL_CREATOR(atr)) == Owner(player)))))
+ return 0;
+ *p = '`';
+ }
+
+ /* Now actually find the attribute. */
+ while (atr) {
+ comp = strcoll(name, AL_NAME(atr));
+ if (comp < 0)
+ break;
+ if (comp == 0)
+ return 1;
+ atr = AL_NEXT(atr);
+ }
+
+ continue_target:
+ *p = '`';
+
+ /* Attribute wasn't on this object. Check a parent or ancestor. */
+ parent_depth++;
+ target = Parent(target);
+ if (!GoodObject(target)) {
+ parent_depth = 0;
+ target = ancestor;
+ }
+ }
+
+ return 0;
+ }
+
+ /** Traversal routine for Can_Write_Attr.
+ * This function determines if an attribute can be written by examining
+ * the tree path to the attribute. As a side effect, missing_name is
+ * set to the name of a missing prefix branch, if any. Yes, side effects
+ * are evil. Please fix if you can.
+ * \param player the player trying to do the write.
+ * \param obj the object targetted for the write.
+ * \param atr the attribute being interrogated.
+ * \param safe whether to check the safe attribute flag.
+ * \retval 0 if the player cannot write the attribute.
+ * \retval 1 if the player can write the attribute.
+ */
+ int
+ can_write_attr_internal(dbref player, dbref obj, ATTR *atr, int safe)
+ {
+ char *p;
+ int comp;
+
+ missing_name[0] = '\0';
+
+ if (!God(player) &&
+ ((AL_FLAGS(atr) & AF_INTERNAL) ||
+ (safe && (AL_FLAGS(atr) & AF_SAFE)) ||
+ !(Wizard(player) ||
+ (!(AL_FLAGS(atr) & AF_WIZARD) &&
+ (!(AL_FLAGS(atr) & AF_LOCKED) ||
+ (AL_CREATOR(atr) == Owner(player)))))))
+ return 0;
+
+ strcpy(missing_name, AL_NAME(atr));
+ atr = List(obj);
+ for (p = strchr(missing_name, '`'); p; p = strchr(p + 1, '`')) {
+ *p = '\0';
+ while (atr) {
+ comp = strcoll(missing_name, AL_NAME(atr));
+ if (comp < 0)
+ return 0;
+ if (comp == 0)
+ break;
+ atr = AL_NEXT(atr);
+ }
+ if (!atr ||
+ (!God(player) &&
+ ((AL_FLAGS(atr) & AF_INTERNAL) ||
+ (safe && (AL_FLAGS(atr) & AF_SAFE)) ||
+ !(Wizard(player) ||
+ (!(AL_FLAGS(atr) & AF_WIZARD) &&
+ (!(AL_FLAGS(atr) & AF_LOCKED) ||
+ (AL_CREATOR(atr) == Owner(player)))))))) {
+ missing_name[0] = '\0';
+ return 0;
+ }
+ *p = '`';
+ }
+
+ return 1;
+ }
+
/** Return the compressed data for an attribute.
* This is a chokepoint function for accessing the chunk data.
* \param atr the attribute struct from which to get the data reference.
*** 1_7_7.624/hdrs/version.h Thu, 04 Sep 2003 17:36:31 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.24 660)
--- 1_7_7.664(w)/hdrs/version.h Mon, 29 Sep 2003 16:42:35 -0500 dunemush (pennmush/c/47_version.h 1.32.1.2.1.7.1.9.1.1.1.17.1.25 660)
***************
*** 1,3 ****
! #define VERSION "PennMUSH version 1.7.7 patchlevel 20 [09/04/2003]"
! #define SHORTVN "PennMUSH 1.7.7p20"
! #define NUMVERSION 001007007020
--- 1,3 ----
! #define VERSION "PennMUSH version 1.7.7 patchlevel 21 [09/23/2003]"
! #define SHORTVN "PennMUSH 1.7.7p21"
! #define NUMVERSION 001007007021
*** 1_7_7.624/hdrs/mushdb.h Sat, 30 Aug 2003 14:51:01 -0500 dunemush (pennmush/d/2_mushdb.h 1.1.1.9.1.1.1.16 660)
--- 1_7_7.664(w)/hdrs/mushdb.h Mon, 29 Sep 2003 16:42:35 -0500 dunemush (pennmush/d/2_mushdb.h 1.1.1.9.1.1.1.17 660)
***************
*** 85,101 ****
/* can p access attribute a on object x? */
#define Can_Read_Attr(p,x,a) \
(!((a)->flags & AF_INTERNAL) && \
! (See_All(p) || \
! (!((a)->flags & AF_MDARK) && \
! (controls(p,x) || ((a)->flags & AF_VISUAL) || \
! (Visual(x) && eval_lock(p,x,Examine_Lock)) || \
! (!Mistrust(p) && (Owner((a)->creator) == Owner(p)))))))
/* can anyone access attribute a on object x? */
#define Is_Visible_Attr(x,a) \
(!((a)->flags & AF_INTERNAL) && \
! !((a)->flags & AF_MDARK) && \
! ((a)->flags & AF_VISUAL))
/* can p write attribute a on object x, assuming p may modify x?
* Must be (1) God, or (2) a non-internal, non-safe flag and
--- 85,96 ----
/* can p access attribute a on object x? */
#define Can_Read_Attr(p,x,a) \
(!((a)->flags & AF_INTERNAL) && \
! (See_All(p) || can_read_attr_internal((p),(x),(a))))
/* can anyone access attribute a on object x? */
#define Is_Visible_Attr(x,a) \
(!((a)->flags & AF_INTERNAL) && \
! can_read_attr_internal(NOTHING,(x),(a)))
/* can p write attribute a on object x, assuming p may modify x?
* Must be (1) God, or (2) a non-internal, non-safe flag and
***************
*** 103,122 ****
* the attrib or (2b2) it's not atrlocked.
*/
#define Can_Write_Attr(p,x,a) \
! (God(p) || \
! (!((a)->flags & AF_INTERNAL) && \
! !((a)->flags & AF_SAFE) && \
! (Wizard(p) || \
! (!((a)->flags & AF_WIZARD) && \
! (((a)->creator == Owner(p)) || !((a)->flags & AF_LOCKED)) \
! ))))
#define Can_Write_Attr_Ignore_Safe(p,x,a) \
! (God(p) || \
! (!((a)->flags & AF_INTERNAL) && \
! (Wizard(p) || \
! (!((a)->flags & AF_WIZARD) && \
! (((a)->creator == Owner(p)) || !((a)->flags & AF_LOCKED)) \
! ))))
/* Can p forward a message to x (via @forwardlist)? */
--- 98,106 ----
* the attrib o