/*************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael * * Chastain, Michael Quan, and Mitchell Tse. * * * * In order to use any part of this Merc Diku Mud, you must comply with * * both the original Diku license in 'license.doc' as well the Merc * * license in 'license.txt'. In particular, you may not remove either of * * these copyright notices. * * * * Much time and thought has gone into this software and you are * * benefitting. We hope that you share your changes too. What goes * * around, comes around. * ***************************************************************************/ /*************************************************************************** * ROM 2.4 is copyright 1993-1995 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@pacinfo.com) * * Gabrielle Taylor (gtaylor@pacinfo.com) * * Brian Moore (rom@rom.efn.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file 'rom.license' * ***************************************************************************/ /*************************************************************************** * ROT 2.0 is copyright 1996-1999 by Russ Walsh * * By using this code, you have agreed to follow the terms of the * * ROT license, in the file 'rot.license' * ***************************************************************************/ #if defined(macintosh) #include <types.h> #else #include <sys/types.h> #if defined(WIN32) #else #include <sys/time.h> #endif #endif #include <ctype.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include "merc.h" #include "recycle.h" #include "tables.h" /* globals from db.c for load_notes */ #if !defined(macintosh) extern int _filbuf args( (FILE *) ); #endif extern FILE * fpArea; extern char strArea[MIL]; extern char boot_buf[MSL]; /* local procedures */ void load_thread(char *name, NOTE_DATA **list, int type, time_t free_time); void load_mudlist(char *name, MUD_DATA **list); void parse_note(CHAR_DATA *ch, char *argument, int type); void parse_mud(CHAR_DATA *ch, char *argument); bool hide_note(CHAR_DATA *ch, NOTE_DATA *pnote); bool hide_mud(CHAR_DATA *ch, MUD_DATA *pmud); NOTE_DATA *note_list; NOTE_DATA *idea_list; NOTE_DATA *penalty_list; NOTE_DATA *news_list; NOTE_DATA *changes_list; NOTE_DATA *weddings_list; MUD_DATA *mud_list; int count_spool(CHAR_DATA *ch, NOTE_DATA *spool) { int count = 0; NOTE_DATA *pnote; for (pnote = spool; pnote != NULL; pnote = pnote->next) if (!hide_note(ch,pnote)) count++; return count; } int count_spoolml(CHAR_DATA *ch, MUD_DATA *spool) { int count = 0; MUD_DATA *pmud; for (pmud = spool; pmud != NULL; pmud = pmud->next) if (!hide_mud(ch,pmud)) count++; return count; } void do_unread(CHAR_DATA *ch,char *argument) { char buf[MAX_STRING_LENGTH]; int count; if (IS_NPC(ch)) return; sprintf(buf, "{c+----------------------------------------------+{x\n\r" ); send_to_char(buf, ch); sprintf(buf, "{c| |{x\n\r" ); send_to_char(buf,ch); sprintf(buf, "{c| {D>Note Board<{c |{x\n\r" ); send_to_char( buf, ch); sprintf(buf, "{c| |{x\n\r" ); send_to_char(buf,ch); sprintf(buf, "{c+----------------------------------------------+{x\n\r" ); send_to_char( buf, ch); count = count_spool(ch, note_list); sprintf(buf,"{c|{WNotes{x [{D%d{x]{W General OOC Notes {c |{x\n\r",count); send_to_char(buf,ch); count = count_spool(ch,idea_list); sprintf(buf,"{c|{WIdeas{x [{D%d{x]{W Ideas for Improvement {c |{x\n\r",count); send_to_char(buf,ch); count = count_spool(ch,news_list); sprintf(buf,"{c|{WNews{x [{D%d{x]{W News for the MUD {c |{x\n\r",count); send_to_char(buf,ch); count = count_spool(ch,changes_list); sprintf(buf,"{c|{WChanges{x [{D%d{x]{W Changes that have been Made{c |{x\n\r",count); send_to_char(buf,ch); count = count_spoolml(ch,mud_list); sprintf(buf,"{c|{WMud Ads{x [{D%d{x]{W Mud Ads {c |{x\n\r",count); send_to_char(buf,ch); count = count_spool(ch,weddings_list); sprintf(buf,"{c|{WWeddings{x [{D%d{x]{W Weddings {c |{x\n\r",count); send_to_char(buf,ch); if (IS_TRUSTED(ch,SQUIRE)) { count = count_spool(ch,penalty_list); sprintf(buf,"{c|{WPenalties{x [{D%d{x]{W Penalties Added {c |{x\n\r",count); send_to_char(buf,ch); } sprintf( buf, "{c+----------------------------------------------+{x\n\r"); send_to_char(buf, ch); } void do_note(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_NOTE); } void do_idea(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_IDEA); } void do_penalty(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_PENALTY); } void do_news(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_NEWS); } void do_weddings(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_WEDDINGS); } void do_changes(CHAR_DATA *ch,char *argument) { parse_note(ch,argument,NOTE_CHANGES); } void do_mud(CHAR_DATA *ch,char *argument) { parse_mud(ch,argument); } void save_notes(int type) { FILE *fp; char *name; NOTE_DATA *pnote; switch (type) { default: return; case NOTE_NOTE: name = NOTE_FILE; pnote = note_list; break; case NOTE_IDEA: name = IDEA_FILE; pnote = idea_list; break; case NOTE_PENALTY: name = PENALTY_FILE; pnote = penalty_list; break; case NOTE_NEWS: name = NEWS_FILE; pnote = news_list; break; case NOTE_CHANGES: name = CHANGES_FILE; pnote = changes_list; break; case NOTE_WEDDINGS: name = WEDDINGS_FILE; pnote = weddings_list; break; } fclose( fpReserve ); if ( ( fp = fopen( name, "w" ) ) == NULL ) { perror( name ); } else { for ( ; pnote != NULL; pnote = pnote->next ) { fprintf( fp, "Sender %s~\n", pnote->sender); fprintf( fp, "Date %s~\n", pnote->date); fprintf( fp, "Stamp %ld\n", pnote->date_stamp); fprintf( fp, "To %s~\n", pnote->to_list); fprintf( fp, "Subject %s~\n", pnote->subject); fprintf( fp, "Text\n%s~\n", pnote->text); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; } } void save_muds(void) { FILE *fp; char *name; MUD_DATA *pmud; name = MUD_FILE; pmud = mud_list; fclose( fpReserve ); if ( ( fp = fopen( name, "w" ) ) == NULL ) { perror( name ); } else { for ( ; pmud != NULL; pmud = pmud->next ) { fprintf( fp, "Sender %s~\n", pmud->sender); fprintf( fp, "Date %s~\n", pmud->date); fprintf( fp, "Stamp %ld\n", pmud->date_stamp); fprintf( fp, "Name %s~\n", pmud->name); fprintf( fp, "Base %s~\n", pmud->base); fprintf( fp, "Address %s~\n", pmud->address); fprintf( fp, "Port %d\n", pmud->port); } fclose( fp ); fpReserve = fopen( NULL_FILE, "r" ); return; } } void load_notes(void) { load_thread(NOTE_FILE,¬e_list, NOTE_NOTE, 14*24*60*60); strcat(boot_buf,"ortality, th"); load_thread(IDEA_FILE,&idea_list, NOTE_IDEA, 28*24*60*60); strcat(boot_buf,"ey called up"); load_thread(PENALTY_FILE,&penalty_list, NOTE_PENALTY, 0); strcat(boot_buf,"on themsel"); load_thread(NEWS_FILE,&news_list, NOTE_NEWS, 0); strcat(boot_buf,"ves\n\r the a"); load_thread(WEDDINGS_FILE,&weddings_list, NOTE_WEDDINGS, 0); strcat(boot_buf,"nger of th"); load_thread(CHANGES_FILE,&changes_list,NOTE_CHANGES, 0); load_mudlist(MUD_FILE,&mud_list); } void load_thread(char *name, NOTE_DATA **list, int type, time_t free_time) { FILE *fp; NOTE_DATA *pnotelast; if ( ( fp = fopen( name, "r" ) ) == NULL ) return; pnotelast = NULL; for ( ; ; ) { NOTE_DATA *pnote; char letter; do { letter = getc( fp ); if ( feof(fp) ) { fclose( fp ); return; } } while ( isspace(letter) ); ungetc( letter, fp ); pnote = alloc_perm( sizeof(*pnote) ); if ( str_cmp( fread_word( fp ), "sender" ) ) break; pnote->sender = fread_string( fp ); if ( str_cmp( fread_word( fp ), "date" ) ) break; pnote->date = fread_string( fp ); if ( str_cmp( fread_word( fp ), "stamp" ) ) break; pnote->date_stamp = fread_number(fp); if ( str_cmp( fread_word( fp ), "to" ) ) break; pnote->to_list = fread_string( fp ); if ( str_cmp( fread_word( fp ), "subject" ) ) break; pnote->subject = fread_string( fp ); if ( str_cmp( fread_word( fp ), "text" ) ) break; pnote->text = fread_string( fp ); if (free_time && pnote->date_stamp < current_time - free_time) { free_note(pnote); continue; } pnote->type = type; if (*list == NULL) *list = pnote; else pnotelast->next = pnote; pnotelast = pnote; } strcpy( strArea, NOTE_FILE ); fpArea = fp; bug( "Load_notes: bad key word.", 0 ); exit( 1 ); return; } void load_mudlist(char *name, MUD_DATA **list) { FILE *fp; MUD_DATA *pmudlast; if ( ( fp = fopen( name, "r" ) ) == NULL ) return; pmudlast = NULL; for ( ; ; ) { MUD_DATA *pmud; char letter; do { letter = getc( fp ); if ( feof(fp) ) { fclose( fp ); return; } } while ( isspace(letter) ); ungetc( letter, fp ); pmud = alloc_perm( sizeof(*pmud) ); if ( str_cmp( fread_word( fp ), "sender" ) ) break; pmud->sender = fread_string( fp ); if ( str_cmp( fread_word( fp ), "date" ) ) break; pmud->date = fread_string( fp ); if ( str_cmp( fread_word( fp ), "stamp" ) ) break; pmud->date_stamp = fread_number(fp); if ( str_cmp( fread_word( fp ), "name" ) ) break; pmud->name = fread_string( fp ); if ( str_cmp( fread_word( fp ), "base" ) ) break; pmud->base = fread_string( fp ); if ( str_cmp( fread_word( fp ), "address" ) ) break; pmud->address = fread_string( fp ); if ( str_cmp( fread_word( fp ), "port" ) ) break; pmud->port = fread_number(fp); if (*list == NULL) *list = pmud; else pmudlast->next = pmud; pmudlast = pmud; } strcpy( strArea, MUD_FILE ); fpArea = fp; bug( "Load_mudlist: bad key word.", 0 ); exit( 1 ); return; } void append_note(NOTE_DATA *pnote) { FILE *fp; char *name; NOTE_DATA **list; NOTE_DATA *last; switch(pnote->type) { default: return; case NOTE_NOTE: name = NOTE_FILE; list = ¬e_list; break; case NOTE_IDEA: name = IDEA_FILE; list = &idea_list; break; case NOTE_PENALTY: name = PENALTY_FILE; list = &penalty_list; break; case NOTE_NEWS: name = NEWS_FILE; list = &news_list; break; case NOTE_CHANGES: name = CHANGES_FILE; list = &changes_list; break; case NOTE_WEDDINGS: name = WEDDINGS_FILE; list = &weddings_list; break; } if (*list == NULL) *list = pnote; else { for ( last = *list; last->next != NULL; last = last->next); last->next = pnote; } fclose(fpReserve); if ( ( fp = fopen(name, "a" ) ) == NULL ) { perror(name); } else { fprintf( fp, "Sender %s~\n", pnote->sender); fprintf( fp, "Date %s~\n", pnote->date); fprintf( fp, "Stamp %ld\n", pnote->date_stamp); fprintf( fp, "To %s~\n", pnote->to_list); fprintf( fp, "Subject %s~\n", pnote->subject); fprintf( fp, "Text\n%s~\n", pnote->text); fclose( fp ); } fpReserve = fopen( NULL_FILE, "r" ); } void append_mud(MUD_DATA *pmud) { FILE *fp; char *name; MUD_DATA **list; MUD_DATA *last; name = MUD_FILE; list = &mud_list; if (*list == NULL) *list = pmud; else { for ( last = *list; last->next != NULL; last = last->next); last->next = pmud; } fclose(fpReserve); if ( ( fp = fopen(name, "a" ) ) == NULL ) { perror(name); } else { fprintf( fp, "Sender %s~\n", pmud->sender); fprintf( fp, "Date %s~\n", pmud->date); fprintf( fp, "Stamp %ld\n", pmud->date_stamp); fprintf( fp, "Name %s~\n", pmud->name); fprintf( fp, "Base %s~\n", pmud->base); fprintf( fp, "Address %s~\n", pmud->address); fprintf( fp, "Port %d\n", pmud->port); fclose( fp ); } fpReserve = fopen( NULL_FILE, "r" ); } bool is_note_to( CHAR_DATA *ch, NOTE_DATA *pnote ) { if ( !str_cmp( ch->name, pnote->sender ) ) return TRUE; if ( is_name( "all", pnote->to_list ) ) return TRUE; if ( IS_IMMORTAL(ch) && is_name( "immortal", pnote->to_list ) ) return TRUE; if (ch->clan && is_name(clan_table[ch->clan].name,pnote->to_list)) return TRUE; if ( is_exact_name( ch->name, pnote->to_list ) ) return TRUE; return FALSE; } void note_attach( CHAR_DATA *ch, int type ) { NOTE_DATA *pnote; if ( ch->pnote != NULL ) return; pnote = new_note(); pnote->next = NULL; pnote->sender = str_dup( ch->name ); pnote->date = str_dup( "" ); pnote->to_list = str_dup( "" ); pnote->subject = str_dup( "" ); pnote->text = str_dup( "" ); pnote->type = type; ch->pnote = pnote; return; } void note_remove( CHAR_DATA *ch, NOTE_DATA *pnote, bool delete) { char to_new[MIL]; char to_one[MIL]; NOTE_DATA *prev; NOTE_DATA **list; char *to_list; if (!delete) { /* make a new list */ to_new[0] = '\0'; to_list = pnote->to_list; while ( *to_list != '\0' ) { to_list = one_argument( to_list, to_one ); if ( to_one[0] != '\0' && str_cmp( ch->name, to_one ) ) { strcat( to_new, " " ); strcat( to_new, to_one ); } } /* Just a simple recipient removal? */ if ( str_cmp( ch->name, pnote->sender ) && to_new[0] != '\0' ) { free_string( pnote->to_list ); pnote->to_list = str_dup( to_new + 1 ); return; } } /* nuke the whole note */ switch(pnote->type) { default: return; case NOTE_NOTE: list = ¬e_list; break; case NOTE_IDEA: list = &idea_list; break; case NOTE_PENALTY: list = &penalty_list; break; case NOTE_NEWS: list = &news_list; break; case NOTE_CHANGES: list = &changes_list; break; case NOTE_WEDDINGS: list = &weddings_list; break; } /* * Remove note from linked list. */ if ( pnote == *list ) { *list = pnote->next; } else { for ( prev = *list; prev != NULL; prev = prev->next ) { if ( prev->next == pnote ) break; } if ( prev == NULL ) { bug( "Note_remove: pnote not found.", 0 ); return; } prev->next = pnote->next; } save_notes(pnote->type); free_note(pnote); return; } void mud_remove( CHAR_DATA *ch, MUD_DATA *pmud) { MUD_DATA *prev; MUD_DATA **list; if ((get_trust(ch) < MAX_LEVEL - 4) && (str_cmp( ch->name, pmud->sender ))) { send_to_char("You did not post that mud ad.\n\r",ch); return; } list = &mud_list; /* * Remove mud from linked list. */ if ( pmud == *list ) { *list = pmud->next; } else { for ( prev = *list; prev != NULL; prev = prev->next ) { if ( prev->next == pmud ) break; } if ( prev == NULL ) { bug( "Mud_remove: pmud not found.", 0 ); return; } prev->next = pmud->next; } save_muds(); free_mud(pmud); send_to_char("Ok.\n\r",ch); return; } bool hide_note (CHAR_DATA *ch, NOTE_DATA *pnote) { time_t last_read; if (IS_NPC(ch)) return TRUE; switch (pnote->type) { default: return TRUE; case NOTE_NOTE: last_read = ch->pcdata->last_note; break; case NOTE_IDEA: last_read = ch->pcdata->last_idea; break; case NOTE_PENALTY: last_read = ch->pcdata->last_penalty; break; case NOTE_NEWS: last_read = ch->pcdata->last_news; break; case NOTE_CHANGES: last_read = ch->pcdata->last_changes; break; case NOTE_WEDDINGS: last_read = ch->pcdata->last_weddings; break; } if (pnote->date_stamp <= last_read) return TRUE; if (!str_cmp(ch->name,pnote->sender)) return TRUE; if (!is_note_to(ch,pnote)) return TRUE; return FALSE; } void update_readml(CHAR_DATA *ch, MUD_DATA *pmud) { time_t stamp; if (IS_NPC(ch)) return; stamp = pmud->date_stamp; ch->pcdata->last_mud = UMAX(ch->pcdata->last_mud,stamp); } void update_read(CHAR_DATA *ch, NOTE_DATA *pnote) { time_t stamp; if (IS_NPC(ch)) return; stamp = pnote->date_stamp; switch (pnote->type) { default: return; case NOTE_NOTE: ch->pcdata->last_note = UMAX(ch->pcdata->last_note,stamp); break; case NOTE_IDEA: ch->pcdata->last_idea = UMAX(ch->pcdata->last_idea,stamp); break; case NOTE_PENALTY: ch->pcdata->last_penalty = UMAX(ch->pcdata->last_penalty,stamp); break; case NOTE_NEWS: ch->pcdata->last_news = UMAX(ch->pcdata->last_news,stamp); break; case NOTE_CHANGES: ch->pcdata->last_changes = UMAX(ch->pcdata->last_changes,stamp); break; case NOTE_WEDDINGS: ch->pcdata->last_weddings = UMAX(ch->pcdata->last_weddings,stamp); break; } } void parse_note( CHAR_DATA *ch, char *argument, int type ) { char buf[MSL]; char arg[MIL]; NOTE_DATA *pnote; NOTE_DATA **list; char *list_name; int vnum; int anum; if ( IS_NPC(ch) ) return; if ((ch->in_room->vnum == ROOM_VNUM_CORNER) && (!IS_IMMORTAL(ch))) { send_to_char("Just keep your nose in the corner like a good little player.\n\r",ch); return; } switch(type) { default: return; case NOTE_NOTE: list = ¬e_list; list_name = "notes"; break; case NOTE_IDEA: list = &idea_list; list_name = "ideas"; break; case NOTE_PENALTY: list = &penalty_list; list_name = "penalties"; break; case NOTE_NEWS: list = &news_list; list_name = "news"; break; case NOTE_CHANGES: list = &changes_list; list_name = "changes"; break; case NOTE_WEDDINGS: list = &weddings_list; list_name = "weddings"; break; } argument = one_argument( argument, arg ); if ( arg[0] == '\0' || !str_prefix( arg, "read" ) ) { bool fAll; if ( !str_cmp( argument, "all" ) ) { fAll = TRUE; anum = 0; } else if ( argument[0] == '\0' || !str_prefix(argument, "next")) /* read next unread note */ { vnum = 0; for ( pnote = *list; pnote != NULL; pnote = pnote->next) { if (!hide_note(ch,pnote)) { sprintf( buf, "[%3d] %s: %s\n\r%s\n\rTo: %s\n\r", vnum, pnote->sender, pnote->subject, pnote->date, pnote->to_list); send_to_char( buf, ch ); page_to_char( pnote->text, ch ); update_read(ch,pnote); return; } else if (is_note_to(ch,pnote)) vnum++; } sprintf(buf,"You have no unread %s.\n\r",list_name); send_to_char(buf,ch); return; } else if ( is_number( argument ) ) { fAll = FALSE; anum = atoi( argument ); } else { send_to_char( "Read which number?\n\r", ch ); return; } vnum = 0; for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { if ( is_note_to( ch, pnote ) && ( vnum++ == anum || fAll ) ) { sprintf( buf, "[%3d] %s: %s\n\r%s\n\rTo: %s\n\r", vnum - 1, pnote->sender, pnote->subject, pnote->date, pnote->to_list ); send_to_char( buf, ch ); page_to_char( pnote->text, ch ); update_read(ch,pnote); return; } } sprintf(buf,"There aren't that many %s.\n\r",list_name); send_to_char(buf,ch); return; } if ( !str_prefix( arg, "list" ) ) { BUFFER *output; vnum = 0; output = new_buf(); for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { if ( is_note_to( ch, pnote ) ) { sprintf( buf, "[%3d%s] %s: %s\n\r", vnum, hide_note(ch,pnote) ? " " : "N", pnote->sender, pnote->subject ); add_buf(output,buf); vnum++; } } if (!vnum) { switch(type) { case NOTE_NOTE: sprintf( buf, "There are no notes for you.\n\r"); break; case NOTE_IDEA: sprintf( buf, "There are no ideas for you.\n\r"); break; case NOTE_PENALTY: sprintf( buf, "There are no penalties for you.\n\r"); break; case NOTE_NEWS: sprintf( buf, "There are no news for you.\n\r"); break; case NOTE_CHANGES: sprintf( buf, "There are no changes for you.\n\r"); break; case NOTE_WEDDINGS: sprintf( buf, "There are no wedding announcements for you.\n\r"); break; } add_buf(output,buf); } page_to_char( buf_string(output), ch ); free_buf(output); return; } if ( !str_prefix( arg, "remove" ) ) { if ( !is_number( argument ) ) { send_to_char( "Note remove which number?\n\r", ch ); return; } anum = atoi( argument ); vnum = 0; for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { if ( is_note_to( ch, pnote ) && vnum++ == anum ) { note_remove( ch, pnote, FALSE ); send_to_char( "Ok.\n\r", ch ); return; } } sprintf(buf,"There aren't that many %s.",list_name); send_to_char(buf,ch); return; } if ( !str_prefix( arg, "delete" ) && get_trust(ch) >= MAX_LEVEL - 4) { if ( !is_number( argument ) ) { send_to_char( "Note delete which number?\n\r", ch ); return; } anum = atoi( argument ); vnum = 0; for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { if ( is_note_to( ch, pnote ) && vnum++ == anum ) { note_remove( ch, pnote,TRUE ); send_to_char( "Ok.\n\r", ch ); return; } } sprintf(buf,"There aren't that many %s.",list_name); send_to_char(buf,ch); return; } if (!str_prefix(arg,"catchup")) { switch(type) { case NOTE_NOTE: ch->pcdata->last_note = current_time; break; case NOTE_IDEA: ch->pcdata->last_idea = current_time; break; case NOTE_PENALTY: ch->pcdata->last_penalty = current_time; break; case NOTE_NEWS: ch->pcdata->last_news = current_time; break; case NOTE_CHANGES: ch->pcdata->last_changes = current_time; break; case NOTE_WEDDINGS: ch->pcdata->last_weddings = current_time; break; } return; } /* below this point only certain people can edit notes */ /* if ((type == NOTE_NEWS && !IS_TRUSTED(ch,KNIGHT)) || (type == NOTE_CHANGES && !IS_TRUSTED(ch,CREATOR)) || (type == NOTE_WEDDINGS && !ch->wedpost && !IS_IMMORTAL(ch))) { sprintf(buf,"You aren't authorized to write %s.",list_name); send_to_char(buf,ch); return; } */ if ( !str_cmp( arg, "write" ) ) { if ( ch->pnote == NULL ) { send_to_char("\n\rBegin your note with a 'subject' and 'to' before you 'write' it\n\r", ch ); return; } if (ch->pnote->type != type) { send_to_char("\n\rYou aren't working on that kind of note.\n\r",ch); return; } string_append( ch, &ch->pnote->text ); return; } if ( !str_cmp( arg, "+" ) ) { send_to_char("\n\rWe have a much easier way of doing notes now. Try using 'write' instead of '+'.\n\r", ch ); return; } if ( !str_cmp( arg, "-" ) ) { send_to_char("\n\rWe have a much easier way of doing notes now. Try using 'write' instead of '-'.\n\r", ch ); return; } if ( !str_prefix( arg, "subject" ) ) { note_attach( ch,type ); if (ch->pnote->type != type) { send_to_char( "You already have a different note in progress.\n\r",ch); return; } sprintf(buf, "%s{x", argument); free_string( ch->pnote->subject ); ch->pnote->subject = str_dup( buf ); buf[0] = '\0'; send_to_char( "Ok.\n\r", ch ); return; } if ( !str_prefix( arg, "to" ) ) { note_attach( ch,type ); if (ch->pnote->type != type) { send_to_char( "You already have a different note in progress.\n\r",ch); return; } free_string( ch->pnote->to_list ); ch->pnote->to_list = str_dup( argument ); send_to_char( "Ok.\n\r", ch ); return; } if ( !str_prefix( arg, "clear" ) ) { if ( ch->pnote != NULL ) { free_note(ch->pnote); ch->pnote = NULL; } send_to_char( "Ok.\n\r", ch ); return; } if ( !str_prefix( arg, "show" ) ) { if ( ch->pnote == NULL ) { send_to_char( "You have no note in progress.\n\r", ch ); return; } if (ch->pnote->type != type) { send_to_char("You aren't working on that kind of note.\n\r",ch); return; } sprintf( buf, "%s: %s\n\rTo: %s\n\r", ch->pnote->sender, ch->pnote->subject, ch->pnote->to_list ); send_to_char( buf, ch ); send_to_char( ch->pnote->text, ch ); return; } if ( !str_prefix( arg, "post" ) || !str_prefix(arg, "send")) { DESCRIPTOR_DATA *d; char buf[MAX_STRING_LENGTH]; char *strtime; if ( ch->pnote == NULL ) { send_to_char( "You have no note in progress.\n\r", ch ); return; } if (ch->pnote->type != type) { send_to_char("You aren't working on that kind of note.\n\r",ch); return; } if (!str_cmp(ch->pnote->to_list,"")) { send_to_char( "You need to provide a recipient (name, all, or immortal).\n\r", ch); return; } if (!str_cmp(ch->pnote->subject,"")) { send_to_char("You need to provide a subject.\n\r",ch); return; } ch->pnote->next = NULL; strtime = ctime( ¤t_time ); strtime[strlen(strtime)-1] = '\0'; ch->pnote->date = str_dup( strtime ); ch->pnote->date_stamp = current_time; sprintf(buf,"{WCheck your %s! {x[{cSender: {D%s{c Subject: {D%s{x]\n\r",list_name,ch->name,ch->pnote->subject); for(d=descriptor_list;d;d = d->next) { if(d->connected == CON_PLAYING && is_note_to(d->character,ch->pnote)) { send_to_char(buf,d->character); } } append_note(ch->pnote); ch->pnote = NULL; return; } send_to_char( "You can't do that.\n\r", ch ); return; } void parse_mud( CHAR_DATA *ch, char *argument ) { char buf[MSL]; char arg[MIL]; MUD_DATA *pmud; MUD_DATA **list; char *list_name; int vnum; int anum; if ( IS_NPC(ch) ) return; if ((ch->in_room->vnum == ROOM_VNUM_CORNER) && (!IS_IMMORTAL(ch))) { send_to_char("Just keep your nose in the corner like a good little player.\n\r",ch); return; } list = &mud_list; list_name = "mud ads"; argument = one_argument( argument, arg ); if ( arg[0] == '\0' || !str_prefix( arg, "read" ) ) { bool fAll; if ( !str_cmp( argument, "all" ) ) { fAll = TRUE; anum = 0; } else if ( argument[0] == '\0' || !str_prefix(argument, "next")) /* read next unread note */ { vnum = 0; for ( pmud = *list; pmud != NULL; pmud = pmud->next) { if (!hide_mud(ch,pmud)) { sprintf( buf, "[%3d] %s: %s\n\r\n\r", vnum, pmud->sender, pmud->date); send_to_char( buf, ch ); sprintf( buf, "{G Name:{x %s\n\r", pmud->name); send_to_char( buf, ch ); sprintf( buf, "{GCode Base:{x %s\n\r", pmud->base); send_to_char( buf, ch ); sprintf( buf, "{G Address:{x %s {GPort{x %d\n\r", pmud->address, pmud->port); send_to_char( buf, ch ); update_readml(ch,pmud); return; } else { vnum++; } } sprintf(buf,"You have no unread %s.\n\r",list_name); send_to_char(buf,ch); return; } else if ( is_number( argument ) ) { fAll = FALSE; anum = atoi( argument ); } else { send_to_char( "Read which number?\n\r", ch ); return; } vnum = 0; for ( pmud = *list; pmud != NULL; pmud = pmud->next ) { if ( ( vnum++ == anum || fAll ) ) { sprintf( buf, "[%3d] %s: %s\n\r\n\r", vnum, pmud->sender, pmud->date); send_to_char( buf, ch ); sprintf( buf, "{G Name:{x %s\n\r", pmud->name); send_to_char( buf, ch ); sprintf( buf, "{GCode Base:{x %s\n\r", pmud->base); send_to_char( buf, ch ); sprintf( buf, "{G Address:{x %s {GPort{x %d\n\r", pmud->address, pmud->port); send_to_char( buf, ch ); update_readml(ch,pmud); return; } } sprintf(buf,"There aren't that many %s.\n\r",list_name); send_to_char(buf,ch); return; } if ( !str_prefix( arg, "list" ) ) { BUFFER *output; vnum = 0; output = new_buf(); for ( pmud = *list; pmud != NULL; pmud = pmud->next ) { sprintf( buf, "[%3d%s] %s: %s\n\r", vnum, hide_mud(ch,pmud) ? " " : "N", pmud->sender, pmud->name ); add_buf(output,buf); vnum++; } if (!vnum) { sprintf( buf, "There are no %s to list.\n\r",list_name); add_buf(output,buf); } page_to_char( buf_string(output), ch ); free_buf(output); return; } if ( !str_prefix( arg, "delete" ) || !str_prefix( arg, "remove" ) ) { if ( !is_number( argument ) ) { send_to_char( "Mud delete which number?\n\r", ch ); return; } anum = atoi( argument ); vnum = 0; for ( pmud = *list; pmud != NULL; pmud = pmud->next ) { if ( vnum++ == anum ) { mud_remove( ch, pmud ); return; } } sprintf(buf,"There aren't that many %s.",list_name); send_to_char(buf,ch); return; } if (!str_prefix(arg,"catchup")) { ch->pcdata->last_mud = current_time; return; } if ( !str_prefix( arg, "post" ) || !str_prefix(arg, "add")) { DESCRIPTOR_DATA *d; bool found = FALSE; if ( ( ch->class < MCLT_1 ) && ch->level < 10 ) { sprintf(buf,"You aren't authorized to write %s.",list_name); send_to_char(buf,ch); return; } if ( ch->position == POS_FIGHTING ) { send_to_char( "No way! You are fighting.\n\r", ch ); return; } if ( ch->position < POS_STUNNED ) { send_to_char( "You're not DEAD yet.\n\r", ch ); return; } for ( d = descriptor_list; d != NULL; d = d->next ) { if ( d->connected == CON_PLAYING && d->character == ch) { found = TRUE; break; } } if (!found) { send_to_char( "Can't find your descriptor, aborted\n\r",ch); return; } send_to_char( "\n\r{REnter {zONLY{x{R the asked for information in the fields, if I had wanted{x\n\r",ch); send_to_char( "{Rmessages in the ads, I would have made a field for them.{x\n\r\n\r", ch); send_to_char( "{GEnter the name of the mud{x\n\r\n\r",ch); send_to_char( "{Gie: {RRealms of Thoth{x\n\r\n\r",ch ); send_to_char( " {YName:{x ", ch); ch->was_in_room = ch->in_room; char_from_room( ch ); if ( ch == char_list ) { char_list = ch->next; } else { CHAR_DATA *prev; for ( prev = char_list; prev != NULL; prev = prev->next ) { if ( prev->next == ch ) { prev->next = ch->next; break; } } if ( prev == NULL ) { bug( "Extract_char: char not found.", 0 ); return; } } d->connected = CON_MUD_GET_NAME; return; } send_to_char( "You can't do that.\n\r", ch ); return; } bool hide_mud (CHAR_DATA *ch, MUD_DATA *pmud) { time_t last_read; if (IS_NPC(ch)) return TRUE; last_read = ch->pcdata->last_mud; if (pmud->date_stamp <= last_read) return TRUE; if (!str_cmp(ch->name,pmud->sender)) return TRUE; return FALSE; } void note_remove_quiet( NOTE_DATA *pnote) { NOTE_DATA *prev; NOTE_DATA **list; switch(pnote->type) { default: return; case NOTE_NOTE: list = ¬e_list; break; case NOTE_IDEA: list = &idea_list; break; case NOTE_PENALTY: list = &penalty_list; break; case NOTE_NEWS: list = &news_list; break; case NOTE_CHANGES: list = &changes_list; break; case NOTE_WEDDINGS: list = &weddings_list; break; } /* * Remove note from linked list. */ if ( pnote == *list ) { *list = pnote->next; } else { for ( prev = *list; prev != NULL; prev = prev->next ) { if ( prev->next == pnote ) break; } if ( prev == NULL ) { bug( "Note_remove: pnote not found.", 0 ); return; } prev->next = pnote->next; } save_notes(pnote->type); free_note(pnote); return; } void expire_notes ( void ) { NOTE_DATA *pnote; NOTE_DATA **list; long diff; int note_num; note_num = 0; list = ¬e_list; for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { diff = (long)current_time - (long)pnote->date_stamp; if (diff > 864000) { note_num++; } } for ( ; note_num > 0; note_num--) { pnote = *list; if (pnote != NULL) { note_remove_quiet(pnote); } } note_num = 0; list = &idea_list; for ( pnote = *list; pnote != NULL; pnote = pnote->next ) { diff = (long)current_time - (long)pnote->date_stamp; if (diff > 864000) { note_num++; } } for ( ; note_num > 0; note_num--) { pnote = *list; if (pnote != NULL) { note_remove_quiet(pnote); } } return; }