/* * db_xdr.c */ #include "copyright.h" #include "config.h" #include "mudconf.h" #include "config.h" #include "externs.h" #include "db.h" #include "vattr.h" #include "attrs.h" #include "alloc.h" #include "powers.h" #include "mmdb.h" #include "debug.h" /* adds for commac */ #include "macro.h" #include "commac.h" #include "comsys.h" #include "myfifo.h" #include "create.h" extern OBJ *db; static void do_save_com_xdr(chmsg * d,struct mmdb_t *mmdb) { mmdb_write_uint32(mmdb, (int) d->time); mmdb_write_opaque(mmdb, d->msg, strlen(d->msg)+1); } void myfifo_trav_r_xdr(myfifo ** foo, struct mmdb_t *mmdb, void (*func) ()) { myfifo_e *tmp; for (tmp = (*foo)->last; tmp !=NULL; tmp = tmp->prev) func(tmp->data, mmdb); } void mmdb_write_object(struct mmdb_t *mmdb, dbref object) { ATRLIST *atrlist; mmdb_write_uint(mmdb, object); mmdb_write_opaque(mmdb, Name(object), strlen(Name(object)) + 1); mmdb_write_uint(mmdb, Location(object)); mmdb_write_uint(mmdb, Zone(object)); mmdb_write_uint(mmdb, Contents(object)); mmdb_write_uint(mmdb, Exits(object)); mmdb_write_uint(mmdb, Link(object)); mmdb_write_uint(mmdb, Next(object)); mmdb_write_uint(mmdb, Owner(object)); mmdb_write_uint(mmdb, Parent(object)); mmdb_write_uint(mmdb, Pennies(object)); mmdb_write_uint(mmdb, Flags(object)); mmdb_write_uint(mmdb, Flags2(object)); mmdb_write_uint(mmdb, Flags3(object)); mmdb_write_uint(mmdb, Powers(object)); mmdb_write_uint(mmdb, Powers2(object)); mmdb_write_uint(mmdb, db[object].at_count); atrlist = db[object].ahead; for(int i = 0; i < db[object].at_count; i++) { mmdb_write_opaque(mmdb, atrlist[i].data, atrlist[i].size); mmdb_write_uint(mmdb, atrlist[i].number); } } #define DB_MAGIC 0x4841475A #define DB_VERSION 3 #define COMMAC_MAGIC 0x434f4d5a /* COMZ */ #define COMMAC_VERSION 1 struct string_dict_entry { char *key; char *data; }; static int mmdb_write_vattr(void *key, void *data, int depth, void *arg) { struct mmdb_t *mmdb = (struct mmdb_t *) arg; struct string_dict_entry *ent = data; VATTR *vp = (VATTR *) ent->data; mmdb_write_opaque(mmdb, vp->name, strlen(vp->name) + 1); mmdb_write_uint(mmdb, vp->number); mmdb_write_uint(mmdb, vp->flags); return 1; } void mmdb_db_write(char *filename) { struct mmdb_t *mmdb; uint32_t xid[5], i; struct timeval tv; rbtree vattr_htab = mudstate.vattr_name_htab.tree; /* commac specific */ int j, k, np, player_users; struct commac *c; struct channel *ch; struct comuser *user; struct macros *m; for(i = 0; i < 5; i++) { xid[i] = rand(); } gettimeofday(&tv, NULL); mmdb = mmdb_open_write(filename); mmdb_write_uint(mmdb, DB_MAGIC); mmdb_write_uint(mmdb, DB_VERSION); mmdb_write_uint(mmdb, tv.tv_sec); mmdb_write_uint(mmdb, tv.tv_usec); mmdb_write_uint(mmdb, mudstate.db_revision++); for(i = 0; i < 5; i++) { mmdb_write_uint(mmdb, xid[i]); } mmdb_write_uint(mmdb, rb_size(vattr_htab)); rb_walk(vattr_htab, WALK_INORDER, mmdb_write_vattr, mmdb); mmdb_write_uint(mmdb, mudstate.db_top); DO_WHOLE_DB(i) { mmdb_write_object(mmdb, i); } /* START COMMAC */ mmdb_write_uint32(mmdb, COMMAC_MAGIC); mmdb_write_uint32(mmdb, COMMAC_VERSION); purge_commac(); np = 0; for(i = 0; i < NUM_COMMAC; i++) { c = commac_table[i]; while (c) { np++; c = c->next; } } mmdb_write_uint32(mmdb, np); for(i = 0; i < NUM_COMMAC; i++) { c = commac_table[i]; while (c) { mmdb_write_uint32(mmdb, c->who); mmdb_write_uint32(mmdb, c->numchannels); mmdb_write_uint32(mmdb, c->macros[0]); mmdb_write_uint32(mmdb, c->macros[1]); mmdb_write_uint32(mmdb, c->macros[2]); mmdb_write_uint32(mmdb, c->macros[3]); mmdb_write_uint32(mmdb, c->macros[4]); mmdb_write_uint32(mmdb, c->curmac); if(c->numchannels > 0) { for(j = 0; j <c->numchannels; j++) { mmdb_write_opaque(mmdb, c->alias +j *6, strlen(c->alias +j * 6)+1); mmdb_write_opaque(mmdb, c->channels[j], strlen(c->channels[j])+1); } } c = c->next; } } /* END COMMAC */ /* START COMSYS */ mmdb_write_uint32(mmdb, num_channels); for(ch = (struct channel *) hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *) hash_nextentry(&mudstate.channel_htab)) { mmdb_write_opaque(mmdb, ch->name, strlen(ch->name)+1); mmdb_write_uint32(mmdb, ch->type); mmdb_write_uint32(mmdb, ch->charge); mmdb_write_uint32(mmdb, ch->charge_who); mmdb_write_uint32(mmdb, ch->amount_col); mmdb_write_uint32(mmdb, ch->num_messages); mmdb_write_uint32(mmdb, ch->chan_obj); k = myfifo_length(&ch->last_messages); mmdb_write_uint32(mmdb, k); if (k) myfifo_trav_r_xdr(&ch->last_messages,mmdb,do_save_com_xdr); player_users = 0; for(j = 0; j < ch->num_users; j++) if(isPlayer(ch->users[j]->who) || isRobot(ch->users[j]->who)) player_users++; mmdb_write_uint32(mmdb,player_users); for(j = 0; j < ch->num_users; j++) { user = ch->users[j]; if(!isPlayer(user->who) && !isRobot(user->who)) continue; mmdb_write_uint32(mmdb, user->who); mmdb_write_uint32(mmdb, user->on); if(strlen(user->title)) { mmdb_write_uint32(mmdb,1); mmdb_write_opaque(mmdb,user->title,strlen(user->title)+1); } else mmdb_write_uint32(mmdb,0); } } /* END COMSYS */ /* START MACRO */ mmdb_write_uint32(mmdb, nummacros); for(i = 0; i <nummacros; i++) { m = macros[i]; mmdb_write_uint32(mmdb, m->player); mmdb_write_uint32(mmdb, m->nummacros); mmdb_write_uint32(mmdb, (int) m->status); mmdb_write_opaque(mmdb, m->desc, strlen(m->desc)+1); for(j = 0; j < m->nummacros; j++) { mmdb_write_opaque(mmdb, m->alias + j * 5, strlen(m->alias +j * 5)+1); mmdb_write_opaque(mmdb, m->string[j], strlen(m->string[j])+1); } } /* END MACRO */ mmdb_close(mmdb); } int mmdb_db_read(char *filename) { struct mmdb_t *mmdb; uint32_t xid[5], i; uint32_t magic, version, revision; uint32_t object; uint32_t vattr_count, object_count; uint32_t vattr_len, vattr_number, vattr_flags; struct timeval tv; rbtree vattr_htab = mudstate.vattr_name_htab.tree; char buffer[4096]; int np, j, k, len; struct commac *c; struct channel *ch; struct comuser *user; struct macros *m; mmdb = mmdb_open_read(filename); magic = mmdb_read_uint32(mmdb); dassert(magic == DB_MAGIC); version = mmdb_read_uint32(mmdb); dassert(version == DB_VERSION); tv.tv_sec = mmdb_read_uint32(mmdb); tv.tv_usec = mmdb_read_uint32(mmdb); mudstate.db_revision = revision = mmdb_read_uint32(mmdb); dprintk("Loading database revision %d, created at %s.", revision, asctime(localtime(&tv.tv_sec))); for(i = 0; i < 5; i++) { xid[i] = mmdb_read_uint32(mmdb); } dprintk("database XID: %08x%08x%08x%08x%08x", xid[0], xid[1], xid[2], xid[3], xid[4]); db_free(); vattr_count = mmdb_read_uint32(mmdb); anum_extend(vattr_count); dprintk("reading in %d vattrs", vattr_count); for(int i = 0; i < vattr_count; i++) { vattr_len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, vattr_len); vattr_number = mmdb_read_uint32(mmdb); vattr_flags = mmdb_read_uint32(mmdb); vattr_define(buffer, vattr_number, vattr_flags); } dprintk("... done."); object_count = mmdb_read_uint32(mmdb); db_grow(object_count); dprintk("reading in %d objects", object_count); for(int i = 0; i < object_count; i++) { object = mmdb_read_uint32(mmdb); vattr_len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, vattr_len); s_Name(object, buffer); s_Location(object, mmdb_read_uint32(mmdb)); s_Zone(object, mmdb_read_uint32(mmdb)); s_Contents(object, mmdb_read_uint32(mmdb)); s_Exits(object, mmdb_read_uint32(mmdb)); s_Link(object, mmdb_read_uint32(mmdb)); s_Next(object, mmdb_read_uint32(mmdb)); s_Owner(object, mmdb_read_uint32(mmdb)); s_Parent(object, mmdb_read_uint32(mmdb)); s_Pennies(object, mmdb_read_uint32(mmdb)); s_Flags(object, mmdb_read_uint32(mmdb)); s_Flags2(object, mmdb_read_uint32(mmdb)); s_Flags3(object, mmdb_read_uint32(mmdb)); s_Powers(object, mmdb_read_uint32(mmdb)); s_Powers2(object, mmdb_read_uint32(mmdb)); vattr_count = mmdb_read_uint32(mmdb); for(int j = 0; j < vattr_count; j++) { vattr_len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, vattr_len); vattr_number = mmdb_read_uint32(mmdb); atr_add_raw(object, vattr_number, buffer); } } load_player_names(); magic = mmdb_read_uint32(mmdb); dassert(magic == COMMAC_MAGIC); version = mmdb_read_uint32(mmdb); dassert(version == COMMAC_VERSION); /* START COMMAC SECTION */ np = mmdb_read_uint32(mmdb); for(i = 0; i < np; i++) { c = create_new_commac(); c->who = mmdb_read_uint32(mmdb); c->numchannels = mmdb_read_uint32(mmdb); c->macros[0] = mmdb_read_uint32(mmdb); c->macros[1] = mmdb_read_uint32(mmdb); c->macros[2] = mmdb_read_uint32(mmdb); c->macros[3] = mmdb_read_uint32(mmdb); c->macros[4] = mmdb_read_uint32(mmdb); c->curmac = mmdb_read_uint32(mmdb); c->maxchannels = c->numchannels; if(c->maxchannels > 0) { c->alias = (char *) malloc(c->maxchannels * 6); c->channels = (char **) malloc(sizeof(char *) * c->maxchannels); for(j = 0; j < c->numchannels; j++) { len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); StringCopy(c->alias + j * 6,buffer); len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); c->channels[j] = (char *) malloc(strlen(buffer) + 1); StringCopy(c->channels[j],buffer); } sort_com_aliases(c); } else { c->alias = NULL; c->channels = NULL; } if((Typeof(c->who) == TYPE_PLAYER) || (!God(Owner(c->who))) || ((!Going(c->who)))) add_commac(c); purge_commac(); } /* END COMMAC SECTION */ /* START COMSYS SECTION */ num_channels = mmdb_read_uint32(mmdb); for( i = 0; i < num_channels; i++) { ch = (struct channel *) malloc(sizeof(struct channel)); len = mmdb_read_uint32(mmdb); mmdb_read(mmdb,buffer,len); strncpy(ch->name, buffer, len); ch->on_users = NULL; hashadd(ch->name, (int *) ch, &mudstate.channel_htab); ch->type = mmdb_read_uint32(mmdb); ch->charge = mmdb_read_uint32(mmdb); ch->charge_who = mmdb_read_uint32(mmdb); ch->amount_col = mmdb_read_uint32(mmdb); ch->num_messages = mmdb_read_uint32(mmdb); ch->chan_obj = mmdb_read_uint32(mmdb); k = mmdb_read_uint32(mmdb); ch->last_messages = NULL; if (k > 0) { for(j = 0; j < k; j++) { chmsg *c; Create(c,chmsg,1); c->time = mmdb_read_uint32(mmdb); len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); c->msg = strdup(buffer); myfifo_push(&ch->last_messages, c); } } ch->num_users = mmdb_read_uint32(mmdb); ch->max_users = ch->num_users; if(ch->num_users > 0) { ch->users = (struct comuser **) calloc(ch->max_users, sizeof(struct comuser *)); for(j =0; j < ch->num_users; j++) { user = (struct comuser *) malloc(sizeof(struct comuser)); ch->users[j] = user; user->who = mmdb_read_uint32(mmdb); user->on = mmdb_read_uint32(mmdb); /* title stuff here */ k = mmdb_read_uint32(mmdb); if (k) { len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); user->title = strdup(buffer); } else user->title = ""; if(!(isPlayer(user->who)) && !(Going(user->who) && (God(Owner(user->who))))) { do_joinchannel(user->who, ch); user->on_next = ch->on_users; ch->on_users = user; } else { user->on_next = ch->on_users; ch->on_users = user; } } sort_users(ch); } else ch->users = NULL; } /* END COMSYS SECTION */ /* BEGIN MACRO SECTION */ nummacros = mmdb_read_uint32(mmdb); maxmacros = nummacros; if(maxmacros > 0) macros = (struct macros **) malloc(sizeof(struct macros *) * nummacros); else macros = NULL; for(i = 0; i < nummacros; i++) { macros[i] = (struct macros *) malloc(sizeof(struct macros)); m = macros[i]; m->player = mmdb_read_uint32(mmdb); m->nummacros = mmdb_read_uint32(mmdb); m->status = mmdb_read_uint32(mmdb); len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); m->desc = strdup(buffer); m->maxmacros = m->nummacros; if(m->nummacros > 0) { m->alias = (char *) malloc(5 * m->maxmacros); m->string = (char **) malloc(sizeof(char *) * m->nummacros); for(j = 0; j < m->nummacros; j++) { len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); strcpy(m->alias + j * 5, buffer); len = mmdb_read_uint32(mmdb); mmdb_read(mmdb, buffer, len); m->string[j] = (char *) malloc(len + 1); strcpy(m->string[j], buffer); } do_sort_macro_set(m); } else { m->alias = NULL; m->string = NULL; } } while (1) { for(i = 0; i < nummacros; i++) if(!isPlayer(macros[i]->player)) break; if( i >= nummacros) break; clear_macro_set(i); } return object_count; }