/* Property of Owen Emlen and Simon Lee - some borrowed from older code, 90% new */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "emlen.h" bool is_note_to (CHAR_DATA * ch, NOTE_DATA * pnote); void note_attach (CHAR_DATA * ch); void note_remove (CHAR_DATA * ch, NOTE_DATA * pnote); void note_delete (NOTE_DATA * pnote); #define MAX_BOARDS 4 char *boards[MAX_BOARDS] = { "Blank", "Immortal Notice Board", "General Chat Board", "Ideas/Complaint Board" }; bool is_note_to (CHAR_DATA * ch, NOTE_DATA * pnote) { if (!str_cmp (NAME (ch), pnote->sender)) return TRUE; if (is_name ("all", pnote->to_list) || is_name ("clan", pnote->to_list)) return TRUE; if (IS_IMMORTAL (ch) && is_name ("immortal", pnote->to_list)) return TRUE; if (is_name (NAME (ch), pnote->to_list)) return TRUE; if (LEVEL (ch) >= 110) return TRUE; return FALSE; } void note_attach (CHAR_DATA * ch) { NOTE_DATA *pnote; check_ced (ch); if (ch->ced->pnote != NULL) return; if (note_free == NULL) { pnote = mem_alloc (sizeof (*ch->ced->pnote)); } else { pnote = note_free; note_free = note_free->next; } pnote->next = NULL; pnote->sender = str_dup (NAME (ch)); pnote->date = str_dup (""); pnote->to_list = str_dup (""); pnote->subject = str_dup (""); pnote->text = str_dup (""); pnote->lines = 0; ch->ced->pnote = pnote; return; } void note_remove (CHAR_DATA * ch, NOTE_DATA * pnote) { char to_new[SML_LENGTH]; char to_one[SML_LENGTH]; FILE *fp; NOTE_DATA *prev; char *to_list; /* * Build a new to_list. * Strip out this recipient. */ to_new[0] = '\0'; to_list = pnote->to_list; while (*to_list != '\0') { to_list = one_argy (to_list, to_one); if (to_one[0] != '\0' && str_cmp (NAME (ch), to_one)) { strcat (to_new, " "); strcat (to_new, to_one); } } /* * Just a simple recipient removal? */ if (LEVEL (ch) < 110 && !is_note_to (ch, pnote)) { if (str_cmp (NAME (ch), pnote->sender) && to_new[0] != '\0') { free_string (pnote->to_list); pnote->to_list = str_dup (to_new + 1); return; } } /* * Remove note from linked list. */ if (pnote == note_list) { note_list = pnote->next; } else { for (prev = note_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; } free_string (pnote->text); free_string (pnote->subject); free_string (pnote->to_list); free_string (pnote->date); free_string (pnote->sender); pnote->next = note_free; note_free = pnote; /* * Rewrite entire list. */ #ifndef WINDOWS // fclose (fpReserve); #endif if ((fp = fopen (NOTE_FILE, "w")) == NULL) { perror (NOTE_FILE); } else { for (pnote = note_list; pnote != NULL; pnote = pnote->next) { fprintf (fp, "Sender %s~\n", fix_string (pnote->sender)); fprintf (fp, "TBoard %d\n", pnote->board_num); fprintf (fp, "Date %s~\n", pnote->date); fprintf (fp, "Stamp %ld\n", pnote->date_stamp); fprintf (fp, "To %s~\n", fix_string (pnote->to_list)); fprintf (fp, "Subject %s~\n", fix_string (pnote->subject)); fprintf (fp, "Text\n%s~\n", fix_string (pnote->text)); fprintf (fp, "End\n"); } fclose (fp); } #ifndef WINDOWS // fpReserve = fopen (NULL_FILE, "r"); #endif return; } void do_note (CHAR_DATA * ch, char *argy) { char buf[STD_LENGTH * 17]; char buf1[STD_LENGTH * 17]; char arg[SML_LENGTH]; NOTE_DATA *pnote; int vnum; int board_here; /*Boards and board nums by Owen Emlen */ SINGLE_OBJECT *obj; int anum; DEFINE_COMMAND ("note", do_note, POSITION_DEAD, 0, LOG_NORMAL, "This command is used to post/read/remove notes.") if (IS_MOB (ch)) return; board_here = 0; obj = get_obj_here (ch, "board", SEARCH_ROOM_FIRST); if (obj == NULL) { board_here = 1; } else board_here = obj->pIndexData->value[9]; buf1[0] = '\0'; argy = one_argy (argy, arg); smash_tilde (argy); if (arg[0] == '\0') { do_note (ch, "read"); return; } if (!str_cmp (arg, "list")) { vnum = 0; sprintf(buf1,"\x1B[34;1m------------------------------------------------------------------------\x1B[37;0m\n\r"); sprintf(buf1+strlen(buf1),"\x1B[36;1m New ### Sender/From Subject\x1B[37;0m\n\r"); sprintf(buf1+strlen(buf1),"\x1B[34;1m------------------------------------------------------------------------\x1B[37;0m\n\r"); for (pnote = note_list; pnote != NULL; pnote = pnote->next) { if (is_note_to (ch, pnote) && (board_here == pnote->board_num || IS_IMMORTAL (ch))) { if (strlen(pnote->subject)>35) { pnote->subject[35]='\0'; } sprintf (buf, "%s \x1B[37;1m%3d\x1B[37;0m From \x1B[35;1m%-14s\x1B[37;0m '\x1B[37;1m%s\x1B[37;0m'\n\r", (pnote->date_stamp > ch->pcdata->last_note && str_cmp (pnote->sender, NAME (ch))) ? "\x1B[34;1m(New)\x1B[37;0m" : " ", vnum, pnote->sender, pnote->subject); strcat (buf1, buf); vnum++; } else vnum++; if (strlen (buf1) > (STD_LENGTH * 16)) { strcat (buf1, "\n\rTOO MANY NOTES.. WAIT UNTIL A GOD REMOVES SOME!\n\r"); break; } } page_to_char (buf1, ch); return; } if (!str_cmp (arg, "read")) { bool fAll; if (!str_cmp (argy, "all")) { fAll = TRUE; anum = 0; } else if (argy[0] == '\0' || !str_prefix (argy, "next")) /* read next unread note */ { vnum = 0; for (pnote = note_list; pnote != NULL; pnote = pnote->next) { if (is_note_to (ch, pnote) && (board_here == pnote->board_num || IS_IMMORTAL (ch)) && str_cmp (NAME (ch), pnote->sender) && ch->pcdata->last_note < pnote->date_stamp) { sprintf (buf,"\x1B[33;1m---------------------------------------------------------------------------\x1B[37;0m\n\r"); sprintf (buf+strlen(buf), "[Note #\x1B[37;1m%d:%d\x1B[37;0m] From: \x1B[35;1m%s\x1B[37;0m To: \x1B[35;1m%s\x1B[37;0m\n\r", vnum, pnote->board_num, pnote->sender, pnote->to_list); if (strlen(pnote->subject)>35) { pnote->subject[35]='\0'; } sprintf (buf+strlen(buf),"%s. Subject: \x1B[37;1m%s\x1B[37;0m\n\r", pnote->date, pnote->subject); sprintf (buf+strlen(buf),"\x1B[33;1m---------------------------------------------------------------------------\x1B[37;0m\n\r"); strcat (buf1, buf); strcat (buf1, pnote->text); ch->pcdata->last_note = UMAX (ch->pcdata->last_note, pnote->date_stamp); page_to_char (buf1, ch); return; } else vnum++; } send_to_char ("You have no unread notes.\n\r", ch); return; } else if (is_number (argy)) { fAll = FALSE; anum = atoi (argy); } else { send_to_char ("Note read which number?\n\r", ch); return; } vnum = 0; for (pnote = note_list; pnote != NULL; pnote = pnote->next) { if ((vnum++ == anum || fAll) && is_note_to (ch, pnote) && (board_here == pnote->board_num || IS_IMMORTAL (ch))) { sprintf (buf,"\x1B[33;1m---------------------------------------------------------------------------\x1B[37;0m\n\r"); sprintf (buf+strlen(buf), "[Note #\x1B[37;1m%d:%d\x1B[37;0m] From: \x1B[35;1m%s\x1B[37;0m To: \x1B[35;1m%s\x1B[37;0m\n\r", vnum - 1, pnote->board_num, pnote->sender, pnote->to_list); if (strlen(pnote->subject)>35) { pnote->subject[35]='\0'; } sprintf (buf+strlen(buf),"Dated %s. Subject: \x1B[37;1m%s\x1B[37;0m\n\r", pnote->date, pnote->subject); sprintf (buf+strlen(buf),"\x1B[33;1m---------------------------------------------------------------------------\x1B[37;0m\n\r"); strcat (buf1, buf); strcat (buf1, pnote->text); page_to_char (buf1, ch); return; } } send_to_char ("No such note.\n\r", ch); return; } if (!str_cmp (arg, "write")) { if (LEVEL (ch) < 100 && board_here == 1) { send_to_char ("You can't write on the immortal notice board.\n\r", ch); return; } check_ced (ch); note_attach (ch); string_append (ch, &ch->ced->pnote->text); return; } if (!str_cmp (arg, "fwrite")) { if (LEVEL (ch) < 100 && board_here == 1) { send_to_char ("You can't write on the immortal notice board.\n\r", ch); return; } check_ced (ch); note_attach (ch); fullscreen_editor (ch, &ch->ced->pnote->text); return; } if (!str_cmp (arg, "+")) { check_ced (ch); note_attach (ch); strcpy (buf, ch->ced->pnote->text); if (strlen (buf) + strlen (argy) >= STD_LENGTH - 200) { send_to_char ("Note too long.\n\r", ch); return; } strcat (buf, argy); strcat (buf, "\n\r"); free_string (ch->ced->pnote->text); ch->ced->pnote->text = str_dup (buf); ch->ced->pnote->lines += 1; send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "-")) { int num, cnt; char new_buf[STD_LENGTH]; const char *str; check_ced (ch); if (ch->ced->pnote == NULL) { send_to_char ("You have to start a note first.\n\r", ch); return; } if (ch->ced->pnote->lines == 0) { send_to_char ("Nothing to delete.\n\r", ch); return; } new_buf[0] = '\0'; str = ch->ced->pnote->text; cnt = 1; for (num = 1; num <= ch->ced->pnote->lines; num++) { while (*str != '\r' && *str != '\0') { ++str; ++cnt; } } strncpy (new_buf, ch->ced->pnote->text, cnt); new_buf[cnt] = '\0'; free_string (ch->ced->pnote->text); ch->ced->pnote->text = str_dup (new_buf); ch->ced->pnote->lines -= 1; send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "subject")) { check_ced (ch); note_attach (ch); free_string (ch->ced->pnote->subject); ch->ced->pnote->subject = str_dup (argy); send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "to")) { check_ced (ch); note_attach (ch); free_string (ch->ced->pnote->to_list); ch->ced->pnote->to_list = str_dup (argy); send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "clear")) { check_ced (ch); if (ch->ced->pnote != NULL) { free_string (ch->ced->pnote->text); free_string (ch->ced->pnote->subject); free_string (ch->ced->pnote->to_list); free_string (ch->ced->pnote->date); free_string (ch->ced->pnote->sender); ch->ced->pnote->next = note_free; note_free = ch->ced->pnote; ch->ced->pnote = NULL; } send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "show")) { check_ced (ch); if (ch->ced->pnote == NULL) { send_to_char ("You have no note in progress.\n\r", ch); return; } sprintf (buf, "%s: %s\n\rTo: %s\n\rLines: %d\n\r", ch->ced->pnote->sender, ch->ced->pnote->subject, ch->ced->pnote->to_list, ch->ced->pnote->lines ); strcat (buf1, buf); strcat (buf1, ch->ced->pnote->text); page_to_char (buf1, ch); return; } if (!str_cmp (arg, "post") || !str_prefix (arg, "send")) { FILE *fp; char *strtime; check_ced (ch); if (ch->ced->pnote == NULL) { send_to_char ("You have no note in progress.\n\r", ch); return; } if (board_here == 1 && LEVEL (ch) < 100) { send_to_char ("This board is reserved for immortals posting messages to mortals.\n\r", ch); send_to_char ("Please post on a public board if you wish to write a note.\n\r", ch); return; } if (!str_cmp (ch->ced->pnote->to_list, "")) { send_to_char ( "You need to provide a recipient (name, all, or immortal).\n\r", ch); return; } if (!str_cmp (ch->ced->pnote->subject, "")) { send_to_char ("You need to provide a subject.\n\r", ch); return; } ch->ced->pnote->next = NULL; strtime = ctime (¤t_time); strtime[strlen (strtime) - 1] = '\0'; ch->ced->pnote->board_num = board_here; ch->ced->pnote->date = str_dup (strtime); ch->ced->pnote->date_stamp = current_time; if (note_list == NULL) { note_list = ch->ced->pnote; } else { for (pnote = note_list; pnote->next != NULL; pnote = pnote->next) ; pnote->next = ch->ced->pnote; } pnote = ch->ced->pnote; ch->ced->pnote = NULL; #ifndef WINDOWS // fclose (fpReserve); #endif if ((fp = fopen (NOTE_FILE, "a")) == NULL) { perror (NOTE_FILE); } else { fprintf (fp, "Sender %s~\n", fix_string (pnote->sender)); fprintf (fp, "TBoard %d\n", pnote->board_num); fprintf (fp, "Date %s~\n", pnote->date); fprintf (fp, "Stamp %ld\n", pnote->date_stamp); fprintf (fp, "To %s~\n", fix_string (pnote->to_list)); fprintf (fp, "Subject %s~\n", fix_string (pnote->subject)); fprintf (fp, "Text\n%s~\n", pnote->text); fprintf (fp, "End\n\n"); fclose (fp); } #ifndef WINDOWS // fpReserve = fopen (NULL_FILE, "r"); #endif send_to_char ("Ok.\n\r", ch); return; } if (!str_cmp (arg, "remove")) { if (!is_number (argy)) { send_to_char ("Note remove which number?\n\r", ch); return; } anum = atoi (argy); vnum = 0; for (pnote = note_list; pnote != NULL; pnote = pnote->next) { if (vnum++ == anum && ( (is_note_to (ch, pnote) && !is_name ("all", pnote->to_list)) || LEVEL (ch) > 109)) { note_remove (ch, pnote); send_to_char ("Ok.\n\r", ch); return; } } send_to_char ("No such note.\n\r", ch); return; } send_to_char ("Huh? Type 'help note' for usage.\n\r", ch); return; }