00001
00002
00003
00004 #include "copyright.h"
00005 #include "config.h"
00006
00007 #include "mudconf.h"
00008 #include "config.h"
00009 #include "externs.h"
00010 #include "db.h"
00011 #include "vattr.h"
00012 #include "attrs.h"
00013 #include "alloc.h"
00014 #include "powers.h"
00015 #include "mmdb.h"
00016 #include "debug.h"
00017
00018
00019 #include "macro.h"
00020 #include "commac.h"
00021 #include "comsys.h"
00022 #include "myfifo.h"
00023 #include "create.h"
00024
00025 extern OBJ *db;
00026
00027 static void do_save_com_xdr(chmsg * d,struct mmdb_t *mmdb)
00028 {
00029 mmdb_write_uint32(mmdb, (int) d->time);
00030
00031 mmdb_write_opaque(mmdb, d->msg, strlen(d->msg)+1);
00032
00033 }
00034
00035 void myfifo_trav_r_xdr(myfifo ** foo, struct mmdb_t *mmdb, void (*func) ())
00036 {
00037 myfifo_e *tmp;
00038
00039
00040 for (tmp = (*foo)->last; tmp !=NULL; tmp = tmp->prev)
00041 func(tmp->data, mmdb);
00042 }
00043
00044 void mmdb_write_object(struct mmdb_t *mmdb, dbref object)
00045 {
00046 ATRLIST *atrlist;
00047
00048 mmdb_write_uint(mmdb, object);
00049 mmdb_write_opaque(mmdb, Name(object), strlen(Name(object)) + 1);
00050 mmdb_write_uint(mmdb, Location(object));
00051 mmdb_write_uint(mmdb, Zone(object));
00052 mmdb_write_uint(mmdb, Contents(object));
00053 mmdb_write_uint(mmdb, Exits(object));
00054 mmdb_write_uint(mmdb, Link(object));
00055 mmdb_write_uint(mmdb, Next(object));
00056 mmdb_write_uint(mmdb, Owner(object));
00057 mmdb_write_uint(mmdb, Parent(object));
00058 mmdb_write_uint(mmdb, Pennies(object));
00059 mmdb_write_uint(mmdb, Flags(object));
00060 mmdb_write_uint(mmdb, Flags2(object));
00061 mmdb_write_uint(mmdb, Flags3(object));
00062 mmdb_write_uint(mmdb, Powers(object));
00063 mmdb_write_uint(mmdb, Powers2(object));
00064 mmdb_write_uint(mmdb, db[object].at_count);
00065 atrlist = db[object].ahead;
00066 for(int i = 0; i < db[object].at_count; i++) {
00067 mmdb_write_opaque(mmdb, atrlist[i].data, atrlist[i].size);
00068 mmdb_write_uint(mmdb, atrlist[i].number);
00069 }
00070 }
00071
00072 #define DB_MAGIC 0x4841475A
00073 #define DB_VERSION 3
00074 #define COMMAC_MAGIC 0x434f4d5a
00075 #define COMMAC_VERSION 1
00076
00077 struct string_dict_entry {
00078 char *key;
00079 char *data;
00080 };
00081
00082 static int mmdb_write_vattr(void *key, void *data, int depth, void *arg)
00083 {
00084 struct mmdb_t *mmdb = (struct mmdb_t *) arg;
00085 struct string_dict_entry *ent = data;
00086 VATTR *vp = (VATTR *) ent->data;
00087
00088 mmdb_write_opaque(mmdb, vp->name, strlen(vp->name) + 1);
00089 mmdb_write_uint(mmdb, vp->number);
00090 mmdb_write_uint(mmdb, vp->flags);
00091 return 1;
00092 }
00093
00094 void mmdb_db_write(char *filename)
00095 {
00096 struct mmdb_t *mmdb;
00097 uint32_t xid[5], i;
00098 struct timeval tv;
00099 rbtree vattr_htab = mudstate.vattr_name_htab.tree;
00100
00101 int j, k, np, player_users;
00102 struct commac *c;
00103 struct channel *ch;
00104 struct comuser *user;
00105 struct macros *m;
00106
00107 for(i = 0; i < 5; i++) {
00108 xid[i] = rand();
00109 }
00110
00111 gettimeofday(&tv, NULL);
00112
00113 mmdb = mmdb_open_write(filename);
00114 mmdb_write_uint(mmdb, DB_MAGIC);
00115 mmdb_write_uint(mmdb, DB_VERSION);
00116 mmdb_write_uint(mmdb, tv.tv_sec);
00117 mmdb_write_uint(mmdb, tv.tv_usec);
00118 mmdb_write_uint(mmdb, mudstate.db_revision++);
00119 for(i = 0; i < 5; i++) {
00120 mmdb_write_uint(mmdb, xid[i]);
00121 }
00122 mmdb_write_uint(mmdb, rb_size(vattr_htab));
00123 rb_walk(vattr_htab, WALK_INORDER, mmdb_write_vattr, mmdb);
00124 mmdb_write_uint(mmdb, mudstate.db_top);
00125 DO_WHOLE_DB(i) {
00126 mmdb_write_object(mmdb, i);
00127 }
00128
00129
00130 mmdb_write_uint32(mmdb, COMMAC_MAGIC);
00131 mmdb_write_uint32(mmdb, COMMAC_VERSION);
00132
00133 purge_commac();
00134 np = 0;
00135
00136 for(i = 0; i < NUM_COMMAC; i++) {
00137 c = commac_table[i];
00138 while (c) {
00139 np++;
00140 c = c->next;
00141 }
00142 }
00143
00144 mmdb_write_uint32(mmdb, np);
00145
00146 for(i = 0; i < NUM_COMMAC; i++) {
00147 c = commac_table[i];
00148 while (c) {
00149 mmdb_write_uint32(mmdb, c->who);
00150 mmdb_write_uint32(mmdb, c->numchannels);
00151 mmdb_write_uint32(mmdb, c->macros[0]);
00152 mmdb_write_uint32(mmdb, c->macros[1]);
00153 mmdb_write_uint32(mmdb, c->macros[2]);
00154 mmdb_write_uint32(mmdb, c->macros[3]);
00155 mmdb_write_uint32(mmdb, c->macros[4]);
00156 mmdb_write_uint32(mmdb, c->curmac);
00157 if(c->numchannels > 0) {
00158 for(j = 0; j <c->numchannels; j++) {
00159 mmdb_write_opaque(mmdb, c->alias +j *6, strlen(c->alias +j * 6)+1);
00160 mmdb_write_opaque(mmdb, c->channels[j], strlen(c->channels[j])+1);
00161 }
00162 }
00163 c = c->next;
00164 }
00165 }
00166
00167
00168 mmdb_write_uint32(mmdb, num_channels);
00169 for(ch = (struct channel *) hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *) hash_nextentry(&mudstate.channel_htab)) {
00170 mmdb_write_opaque(mmdb, ch->name, strlen(ch->name)+1);
00171 mmdb_write_uint32(mmdb, ch->type);
00172 mmdb_write_uint32(mmdb, ch->charge);
00173 mmdb_write_uint32(mmdb, ch->charge_who);
00174 mmdb_write_uint32(mmdb, ch->amount_col);
00175 mmdb_write_uint32(mmdb, ch->num_messages);
00176 mmdb_write_uint32(mmdb, ch->chan_obj);
00177 k = myfifo_length(&ch->last_messages);
00178 mmdb_write_uint32(mmdb, k);
00179
00180 if (k)
00181 myfifo_trav_r_xdr(&ch->last_messages,mmdb,do_save_com_xdr);
00182
00183 player_users = 0;
00184 for(j = 0; j < ch->num_users; j++)
00185 if(isPlayer(ch->users[j]->who) || isRobot(ch->users[j]->who))
00186 player_users++;
00187
00188 mmdb_write_uint32(mmdb,player_users);
00189 for(j = 0; j < ch->num_users; j++) {
00190 user = ch->users[j];
00191 if(!isPlayer(user->who) && !isRobot(user->who))
00192 continue;
00193 mmdb_write_uint32(mmdb, user->who);
00194 mmdb_write_uint32(mmdb, user->on);
00195 if(strlen(user->title)) {
00196 mmdb_write_uint32(mmdb,1);
00197 mmdb_write_opaque(mmdb,user->title,strlen(user->title)+1);
00198 } else
00199 mmdb_write_uint32(mmdb,0);
00200 }
00201 }
00202
00203
00204
00205 mmdb_write_uint32(mmdb, nummacros);
00206
00207 for(i = 0; i <nummacros; i++) {
00208 m = macros[i];
00209 mmdb_write_uint32(mmdb, m->player);
00210 mmdb_write_uint32(mmdb, m->nummacros);
00211 mmdb_write_uint32(mmdb, (int) m->status);
00212 mmdb_write_opaque(mmdb, m->desc, strlen(m->desc)+1);
00213 for(j = 0; j < m->nummacros; j++) {
00214 mmdb_write_opaque(mmdb, m->alias + j * 5, strlen(m->alias +j * 5)+1);
00215 mmdb_write_opaque(mmdb, m->string[j], strlen(m->string[j])+1);
00216 }
00217 }
00218
00219 mmdb_close(mmdb);
00220 }
00221
00222 int mmdb_db_read(char *filename)
00223 {
00224 struct mmdb_t *mmdb;
00225 uint32_t xid[5], i;
00226 uint32_t magic, version, revision;
00227 uint32_t object;
00228 uint32_t vattr_count, object_count;
00229 uint32_t vattr_len, vattr_number, vattr_flags;
00230 struct timeval tv;
00231 rbtree vattr_htab = mudstate.vattr_name_htab.tree;
00232 char buffer[4096];
00233 int np, j, k, len;
00234 struct commac *c;
00235 struct channel *ch;
00236 struct comuser *user;
00237 struct macros *m;
00238
00239 mmdb = mmdb_open_read(filename);
00240 magic = mmdb_read_uint32(mmdb);
00241 dassert(magic == DB_MAGIC);
00242 version = mmdb_read_uint32(mmdb);
00243 dassert(version == DB_VERSION);
00244
00245 tv.tv_sec = mmdb_read_uint32(mmdb);
00246 tv.tv_usec = mmdb_read_uint32(mmdb);
00247
00248 mudstate.db_revision = revision = mmdb_read_uint32(mmdb);
00249
00250 dprintk("Loading database revision %d, created at %s.", revision,
00251 asctime(localtime(&tv.tv_sec)));
00252 for(i = 0; i < 5; i++) {
00253 xid[i] = mmdb_read_uint32(mmdb);
00254 }
00255
00256 dprintk("database XID: %08x%08x%08x%08x%08x", xid[0],
00257 xid[1], xid[2], xid[3], xid[4]);
00258 db_free();
00259 vattr_count = mmdb_read_uint32(mmdb);
00260 anum_extend(vattr_count);
00261 dprintk("reading in %d vattrs", vattr_count);
00262 for(int i = 0; i < vattr_count; i++) {
00263 vattr_len = mmdb_read_uint32(mmdb);
00264 mmdb_read(mmdb, buffer, vattr_len);
00265 vattr_number = mmdb_read_uint32(mmdb);
00266 vattr_flags = mmdb_read_uint32(mmdb);
00267 vattr_define(buffer, vattr_number, vattr_flags);
00268 }
00269 dprintk("... done.");
00270
00271 object_count = mmdb_read_uint32(mmdb);
00272 db_grow(object_count);
00273 dprintk("reading in %d objects", object_count);
00274 for(int i = 0; i < object_count; i++) {
00275 object = mmdb_read_uint32(mmdb);
00276 vattr_len = mmdb_read_uint32(mmdb);
00277 mmdb_read(mmdb, buffer, vattr_len);
00278 s_Name(object, buffer);
00279 s_Location(object, mmdb_read_uint32(mmdb));
00280 s_Zone(object, mmdb_read_uint32(mmdb));
00281 s_Contents(object, mmdb_read_uint32(mmdb));
00282 s_Exits(object, mmdb_read_uint32(mmdb));
00283 s_Link(object, mmdb_read_uint32(mmdb));
00284 s_Next(object, mmdb_read_uint32(mmdb));
00285 s_Owner(object, mmdb_read_uint32(mmdb));
00286 s_Parent(object, mmdb_read_uint32(mmdb));
00287 s_Pennies(object, mmdb_read_uint32(mmdb));
00288 s_Flags(object, mmdb_read_uint32(mmdb));
00289 s_Flags2(object, mmdb_read_uint32(mmdb));
00290 s_Flags3(object, mmdb_read_uint32(mmdb));
00291 s_Powers(object, mmdb_read_uint32(mmdb));
00292 s_Powers2(object, mmdb_read_uint32(mmdb));
00293 vattr_count = mmdb_read_uint32(mmdb);
00294 for(int j = 0; j < vattr_count; j++) {
00295 vattr_len = mmdb_read_uint32(mmdb);
00296 mmdb_read(mmdb, buffer, vattr_len);
00297 vattr_number = mmdb_read_uint32(mmdb);
00298 atr_add_raw(object, vattr_number, buffer);
00299 }
00300 }
00301 load_player_names();
00302
00303 magic = mmdb_read_uint32(mmdb);
00304 dassert(magic == COMMAC_MAGIC);
00305 version = mmdb_read_uint32(mmdb);
00306 dassert(version == COMMAC_VERSION);
00307
00308 np = mmdb_read_uint32(mmdb);
00309 for(i = 0; i < np; i++) {
00310 c = create_new_commac();
00311 c->who = mmdb_read_uint32(mmdb);
00312 c->numchannels = mmdb_read_uint32(mmdb);
00313 c->macros[0] = mmdb_read_uint32(mmdb);
00314 c->macros[1] = mmdb_read_uint32(mmdb);
00315 c->macros[2] = mmdb_read_uint32(mmdb);
00316 c->macros[3] = mmdb_read_uint32(mmdb);
00317 c->macros[4] = mmdb_read_uint32(mmdb);
00318 c->curmac = mmdb_read_uint32(mmdb);
00319 c->maxchannels = c->numchannels;
00320 if(c->maxchannels > 0) {
00321 c->alias = (char *) malloc(c->maxchannels * 6);
00322 c->channels = (char **) malloc(sizeof(char *) * c->maxchannels);
00323
00324 for(j = 0; j < c->numchannels; j++) {
00325 len = mmdb_read_uint32(mmdb);
00326 mmdb_read(mmdb, buffer, len);
00327
00328 StringCopy(c->alias + j * 6,buffer);
00329
00330 len = mmdb_read_uint32(mmdb);
00331 mmdb_read(mmdb, buffer, len);
00332
00333 c->channels[j] = (char *) malloc(strlen(buffer) + 1);
00334 StringCopy(c->channels[j],buffer);
00335
00336 }
00337 sort_com_aliases(c);
00338 } else {
00339 c->alias = NULL;
00340 c->channels = NULL;
00341 }
00342 if((Typeof(c->who) == TYPE_PLAYER) || (!God(Owner(c->who))) || ((!Going(c->who))))
00343 add_commac(c);
00344 purge_commac();
00345 }
00346
00347
00348
00349 num_channels = mmdb_read_uint32(mmdb);
00350
00351 for( i = 0; i < num_channels; i++) {
00352 ch = (struct channel *) malloc(sizeof(struct channel));
00353
00354
00355 len = mmdb_read_uint32(mmdb);
00356 mmdb_read(mmdb,buffer,len);
00357
00358 strncpy(ch->name, buffer, len);
00359 ch->on_users = NULL;
00360
00361 hashadd(ch->name, (int *) ch, &mudstate.channel_htab);
00362 ch->type = mmdb_read_uint32(mmdb);
00363 ch->charge = mmdb_read_uint32(mmdb);
00364 ch->charge_who = mmdb_read_uint32(mmdb);
00365 ch->amount_col = mmdb_read_uint32(mmdb);
00366 ch->num_messages = mmdb_read_uint32(mmdb);
00367 ch->chan_obj = mmdb_read_uint32(mmdb);
00368 k = mmdb_read_uint32(mmdb);
00369 ch->last_messages = NULL;
00370
00371 if (k > 0) {
00372 for(j = 0; j < k; j++) {
00373 chmsg *c;
00374 Create(c,chmsg,1);
00375 c->time = mmdb_read_uint32(mmdb);
00376 len = mmdb_read_uint32(mmdb);
00377 mmdb_read(mmdb, buffer, len);
00378 c->msg = strdup(buffer);
00379 myfifo_push(&ch->last_messages, c);
00380 }
00381
00382 }
00383 ch->num_users = mmdb_read_uint32(mmdb);
00384 ch->max_users = ch->num_users;
00385
00386 if(ch->num_users > 0) {
00387 ch->users = (struct comuser **) calloc(ch->max_users, sizeof(struct comuser *));
00388
00389 for(j =0; j < ch->num_users; j++) {
00390 user = (struct comuser *) malloc(sizeof(struct comuser));
00391
00392 ch->users[j] = user;
00393
00394 user->who = mmdb_read_uint32(mmdb);
00395 user->on = mmdb_read_uint32(mmdb);
00396
00397
00398 k = mmdb_read_uint32(mmdb);
00399 if (k) {
00400 len = mmdb_read_uint32(mmdb);
00401 mmdb_read(mmdb, buffer, len);
00402 user->title = strdup(buffer);
00403 }
00404 else
00405 user->title = "";
00406 if(!(isPlayer(user->who)) && !(Going(user->who) && (God(Owner(user->who))))) {
00407 do_joinchannel(user->who, ch);
00408 user->on_next = ch->on_users;
00409 ch->on_users = user;
00410 } else {
00411 user->on_next = ch->on_users;
00412 ch->on_users = user;
00413 }
00414 }
00415 sort_users(ch);
00416 } else
00417 ch->users = NULL;
00418 }
00419
00420
00421
00422
00423
00424 nummacros = mmdb_read_uint32(mmdb);
00425 maxmacros = nummacros;
00426
00427 if(maxmacros > 0)
00428 macros = (struct macros **) malloc(sizeof(struct macros *) * nummacros);
00429 else
00430 macros = NULL;
00431
00432 for(i = 0; i < nummacros; i++) {
00433 macros[i] = (struct macros *) malloc(sizeof(struct macros));
00434
00435 m = macros[i];
00436 m->player = mmdb_read_uint32(mmdb);
00437 m->nummacros = mmdb_read_uint32(mmdb);
00438 m->status = mmdb_read_uint32(mmdb);
00439 len = mmdb_read_uint32(mmdb);
00440 mmdb_read(mmdb, buffer, len);
00441 m->desc = strdup(buffer);
00442
00443 m->maxmacros = m->nummacros;
00444
00445 if(m->nummacros > 0) {
00446 m->alias = (char *) malloc(5 * m->maxmacros);
00447 m->string = (char **) malloc(sizeof(char *) * m->nummacros);
00448
00449 for(j = 0; j < m->nummacros; j++) {
00450 len = mmdb_read_uint32(mmdb);
00451 mmdb_read(mmdb, buffer, len);
00452 strcpy(m->alias + j * 5, buffer);
00453 len = mmdb_read_uint32(mmdb);
00454 mmdb_read(mmdb, buffer, len);
00455 m->string[j] = (char *) malloc(len + 1);
00456 strcpy(m->string[j], buffer);
00457
00458 }
00459 do_sort_macro_set(m);
00460 } else {
00461 m->alias = NULL;
00462 m->string = NULL;
00463 }
00464 }
00465 while (1) {
00466 for(i = 0; i < nummacros; i++)
00467 if(!isPlayer(macros[i]->player))
00468 break;
00469 if( i >= nummacros)
00470 break;
00471 clear_macro_set(i);
00472 }
00473 return object_count;
00474 }