home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / d-linux.zip / dm-dist / board.c < prev    next >
C/C++ Source or Header  |  1991-03-01  |  9KB  |  342 lines

  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <ctype.h>
  4.  
  5. #include "utils.h"
  6. #include "structs.h"
  7. #include "comm.h"
  8.  
  9.  
  10. #define MAX_MSGS 30                   /* Max number of messages.          */
  11. #define SAVE_FILE "board.messages"    /* Name of file for saving messages */
  12. #define BOARD_OBJECT  xxx           /* what are we?                     */
  13. #define BOARD_ROOM    xxx           /* where are we?                    */
  14. #define MAX_MESSAGE_LENGTH 2048     /* that should be enough            */
  15.  
  16. char *msgs[MAX_MSGS];
  17. char *head[MAX_MSGS];
  18. int msg_num;
  19.  
  20. void board_write_msg(struct char_data *ch, char *arg);
  21. int board_display_msg(struct char_data *ch, char *arg);
  22. int board_remove_msg(struct char_data *ch, char *arg);
  23. void board_save_board();
  24. void board_load_board();
  25. void board_reset_board();
  26. void error_log();
  27. void board_fix_long_desc(int num, char *headers[MAX_MSGS]);
  28. int board_show_board(struct char_data *ch, char *arg);
  29.  
  30. /* I have used cmd number 180-182 as the cmd numbers here. */
  31. /* The commands would be, in order : NOTE <header>         */
  32. /* READ <message number>, REMOVE <message number>          */
  33. /* LOOK AT BOARD should give the long desc of the board    */
  34. /* and that should equal a list of message numbers and     */
  35. /* headers. This is done by calling a function that sets   */
  36. /* the long desc in the board object. This function is     */
  37. /* called when someone does a REMOVE or NOTE command.      */
  38. /* I have named the function board_fix_long_desc(). In the */
  39. /* board_write_msg() function there is a part that should  */
  40. /* be replaced with a call to some dreadful routine used   */
  41. /* by the STRING command to receive player input. It is    */
  42. /* reputed to lurk somewhere within the limits of an evil  */
  43. /* file named act.comm.c.....*/
  44.  
  45. /* saving the board after the addition of a new messg      */
  46. /* poses a slight problem, since the text isn't actually   */
  47. /* entered in board_write. What I'll do is to let board()  */
  48. /* save the first time a 'look' is issued in the room..    */
  49. /* ugh! that's ugly - gotta think of something better.     */
  50. /* -quinn                                                  */
  51.  
  52. /* And here is the board...correct me if I'm wrong. */
  53.  
  54.  
  55. int board(struct char_data *ch, int cmd, char *arg)
  56. {
  57.     static int has_loaded = 0;
  58.  
  59.     if (!ch->desc)
  60.         return(FALSE); /* By MS or all NPC's will be trapped at the board */
  61.  
  62.     /* note: I'll let display and remove return 0 if the arg was non-board- */
  63.     /* related. Thus, it'll be possible to read other things than the board */
  64.     /* while you're in the room. Conceiveably, you could do this for write, */
  65.     /* too, but I'm not in the mood for such hacking.                       */
  66.  
  67.     if (!has_loaded)
  68.     {
  69.         board_load_board();
  70.         has_loaded = 1;
  71.     }
  72.  
  73.     switch (cmd) {
  74.         case 15:  /* look */
  75.             return(board_show_board(ch, arg));
  76.         case 149: /* write */
  77.             board_write_msg(ch, arg);
  78.         return 1;
  79.         case 63: /* read */
  80.             return(board_display_msg(ch, arg));
  81.         case 66: /* remove */
  82.             return(board_remove_msg(ch, arg));
  83.         default:
  84.             return 0;
  85.     }
  86. }
  87.  
  88.  
  89. void board_write_msg(struct char_data *ch, char *arg) {
  90.     if (msg_num > MAX_MSGS - 1) {
  91.         send_to_char("The board is full already.\n\r", ch);
  92.         return;
  93.     }
  94.     /* skip blanks */
  95.     for(; isspace(*arg); arg++);
  96.     if (!*arg) {
  97.         send_to_char("We must have a headline!\n\r", ch);
  98.         return;
  99.     }
  100.     head[msg_num] = (char *)malloc(strlen(arg) + strlen(GET_NAME(ch)) + 4);
  101.     /* +4 is for a space and '()' around the character name. */
  102.     if (!head[msg_num]) {
  103.         error_log("Malloc for board header failed.\n\r");
  104.         send_to_char("The board is malfunctioning - sorry.\n\r", ch);
  105.         return;
  106.     }
  107.     strcpy(head[msg_num], arg);
  108.     /* Is this clumsy?  - four strcat() in a row I mean..*/
  109.     strcat(head[msg_num], " (");
  110.     strcat(head[msg_num], GET_NAME(ch));
  111.     strcat(head[msg_num], ")");
  112.     msgs[msg_num] = NULL;
  113.  
  114.     send_to_char("Write your message. Terminate with a @.\n\r\n\r", ch);
  115.     act("$n starts to write a message.", TRUE, ch, 0, 0, TO_ROOM);
  116.  
  117.     ch->desc->str = &msgs[msg_num];
  118.     ch->desc->max_str = MAX_MESSAGE_LENGTH;
  119.  
  120.     msg_num++;
  121. }
  122.  
  123.  
  124. int board_remove_msg(struct char_data *ch, char *arg) {
  125.     int ind, msg;
  126.     char buf[256], number[MAX_INPUT_LENGTH];
  127.  
  128.     if (GET_LEVEL(ch) < 10) {
  129.         send_to_char("Due to misuse of the REMOVE command, only 10th level\n\r", ch);
  130.         send_to_char("and above can remove messages.\n\r", ch);
  131.         return;
  132.     }
  133.  
  134.     one_argument(arg, number);
  135.  
  136.     if (!*number || !isdigit(*number))
  137.         return(0);
  138.     if (!(msg = atoi(number))) return(0);
  139.     if (!msg_num) {
  140.         send_to_char("The board is empty!\n\r", ch);
  141.         return(1);
  142.     }
  143.     if (msg < 1 || msg > msg_num) {
  144.         send_to_char("That message exists only in your imagination..\n\r",
  145.             ch);
  146.         return(1);
  147.     }
  148.  
  149.     ind = msg;
  150.     free(head[--ind]);
  151.     if (msgs[ind])
  152.         free(msgs[ind]);
  153.     for (; ind < msg_num -1; ind++) {
  154.         head[ind] = head[ind + 1];
  155.         msgs[ind] = msgs[ind + 1];
  156.     }
  157.     msg_num--;
  158.     send_to_char("Message removed.\n\r", ch);
  159.     sprintf(buf, "$n just removed message %d.", ind + 1);
  160.     act(buf, FALSE, ch, 0, 0, TO_ROOM);
  161.     board_save_board();
  162.  
  163.     return(1);
  164. }
  165.  
  166. void board_save_board() {
  167.     FILE *the_file;        
  168.     int ind, len;
  169.     if (!msg_num) {
  170.         error_log("No messages to save.\n\r");
  171.         return;
  172.     }
  173.     the_file = fopen(SAVE_FILE, "wb");
  174.     if (!the_file) {
  175.         error_log("Unable to open/create savefile..\n\r");
  176.         return;
  177.     }
  178.     fwrite(&msg_num, sizeof(int), 1, the_file);
  179.     for (ind = 0; ind < msg_num; ind++) {
  180.         len = strlen(head[ind]) + 1;
  181.         fwrite(&len, sizeof(int), 1, the_file);
  182.         fwrite(head[ind], sizeof(char), len, the_file);
  183.         len = strlen(msgs[ind]) + 1;
  184.         fwrite(&len, sizeof(int), 1, the_file);
  185.         fwrite(msgs[ind], sizeof(char), len, the_file);
  186.     }
  187.     fclose(the_file);
  188.     board_fix_long_desc(msg_num, head);
  189.     return;
  190. }
  191.  
  192. void board_load_board() {
  193.     FILE *the_file;
  194.     int ind, len = 0;
  195.  
  196.     board_reset_board();
  197.     the_file = fopen(SAVE_FILE, "rb");
  198.     if (!the_file) {
  199.         error_log("Can't open message file. Board will be empty.\n\r",0);
  200.         return;
  201.     }
  202.     fread(&msg_num, sizeof(int), 1, the_file);
  203.     
  204.     if (msg_num < 1 || msg_num > MAX_MSGS || feof(the_file)) {
  205.         error_log("Board-message file corrupt or nonexistent.\n\r");
  206.         fclose(the_file);
  207.         return;
  208.     }
  209.     for (ind = 0; ind < msg_num; ind++) {
  210.         fread(&len, sizeof(int), 1, the_file);
  211.         head[ind] = (char *)malloc(len + 1);
  212.         if (!head[ind]) {
  213.             error_log("Malloc for board header failed.\n\r");
  214.             board_reset_board();
  215.             fclose(the_file);
  216.             return;
  217.         }
  218.         fread(head[ind], sizeof(char), len, the_file);
  219.         fread(&len, sizeof(int), 1, the_file);
  220.         msgs[ind] = (char *)malloc(len + 1);
  221.         if (!msgs[ind]) {
  222.             error_log("Malloc for board msg failed..\n\r");
  223.             board_reset_board();
  224.             fclose(the_file);
  225.             return;
  226.         }
  227.         fread(msgs[ind], sizeof(char), len, the_file);
  228.     }
  229.     fclose(the_file);
  230.     board_fix_long_desc(msg_num, head);
  231.     return;
  232. }
  233.  
  234. void board_reset_board() {
  235.     int ind;
  236.     for (ind = 0; ind < MAX_MSGS; ind++) {
  237.         free(head[ind]);
  238.         free(msgs[ind]);
  239.     }
  240.     msg_num = 0;
  241.     board_fix_long_desc(0, 0);
  242.     return;
  243. }
  244.  
  245. void error_log(char *str) {    /* The original error-handling was MUCH */
  246.     fputs("Board : ", stderr);    /* more competent than the current but  */
  247.     fputs(str, stderr);    /* I got the advice to cut it out..;)   */
  248.     return;
  249. }
  250.  
  251. int board_display_msg(struct char_data *ch, char *arg) {
  252.     char buf[512], number[MAX_INPUT_LENGTH], buffer[MAX_STRING_LENGTH];
  253.     int msg;
  254.     one_argument(arg, number);
  255.     if (!*number || !isdigit(*number))
  256.         return(0);
  257.     if (!(msg = atoi(number))) return(0);
  258.     if (!msg_num) {
  259.         send_to_char("The board is empty!\n\r", ch);
  260.         return(1);
  261.     }
  262.     if (msg < 1 || msg > msg_num) {
  263.         send_to_char("That message exists only in your imagination..\n\r",
  264.             ch);
  265.         return(1);
  266.     }
  267.  
  268.     /*  sprintf(buf, "$n reads message %d titled : %s.",
  269.         msg, head[msg - 1]);
  270.     act(buf, TRUE, ch, 0, 0, TO_ROOM);    */
  271.  
  272.     /* Can PERFORM() handle this...?  no. Sorry*/
  273.     /* sprintf(ch, "Message %d    : %s\n\r%s", msg, head[msg - 1], msgs[msg - 1]); */
  274.     /* Bad news */
  275.  
  276.     sprintf(buffer, "Message %d : %s\n\r\n\r%s", msg, head[msg - 1],
  277.         msgs[msg - 1]);
  278.     page_string(ch->desc, buffer, 1);
  279.     return(1);
  280. }
  281.  
  282.  
  283.         
  284. void board_fix_long_desc(int num, char *headers[MAX_MSGS]) {
  285.  
  286.     struct obj_data *ob;
  287.  
  288.  
  289.  
  290.  
  291.     /**** Assign the right value to this pointer..how? ****/
  292.     /**** It should point to the bulletin board object ****/
  293.     /**** Then make ob.description point to a malloced ****/
  294.     /**** space containing itoa(msg_num) and all the   ****/
  295.     /**** headers. In the format :
  296.     This is a bulletin board. Usage : READ/REMOVE <message #>, NOTE <header>
  297.     There are 12 messages on the board.
  298.     1    : Re : Whatever and something else too.
  299.     2    : I don't agree with Rainbird.
  300.     3    : Me neither.
  301.     4     : Groo got hungry again - bug or sabotage?
  302.  
  303.     Well...something like that..;)                ****/
  304.     
  305.     /**** It is always to contain the first line and   ****/
  306.     /**** the second line will vary in how many notes  ****/
  307.     /**** the board has. Then the headers and message  ****/
  308.     /**** numbers will be listed.                ****/
  309.     return;
  310. }
  311.  
  312.  
  313.  
  314.  
  315. int board_show_board(struct char_data *ch, char *arg)
  316. {
  317.     int i;
  318.     char buf[MAX_STRING_LENGTH], tmp[MAX_INPUT_LENGTH];
  319.  
  320.     one_argument(arg, tmp);
  321.  
  322.     if (!*tmp || !isname(tmp, "board bulletin"))
  323.         return(0);
  324.  
  325.     act("$n studies the board.", TRUE, ch, 0, 0, TO_ROOM);
  326.  
  327.     strcpy(buf,
  328. "This is a bulletin board. Usage: READ/REMOVE <messg #>, WRITE <header>\n\r");
  329.     if (!msg_num)
  330.         strcat(buf, "The board is empty.\n\r");
  331.     else
  332.     {
  333.         sprintf(buf + strlen(buf), "There are %d messages on the board.\n\r",
  334.             msg_num);
  335.         for (i = 0; i < msg_num; i++)
  336.             sprintf(buf + strlen(buf), "%-2d : %s\n\r", i + 1, head[i]);
  337.      }
  338.     page_string(ch->desc, buf, 1);
  339.  
  340.     return(1);
  341. }
  342.