/* note, this is still under construction... */ /* * items.c */ #include <ctype.h> #include <string.h> #include <malloc.h> #include <sys/stat.h> #include <sys/time.h> #include <stdio.h> #include <fcntl.h> #include <memory.h> #include "config.h" #include "player.h" #include "fix.h" #include "items.h" /* externs */ extern char *upper_from_saved(saved_player * sp); extern char *check_legal_entry(player *, char *, int); extern char *store_string(), *store_int(); extern char *get_string(), *get_int(); extern char *gstring_possessive(), *gstring(), *end_string(), *next_space(); extern player *find_player_global_quiet(char *), *find_player_global(char *); extern player *find_player_absolute_quiet(char *); extern saved_player *find_saved_player(char *); extern void log(char *, char *); extern void tell_player(player *, char *); extern char *number2string(int); extern char *full_name(player *); extern char *get_gender_string(player *); extern void save_player(player *); extern void pager(player *, char *, int); extern int global_tag(player *, char *); extern void cleanup_tag(player **, int); extern void TELLROOM(), ADDSTACK(), ENDSTACK(), TELLPLAYER(), LOGF(), SUWALL(); extern saved_player **saved_hash[]; extern int strnomatch(char *, char *, int); struct s_item *top_item; int item_unique; void check_special_effect(); /* delete and entry from someones list */ void delete_entry_item(saved_player * sp, item * l) { item *scan; if (!sp) return; scan = sp->item_top; if (scan == l) { sp->item_top = l->next; FREE(l); return; } while (scan) if (scan->next == l) { scan->next = l->next; FREE(l); return; } else scan = scan->next; log("error", "Tried to delete item that wasn't there.\n"); } /* compress list */ void tmp_comp_item(saved_player * sp) { char *oldstack; item *l, *next, *z, *znext; l = sp->item_top; oldstack = stack; stack = store_int(stack, 0); while (l) { next = l->next; if (l->id < 0) { log("error", "Bad item entry on compress .. auto deleted.\n"); delete_entry_item(sp, l); } else { stack = store_int(stack, l->id); stack = store_int(stack, l->number); stack = store_int(stack, l->flags); } l = next; } store_int(oldstack, ((int) stack - (int) oldstack)); } void compress_item(saved_player * sp) { char *oldstack; int length; item *new, *l, *next; if (sp->system_flags & COMPRESSED_ITEMS) return; sp->system_flags |= COMPRESSED_ITEMS; oldstack = stack; tmp_comp_item(sp); length = (int) stack - (int) oldstack; if (length == 4) { sp->item_top = 0; stack = oldstack; return; } new = (item *) MALLOC(length); memcpy(new, oldstack, length); l = sp->item_top; while (l) { next = l->next; FREE(l); l = next; } sp->item_top = new; stack = oldstack; } /* decompress list */ void decompress_item(saved_player * sp) { item *l; char *old, *end, *start; int length; if (!(sp->system_flags & COMPRESSED_ITEMS)) return; sp->system_flags &= ~COMPRESSED_ITEMS; old = (char *) sp->item_top; start = old; if (!old) return; old = get_int(&length, old); end = old + length - 4; sp->item_top = 0; while (old < end) { l = (item *) MALLOC(sizeof(item)); old = get_int(&(l->id), old); old = get_int(&(l->number), old); old = get_int(&(l->flags), old); l->next = sp->item_top; l->loc_next = 0; sp->item_top = l; l->owner = sp; } FREE(start); } /* save list */ void construct_item_save(saved_player * sp) { int length; char *where; if (!(sp->system_flags & COMPRESSED_ITEMS) && (!find_player_absolute_quiet(sp->lower_name))) compress_item(sp); if (sp->system_flags & COMPRESSED_ITEMS) { if (sp->item_top) { where = (char *) sp->item_top; (void) get_int(&length, where); memcpy(stack, where, length); stack += length; } else stack = store_int(stack, 4); } else tmp_comp_item(sp); } /* retrieve list */ char *retrieve_item_data(saved_player * sp, char *where) { int length; (void) get_int(&length, where); if (length == 4) sp->item_top = 0; else { sp->system_flags |= COMPRESSED_ITEMS; sp->item_top = (item *) MALLOC(length); memcpy(sp->item_top, where, length); } where += length; return where; } /* count list entries */ int count_items(player * p) { item *l, *s; int count = 0; if (!p->saved) return 0; if (!p->saved->item_top) return 0; for (l = p->saved->item_top; l; l = l->next) { count++; } return count; } /* s_item stuff starts here! */ int count_sitem() { struct s_item *l; int count = 0; if (!top_item) return 0; for (l = top_item; l; l = l->next) count++; return count; } char *extract_sitem(char *stack2){ struct s_item *d; d = (struct s_item *) MALLOC(sizeof(struct s_item)); memset(d, 0, sizeof(struct s_item)); stack2 = get_string(d->desc, stack2); stack2 = get_string(d->name, stack2); stack2 = get_string(d->author, stack2); stack2 = get_int(&d->id, stack2); stack2 = get_int(&d->sflags, stack2); stack2 = get_int(&d->value, stack2); d->next = top_item; top_item = d; return stack2; } void save_sitem(struct s_item *s) { stack = store_string(stack, s->desc); stack = store_string(stack, s->name); stack = store_string(stack, s->author); stack = store_int(stack, s->id); stack = store_int(stack, s->sflags); stack = store_int(stack, s->value); } /* throw all the saved items to disk */ void sync_sitems(int background) { int n, fd, count, len; struct itimerval new; char *oldstack; struct s_item *z; oldstack = stack; if (background && fork()) return; #ifdef PC fd = open("files\\notes\\track", O_CREAT | O_WRONLY | O_TRUNC | O_BINARY); #else fd = open("files/items/saved.items", O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, S_IRUSR | S_IWUSR); #endif if (fd < 0) handle_error("Failed to open items file."); count = count_sitem(); stack = store_int(stack, count); stack = store_int(stack, item_unique); if (top_item) for (z = top_item; z; z = z->next) { save_sitem(z); } len = (int) stack - (int) oldstack; if (write(fd, oldstack, len) < 0) handle_error("Ack! Can't save the saved items!!"); close(fd); stack = oldstack; if (background) exit(0); } /* * load all notes from disk this should be changed for arbitary hashes */ void init_sitems() { int length, fd, count; char *oldstack; oldstack = stack; if (sys_flags & VERBOSE || sys_flags & PANIC) log("boot", "Loading notes from disk"); fd = open("files/items/saved.items", O_RDONLY | O_NDELAY); if (fd < 0) { sprintf(oldstack, "Failed to load items file"); stack = end_string(oldstack); log("error", oldstack); top_item = 0; item_unique = 0; stack = oldstack; } else { length = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); if (length) { if (read(fd, oldstack, length) < 0) handle_error("Damnit, s_items aren't loading"); stack = get_int(&count, stack); stack = get_int(&item_unique, stack); for (; count; count--) stack = extract_sitem(stack); } close(fd); } stack = oldstack; } struct s_item *find_item_before(struct s_item *scan) { struct s_item *s; for (s = top_item; s; s = s->next) { if (s->next == scan) return s; } return 0; } struct s_item *find_item(char *name, int id) { struct s_item *s; for (s = top_item; s; s = s->next) if (((name) && !strcasecmp(s->name, name)) || s->id == id) return s; return 0; } item *find_pitem(saved_player *sp, int id) { item *i; if (sp->system_flags & COMPRESSED_ITEMS) decompress_item(sp); if (!(sp) || !(sp->item_top)) return 0; for (i = sp->item_top; i; i = i->next) if (i->id == id) return i; return 0; }