#include <stdio.h> #include <stdlib.h> #include <string.h> #include "externs.h" #include "db.h" #include "attrib.h" #define OSEE AF_OSEE #define SDARK AF_DARK #define WIZARD AF_WIZARD #define UNIMP AF_UNIMP #define NOMOD AF_NOMOD #define DATE AF_DATE #define INH AF_INHERIT #define LOCK AF_LOCK #define FUNC AF_FUNC #define DBREF AF_DBREF #define NOMEM AF_NOMEM #define AHAVEN AF_HAVEN #define APROG AF_PROG /* Start new attribute declarations with numbers 1000 and higher. */ ATTR atr_list[] = { {"Fail", INH, 1}, {"PFail", INH|APROG, 2}, {"Succ", INH, 3}, {"PSucc", INH|APROG, 4}, {"Password", WIZARD|SDARK|NOMOD, 5}, {"Desc", INH|OSEE, 6}, {"PDesc", INH|APROG, 7}, {"Sex", INH|OSEE, 8}, {"Drop", INH, 9}, {"PDrop", INH|APROG, 10}, {"Color", INH|OSEE, 11}, {"Startup", INH|WIZARD, 12}, {"LastDisc", WIZARD|DATE|OSEE, 13}, {"LastConn", WIZARD|DATE|OSEE, 14}, {"Enter", INH, 15}, {"PEnter", INH|APROG, 16}, {"Idle", INH, 17}, {"Away", INH, 18}, {"Alias", OSEE, 19}, {"Efail", INH, 20}, {"PEfail", INH|APROG, 21}, {"Leave", INH, 22}, {"PLeave", INH|APROG, 23}, {"Quota", SDARK|NOMOD|WIZARD|NOMEM, 24}, {"TZ", INH, 25}, {"Email", WIZARD, 26}, {"Move", INH, 27}, {"PMove", INH|APROG, 28}, {"Lock", INH|LOCK, 29}, {"LEnter", INH|LOCK, 30}, {"LUse", INH|LOCK, 31}, {"Ufail", INH, 32}, {"PUfail", INH|APROG, 33}, {"Connect", INH, 34}, {"PConnect", INH|APROG, 35}, {"Disconnect", INH, 36}, {"PDisconnect", INH|APROG, 37}, {"WhoFlags", INH, 38}, {"PPage", INH|APROG, 39}, {"LHide", INH|LOCK, 40}, {"LPage", INH|LOCK, 41}, {"Notify", INH, 42}, {"LLeave", INH|LOCK, 43}, {"LFail", INH, 44}, {"PLfail", INH|APROG, 45}, {"Doing", INH|OSEE, 46}, {"Defown", INH|DBREF|WIZARD, 47}, {"LastSite", SDARK|WIZARD|NOMOD, 48}, {"WhoIs", INH|OSEE, 49}, {"PWhoIs", INH|APROG, 50}, {"RName", INH|WIZARD, 51}, {"Connects", INH|OSEE|WIZARD|NOMOD, 52}, {"Caption", INH|OSEE, 53}, {"Parent", INH, 54}, {"PParent", INH|APROG, 55}, {"UnParent", INH, 56}, {"PUnParent", INH|APROG, 57}, {"LSee", INH|LOCK, 58}, {"MOTD", WIZARD|SDARK, 59}, {"Rainbow", NOMOD|SDARK, 60}, {"WhoIdle", INH, 61}, {"WhoColor", WIZARD|SDARK, 62}, {"LastLoc", NOMOD|SDARK, 63}, {"North", WIZARD|DBREF, 64}, {"South", WIZARD|DBREF, 65}, {"East", WIZARD|DBREF, 66}, {"West", WIZARD|DBREF, 67}, {"Northeast", WIZARD|DBREF, 68}, {"Northwest", WIZARD|DBREF, 69}, {"Southeast", WIZARD|DBREF, 70}, {"Southwest", WIZARD|DBREF, 71}, {"CQuota", NOMOD|SDARK, 72}, {"Pennies", WIZARD|SDARK, 73}, {"BadLogins", WIZARD|SDARK|NOMOD, 74}, {NULL, 0L, -1} }; #undef OSEE #undef SDARK #undef WIZARD #undef UNIMP #undef NOMOD #undef DATE #undef INH #undef LOCK #undef FUNC #undef DBREF #undef NOMEM #undef AHAVEN #undef APROG ATTR *find_attr(char *atrname) { ATTR *a; for(a = &atr_list[0];a->name;a++) if(!string_compare(a->name, atrname)) break; if(!a->name) return((ATTR *)NULL); return(a); } ATTR *find_attr_by_num(int atrnum) { ATTR *a; for(a = &atr_list[0];a->name;a++) if(a->atrnum == atrnum) return(a); return((ATTR *)NULL); } ALIST *find_attr_on_obj(OBJ *thing, ATTR *attr) { ALIST *ptr; for(ptr = thing->attrlist;ptr;ptr = ptr->next) if(ptr->attr == attr) break; return(ptr); } /* Clear an attribute in the list */ void atr_clr(OBJ *thing, char *atrname) { ATTR *attr; if(!(attr = find_attr(atrname))) { log_error(tprintf("atr_clr(): Couldn't find attribute \"%s\"", atrname)); return; } atr_clr_a(thing, attr); } void atr_clr_a(OBJ *thing, ATTR *attr) { ALIST *ptr, *ptrprev = NULL; for(ptr = thing->attrlist;ptr;ptr = ptr->next) { if(ptr->attr == attr) break; ptrprev = ptr; } if(!ptr) return; if(!ptrprev) thing->attrlist = thing->attrlist->next; else ptrprev->next = ptr->next; stack_free(ptr->value); stack_free(ptr); } /* Add attribute to list */ void atr_add(OBJ *thing, char *atrname, char *val) { ATTR *attr; if(!(attr = find_attr(atrname))) { log_error(tprintf("atr_add(): Couldn't find attribute \"%s\"", atrname)); return; } atr_add_a(thing, attr, val); } void atr_add_a(OBJ *thing, ATTR *attr, char *val) { ALIST *ptr, *newattr; extern int loading_db; extern OBJ *cmd_plyr; /* Objects set NOMODIFY can't be modified. Period. */ /* The only exception is during the database load routine. */ if(thing->flags & NOMODIFY && !loading_db) { if(cmd_plyr) { notify(cmd_plyr, tprintf("|+R|WARNING|+W|: %s |C|is set NOMODIFY!", unparse_object(cmd_plyr, thing))); notify(cmd_plyr, tprintf("|+R|WARNING|+W|: |C|Attribute '%s' left untouched.", attr->name)); notify(cmd_plyr, "|+R|WARNING|+W|: |C|Ignore any messages regarding succession."); } return; } /* Sanity check */ if(!attr) return; if(!val) val = ""; if(!(ptr = find_attr_on_obj(thing, attr))) /* Have to add a new one */ { if(!*val) /* Nevermind, we got lucky */ return; newattr = (ALIST *)stack_alloc(sizeof(ALIST), 1, 0); newattr->attr = attr; newattr->value = NULL; /* We'll set this in a sec */ newattr->next = NULL; if(thing->attrlist) { for(ptr = thing->attrlist;ptr->next;ptr = ptr->next); ptr->next = newattr; } else thing->attrlist = newattr; ptr = newattr; } if(!*val) { atr_clr_a(thing, attr); return; } if(!ptr->value) ptr->value = stack_string_alloc(val, 1); else ptr->value = stack_string_realloc(ptr->value, val); } char *atr_get(OBJ *thing, char *atrname) { ATTR *attr; if(!(attr = find_attr(atrname))) { log_error(tprintf("atr_get(): Couldn't find attribute \"%s\"", atrname)); return(""); } return(atr_get_a(thing, attr)); } char *atr_get_a(OBJ *thing, ATTR *attr) { ALIST *ptr; if((ptr = find_attr_on_obj(thing, attr))) return(ptr->value); return(""); } void atr_free(OBJ *thing) { ALIST *ptr, *ptrnext; for(ptr = thing->attrlist;ptr;ptr = ptrnext) { ptrnext = ptr->next; stack_free(ptr->value); stack_free(ptr); } thing->attrlist = NULL; } int parse_attrib(OBJ *player, char *str, OBJ **thing, ATTR **attr) { char *s; char buf[4096]; strcpy(buf, str); if(!(s = strchr(buf, '/'))) return(0); *s++ = '\0'; if(!(*thing = match_object(player, buf, NOTYPE))) return(0); if(!(*attr = find_attr(s))) return(0); if((*attr)->flags & AF_DARK && !can_see_atr(player, *thing, *attr)) return(0); return(1); } char *unparse_atr_flags(unsigned long flags) { char buf[4096]; char *b = buf; if(flags & AF_WIZARD) *b++ = 'W'; if(flags & AF_UNIMP) *b++ = 'U'; if(flags & AF_OSEE) *b++ = 'O'; if(flags & AF_INHERIT) *b++ = 'I'; if(flags & AF_DARK) *b++ = 'D'; if(flags & AF_DATE) *b++ = 'd'; if(flags & AF_LOCK) *b++ = 'L'; if(flags & AF_FUNC) *b++ = 'F'; if(flags & AF_HAVEN) *b++ = 'H'; *b = '\0'; return(stack_string_alloc(buf, 0)); } char *unparse_attr(ALIST *atr) { char buf[4096] = "|+B|"; sprintf(buf+strlen(buf), "%s|+C|[|+W|%s|+C|]%s:|n| ", atr->attr->name, unparse_atr_flags(atr->attr->flags), (atr->attr->flags & AF_FUNC)?"()":""); return(stack_string_alloc(buf, 0)); } void my_atr_add(OBJ *thing, char *atrname, long increase) { int temp; temp = atol(atr_get(thing, atrname)); atr_add(thing, atrname, tprintf("%ld", temp+increase)); } void do_cpattr(OBJ *player, char *arg1, char *arg2) { OBJ *source, *dest; ATTR *attr_source, *attr_dest; if(!(parse_attrib(player, arg1, &source, &attr_source))) { notify(player, "No match."); return; } if(!controls(player, source, POW_MODIFY)) { notify(player, perm_denied()); return; } if(!(parse_attrib(player, arg2, &dest, &attr_dest))) { notify(player, "No match."); return; } if(!controls(player, dest, POW_MODIFY)) { notify(player, perm_denied()); return; } atr_add_a(dest, attr_dest, atr_get_a(source, attr_source)); notify(player, "Copied."); }