Instructions

Copy and paste the below code into a compatible MUSH or MUX.

MUSHCode for Myrddin's BBS v4.0.6

@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@
@@ NO EDITING OF THIS FILE IS NECESSARY
@@
@@ NOT NECESSARY TO PRE-CREATE ANY OBJECTS
@@
@@ Just upload this file directly to your game, it will create the
@@ necessary objects for you and modify all referenced dbref's in the
@@ code.
@@
@@ The help files for the Bulletin Board are available at:
@@ http://www.mushcode.com/ViewFile.aspx?Id=217 (ASCII version)
@@ or http://www.mushcode.com/ViewFile.aspx?Id=220 (MUSHCode version)
@@
@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

@set me=quiet
@@ WEB OFF
@pemit me=[repeat(=,78)]%r[center(Constructing Myrddin's BBS v4.0.6,78)]%r[repeat(-,78)]%rPlease wait...%r

@create bbpocket=10
@@ WEB ON
@lock bbpocket=me
@Desc bbpocket=[iter(setdiff(lattr(me),Desc),ljust(##,18))]
&BBTIME bbpocket=extract(time(), 1, 3)
&GET_GROUP bbpocket=switch(isnum(%0),1,extract(v(groups),%0,1),locate(#222,%0,ni))
&NXT_MESS bbpocket=1
&VALID_GROUPS bbpocket=iter(v(groups),switch(and(u(##/can%1,%0),not(member(get(%0/bb_omit),##))),1,##))
&ISGROUPREAD bbpocket=switch(setdiff(%1,get(%0/bb_read)),,,U)
&UNREADNUMS bbpocket=sort(iter(setdiff(get(%1/mess_lst),get(%0/bb_read)),member(get(%1/mess_lst),##)))
&FN_MAKELIST bbpocket=map(me/fn_maplist,secure(%0))
&FN_MAPLIST bbpocket=switch(strmatch(%0,?*-*),1,lnum(before(%0,-),after(%0,-)),%0)
&FN_MAPLIST_2 bbpocket=switch(strmatch(%0,*-*),1,u(fn_lnum,before(%0,-),after(%0,-)),%0)
&FN_UNREAD_LIST bbpocket=edit(sort(iter(%0,member(%1,##))),%b,\,%b)
&FN_LNUM bbpocket=iter(lnum(add(sub(%1,%0),1)),add(##,%0))

@switch lnum(1,2)=1 2,{@pemit %#=BBS INSTALLER> Your lnum() accepts two arguments. Good.; &FN_MAPLIST_2 bbpocket; &FN_LNUM bbpocket},{@pemit %#=BBS INSTALLER> Hmmm. Your lnum() is archaic... I'll have to use my own.; @mvattr bbpocket=FN_MAPLIST_2,FN_MAPLIST}

&ADDEM bbpocket=add(%0,%1)
&B36_DIGITS bbpocket=0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
&B36_POWS bbpocket=1 36 1296 46656 1679616 60466176
&FN_B36_MAGS bbpocket=revwords(iter(v(b36_pows),switch([div(##,%0)]:[eq(##,%0)],0:*,##,*:1,##)))
&FN_B36-TO-B10 bbpocket=[setq(0,ucstr(%0))][setq(1,strlen(%q0))][fold(me/addem,[iter(lnum(%q1),mul(sub(member(v(b36_digits),mid(%q0,##,1)),1),power(36,sub(sub(%q1,##),1))))],0)]
&FN_B10-TO-B36 bbpocket=[setq(0,%0)][edit(iter(u(fn_b36_mags,%q0),[extract(v(b36_digits),add(div(%q0,##),1),1)][setq(0,sub(%q0,mul(##,div(%q0,##))))]),%b,)]
&FN_INC_NEXT_MESS bbpocket=u(fn_b10-to-b36,add(u(fn_b36-to-b10,%0),1))
&VALID_CONFIGS bbpocket=anonymous timeout
&VALID_GLOBAL_CONFIGS bbpocket=timeout autotimeout
&CONFIG_TIMEOUT bbpocket=2592000
&TR_TIMEOUT bbpocket=@dolist v(groups)={@trigger me/tr_timeout_group=##}
&TR_TIMEOUT_GROUP bbpocket=@dolist get(%0/mess_lst)={@switch and(extract(get(%0/hdr_##),5,1,|),gt(secs(),extract(get(%0/hdr_##),5,1,|)))=1,{&hdr_## %0; &bdy_## %0; &mess_lst %0=[remove(get(%0/mess_lst),##)]; &master_lst #222=[remove(get(#222/master_lst),##)]}}
&DO_TIMEOUTS bbpocket=@trigger me/tr_timeout; @wait 86400={@trigger me/do_timeouts}
&TR_CONFIG_ANONYMOUS bbpocket=&anonymous %0=[ifelse([%1],[%1],)]; @pemit %2=Posters on the [name(%0)] group will show up as [ifelse([%1],['%1'],themselves)].
&TR_CONFIG_TIMEOUT bbpocket=&config_timeout %0=[mul(%1,86400)]; @pemit %2=New messages for group '[name(%0)]' have [ifelse(%1,a %1 day,no)] timeout.
&TR_GCONFIG_TIMEOUT bbpocket=&config_timeout me=[mul(%0,86400)]; @pemit %1=BB global config parameter 'timeout': [ifelse(%0,%0 days,none)].%rAny new groups will have this value set as their default timeout.
&TR_GCONFIG_AUTOTIMEOUT bbpocket=@switch [eq(hasattr(me,startup),setr(0,switch(%0,on,1,0)))]:%0=1:*,{@pemit %1=BB autotimeout is already [ifelse(%q0,on,off)].},0:on,{@startup me=@trigger me/do_timeouts; @trigger me/do_timeouts; @pemit %1=BB autotimeout turned on.},{@startup me; @pemit %1=BB autotimeout turned off.; @halt me}
&FN_MSG_FLAGS bbpocket=switch([member(get(%0/bb_read),%2)]:[u(fn_timeout_close,index(get(%1/hdr_%2),|,5,1))],0:*,U,*:1,T)
&TR_POST_NOTIFY bbpocket=@switch hasflag(%0,DARK)=0,{@pemit/list iter(remove(lwho(),%0),switch(or(member([get(##/bb_omit)] [get(##/bb_silent)],%1),not(u(%1/canread,##))),0,##))=(New BB message ([member(v(groups),%1)]/%2) posted to '[name(%1)]' by [ifelse(hasattr(%1,anonymous),get(%1/anonymous),name(%0))]: %3)}
&FN_TIMEOUT_CLOSE bbpocket=switch(%0:[lte(sub(%0,secs()),259200)],0:*,0,*:1,1,0)
&FN_HASCONFIG bbpocket=or(hasattr(%0,anonymous),neq(get(%0/config_timeout),get(#222/config_timeout)))
&VERSION bbpocket=4.0.6
@set bbpocket=!HALT
@set bbpocket=INHERIT
@set bbpocket=SAFE

@switch strlen(repeat(.,7998))=7998,&BUFFER_SIZE bbpocket=8000,&BUFFER_SIZE bbpocket=4000

@@ WEB OFF
@create mbboard=10
@@ WEB ON
@lock mbboard=me
@Desc mbboard=[iter(setdiff(lattr(me),Desc),ljust(##,18))]
@Fail mbboard=It's bolted down... you aint budgin' it.
&CMD_+BBNEWGROUP mbboard=$+bbnewgroup *:@switch hasflag(%#,wizard)=1, {@create %0; @wait 1={@switch [setr(0,num(%0))]=#-1,{@pemit %#=That's not a good name for a group.},{&groups #222=[switch(words(get(#222/groups)),0,,[get(#222/groups)]%b)]%q0; &own %q0=%#; @set %q0=safe; @set %q0=inherit; &last_mod %q0=[u(#222/bbtime)]; &CANREAD %q0=1; &CANWRITE %q0=1; &config_timeout %q0=[get(#222/config_timeout)]; @pemit %#=Group number [member(get(#222/groups),%q0)] added as '%0'. Messages will have [ifelse(get(%q0/config_timeout),a [div(get(%q0/config_timeout),86400)] day,no)] timeout.}}}, {@pemit %#=You can't add groups to the message base.}
&CMD_+BBLOCK mbboard=$+bblock *=*/*:@switch hasflag(%#,wizard)=1,{@switch member(get(#222/groups),setr(0,u(#222/get_group,%0)))=0,{@pemit %#=No such group as '%0'.},{@switch %1=flag,{&CANREAD %q0=\[or(hasflag(\%0,%2),hasflag(\%0,wizard))]},{&CANREAD %q0=\[or(match(get(\%0/%1),%2),hasflag(\%0,wizard))]}; @wait 1={&CANWRITE %q0=[get(%q0/CANREAD)]}; @pemit %#=Group '%0' locked. Only people with %1=%2 can access.}},{@pemit %#=You cannot lock message groups.}
&CMD_+BBCLEARGROUP mbboard=$+bbcleargroup *:@switch and(hasflag(%#, wizard),member(get(#222/groups),setr(0,u(#222/get_group,%0))))=1, {&delete_grp #222=%q0; @pemit %#=%r[space(15)]******** Warning ********%r%rDeleting Group #%0 will also delete the [words(get(%q0/mess_lst))] messages in that group.%rIf you still wish to proceed, type '+bbconfirm %0'%r%r[space(15)][repeat(*,25)]%r}, {&delete_grp #222; @pemit %#=You can't remove that group (either that group does not exist, or you are not the owner).}
&DO_CLEARGROUP mbboard=$+bbconfirm *:@switch get(#222/DELETE_GRP)=[setr(0,u(#222/get_group,%0))], {&groups #222=[remove(get(#222/groups),%q0)]; &master_lst #222=[setdiff(get(#222/master_lst),get(%q0/mess_lst))]; @nuke %q0; &delete_grp #222; @pemit %#=Group number %0 removed.}, {&delete_grp #222; @pemit %#=That group has not been marked for deletion. Use '+bbcleargroup <#>' to mark a group for deletion.}

&CMD_+BBPOST mbboard=$+bbpost */*=*:@switch member(u(#222/valid_groups,%#,write),setr(0,u(#222/get_group,%0)))=0, {@pemit %#=Either you do not subscribe to Group #%0, or are unable to post to it.},{&mess_lst %q0=[cat(get(%q0/mess_lst),setr(1,get(#222/nxt_mess)))]; &nxt_mess #222=[ulocal(#222/fn_inc_next_mess,%q1)]; &master_lst #222=[cat(get(#222/master_lst),%q1)]; &hdr_%q1 %q0=[mid(%1, 0, 34)]|[u(#222/bbtime)]|[edefault(%q0/anonymous,mid(name(%#),0,24))]|[owner(%#)]|[ifelse(get(%q0/config_timeout),add(get(%q0/config_timeout),secs()),0)]; &last_mod %q0=[u(#222/bbtime)]; &bdy_%q1 %q0=[%2][ifelse(and(hasattr(%#,bb_sig),not(hasattr(%q0,anonymous))),{%r[ulocal(%#/bb_sig)]},)]; @pemit %#=You post your note about '%1' in group [member(get(#222/groups),%q0)] ([name(%q0)]) as message #[member(get(%q0/mess_lst),%q1)][ifelse(and(hasattr(%#,bb_sig),hasattr(%q0,anonymous)),{%b%bThis is an anonymous group, your BB_SIG was -not- appended.},)]; &bb_read %#=[setunion(get(%#/bb_read),%q1)]; @trigger #222/tr_post_notify=%#,%q0,[member(get(%q0/mess_lst),%q1)],[mid(%1, 0, 34)]}

&CMD_+BBREMOVE mbboard=$+bbremove */*:@dolist [setq(0,u(#222/get_group,%0))][revwords(sort(u(#222/fn_makelist,%1)))]={@switch or(strmatch(index(get(%q0/HDR_[setr(1,extract(get(%q0/MESS_LST),##,1))]),|,4, 1),%#), hasflag(%#,wizard))=1, {&HDR_%q1 %q0; &BDY_%q1 %q0; &MESS_LST %q0=[remove(get(%q0/MESS_LST),%q1)]; &MASTER_LST #222=[remove(get(#222/MASTER_LST),%q1)]; @pemit %#=Message ## removed from group #[member(get(#222/groups),%q0)] ([name(%q0)]).}, {@pemit %#=Either message ## does not exist, or you were not the original poster.}}


&CMD_+BBREAD2 mbboard=$+bbread *:@switch strmatch([%0],*/*)=0,{@switch member(u(#222/valid_groups,%#,read),setr(0,u(#222/get_group,%0)))=0,{@pemit %#=[switch(%q0,#-2,That Group name is not specific enough.,You do not subscribe to that Group.)]},{@pemit %#=[repeat(=,78)]%r[center(**** [name(%q0)] ****,78)]%r[space(8)]Message[space(28)]Posted[space(8)]By%r[repeat(-,78)]; @dolist get(%q0/MESS_LST)={@pemit %#=[ljust([member(get(#222/groups),%q0)]/[member(get(%q0/MESS_LST),##)],6)][ljust(u(#222/fn_msg_flags,%#,%q0,##),2)][ljust(index(setr(1,get(%q0/HDR_##)),|,1,1),35)][ljust(index(%q1,|,2,1),14)][mid([index(%q1,|,3,1)][ifelse(and(hasattr(%q0,anonymous),hasflag(%#,wizard)),%b\([name(index(%q1,|,4,1))]\),)],0,21)][switch(member(get(%q0/MESS_LST),##),words(get(%q0/MESS_LST)),%r[repeat(=,78)])]}}},{@switch member(u(#222/valid_groups,%#,read),setr(0,u(#222/get_group,setr(2,first(%0,/)))))=0,{@pemit %#=[switch(%q0,#-2,That Group name is not specific enough.,You do not subscribe to that Group.)]},{@dolist [setq(4,member(get(#222/groups),%q0))][switch(rest(%0,/),u,u(#222/unreadnums,%#,%q0),u(#222/fn_makelist,rest(%0,/)))]={@switch [and(lte(##,words(get(%q0/MESS_LST))),isnum(##),gt(##,0))]=0,{@pemit %#=Message %q4/## ([name(%q0)]/##) does not exist.},{@pemit %#=%r[center(= [name(%q0)] =,78,=)]%r[ljust(Message: %q4/##[switch(u(#222/fn_timeout_close,index(setr(3,get(%q0/HDR_[extract(get(%q0/MESS_LST),##,1)])),|,5,1)),1,{%b(timeout warning)})],35)]Posted[space(8)]Author%r[ljust(index(%q3,|,1,1),35)][ljust(index(%q3,|,2,1),14)][mid([index(%q3,|,3,1)][ifelse(and(hasattr(%q0,anonymous),hasflag(%#,wizard)),%b\([name(index(%q3,|,4,1))]\),)],0,29)]%r[repeat(-,78)]%r[get(%q0/BDY_[extract(get(%q0/MESS_LST),##,1)])]%r[repeat(=,78)]; &bb_read %#=[setunion(get(%#/bb_read),[extract(get(%q0/MESS_LST),##,1)])]}}; @wait 2={&bb_read %#=[setinter(get(%#/bb_read),get(#222/master_lst))]}}}

&CMD_+BBEDIT mbboard=$+bbedit */*=*/*:@switch strmatch(index(get([setq(0,u(#222/get_group,%0))]%q0/HDR_[setq(1,extract(get(%q0/MESS_LST),%1,1))]%q1),|,4, 1),%#)=1,{&BDY_%q1 %q0=[edit(get(%q0/BDY_%q1),{%2},{%3})]; @pemit %#=[repeat(=,78)]%rMessage [member(get(#222/groups),%q0)]/%1 ([name(%q0)]/%1) now reads:%r[repeat(-,78)]%r[get(%q0/BDY_%q1)]%r[repeat(=,78)]}, {@pemit %#=Either that message does not exist, or you were not the original poster.}
&CMD_+BBLEAVE mbboard=$+bbleave *:@switch member(u(#222/valid_groups,%#,read),[setq(0,u(#222/get_group,%0))]%q0)=0,{@pemit %#=You aren't currently subscribing to Board #%0. No ommission necessary.},{&bb_omit %#=[setunion(get(%#/bb_omit),%q0)]; @pemit %#=You have removed yourself from the [name(%q0)] board.}
&CMD_+BBJOIN mbboard=$+bbjoin *:@switch member(NULL [get(%#/bb_omit)],[setq(0,u(#222/get_group,%0))]%q0)=0,{@pemit %#=[switch(member(u(#222/valid_groups,%#,read),%q0),0,{Sorry, you don't have access to that board.},{You are already a member of the [name(%q0)] board.})]},{&bb_omit %#=[setdiff(get(%#/bb_omit),%q0)]; @pemit %#=You have joined the [name(%q0)] board.}

&CMD_+BBSCAN mbboard=$+bbscan: @pemit %#=[switch(hasattr(#222,BB_POST_HDR_%#),1,** BB Warning: You are in the middle of writing a bbpost. **%r)][switch(setdiff(iter(setr(0,u(#222/VALID_GROUPS,%#,read)),get(##/MESS_LST)),setr(1,get(%#/BB_READ))),,There are no unread postings on the Global Bulletin Board.,[center(- Unread Postings on the Global Bulletin Board -,78,-)][setq(9,get(#222/GROUPS))][trim(iter(%q0,switch(setr(2,setdiff(setr(3,get(##/MESS_LST)),%q1)),,,%r[name(##)] \(#[member(%q9,##)]\): [words(%q2)] unread \([u(#222/FN_UNREAD_LIST,%q2,%q3)]\))),b)]%r[center(- BBS at [round(mul(fdiv(strlen(get(#222/MASTER_LST)),get(#222/BUFFER_SIZE)),100),1)]\\% capacity -,78,-)])]

&CMD_+BBLIST mbboard=$+bblist:@pemit %#=[repeat(=,78)]%r[ljust(Available Bulletin Board Groups,37)]Member?[space(8)]Timeout (in days)%r[repeat(-,78)]%r%b[iter(get(#222/groups),switch(u(##/canread,%#),1,{%r%b[trim([ljust(member(get(#222/groups),##),5)][ljust(name(##),32)][ljust(switch(member(get(%#/bb_omit),##),0,Yes,No),19)][rjust(ifelse(get(##/config_timeout),div(get(##/config_timeout),86400),none),4)])]}))]%r[repeat(-,78)]%rTo join groups, type '+bbjoin <group number or name>'%r[repeat(=,78)]
&CREDITS mbboard=Myrddin's BBS was written by Myrddin@Witchcraft/Dreaming/Elysium (email: merlin@firstmagic.com). The most recent version of this code can be found at http://www.firstmagic.com/~merlin/mushcode, or via anonymous ftp from ftp.firstmagic.com in the /pub/merlin directory. Please refer interested parties to myself or those addresses, thank you. :)
@set mbboard/CREDITS = no_command
&CMD_+BBCATCHUP mbboard=$+bbcatchup *:@switch lcstr(%0)=all,{&bb_read %#=[get(#222/master_lst)]; @pemit %#=All postings on all boards marked as read.},{@dolist [setq(1,u(#222/valid_groups,%#,read))][u(#222/fn_makelist,%0)]={@switch member(%q1,[setq(0,u(#222/get_group,##))]%q0)=0,{@pemit %#=You do not subscribe to Group ##.},{ &bb_read %#=[setunion(get(%#/bb_read),get(%q0/MESS_LST))]; @pemit %#=All postings on Group #[member(get(#222/groups),%q0)] ([name(%q0)]) marked as read.}}}
&CMD_+BBMOVE mbboard=$+bbmove */* to *:@switch and(member(u(#222/valid_groups,%#,read),[setq(0,u(#222/get_group,%0))]%q0),member(u(#222/valid_groups,%#,write),[setq(2,u(#222/get_group,%2))]%q2),not(strmatch(%q0,%q2)))=0,{@pemit %#=One of the selected groups is not valid (either it doesn't exist, you can't write to it, or you tried to 'move' to the same group).},{@switch or(strmatch(index(get(%q0/HDR_[setq(1,extract(get(%q0/MESS_LST),%1,1))]%q1),|,4, 1),%#), and(hasflag(%#,wizard),member(get(%q0/MESS_LST),%q1)))=1,{&HDR_%q1 %q2=[get(%q0/HDR_%q1)]; &BDY_%q1 %q2=[get(%q0/BDY_%q1)]; &MESS_LST %q2=[cat(get(%q2/mess_lst),%q1)]; &MESS_LST %q0=[remove(get(%q0/MESS_LST),%q1)]; &HDR_%q1 %q0; &BDY_%q1 %q0; @pemit %#=Message '%1' removed from group '%0' and added to group '%2' as message #[member(get(%q2/mess_lst),%q1)]},{@pemit %#=Not a valid message number for that group.}}
&CMD_+BBWRITELOCK mbboard=$+bbwritelock *=*/*:@switch hasflag(%#,wizard)=1,{@switch member(get(#222/groups),[setq(0,u(#222/get_group,%0))]%q0)=0,{@pemit %#=No such group as '%0'.},{@switch %1=flag,{&CANWRITE %q0=\[or(hasflag(\%0,%2),hasflag(\%0,wizard))]},{&CANWRITE %q0=\[or(match(get(\%0/%1),%2),hasflag(\%0,wizard))]}; @pemit %#=Group '%0' locked. Only people with %1=%2 can write.}},{@pemit %#=You cannot lock message groups.}
&CMD_+BBPOST2 mbboard=$+bbpost */*:@switch hasattr(#222,bb_post_hdr_%#)=1,{@pemit %#=You are already in the middle of writing a bbpost.},{@switch strmatch(%1,*=*)=0,{@switch member(u(#222/valid_groups,%#,write),[setq(0,u(#222/get_group,%0))]%q0)=0,{@pemit %#=Either you do not subscribe to Group #%0 or are unable to post to it.},{&bb_post_hdr_%# #222=%q0|[mid(%1,0,34)]; @pemit %#=%rYou start your posting to Group #[member(get(#222/groups),%q0)] ([name(%q0)]).%rYou can now compose the body of the post by using '+bbwrite <text>'%ror '+bb <text>'. When you are finished, type '+bbpost' by itself.[ifelse(and(hasattr(%#,bb_sig),hasattr(%q0,anonymous)),{%b%bThis is an anonymous group. Your BB_SIG will -not- be appended.},)]}}}
&CMD_+BBWRITE mbboard=$+bbwrite *:@switch hasattr(#222,bb_post_hdr_%#)=0,{@pemit %#=You do not have a bbpost in progress.},{&bb_post_bdy_%# #222=[get(#222/bb_post_bdy_%#)]%0; @pemit %#=Text added to bbpost.}
&CMD_+BBPROOF mbboard=$+bbproof:@switch hasattr(#222,bb_post_hdr_%#)=0,{@pemit %#=You do not have a bbpost in progress.},{@pemit %#=[center(= BB Post in Progress =,78,=)]%rGroup: %b[name(index(get(#222/bb_post_hdr_%#),|,1,1))]%rTitle: %b[index(get(#222/bb_post_hdr_%#),|,2,1)]%r[repeat(-,78)]%r[trim(get(#222/bb_post_bdy_%#))]%r[repeat(=,78)]}
&CMD_+BBPOST-POST mbboard=$+bbpost:@switch [hasattr(#222,bb_post_hdr_%#)]:[hasattr(#222,bb_post_bdy_%#)]=0:0,{@pemit %#=You do not have a bbpost in progress.},1:0,{@pemit %#=Your post is empty. Please add text with the '+bbwrite <text>' command or discard the posting with the '+bbtoss' command.},{&mess_lst [setr(0,index(get(#222/bb_post_hdr_%#),|,1,1))]=[cat(get(%q0/mess_lst),setr(1,get(#222/nxt_mess)))]; &nxt_mess #222=[ulocal(#222/fn_inc_next_mess,%q1)]; &master_lst #222=[cat(get(#222/master_lst),%q1)]; &hdr_%q1 %q0=[index(get(#222/bb_post_hdr_%#),|,2,1)]|[u(#222/bbtime)]|[edefault(%q0/anonymous,mid(name(%#),0,24))]|[owner(%#)]|[ifelse(get(%q0/config_timeout),add(get(%q0/config_timeout),secs()),0)]; &last_mod %q0=[u(#222/bbtime)]; &bdy_%q1 %q0={[trim(get(#222/bb_post_bdy_%#))][ifelse(and(hasattr(%#,bb_sig),not(hasattr(%q0,anonymous))),{%r[ulocal(%#/bb_sig)]},)]}; @pemit %#=You post your note about '[index(get(#222/bb_post_hdr_%#),|,2,1)]' in group '[name(%q0)]' as message #[member(get(%q0/mess_lst),%q1)]; &bb_read %#=[setunion(get(%#/bb_read),%q1)]; @trigger #222/tr_post_notify=%#,%q0,[member(get(%q0/mess_lst),%q1)],[index(get(#222/bb_post_hdr_%#),|,2,1)]; &bb_post_bdy_%# #222; &bb_post_hdr_%# #222}
&CMD_+BBREAD mbboard=$+bbread:@pemit %#=[repeat(=,78)]%r[space(7)]Group Name[space(20)]Last Post[space(6)]# of messages%r[repeat(-,78)][iter(u(#222/valid_groups,%#,read),%r[rjust(member(get(#222/groups),##),2)][center([switch([get(##/CANREAD)]:[get(##/CANWRITE)]:[u(##/CANWRITE,%#)],1:1:1,,1:*:1,{(-)},1:*:0,-,*)],5)][ljust(name(##),30)][ljust(get(##/LAST_MOD),20)][rjust(words([setq(0,get(##/MESS_LST))]%q0),3)]%b[ljust(u(#222/isgroupread,%#,%q0),2)])]%r[repeat(-,78)]%r[center('*' = restricted[space(5)]'-' = read only[space(5)]'\(-\)' = read only\, but you can write,78)]%r[center(=[switch(hasflag(%#,wizard),1,{= BBS at [round(mul(fdiv(strlen(get(#222/master_lst)),get(#222/buffer_size)),100),1)]\\% capacity =},=)]=,78,=)]
&CMD_+BBTOSS mbboard=$+bbtoss:@switch hasattr(#222,bb_post_hdr_%#)=0,{@pemit %#=You do not have bbpost in progress.},{&bb_post_hdr_%# #222; &bb_post_bdy_%# #222; @pemit %#=Your bbpost has been discarded.}
&CMD_+BB mbboard=$+bb *:@switch hasattr(#222,bb_post_hdr_%#)=0,{@pemit %#=You do not have a bbpost in progress.},{&bb_post_bdy_%# #222=[get(#222/bb_post_bdy_%#)]%b%0; @pemit %#=Text added to bbpost.}
&CMD_+BBEDIT2 mbboard=$+bbedit *=*/*:@switch strmatch([setq(0,ucstr(%0))]%q0,*/*)=0,{@switch %q0=TEXT,{@edit #222/bb_post_bdy_%#={%1},{%2}},TITLE,{&bb_post_hdr_%# #222=[index(get(#222/bb_post_hdr_%#),|,1,1)]|[edit(index(get(#222/bb_post_hdr_%#),|,2,1),{%1},{%2})]}; @wait 0={@pemit %#=[center(= BB Post in Progress =,78,=)]%rGroup: %b[name(index(get(#222/bb_post_hdr_%#),|,1,1))]%rTitle: %b[index(get(#222/bb_post_hdr_%#),|,2,1)]%r[repeat(-,78)]%r[trim(get(#222/bb_post_bdy_%#))]%r[repeat(=,78)]}}
&CMD_+BBHELP mbboard=$+bbhelp:@pemit %#=Please use '+help bb'.
&CMD_+BBCONFIG mbboard=$+bbconfig:@pemit %#=[center(= Myrddin's Global BBS v[get(#222/version)] =,78,=)]%rGlobal Config Parameters:%r%r[rjust(timeout:,15)] [div(get(#222/config_timeout),86400)] days%r[rjust(autotimeout:,15)] [ifelse(hasattr(#222,startup),on,off)]%r[repeat(-,78)]%rBoard Config Parameters:%r%r%b[iter(filter(#222/fn_hasconfig,get(#222/groups)),%b%b[name(##)]%r[ifelse(hasattr(##,anonymous),[space(5)]anonymous: [get(##/anonymous)]%r,)][ifelse(neq(get(##/config_timeout),get(#222/config_timeout)),[space(5)]timeout: [div(get(##/config_timeout),86400)] days%r,)]%r)][repeat(=,78)]
&CMD_+BBCONFIG2 mbboard=$+bbconfig *=*:@switch [strmatch(%0,*/*)]:[hasflag(%#,wizard)]=1:*,{},0:0,{@pemit %#=Huh?%b%b(Type "help" for help.)},{@switch [member(get(#222/valid_global_configs),lcstr(%0))]=0,{@pemit %#=Valid global config parameters are: [get(#222/valid_global_configs)]},{@trigger #222/tr_gconfig_%0=%1,%#}}
&CMD_+BBCONFIG3 mbboard=$+bbconfig */*=*:@switch/first hasflag(%#,wizard)=0,{@pemit %#=Huh?%b%b(Type "help" for help.)},{@switch [setr(0,u(#222/get_group,%0))]:[member(get(#222/valid_configs),lcstr(%1))]=#-1:*,{@pemit %#='%0' is not a valid group name.},#-2:*,{@pemit %#='%0' is not specific enough.},*:0,{@pemit %#=Valid config parameters are: [get(#222/valid_configs)]},{@trigger #222/tr_config_%1=%q0,%2,%#}}
&CMD_+BBTIMEOUT mbboard=$+bbtimeout */*=*:@dolist [sort(u(#222/fn_makelist,%1))][setq(0,u(#222/get_group,%0))]={@switch [or(strmatch(index(get(%q0/HDR_[setq(1,extract(get(%q0/MESS_LST),##,1))]%q1),|,4, 1),%#), hasflag(%#,wizard))]:[and(isnum(%2),or(and(gt(%2,0),lte(mul(%2,86400),get(%q0/config_timeout))),and(not(get(%q0/config_timeout)),gte(%2,0)),hasflag(%#,wizard)))]=1:1, {&hdr_%q1 %q0=[replace(get(%q0/hdr_%q1),5,ifelse(%2,add(secs(),mul(%2,86400)),0),|)]; @pemit %#=Message ## in group '[name(%q0)]' has [ifelse(%2,a %2 day,no)] timeout.}, 0:*,{@pemit %#=Either message ## does not exist, or you were not the original poster.},*:0,{@pemit %#=Sorry, '%2' is not a valid number of days for a timeout on the '[name(%q0)]' board. [ifelse(get(%q0/config_timeout),Maximum timeout is [div(get(%q0/config_timeout),86400)] days.,)]}}
&CMD_+BBSEARCH mbboard=$+bbsearch */*:@switch [member(u(#222/valid_groups,%#,write),setr(0,u(#222/get_group,%0)))]:[hasattr(%q0,anonymous)]:[isdbref(setr(1,locate(%#,*%1,p)))]=0:*:*,{@pemit %#=BB Group '%0' is either an invalid Group, an unreadable Group, or a Group you do not subscribe to.},1:1:*,{@pemit %#=BB Group '[name(%q0)]' is an anonymous group.},1:0:0,{@pemit %#=No such player '%1'.},{@switch words(setr(2,grep(%q0,hdr_*,|%q1|)))=0,{@pemit %#=[name(%q1)] hasn't posted any messages to the '[name(%q0)]' Group.},{@pemit %#=%r[repeat(=,78)]%r[center(**** [name(%q0)] ****,78)]%r[space(8)]Message[space(28)]Posted[space(8)]By%r[repeat(-,78)]; @dolist %q2={@pemit %#=[ljust([member(get(#222/groups),%q0)]/[member(get(%q0/mess_lst),last(##,_))],6)][ljust(u(#222/fn_msg_flags,%#,%q0,last(##,_)),2)][ljust(index([setr(3,get(%q0/##))],|,1,1),35)][ljust(index(%q3,|,2,1),14)][mid([index(%q3,|,3,1)],0,21)][switch(member(%q2,##),words(%q2),%r[repeat(=,78)])]}}}
&CMD_+BBSEARCH_NOGREP mbboard=$+bbsearch */*:@switch [member(u(#222/valid_groups,%#,write),setr(0,u(#222/get_group,%0)))]:[hasattr(%q0,anonymous)]:[isdbref(setr(1,locate(%#,*%1,p)))]=0:*:*,{@pemit %#=You do not subscribe to that Group.},1:1:*,{@pemit %#=BB Group '[name(%q0)]' is an anonymous group.},1:0:0,{@pemit %#=No such player '%1'.},{@switch words(setr(2,u(#222/fn_grep,%q0,hdr_*,|%q1|)))=0,{@pemit %#=[name(%q1)] hasn't posted any messages to the '[name(%q0)]' Group.},{@pemit %#=%r[repeat(=,78)]%r[center(**** [name(%q0)] ****,78)]%r[space(8)]Message[space(28)]Posted[space(8)]By%r[repeat(-,78)]; @dolist %q2={@pemit %#=[ljust([member(get(#222/groups),%q0)]/[member(get(%q0/mess_lst),last(##,_))],6)][ljust(u(#222/fn_msg_flags,%#,%q0,last(##,_)),2)][ljust(index([setr(3,get(%q0/##))],|,1,1),35)][ljust(index(%q3,|,2,1),14)][mid([index(%q3,|,3,1)],0,21)][switch(member(%q2,##),words(%q2),%r[repeat(=,78)])]}}}
&CMD_+BBNOTIFY mbboard=$+bbnotify *=*:@switch/first [member(u(#222/valid_groups,%#,read),setr(0,u(#222/get_group,%0)))]:[member(on off,lcstr(%1))]:[lcstr(%1)]=0:*:*,{@pemit %#=[switch(%q0,#-2,That Group name is not specific enough.,You do not subscribe to that Group.)]},*:0:*,{@pemit %#=Invalid choice '%1'. Choices are 'on' or 'off'.},*:*:off,{&bb_silent %#=[setunion(get(%#/bb_silent),%q0)]; @pemit %#=Post notification for BB Group '[name(%q0)]' turned off. You will no longer be notified of new postings to that Group.},{&bb_silent %#=[setdiff(get(%#/bb_silent),%q0)]; @pemit %#=Post notification for BB Group '[name(%q0)]' turned on. You will now be notified of new postings to that Group.}
@set mbboard=!HALT
@set mbboard=INHERIT
@set mbboard=SAFE

&FN_IFELSE bbpocket=switch({%0},0,{%2},,{%2},{%1})
&FN_SETR bbpocket=[setq(%0,%1)][s(\%q%0)]
&FN_GREP bbpocket=iter(lattr(%0/%1),switch(strmatch(get(%0/##),*%2*),1,##))

@@ WEB OFF
@switch ifelse(1,1,0)=1,{@pemit %#=BBS INSTALLER> You have a working ifelse(). Good.; &FN_IFELSE bbpocket;},{@pemit %#=BBS INSTALLER> You don't have an ifelse() func. That's ok, I'll make my own.%r[space(15)]IMPORTANT: #1 Needs to execute the following command AND put%r[space(15)]it in its @startup:%r[space(15)]@function/priv ifelse=<dbref of bbpocket>/fn_ifelse}
@switch setr(0,1)=1,{@pemit %#=BBS INSTALLER> You have a working setr(). Good.; &FN_SETR bbpocket;},{@pemit %#=BBS INSTALLER> You don't have an setr() func. That's ok, I'll make my own.%r[space(15)]IMPORTANT: #1 Needs to execute the following command AND put%r[space(15)]it in its @startup:%r[space(15)]@function/priv setr=<dbref of bbpocket>/fn_setr}
@switch [first(grep(me,*,a))]=#-1,{@pemit %#=BBS INSTALLER> You don't have grep()... that's ok, I'll make my own.; @mvattr mbboard=CMD_+BBSEARCH_NOGREP,CMD_+BBSEARCH},{&FN_GREP bbpocket; &CMD_+BBSEARCH_NOGREP mbboard}
@@ WEB ON


@switch version()=TinyMUSH *version 3.*,{@set mbboard=COMMANDS; @set mbboard=STOP},TinyMUSH version 2.2.*,{@set mbboard=COMMANDS; @set mbboard=STOP},PennMUSH*,{@edit mbboard/CMD_+BBNEWGROUP=inherit,wizard; @set bbpocket=!INHERIT; @set bbpocket=WIZARD; @set mbboard=!INHERIT; @set mbboard=WIZARD; @set mbboard=!NO_COMMAND; @power bbpocket=see_all; @edit mbboard/CMD_+NEWGROUP={&CANREAD},{@set \%q0=NO_WARN; &CANREAD}}

@@
@@ The following insure that @attribute/access works
@@
&bb_read me=1
&bb_read me
&bb_omit me=1
&bb_omit me
&bb_silent me=1
&bb_silent me

@@ WEB OFF
@pemit %#=BBS INSTALLER> Cleaning up attributes...%r
@force me=@edit [num(bbpocket)]/*=#222,[num(bbpocket)]
@force me=@edit [num(mbboard)]/*=#222,[num(bbpocket)]

@@ need to wait so that the @forces above can finish
@wait 3={@tel bbpocket=mbboard; @name mbboard=BBS - Myrddin's Global BBS v4.0.6; @set me=!quiet}

@switch/first %#:[first(version())]=#1:Tiny*,{@attribute/access bb_read=hidden wizard; @attribute/access bb_omit=hidden wizard},#1:Penn*,{@set bboard=WIZARD},*:Tiny*,{@pemit me=Reminder! Make sure #1 executes the following:%r%b%b@attribute/access bb_read=hidden wizard%r%b%b@attribute/access bb_omit=hidden wizard%r%b%b@attribute/access bb_silent=hidden wizard},{@pemit me=Reminder! Make sure #1 sets the BBS WIZARD}

@wait 1=@pemit me=%rBulletin Board construction complete. Just place the Global BB in the Master Room... Enjoy!%r[repeat(=,78)]