/***************************************************************************** * DikuMUD (C) 1990, 1991 by: * * Sebastian Hammer, Michael Seifert, Hans Henrik Staefeldt, Tom Madsen, * * and Katja Nyboe. * *---------------------------------------------------------------------------* * MERC 2.1 (C) 1992, 1993 by: * * Michael Chastain, Michael Quan, and Mitchell Tse. * *---------------------------------------------------------------------------* * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by: Derek Snider. * * Team: Thoric, Altrag, Blodkai, Narn, Haus, Scryn, Rennard, Swordbearer, * * gorog, Grishnakh, Nivek, Tricops, and Fireblade. * *---------------------------------------------------------------------------* * SMAUG 1.7 FUSS by: Samson and others of the SMAUG community. * * Their contributions are greatly appreciated. * *---------------------------------------------------------------------------* * LoP (C) 2006, 2007, 2008 by: the LoP team. * *****************************************************************************/ #include <stdio.h> #include "h/mud.h" #include "h/bti.h" BTI_DATA *first_bti, *last_bti; int top_bti; void free_bti( BTI_DATA *bti ) { STRFREE( bti->text ); STRFREE( bti->poster ); DISPOSE( bti ); } void remove_bti( BTI_DATA *bti ) { UNLINK( bti, first_bti, last_bti, next, prev ); top_bti--; } void free_all_bti( void ) { BTI_DATA *bti, *bti_next; for( bti = first_bti; bti; bti = bti_next ) { bti_next = bti->next; remove_bti( bti ); free_bti( bti ); } } void add_bti( BTI_DATA *bti ) { LINK( bti, first_bti, last_bti, next, prev ); top_bti++; } void save_bti( void ) { BTI_DATA *bti; FILE *fp; if( !first_bti ) { remove_file( BTI_FILE ); return; } if( !( fp = fopen( BTI_FILE, "w" ) ) ) { bug( "%s: Can't open %s for writing.", __FUNCTION__, BTI_FILE ); return; } for( bti = first_bti; bti; bti = bti->next ) { fprintf( fp, "%s", "#BTI\n" ); if( bti->poster ) fprintf( fp, "Poster %s~\n", bti->poster ); fprintf( fp, "Time %ld\n", bti->added ); fprintf( fp, "Type %d\n", bti->type ); fprintf( fp, "Room %d\n", bti->room ); if( bti->text ) fprintf( fp, "Text %s~\n", strip_cr( bti->text ) ); fprintf( fp, "%s", "End\n\n" ); } fprintf( fp, "%s", "#END\n" ); fclose( fp ); fp = NULL; } void fread_bti( FILE *fp ) { const char *word; bool fMatch; BTI_DATA *bti; CREATE( bti, BTI_DATA, 1 ); for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = false; switch( UPPER( word[0] ) ) { case '*': fMatch = true; fread_to_eol( fp ); break; case 'E': if( !str_cmp( word, "End" ) ) { add_bti( bti ); return; } break; case 'P': KEY( "Poster", bti->poster, fread_string( fp ) ); break; case 'R': KEY( "Room", bti->room, fread_number( fp ) ); break; case 'T': KEY( "Text", bti->text, fread_string( fp ) ); KEY( "Time", bti->added, fread_time( fp ) ); KEY( "Type", bti->type, fread_number( fp ) ); break; } if( !fMatch ) { bug( "%s: no match: %s", __FUNCTION__, word ); fread_to_eol( fp ); } } free_bti( bti ); } void load_bti( void ) { FILE *fp; top_bti = 0; first_bti = last_bti = NULL; if( !( fp = fopen( BTI_FILE, "r" ) ) ) return; for( ;; ) { char letter; const char *word; letter = fread_letter( fp ); if( letter == '*' ) { fread_to_eol( fp ); continue; } if( letter != '#' ) { bug( "%s: # not found.", __FUNCTION__ ); break; } word = feof( fp ) ? "END" : fread_word( fp ); if( !str_cmp( word, "BTI" ) ) { fread_bti( fp ); continue; } else if( !str_cmp( word, "END" ) ) break; else { bug( "%s: bad section (%s).", __FUNCTION__, word ); fread_to_eol( fp ); continue; } } fclose( fp ); fp = NULL; } /* Find a specif bti entry using a number */ BTI_DATA *find_bti( CHAR_DATA *ch, int num ) { BTI_DATA *bti; int cnt = 0; if( !ch || num <= 0 ) return NULL; for( bti = first_bti; bti; bti = bti->next ) { if( ++cnt == num ) return bti; } return NULL; } void show_bti( CHAR_DATA *ch, BTI_DATA *bti, int count ) { ch_printf( ch, "&C[&W%4d&C] &W%7s &CPosted by &W%s &Cfrom room [&W%d&C] %s&D\r\n", count, bti->type == 0 ? "BUG" : bti->type == 1 ? "IDEA" : bti->type == 2 ? "TYPO" : "UNKNOWN", bti->poster ? bti->poster : "(Unknown)", bti->room, distime( bti->added ) ); ch_printf( ch, "&W%s&D\r\n", bti->text ? bti->text : "(Not set yet)" ); } CMDF( do_bti ) { BTI_DATA *bti; int count = 0; char arg[MIL]; if( !ch || is_npc( ch ) || !ch->desc ) return; set_pager_color( AT_HELP, ch ); argument = one_argument( argument, arg ); /* Show all the bti data if no arg or not a number */ if( !arg || arg[0] == '\0' || !is_number( arg ) ) { for( bti = first_bti; bti; bti = bti->next ) { count++; show_bti( ch, bti, count ); } if( count == 0 ) send_to_char( "No bti to show.\r\n", ch ); return; } count = atoi( arg ); if( !( bti = find_bti( ch, count ) ) ) { send_to_char( "No such bti to modify.\r\n", ch ); return; } argument = one_argument( argument, arg ); if( !is_immortal( ch ) ) { show_bti( ch, bti, count ); return; } /* Remove a bti entry */ if( !str_cmp( arg, "remove" ) ) { remove_bti( bti ); save_bti( ); send_to_char( "That bti was removed and the bti was saved.\r\n", ch ); return; } /* Handle displaying it again if the right argument wasnt given */ show_bti( ch, bti, count ); } void newbti( CHAR_DATA *ch, int type, char *argument ) { BTI_DATA *bti; const char *msg = "unknown"; if( !ch ) return; if( type == 0 ) msg = "bug"; else if( type == 1 ) msg = "idea"; else if( type == 2 ) msg = "typo"; set_char_color( AT_PLAIN, ch ); if( !argument || argument[0] == '\0' ) { ch_printf( ch, "\r\nUsage: '%s <message>'\r\n", msg ); return; } CREATE( bti, BTI_DATA, 1 ); bti->poster = STRALLOC( ch->name ); bti->added = current_time; bti->text = STRALLOC( argument ); bti->type = type; bti->room = ch->in_room ? ch->in_room->vnum : 0; add_bti( bti ); save_bti( ); ch_printf( ch, "Thanks, your %s notice has been recorded.\r\n", msg ); } CMDF( do_bug ) { newbti( ch, 0, argument ); } CMDF( do_idea ) { newbti( ch, 1, argument ); } CMDF( do_typo ) { newbti( ch, 2, argument ); }