#include "mail.h" inherit "/obj/misc/board"; /* Modified by Nivek, 5/1/94, removing the 'mark current as read' * thing, which was causing many to miss a number of notes. The * 'skip' command does the same thing. * Also added some more feedback to the 'new' command, and fixed some * minor spacing things in 'next' and 'prev'. * Me again, 5/8/94, adding a 'board' command with no args, which * tells which board you're holding, and how many new notes there * are. */ #include "board.h" void setup() { ::setup(); action_pri = 3; reset_drop(); set_get(); } /* setup() */ int help( string str ) { if( str != "board" ) return 0; write( "%^YELLOW%^Commands for this board are:%^RESET%^\n" + "read <note number> - Read a note.\n" + "post <subject> - Post a new note\n" + "boards - List all boards.\n" + "store <note number> <file> - Save note to file.\n" + "eat <note number> - Remove an note.\n" + "reply <note number> - Send mail to the poster.\n" + "followup <note number> - Post a followup note\n" + "summary [all] - List boards with new notes.\n" + "next - Goto next board.\n" + "prev - Goto prev board.\n" + "new - Goto next board with new notes.\n" + "board <board name> - Goto named board.\n" + "skip - Mark all notes as read.\n" + "%^YELLOW%^Board configuration commands:%^RESET%^\n" + "timeout <time> - Set note experation time.\n" + "minimum <num> - Min number to leave active.\n" + "maximum <num> - Max notes before auto experation.\n" + "archive <name|none> - Archive file name.\n" + "security - List who can access this board.\n" + "add <name> - Add someone to the access list.\n" + "remove <name> - Remove someone from the access list.\n" + "arts - Give file names of notes.\n" + "killfile <board name> - Set your kill file for this board.\n" ); return 1; } /* * Need to redefine this to add all the extra bits and wombles to it. */ string long( string str, int dark ) { int i, irp; mixed *stuff; string ret, help; mapping news_rc; help = "Use 'help board' for instructions.\n"; stuff = (mixed *)BOARD_HAND->get_subjects( board_name ); ret = "A bulletin board (" + board_name + ").\n"; irp = (int)BOARD_HAND->query_minimum( board_name ); if( irp ) ret += "Minimum number of messages left by auto magic deletion is " + irp + ".\n"; irp = (int)BOARD_HAND->query_maximum( board_name ); if( irp ) ret += "Maximum number of messages on this board is " + irp + ".\n"; irp = (int)BOARD_HAND->query_timeout( board_name ); if( irp ) ret += "Messages will automaticaly time out in " + irp + " days.\n"; irp = (int)BOARD_HAND->query_archive( board_name ); if( irp ) ret += "Deleted messages are archived in " + irp + ".\n"; ret += help; if( !sizeof( stuff ) ) return ret + "The board is completely empty.\n"; news_rc = (mapping)this_player()->query_property( NEWS_RC ); if( !news_rc ) news_rc = ([ ]); for( i = 0; i < sizeof( stuff ); i++ ) if( news_rc[ board_name ] < stuff[ i ][ B_TIME ] ) ret += sprintf( "N %2d: %-=*s\n", i + 1, ( int ) this_player()->query_cols() - 6, stuff[ i ][ B_SUBJECT ] + " (" + capitalize( stuff[ i ][ B_NAME ] ) + " " + the_date( stuff[ i ][ B_TIME ] ) + ")" ); else ret += sprintf( " %2d: %-=*s\n", i + 1, ( int ) this_player()->query_cols() - 6, stuff[ i ][ B_SUBJECT ] + " (" + capitalize( stuff[ i ][ B_NAME ] ) + " " + the_date( stuff[ i ][ B_TIME ] ) + ")" ); return ret; } /* long() */ void init() { ::init(); add_action( "save_note", "store", action_pri ); add_action( "next", "next", action_pri ); add_action( "prev", "prev", action_pri ); add_action( "new", "new", action_pri ); add_action( "board", "b*oard", action_pri ); add_action( "list_boards", "boards", action_pri ); add_action( "kfile", "killfile", action_pri ); add_action( "do_security", "security", action_pri ); add_action( "do_add", "add" ); add_action( "do_remove", "remove" ); add_action( "do_timeout", "timeout" ); add_action( "do_minimum", "minimum" ); add_action( "do_maximum", "maximum" ); add_action( "do_archive", "archive" ); add_action( "do_summary", "summary" ); add_action( "do_skip", "skip" ); add_action( "do_art_nos", "arts" ); add_action( "help", "help", 1 ); } /* init() */ int save_note( string arg ) { int which; string file; mixed * stuff; if( !arg || (sscanf( arg, "%d %s", which, file ) != 2) ) { notify_fail( "Syntax: store <note number> <file name>\n" ); return 0; } stuff = (mixed *)BOARD_HAND->get_subjects( board_name ); if( which < 1 || which > sizeof( stuff ) ) { notify_fail( "Invalid note number.\n" ); return 0; } which--; /* 1..n */ file += ".note"; if( !MASTER_OB->valid_write( file, this_player()->query_name() ) ) { notify_fail( "The master object appears and prevents you.\n" ); return 0; } seteuid( "Root" ); write_file( file, stuff[ which ][ B_SUBJECT ] + "\n\n" + BOARD_HAND->get_message( board_name, which ) ); write( "Ok.\n" ); return 1; } /* save_note() */ void set_board_name( string str ) { board_name = str; } void set_datafile( string str ) { board_name = str; } int next() { int i; string *boards; boards = (string *)BOARD_HAND->list_of_boards(); if( (i = member_array( board_name, boards )) == -1 ) i = 0; else i = (i + 1) % sizeof( boards ); board_name = boards[ i ]; write( "Gone to board: " + board_name + ".\n" ); return 1; } /* next() */ int prev() { int i; string *boards; boards = (string *)BOARD_HAND->list_of_boards(); if( (i = member_array( board_name, boards )) == -1 ) i = 0; else i = (i - 1 + sizeof( boards )) % sizeof( boards ); board_name = boards[ i ]; write( "Gone to board: " + board_name + ".\n" ); return 1; } /* prev() */ int kfile( string arg ) { this_player()->add_property( "news_kill_" + lower_case( arg ), 1 ); return 1; } /* kfile() */ int new() { int i; string *boards; mixed * stuff; mixed otherstuff; mapping news_rc; boards = (string *)BOARD_HAND->list_of_boards(); /* start from the begining and search for one with new notes. */ news_rc = (mapping)this_player()->query_property( NEWS_RC ); for( i = 0; i < sizeof( boards ); i++ ) { if( !this_player()->query_property( "news_kill_" + boards[ i ] ) ) { stuff = (mixed *)BOARD_HAND->get_subjects( boards[ i ] ); if( !sizeof( stuff ) ) continue; if ( find_new( boards[ i ] ) ) { board_name = boards[ i ]; write( "The " + board_name + " board has new messages.\n" ); return 1; } } } notify_fail( "No boards with new messages.\n" ); return 0; } /* new() */ int board( string str ) { int i; string *boards; if( !str ) { i = sizeof( (mixed *)BOARD_HAND->get_subjects( board_name ) ); write( "You are switched to the " + board_name + " board, with " + ( ( find_new( board_name ) )? ( i - find_new( board_name ) + 1 ) : "no" ) + " new messages.\n" ); return 1; } boards = (string *)BOARD_HAND->list_of_boards(); if( (i = member_array( str, boards )) == -1 ) { notify_fail( "The board " + str + " does not exist sorry.\n" ); return 0; } write( "Board changed to " + str + ", which " + ( ( find_new( str ) )? "has" : "does not have" ) + " new messages.\n" ); board_name = str; return 1; } /* board() */ int list_boards() { write( "The current boards are '" + implode( (string *)BOARD_HAND->list_of_boards(), "', '" ) + "'.\n" ); return 1; } /* boards() */ int do_security() { write( "The current people in this boards security array are :\n" + implode( (string *)BOARD_HAND->query_security( board_name ), ", " ) + "\n" ); return 1; } /* do_security() */ int do_add( string name ) { if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; notify_fail( "Syntax: " + query_verb() + " <name>\n" ); return( int ) BOARD_HAND->add_allowed( board_name, name ); } /* do_add() */ int do_remove( string name ) { if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; notify_fail( "Syntax: " + query_verb() + " <name>\n" ); return( int ) BOARD_HAND->remove_allowed( board_name, name ); } /* do_remove() */ int do_timeout( string name ) { int i; if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; notify_fail( "Syntax: " + query_verb() + " <name>\n" ); if( !name || sscanf( name, "%d", i ) != 1 ) return 0; return( int ) BOARD_HAND->set_timeout( board_name, i ); } /* do_timeout() */ int do_minimum( string name ) { int i; if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; notify_fail( "Syntax: " + query_verb() + " <name>\n" ); if( !name || sscanf( name, "%d", i ) != 1 ) return 0; return( int ) BOARD_HAND->set_minimum( board_name, i ); } /* do_minimum() */ int do_maximum( string name ) { int i; if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; notify_fail( "Syntax: " + query_verb() + " <name>\n" ); if( !name || (sscanf( name, "%d", i ) != 1) ) return 0; printf( "here\n" ); return( int ) BOARD_HAND->set_maximum( board_name, i ); } /* do_maximum() */ int do_archive( string name ) { if( this_player() != this_player( 1 ) || !interactive( previous_object() ) ) return 0; if( !name ) return 0; if( name != "none" ) return( int ) BOARD_HAND->set_archive( board_name, name ); return( int ) BOARD_HAND->set_archive( board_name ); } /* do_archive() */ move( object dest, string s1, string s2 ) { int ret; if( !objectp( dest ) ) return ::move( dest, s1, s2 ); if( interactive( dest ) ) { ret =::move( dest, s1, s2 ); if( ret ) return ret; seteuid( geteuid( dest ) ); return 0; } return ::move( dest, s1, s2 ); } /* move() */ mixed query_static_auto_load() { return board_name; } /* query_static_auto_load() */ void init_static_arg( mixed board ) { if( stringp( board ) ) board_name = board; } /* init_static_auto_load() */ /* Much of the following code is ugly. This is entirely my fault. * After adding find_new(), I found that I had to change this * function as well, and I did it in a sloppy, piecewise manner, * and I'm tired and lazy and I haven't slept in a long time and * my back hurts and I have a load of stuff to move upstairs from * the garage, etc., etc. * Nivek */ int do_summary( string str ) { int i, no, amt; string *boards; mapping news_rc; mixed * stuff; boards = (string *)BOARD_HAND->list_of_boards(); /* start from the begining and search for one with new notes. */ news_rc = (mapping)this_player()->query_property( NEWS_RC ); if ( !news_rc ) news_rc = ([ ]); for( i = 0; i < sizeof( boards ); i++ ) { if( !this_player()->query_property( "news_kill_" + boards[ i ] ) ) { stuff = (mixed *)BOARD_HAND->get_subjects( boards[ i ] ); if( !sizeof( stuff ) ) continue; amt = find_new( boards[ i ] ); if ( amt ) amt -= 2; else amt = sizeof( stuff ) - 1; if( amt != sizeof( stuff ) - 1 ) { write( "The " + boards[ i ] + " board has " + (sizeof( stuff ) - amt - 1) + " new messages.\n" ); no++; } else if( str == "all" ) { write( "The " + boards[ i ] + " board has no new messages.\n" ); no++; } } } notify_fail( "No boards with new messages.\n" ); return no; } /* do_summary() */ /* Skip does the same as a new, but marks the board as read. */ int do_skip() { mapping news_rc; mixed * otherstuff; news_rc = (mapping)this_player()->query_property( NEWS_RC ); otherstuff = (mixed *)BOARD_HAND->get_subjects( board_name ); if( sizeof( otherstuff ) ) { news_rc[ board_name ] = otherstuff[ sizeof( otherstuff ) - 1 ][ B_TIME ]; this_player()->add_property( NEWS_RC, news_rc ); } write( "Marked all of " + board_name + " as read.\n" ); if( !new() ) { write( "No new messages.\n" ); } return 1; } /* do_skip() */ int do_art_nos() { int i; mixed * otherstuff; otherstuff = (mixed *)BOARD_HAND->get_subjects( board_name ); for( i = 0; i < sizeof( otherstuff ); i++ ) printf( "%2d# %-20s %d\n", i, otherstuff[ i ][ B_NAME ], otherstuff[ i ][ B_NUM ] ); return 1; } /* do_art_nos() */