/************************************************************************** * Find and fix bad perms in databases. * Version 1.0: (C) 1996, 1997 Brooke Paul * Dedicated to Styx (roy@tesla.tech.cerritos.edu) */ #include "mstruct.h" #include "mextern.h" #include <stdio.h> #include <unistd.h> #ifndef WIN32 #include <signal.h> #endif #define PRINTF(a) write(fd, a, strlen(a)) #define ISSET(p,f) ((p)->flags[(f)/8] & 1<<((f)%8)) extern int find_crt_slot(), find_obj_slot(); extern void end(); int fd=1, Rlow=1, Rhi=10000, n=0, index, dbm, dbo, ff, changed=0, rnum; /* OPTIONS: Set and unset these before compilation to configure */ int verbose=0; /* indicates verbose output -- WARNING: can be VERY verbose */ int cleanup=1; /* will flush clean _all_ rooms after check */ int writeok=1; /* permission to alter database, 0=readonly */ int spinner=1; /* little spinner and message window toggle */ main(argc, argv) int argc; char *argv[]; { int found, y, l, slot=0, dots=0; char str[80]; room *rom; ctag *cp, *ctemp; otag *op, *otemp; #ifndef WIN32 signal(SIGSEGV, end); #endif clearscreen(); if(argc>1){ if(!isdigit(argv[1][0])){ sprintf(str, "Syntax: %s room# or %s\n", argv[0], argv[0]); write(fd, str, strlen(str)); exit(0); } Rlow = atoi(argv[1]); if(argv[2]) Rhi = atoi(argv[2]); else Rhi = Rlow +1; } sprintf(str, "", 0); posit(0,0); printf("Mordor Database Utility v1.0 (c) 1996\n\n"); if(cleanup) strcat(str, "All rooms will be cleaned.\n"); if(writeok) strcat(str, "All changes will be saved.\n"); else strcat(str, "Readonly mode. Changes not saved.\n"); write(fd, str, strlen(str)); posit(8,0); printf("Working "); for(rnum=Rlow; rnum<Rhi; rnum++) { n=load_rom_from_file(rnum, &rom); if(n<0) continue; if(!rom) continue; if(spinner) { dots++; if(dots > 4 ) dots=1; spin(dots); } cp=rom->first_mon; while(cp) { if(ISSET(cp->crt, MPERMT)) { if(verbose) { sprintf(str, "Room %d has a perm %s.", rnum,cp->crt); if(!spinner) write(fd, str, strlen(str)); else message(str); } F_CLR(cp->crt, MPERMT); } found=0; n=find_crt_num(cp->crt); for(y=0; y<=9; y++) { if(rom->perm_mon[y].misc==n && n){ found=1; break; } } if(!found) { if(verbose) { sprintf(str, "Room %d has a bad perm creature: %s.", rnum, cp->crt); if(!spinner) write(fd, str, strlen(str)); else message(str); } /* add monster to DB */ if(!n && writeok) { slot=0; dbm=find_crt_slot(); op=cp->crt->first_obj; while(op) { l=find_obj_num(op->obj); if(!l) { sprintf(str, "### Unique object in inventory not saved."); if(!spinner) write(fd, str, strlen(str)); else message(str); op=op->next_tag; continue; } cp->crt->carry[slot]=(long)l; slot++; if(slot>9){ sprintf(str, "### Only first 10 objects in inventory saved."); if(!spinner) write(fd, str, strlen(str)); else message(str); break; } op=op->next_tag; } op=cp->crt->first_obj; cp->crt->first_obj=0; while(op) { otemp=op->next_tag; free_obj(op->obj); free(op); op=otemp; } sprintf(str, "%s/m%02d", MONPATH, dbm/MFILESIZE); ff = open(str, O_WRONLY | O_CREAT, ACC); if(ff == -1) { close(ff); merror("File open error", FATAL); return(0); } l = lseek(ff, (long)((dbm%MFILESIZE)*sizeof(creature)), 0); l = write(ff, cp->crt, sizeof(creature)); if(l < sizeof(creature)) merror("write_crt", FATAL); close(ff); sprintf(str, "### Creature %d updated for room %d.", dbm, rnum); if(!spinner) write(fd, str, strlen(str)); else message(str); } /* writeok */ /* properly perm monster */ l=0; while(rom->perm_mon[l].misc) { l++; } if(l>9) { sprintf(str, "### Room %d is already full of perm creatures.", rom->rom_num); if(!spinner) write(fd, str, strlen(str)); else message(str); break; } changed=1; if(!n) rom->perm_mon[l].misc=dbm; else rom->perm_mon[l].misc=n; rom->perm_mon[l].interval=7200; } /* !found */ cp=cp->next_tag; } l=0; while(rom->perm_mon[l].misc && l<10) { if(rom->perm_mon[l].interval < 5) { sprintf(str, "### Interval fixed on monster %d in room %d.", rom->perm_mon[l].misc, rnum); if(!spinner) write(fd, str, strlen(str)); else message(str); } rom->perm_mon[l].interval=3600; l++; } op=rom->first_obj; while(op) { if(ISSET(op->obj, OPERMT)) { if(verbose){ sprintf(str, "Room %d has a perm %s.", rnum,op->obj); if(!spinner) write(fd, str, strlen(str)); else message(str); } F_CLR(op->obj,OPERMT); } found=0; n=find_obj_num(op->obj); for(y=0; y<=9; y++) { if(rom->perm_obj[y].misc==n && n){ found=1; break; } } if(!found) { if(verbose){ sprintf(str, "Room %d has a bad perm object: %s.", rnum, op->obj); if(!spinner) write(fd, str, strlen(str)); else message(str); } if(!n && writeok) { dbo=find_obj_slot(); sprintf(str, "%s/o%02d", OBJPATH, dbo/OFILESIZE); ff = open(str, O_WRONLY | O_CREAT, ACC); if(ff == -1) { close(ff); merror("File open error", FATAL); return(0); } l = lseek(ff, (long)((dbo%OFILESIZE)*sizeof(object)), 0); op->obj->parent_rom = 0; op->obj->parent_obj = 0; op->obj->first_obj = 0; op->obj->parent_crt = 0; l = write(ff, op->obj, sizeof(object)); if(l < sizeof(object)) merror("write_obj", FATAL); close(ff); sprintf(str, "### Object %d updated for room %d.", dbo, rnum); if(!spinner) write(fd, str, strlen(str)); else message(str); } /* properly perm object */ l=0; while(rom->perm_obj[l].misc) { l++; } if(l>9) { sprintf(str, "### Room %d is already full of perm objects.", rom->rom_num); if(!spinner) write(fd, str, strlen(str)); else message(str); break; } changed=1; if(!n) rom->perm_obj[l].misc=dbo; else rom->perm_obj[l].misc=n; rom->perm_obj[l].interval=(long)7200; } op=op->next_tag; } /* !found */ l=0; while(rom->perm_obj[l].misc && l<10) { if(rom->perm_obj[l].interval < 5) { sprintf(str, "### Interval fixed on object %d in room %d.", rom->perm_obj[l].misc, rnum); if(!spinner) write(fd, str, strlen(str)); else message(str); } rom->perm_obj[l].interval=3600; l++; } if(changed || cleanup) { /* flush the room */ cp=rom->first_mon; rom->first_mon=0; while(cp) { ctemp = cp->next_tag; free_crt(cp->crt); free(cp); cp = ctemp; } op = rom->first_obj; rom->first_obj = 0; while(op) { otemp = op->next_tag; free_obj(op->obj); free(op); op = otemp; } if(writeok) { if(verbose) { sprintf(str, "Saving Room %d.", rnum); if(!spinner) write(fd, str, strlen(str)); else message(str); } save_rom_to_file(rnum, rom); } } if(rom) free_rom(rom); changed=0; } posit(0,20); sprintf(str, "Processed %d rooms.\nDone.", Rhi-Rlow); write(fd, str, strlen(str)); exit(0); } int find_obj_num(obj_ptr) object *obj_ptr; { int i; object *obj_src; for (i=0;i<OMAX;i++) { if(load_obj_from_file(i, &obj_src) < 0) continue; if(!strcmp(obj_ptr->name, obj_src->name)) { if(obj_src) free(obj_src); break; } if(obj_src) free(obj_src); } if(i<OMAX) return(i); else return(0); } int find_crt_num(crt_ptr) creature *crt_ptr; { int i; creature *crt_src; for (i=0;i<CMAX;i++) { if(load_crt_from_file(i, &crt_src) < 0) continue; if(!strcmp(crt_ptr->name, crt_src->name)) { if(crt_src) free(crt_src); break; } if(crt_src) free(crt_src); } if(i<CMAX) return(i); else return(0); } int find_obj_slot() { int i, fd=1; char str[80]; object obj; for(i=2; i<=OMAX; i++) { if(load_obj_from_file(i, &obj) < 0) break; } if(verbose) { sprintf(str, "Object slot open at %d.", i); message(str); } return(i); } int find_crt_slot() { int i; char str[80]; creature crt; for(i=2; i<=CMAX; i++) { if(load_crt_from_file(i, &crt) < 0) break; } if(verbose) { sprintf(str, "Creature slot open at %d.", i); message(str); } return(i); } #ifndef WIN32 void end() { char str[80]; sprintf(str, "\n\nCheck DB has encountered an error.\nPlease restart at room %d.\n", rnum); write(fd, str, strlen(str)); } #endif