[CODE] World database

From: AFCervo (chrisf@PTDPROLOG.NET)
Date: 08/05/97


Not so long ago the head builder on the mud I am imp at happened to be
complaining about not being able to remember everyone's olc zones.  This
is a simple command that through a binary file can store player names and
zones...it does need some format changes to make it look cool :)  I'll
leave that to your imaginations :)  Anyway it is drop in code, but assumes
you can add the command ACMD(do_build) and the build command into
interpreter.c :)  And if build is used and you change it to another
command...don't forget to update all of the error messages :P  Anyway it
is cheesy, but might be useful *shrugs*  If you know better ways of
handling binary files that might use less memory and stuff please do email
me back :)  Suggestions, ideas, better ways to code reply to my email or
the group :)  Flames... see /dev/null for a response...


 ---------------
| Cervo R.O.T.   |
 ---------------

/* don't forget in interpreter.c to add

an ACMD(do_bmanage);

and the line in the interpreter array

{ "build", POS_DEAD, do_bmanage, LVL_IMPL, 0 },

It's a very GOOD idea to make it imp only as it is pretty slow and all...... */

ACMD(do_bmanage) {
   char *arg, *arg2, *arg3;
   
   void list_database(struct char_data *ch);
   void add_database(struct char_data *ch, char *name, char *num);
   void remove_database(struct char_data *ch, char *number);
   if (!*argument) {
      send_to_char("Usage build [list add remove]\n", ch );
      return;
   }
   arg = (char *) calloc(50, sizeof(char));
   argument = one_argument(argument, arg);
   if (!str_cmp(arg, "list"))
      list_database(ch);
   else if (!str_cmp(arg, "add")) {
      arg2 = (char *) calloc(50, sizeof(char));
      argument = one_argument(argument, arg2);
      if (!*arg2) {
         send_to_char("ERROR: No name!\nUsage build add name zonnum ie: build add smoke 250\n", ch);
         return;
      }
      arg3 = (char *) calloc(50, sizeof(char));
      argument = one_argument(argument, arg3);
      if (!*arg3) {
         send_to_char("ERROR: No zonenumber!\nUSAGE: build add smoke 250\n", ch );
         return;
      }
      add_database(ch, arg2, arg3);
   }
   else if (!str_cmp(arg, "remove")) {
      arg2 = (char *) calloc(50, sizeof(char));
      argument = one_argument(argument, arg2);
      if (!*arg2) {
         send_to_char("ERROR: No Zone Number to remove\nUSAGE: build remove number ie: build remove 120\r\n", ch );
         return;
      }
      remove_database(ch, arg2);
   }
   else {
      send_to_char("ERROR: Invalid mode specified try ""build list"" or ""build add"" or ""build remove""\r\n", ch );
      return;
   }
}

struct dbase_struct {
   char name[120];
   char number[50];
   int deleted;
};

#define dbasefil "etc/buildbase.cdb" /* Bet you're wondering what cdb is :P  Cervo Data Base of course :P */

void remove_database(struct char_data *ch, char *number) {
   FILE *fp, *newdb;
   struct dbase_struct db;
   int done = FALSE, pos = 0;
   
   if ( (fp = fopen(dbasefil, "r+")) == NULL ) {
      send_to_char("The database is not openable...seek help!!\r\n", ch );
      fprintf(stderr, "ERROR: check permissions to database file....\n");
      return;  /*  Not entirely true, if someone deletes it it isn't there to open...*/
   }
   for (;;) {
      fread(&db, sizeof(struct dbase_struct), 1, fp );
      pos++;
      if (feof(fp))
         break;
      if (!str_cmp(db.number, number)) {
         db.deleted = TRUE;
         done = TRUE;
         fseek(fp, sizeof(struct dbase_struct) * (pos -1) , SEEK_SET);;
         fwrite(&db, sizeof(struct dbase_struct), 1, fp);
         break;
      }
   }
   if (done == FALSE) {
      fclose(fp);
      send_to_char("The entry you wanted to delete cannot be located\r\n", ch );
      return;
   }
   if ( (newdb = fopen("etc/newdb.cdb", "w+")) == NULL ) {
      send_to_char("The new file cannot be created\r\n", ch);
      fprintf(stderr, "ERROR: new database will not be created check permissions\n");
      return;
   }
   fseek(fp, 0, SEEK_SET);
   for(;;) {
     fread(&db, sizeof(struct dbase_struct), 1, fp);
     if (feof(fp))
        break;
     if (db.deleted == FALSE)
        fwrite(&db, sizeof(struct dbase_struct), 1, newdb);
   }
   fclose(fp);
   fclose(newdb);
   remove(dbasefil);  /* not to sure on the portability of these two commands */
   rename("etc/newdb.cdb", dbasefil);
   send_to_char("The task was completed successfully\r\n", ch );
}
void add_database(struct char_data *ch, char *name, char *number) {
   FILE *fp;
   struct dbase_struct db;
   
   if ((fp = fopen(dbasefil, "a")) == NULL) {
      fprintf(stderr, "ERROR: Database cannot be opened db_add\n");
      send_to_char("ERROR: The database cannot be opened\r\n", ch );
      return;
   }
   db.deleted = FALSE;
   strcpy(db.name, name);
   strcpy(db.number, number);
   fwrite(&db, sizeof(struct dbase_struct), 1, fp);
   fclose(fp);
   send_to_char("The database was updated successfully\r\n", ch );
   return;
}
void list_database(struct char_data *ch) {
   FILE *fp;
   struct dbase_struct db;
   if ((fp = fopen(dbasefil, "r")) == NULL) {
      send_to_char("The database is empty...\r\n", ch);
      return;
   }
   send_to_char(" Name      Zone\r\n", ch );
   for (;;) {
      fread(&db, sizeof(struct dbase_struct), 1, fp);
      if (feof(fp))
         break;
      sprintf(buf, "%s --- %s\r\n", db.name, db.number);
      send_to_char(buf, ch );   
   }
   fclose(fp);
}

#undef dbasefil

/* I imagine that this code can be made shorter + faster, but it works for me.  After being pestered by
the head builder to build him something to keep track of all olc zones this is
the result.  He wanted it command lined and not in menu form, so it is all set.  Also I didn't want it
loaded in memory, and making the mud's memory consumption any bigger, so I made it work right out of a
binary file.

  I hope you find this code useful, feel free to modify it, change it, and distribute it at will.  It would
be interesting to see some of the modification people make :) *hint hint*  Anyway just maybe mention me
in the credits file, or if you write a help file on this :)  But nothing big and fancy.......



        Cervo ..............one of the friendly imps at Realms Of Terror...
        
        If in any way you need to contact me please email chrisf@ptdprolog.net */


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/08/00 PST