( BBSnotify.muf by Daerkannon Shimmerscale of the Den ) ( Version 2.1 March 17, 1997 ) ( Bug reports or port requests to winkelma@nyquist.ee.ualberta.ca ) ( To use make an exit called bbsnotify;bbs and link it to this program) ( Must be set M3 or higher to function ) ( Now include a pair of options only wizards may set: ) ( ~bbstel: ) ( Set this prop to 'yes' if you want the teleporting function enabled. ) ( Default is 'no' ie. disabled. ) ( ~teldef: ) ( Set this prop to the default value for an individual bbs' teleport ) ( enable prop. ie. 'yes' will have each bbs set enabled by default and ) ( 'no' will have each bbs set disabled by default. ) ( Default is 'yes' ie. enabled ) $include $lib/lmgr $include $lib/debug $include $lib/strings lvar bbcount lvar msgcount lvar index lvar pattern : stripbbsnotifylist (s -- s') "" "_bbsnotify/list/" subst ; : stripbbread (s -- s') "" "_bbsread/" subst ; : stripbbremoved (s -- s') "" "_bbsnotify/removed/" subst ; : isvalidbb? (d -- i) "msgs#/i" getpropstr not not ; : connect_notify? (-- i) me @ "_bbsnotify/connect" getpropstr "yes" stringcmp not ; : expert? (-- i) me @ "_bbsnotify/expert" getpropstr "yes" stringcmp not ; : teleport? (-- i) me @ .wizard? prog "~bbstel" getpropstr "yes" stringcmp not or ; : teleport_to? (d -- i) dup room? not if dup location else dup then "j" flag? not if pop 0 exit then "_bbsnotify/tel" getpropstr dup if prog "~teldef" getpropstr dup not if pop "yes" then stringcmp not else pop prog "~teldef" getpropstr "no" stringcmp then ; : tel_succ (-- s) me @ "_bbsnotify/tsucc" getpropstr dup if exit then pop prog "_bbsnotify/tsucc" getpropstr dup if exit then pop "You warp off to read the %b!" ; : tel_osucc (-- s) me @ "_bbsnotify/tosucc" getpropstr dup if exit then pop prog "_bbsnotify/tosucc" getpropstr dup if exit then pop "warps off to read the %b!" ; : tel_odrop (-- s) me @ "_bbsnotify/todrop" getpropstr dup if exit then pop prog "_bbsnotify/todrop" getpropstr dup if exit then pop "warps in to read the %b!" ; : bsubst (s -- s') 1 "_bbsnotify/list" me @ .lmgr-getelem "%b" subst ; : header ( -- ) "BBSNotify.muf Version 2.1 By Daerkannon Shimmerscale" .tell "--------------------------------------------------------------------------" .tell ; : unread (i d -- i) dup isvalidbb? not if pop pop 0 exit then dup "msgs#" getpropstr dup not if pop pop pop 0 exit then "msgs#/" swap strcat getpropstr atoi swap - dup 0 < if pop 0 then ; : removed? (d -- i) "_bbsnotify/removed/" swap intostr strcat me @ swap getpropval ; : matched? (s -- i) dup not if exit then pattern @ smatch ; : store_pattern (s -- ) "" "{" subst "" "}" subst "" "[" subst "" "]" subst "" "`" subst "" "|" subst strip "*|*" swap "|" subst pattern ! ; : getbbname (d -- s) dup "_bbsnotify/alias" getpropstr dup if swap pop else pop name then ; : getbbdir (d -- s) "_bbsnotify/dir" getpropstr ; : copy_me_to_db (s -- ) prog over me @ 4 rotate getprop setprop ; : copy_me_to_remove (s --) me @ over "_bbsnotify/removed/" "_bbsread/" subst me @ 4 rotate getprop setprop ; : addrecord (d s -- ) index @ "_bbsnotify/list" me @ .lmgr-putelem dup intostr index @ "_bbsnotify/dblist" me @ .lmgr-putelem intostr "_bbsread/" swap strcat copy_me_to_db ; : BBSCount ( -- i1 i2) 0 bbcount ! 0 msgcount ! "_bbsread/" begin me @ swap nextprop dup not if pop break then dup dup me @ swap getpropval dup not if pop pop continue then swap stripbbread atoi dbref dup ok? not if pop pop continue then dup isvalidbb? not if pop pop continue then dup removed? if pop pop continue then unread dup not if pop continue then msgcount @ + msgcount ! bbcount @ 1 + bbcount ! repeat bbcount @ msgcount @ ; : build_all (s -- ) store_pattern "_bbsread/" 1 index ! begin prog swap nextprop dup not if pop break then dup dup prog swap getpropval not if pop continue then stripbbread atoi dbref dup ok? not if pop continue then dup isvalidbb? not if pop continue then dup getbbname dup matched? not if pop pop continue then index @ "_bbsnotify/list" me @ .lmgr-putelem intostr index @ "_bbsnotify/dblist" me @ .lmgr-putelem index @ 1 + index ! repeat ; : build_list (s -- ) store_pattern "_bbsread/" 1 index ! begin me @ swap nextprop dup not if pop break then dup dup me @ swap getpropval not if pop continue then stripbbread atoi dbref dup ok? not if pop continue then dup isvalidbb? not if pop continue then dup removed? if pop continue then dup getbbname dup matched? not if pop pop continue then addrecord index @ 1 + index ! repeat ; : build_unread (s -- ) store_pattern "_bbsread/" 1 index ! begin me @ swap nextprop dup not if pop break then dup dup me @ swap getpropval dup not if pop continue then swap stripbbread atoi dbref dup ok? not if pop pop continue then dup isvalidbb? not if pop pop continue then dup removed? if pop pop continue then swap over unread not if pop continue then dup getbbname dup matched? not if pop pop continue then addrecord index @ 1 + index ! repeat ; : build_removed (s -- ) store_pattern "_bbsnotify/removed/" 1 index ! begin me @ swap nextprop dup not if pop break then dup dup me @ swap getpropval not if pop continue then stripbbremoved atoi dbref dup ok? not if pop continue then dup isvalidbb? not if pop continue then dup getbbname dup matched? not if pop pop continue then addrecord index @ 1 + index ! repeat ; : index_bbs ( -- ) 1 index ! begin index @ "_bbsnotify/list" me @ .lmgr-getelem dup not if pop break then index @ "_bbsnotify/dblist" me @ .lmgr-getelem .atodbref dup room? not if location then me @ .wizard? if unparseobj else name then " (" swap strcat ")" strcat strcat index @ intostr ": " strcat swap strcat .tell index @ 1 + index ! repeat ; : list_bbs ( -- ) 1 index ! begin index @ "_bbsnotify/list" me @ .lmgr-getelem dup not if pop break then index @ "_bbsnotify/dblist" me @ .lmgr-getelem .atodbref dup room? not if location then me @ .wizard? if unparseobj else name then " (" swap strcat ")" strcat strcat .tell index @ 1 + index ! repeat ; : list_dir_bbs ( -- ) 1 index ! begin index @ "_bbsnotify/list" me @ .lmgr-getelem dup not if pop break then index @ "_bbsnotify/dblist" me @ .lmgr-getelem .atodbref swap over dup room? not if location then me @ .wizard? if unparseobj else name then " (" swap strcat ")" strcat strcat .tell getbbdir dup not if pop "None" then "Directions: " swap strcat .tell index @ 1 + index ! repeat ; : remove_list ( -- ) "_bbsnotify/list" me @ .lmgr-deletelist "_bbsnotify/dblist" me @ .lmgr-deletelist ; : global_cleanup ( -- ) prog "_bbshold" "yes" 0 addprop 60 sleep preempt "_bbsread/" begin prog swap nextprop dup not if pop break then dup stripbbread atoi dbref dup ok? if "msgs#/i" getpropstr else pop 0 then if continue then dup prog swap remove_prop repeat prog "_bbshold" remove_prop prog "_lastmaint" "" systime addprop ; : main debugoff dup not if ( default action checks for unread messages ) pop BBSCount msgcount ! bbcount ! "There %1 %2 unread message%3 on %4 bulletin board%5." msgcount @ 1 = if "is" "%1" subst "" "%3" subst else "are" "%1" subst "s" "%3" subst then msgcount @ not if "no" "%2" subst else msgcount @ intostr "%2" subst then bbcount @ 1 = if "" "%5" subst else "s" "%5" subst then bbcount @ not if "any" "%4" subst else bbcount @ intostr "%4" subst then .tell exit then dup "connect" stringpfx if ( check for unread messages on connect ) pop connect_notify? not if exit then "There %1 %2 unread message%3 on %4 bulletin board%5." BBSCount msgcount ! bbcount ! msgcount @ 1 = if "is" "%1" subst "" "%3" subst else "are" "%1" subst "s" "%3" subst then msgcount @ not if "no" "%2" subst else msgcount @ intostr "%2" subst then bbcount @ 1 = if "" "%5" subst else "s" "%5" subst then bbcount @ not if "no" "%4" subst else bbcount @ intostr "%4" subst then msgcount @ if .tell else pop then me @ "_bbsnotify/env/last" getpropstr atoi systime 15 - >= if exit then me @ "_bbsnotify/env/last" systime intostr 0 addprop me @ begin location "_bbsnotify/envlist" envpropstr dup not if exit then " " explode begin dup not if pop break then 1 - swap dup dup me @ swap "_bbsread/" swap "" "#" subst strcat getpropval swap .atodbref unread not if pop continue then .atodbref "_bbsnotify/envnotify" getpropstr .tell repeat repeat exit then prog "_bbshold" getpropstr if "Sorry, BBSNotify is performing maintainance right now and is unavailable." .tell "Please wait for a minute and try again." .tell exit then dup "#all" stringpfx if ( lists all string matched bulletin boards ) " " .split swap pop strip prog "_lastmaint" getpropval systime 86400 - < if fork dup -1 = if "Timequeue full." .tell exit then not if global_cleanup exit then then "I know about the following bulletin boards:" .tell build_all list_bbs remove_list "Done." .tell exit then dup "#l" stringpfx if ( lists string matched bulletin boards ) " " .split swap pop strip "You are following the following bulletin boards:" .tell build_list list_bbs remove_list "Done." .tell exit then dup "#rl" stringpfx if ( lists string matched bulletin boards ) " " .split swap pop strip "You have removed the following bulletin boards:" .tell build_removed list_bbs remove_list "Done." .tell exit then dup "#un" stringpfx if ( lists string matched bulletin boards with unread messages ) " " .split swap pop strip "There are unread messages on the following bulletin boards:" .tell build_unread list_bbs remove_list "Done." .tell exit then dup "#dir" stringpfx if ( lists string matched bulletin board directions ) " " .split swap pop strip "Bulletin Board Directions:" .tell build_all list_dir_bbs remove_list "Done." .tell exit then dup "#udir" stringpfx if ( lists string matched bulletin board directions ) " " .split swap pop strip "Bulletin Board Directions:" .tell build_unread list_dir_bbs remove_list "Done." .tell exit then dup "#clean" stringpfx if ( removes prop entry for 'dead' bulletin boards from prop dir ) pop "_bbsread/" begin me @ swap nextprop dup not if pop break then dup stripbbread atoi dbref dup ok? if "msgs#/i" getpropstr else pop 0 then if continue then dup me @ swap remove_prop bbcount @ 1 + bbcount ! repeat bbcount @ dup not if "No invalid bulletin boards were found." .tell then dup 1 = if "Cleaned 1 invalid bulletin board." .tell else intostr "Cleaned " swap strcat " invalid bulletin boards." strcat .tell then exit then dup "#rem" stringpfx if ( remove bulletin board from notification list ) " " .split swap pop strip dup not if build_list index_bbs "Remove which bulletin board from your notification list?" .tell read dup atoi not if remove_list build_list else atoi dup "_bbsnotify/list" me @ .lmgr-getelem swap "_bbsnotify/dblist" me @ .lmgr-getelem remove_list 1 "_bbsnotify/dblist" me @ .lmgr-putelem 1 "_bbsnotify/list" me @ .lmgr-putelem then else build_list then 0 index ! begin index @ 1 + index ! index @ "_bbsnotify/list" me @ .lmgr-getelem not if break then expert? not if index @ "_bbsnotify/list" me @ .lmgr-getelem .tell "Remove this bulletin board? (y/n)" .tell read "y" stringpfx not if continue then then index @ "_bbsnotify/dblist" me @ .lmgr-getelem "_bbsread/" swap strcat copy_me_to_remove index @ "_bbsnotify/list" me @ .lmgr-getelem " removed." strcat .tell repeat remove_list "Done." .tell exit then dup "#tel" stringpfx if ( teleport to a bulletin board ) teleport? not if "Sorry, this function has been disabled." .tell exit then " " .split swap pop strip build_all me @ "_bbsnotify/list#" getpropstr atoi 1 > if index_bbs "Teleport to which bulletin board?" .tell read dup atoi not if remove_list build_all else atoi dup "_bbsnotify/list" me @ .lmgr-getelem swap "_bbsnotify/dblist" me @ .lmgr-getelem remove_list 1 "_bbsnotify/dblist" me @ .lmgr-putelem 1 "_bbsnotify/list" me @ .lmgr-putelem then then expert? not if 1 "_bbsnotify/list" me @ .lmgr-getelem .tell "Teleport to this bulletin board?" .tell read "y" stringpfx not if remove_list exit then then 1 "_bbsnotify/dblist" me @ .lmgr-getelem .atodbref dup teleport_to? not if "Cannot teleport to |. Aborting." 1 "_bbsnotify/list" me @ .lmgr-getelem "|" subst .tell exit then tel_succ bsubst .tell tel_osucc bsubst .omdisplay (formats and displays an omsg to the room) dup room? not if location then dup me @ tel_odrop bsubst .omsg-sub (formats an omsg) notify_except me @ swap moveto exit then dup "#rest" stringpfx if ( restore bulletin board to notification list ) " " .split swap pop strip dup not if build_removed index_bbs "Restore which bulletin board to your notification list?" .tell read dup atoi not if remove_list build_removed else atoi dup "_bbsnotify/list" me @ .lmgr-getelem swap "_bbsnotify/dblist" me @ .lmgr-getelem remove_list 1 "_bbsnotify/dblist" me @ .lmgr-putelem 1 "_bbsnotify/list" me @ .lmgr-putelem then else build_removed then 0 index ! begin index @ 1 + index ! index @ "_bbsnotify/list" me @ .lmgr-getelem not if break then expert? not if index @ "_bbsnotify/list" me @ .lmgr-getelem .tell "Restore this bulletin board? (y/n)" .tell read "y" stringpfx not if continue then then index @ "_bbsnotify/dblist" me @ .lmgr-getelem "_bbsnotify/removed/" swap strcat me @ swap remove_prop index @ "_bbsnotify/list" me @ .lmgr-getelem " restored." strcat .tell repeat remove_list "Done." .tell exit then dup "#cat" stringpfx if ( remove bulletin board from notification list ) " " .split swap pop strip dup not if build_unread index_bbs "Catchup on all messages for which bulletin board??" .tell read dup atoi not if remove_list build_unread else atoi dup "_bbsnotify/list" me @ .lmgr-getelem swap "_bbsnotify/dblist" me @ .lmgr-getelem remove_list 1 "_bbsnotify/dblist" me @ .lmgr-putelem 1 "_bbsnotify/list" me @ .lmgr-putelem then else build_unread then 0 index ! begin index @ 1 + index ! index @ "_bbsnotify/list" me @ .lmgr-getelem not if break then expert? not if index @ "_bbsnotify/list" me @ .lmgr-getelem .tell "Catchup on all messages for this bulletin board? (y/n)" .tell read "y" stringpfx not if continue then then index @ "_bbsnotify/dblist" me @ .lmgr-getelem dup .atodbref "msgs#/i" getpropstr atoi 1 - swap "_bbsread/" swap strcat me @ swap rot setprop index @ "_bbsnotify/list" me @ .lmgr-getelem " updated." strcat .tell repeat remove_list "Done." .tell exit then dup "#hist" stringpfx if ( History of BBSNotify ) pop ( -------------------------------------------------------------------------- ) header "Revision History:" .tell "2.1 - Fixed bug with upper case letters for commands" .tell " - Some commands can now be run using the first few letters" .tell " - Added option to list only directions to unread BB's" .tell " - Can now teleport to BB's with options for disabling" .tell "2.0 - Changed handling of internal temporary lists" .tell " - Fixed bug with empty bulletin boards" .tell " - Added estimate of # of unread messages" .tell " - Add global board database" .tell " - Changed #list to do all watched boards" .tell " - Added #unread to do unread messages" .tell " - Added #all to list all known boards" .tell " - Added #rlist to list removed boards" .tell " - Added string matching to #list, #all, #unread & #rlist" .tell " - Changed #remove to add string matching" .tell " - Added expert mode" .tell " - Added #restore and #catchup functions" .tell " - Added global database autocleanup feature" .tell " - Added EnvNotify functionality" .tell " - Wizards see full object name of boards" .tell "1.61 - Fixed minor bug with BB's on rooms" .tell "1.6 - Fixed [again] unread messages bug" .tell " - Fixed bug with /'s in BB names" .tell "1.5 - Fixed bug that crashed bbs #list" .tell " - Fixed bbs #remove problem with not clearing temporary list" .tell " - Fixed grammar mistake in connect message, changed notify messages" .tell " - Added #on/#off toggle for connect notification" .tell " - Added #dir function" .tell " - Added #history" .tell " - Updated #help functions" .tell " - Added location of BB to #list and #dir functions" .tell " - Fixed unread function to correctly update for unread messages" .tell "1.2 - Initial Public Release" .tell "Credits:" .tell "Thanks to Points for porting this program to FurryMUCK, and for helping" .tell "with debugging and passing on ideas. Thanks to all those people who" .tell "found a bug or submitted an idea for BBSNotify." .tell "Thanks to Mystique for helping with some of the subroutines." .tell "Done." .tell exit then dup "#props" stringpfx if ( More Help! ) pop ( -------------------------------------------------------------------------- ) header "_bbsnotify/alias:" .tell " @set this prop on the bulletin board object and give the bulletin" .tell " a board meaningful alias. The default name for the bulletin board" .tell " is the object that the bulletin board is stored on." .tell "_bbsnotify/dir:" .tell " @set this prop on the bulletin board object with directions to the" .tell " bulletin board. [usually from some common point of origin]" .tell "_bbsnotify/envlist: ..." .tell " @set this prop in the enviroment room of an area to notify chars of" .tell " unread messages on specific boards. The 's are the dbrefs of" .tell " the boards in question. See also _bbsnotify/envnotify." .tell "_bbsnotify/envnotify:" .tell " This prop is set on the bulletin board object and contains the message" .tell " that EnvNotify uses to notify a char of unread messages. This message" .tell " should be meaningful. See also _bbsnotify/envlist." .tell "_bbsnotify/tel:" .tell " Set this prop to either yes or no if you want people to be able to" .tell " teleport to your bulletin board or not. Default is yes." .tell "Done." .tell exit then dup "#help2" stringpfx if ( Help! ) pop ( -------------------------------------------------------------------------- ) header "bbs #dir - Lists all bulletin boards matching and" .tell " the directions to them (if they exist). See #help2." .tell " If no specified, then matches all known boards." .tell "bbs #udir - As above for unread bulletin boards." .tell "bbs #all - Lists all known boards matching (as #dir)" .tell "bbs #list - Lists watched boards matching (as #dir)" .tell "bbs #rlist - Lists removed boards matching (as #dir)" .tell "bbs #unread - Lists watched boards with unread messages matching" .tell " (as #dir)." .tell "bbs #remove - Removes a bulletin board from your list. If no" .tell " given, it will interactively ask which one(s)" .tell " to remove. Otherwise it attempts to remove all" .tell " matching boards." .tell "bbs #restore - Restore a bulletin board from your list. As #remove" .tell "bbs #catchup - Mark all messages on one or more boards as read." .tell " As #remove" .tell "bbs #tel - Teleports you to the first bbs that matches ." .tell " If no given, then it will interactively ask" .tell " for your destination. Subject to teleport props" .tell " set by the wizards and BBS owners." .tell "Done." .tell exit then dup "#help" stringpfx if ( Help! ) pop ( -------------------------------------------------------------------------- ) header "bbs - Looks for unread messages. Also displays an" .tell " estimate of the number of messages unread. Msgs" .tell " deleted between reads are still counted as unread." .tell "bbs #help - This screen" .tell "bbs #help2 - More help!" .tell "bbs #props - Help for builders" .tell "bbs #history - Revision history and credits of BBSNotify (spammy)" .tell "bbs #con - Toggle connection notify on/off. Default off." .tell "bbs #expert - Toggle expert mode on/off. Default off. Expert" .tell " mode skips confirmation of actions." .tell "bbs #clean - Cleans up unused bulletin board props on your" .tell " character. Does not need to be run frequently." .tell "Done." .tell exit then dup "#con" stringpfx if ( Toggle connection notification on/off ) pop connect_notify? if me @ "_bbsnotify/connect" remove_prop "Connection notify turned off." .tell else me @ "_bbsnotify/connect" "yes" 0 addprop "Connection notify turned on." .tell then exit then dup "#expert" stringpfx if ( Toggle expert mode on/off ) pop expert? if me @ "_bbsnotify/expert" remove_prop "Expert mode disabled." .tell else me @ "_bbsnotify/expert" "yes" 0 addprop "Expert mode enabled." .tell then exit then "Invalid command. bbs #help for more info." .tell ;