char *coin_string(long worth) { static char cbuf[MAX_BUFFER]; long coins=0; long x; for(x = 0; coin_table[x].name; x++) ; cbuf[0] = '\0'; for(x--; x>=0 ; x--) { coins = worth/coin_table[x].worth; worth -= coins*coin_table[x].worth; if(!coins) continue; sprintf(cbuf+strlen(cbuf),"%li %s, ",coins, coin_table[x].ansi_name); } if(!ValidString(cbuf)) strcpy(cbuf,"no coins"); else cbuf[strlen(cbuf)-2] = '\0'; // strip comma and space return cbuf; }
long roomflags_name(char *str) { if(!ValidString(str)) return -1; if(!strcasecmp(str, "heal")) return RFLAG_HEAL; // else if(!strcasecmp(str, "glow")) return OFLAG_GLOW; return -1; }
/////////////// // UTILITIES // /////////////// long critflags_name(char *str) { if(!ValidString(str)) return -1; if(!strcasecmp(str, "mount")) return CFLAG_MOUNT; else if(!strcasecmp(str,"banker")) return CFLAG_BANKER; return -1; }
long objflags_name(char *str) { if(!ValidString(str)) return -1; if(!strcasecmp(str, "notake")) return OFLAG_NOTAKE; else if(!strcasecmp(str, "glow")) return OFLAG_GLOW; else if(!strcasecmp(str, "hum")) return OFLAG_HUM; return -1; }
char *compact_obj_list(char *buf, OBJECT *objs, bool room) { OBJECT *obj; OBJECT *xobj; long current; long count; long num; long *found; for(obj = objs, count=1; obj; obj = obj->next_content) count++; found = malloc(sizeof(long)*count); memset(found, 0, sizeof(long)*count); buf[0] = '\0'; for(obj = objs, current=0; obj; obj = obj->next_content, current++) { if(found[current]) continue; for(xobj = objs, count=0, num=0; xobj; xobj = xobj->next_content, count++) { if(found[count]) continue; if(obj->vnum == xobj->vnum && !strcasecmp(room ? obj->long_descr : obj->name, room ? xobj->long_descr : xobj->name)) { num++; found[count] = 1; } } if((room && strlen(obj->long_descr)+strlen(buf) > MAX_BUFFER) || (strlen(obj->name)+strlen(buf) > MAX_BUFFER)) { strcat(&buf[MAX_BUFFER-25],"\n\rTRUNCATED...\n\r"); break; } if(num>1) sprintf(buf+strlen(buf),"(%-2li)%s\n\r", num, room ? obj->long_descr : obj->name); else sprintf(buf+strlen(buf),"%s\n\r", room ? obj->long_descr : obj->name); } free(found); if (ValidString(buf)) buf[strlen(buf)-2] = '\0'; return buf; }
bool XdbAllKeys(Transaction *t, const Vector<TOperand*> &arguments, TOperand **result) { BACKEND_ARG_COUNT(1); BACKEND_ARG_STRING(0, db_name, db_length); XdbInfo &info = GetDatabaseInfo(db_name, false); // return an empty list if the database doesn't exist if (!info.xdb->Exists()) { *result = new TOperandList(t); return true; } TOperandList *list = new TOperandList(t); // scratch buffer for the key Buffer key; // bulk buffer for storing lots of keys. instead of continually // reallocating this, when we run out of space just make a new buffer. // the buffer will be pretty big to reduce the number of allocations // we end up going (we'll still have to do one allocation per key // for the TOperandString). Buffer *buf = NULL; for (uint32_t stream = info.xdb->MinDataStream(); stream <= info.xdb->MaxDataStream(); stream++) { // reset the scratch buffer and get the next key key.Reset(); info.xdb->LookupKey(stream, &key); size_t key_length = key.pos - key.base; if (!ValidString(key.base, key_length)) { logout << "ERROR: Database contains a key that is not NULL-terminated." << endl; return false; } if (buf == NULL || !buf->HasRemaining(key_length)) { buf = new Buffer(4096 * 16 + key_length); t->AddBuffer(buf); } list->PushOperand(new TOperandString(t, buf->pos, key_length)); buf->Append(key.base, key_length); } *result = list; return true; }
int is_number(char *str) { int i; if( !ValidString(str) ) return 0; for( i = 0; i < strlen(str); i++ ) { if( !isdigit(str[i]) ) return 0; } return 1; }
// this allocates memory for a string... it first checks if the location that // we are writing to has memory on it already, if it does, it frees it, then // writes the string to it. this is to keep memory from building up over time // .. debugging stuff in it right now void str_dup(char **destination, char *str) { if(!str) { mudlog("STRDUP error -- destination=%s",*destination); str = ""; } if(ValidString(*destination)) // if(*destination) { DeleteObject(*destination) } *destination = malloc(sizeof(char) * (strlen(str)+1)); strcpy(*destination,str); }
int main(int argc, const char **argv) { print_stats.Enable(); Vector<const char*> unspecified; bool parsed = Config::Parse(argc, argv, &unspecified); if (!parsed || unspecified.Size() != 1) { Config::PrintUsage(USAGE); return 1; } const char *file = unspecified[0]; Xdb *xdb = new Xdb(file, false, false, true); if (!xdb->Exists()) { delete xdb; return 0; } if (print_stats.IsSpecified()) { xdb->PrintStats(); delete xdb; return 0; } Buffer key; for (uint32_t stream = xdb->MinDataStream(); stream <= xdb->MaxDataStream(); stream++) { key.Reset(); xdb->LookupKey(stream, &key); Assert(ValidString(key.base, key.pos - key.base)); logout << (const char*) key.base << endl; } delete xdb; return 0; }
// str_add("borlak pip","durf") returns "borlak pip durf" char *str_add(char *str, char *addition, char delimeter) { static char buf[MAX_BUFFER]; long x; if(strlen(str) + strlen(addition) > sizeof(buf)-1) { mudlog("str_add: trying to add strings bigger than max_buffer!" "\n\rSTR=%s\n\rADDITION=%s", str, addition); return str; } buf[0] = '\0'; if(ValidString(str)) { strcpy(buf,str); x = strlen(buf); buf[x] = delimeter; buf[x+1] = '\0'; } strcat(buf,addition); return buf; }
void reset_update(void) { char buf[MAX_BUFFER]; CREATURE *crit=0; OBJECT *obj=0, *container=0;; RESET *reset=0, *reset_next=0, *orig=0; EXIT *exit=0; long min=0; for(reset = hash_reset[(current_time)%HASH_KEY]; reset; reset = reset_next) { reset_next = reset->next_hash; if(current_time < reset->poptime) continue; if( percent() < reset->chance || (reset->max && reset->loaded >= reset->max)) { add_reset(reset); continue; } obj = container = 0; crit = 0; for(orig = reset; reset; reset = reset->next) { // each reset has a chance to load.. don't have to calculate the first reset again though // hence the reset->prev if((reset->prev && percent() < reset->chance) || (reset->max && reset->loaded >= reset->max)) continue; min = reset->min; while(min > 0 && reset->loaded < reset->max) { switch(reset->loadtype) { case TYPE_CREATURE: crit = new_creature(reset->crit->vnum); crit->reset = reset; reset->loaded++; // trans crit to room trans(crit, reset->room); // if builder put in some command for the mob to do at spawn, put it here if(reset->command) interpret(crit, reset->command); // reset container to 0 in case more objects load on this mob container = 0; break; case TYPE_OBJECT: obj = new_object(reset->obj->vnum); obj->reset = reset; reset->loaded++; // trans obj to container, or crit, or room.. in that order trans(obj, container ? (void*)container : crit ? (void*)crit : (void*)reset->room); // when object pops on a mob the builder has the option to make the crit wear it... if(crit && ValidString(reset->command)) { sprintf(buf, "wear %s", reset->command); interpret(crit, buf); } // if this is a container, set the pointer so stacking can occur if(obj->objtype == OBJ_CONTAINER) container = obj; break; case TYPE_EXIT: if(!(exit = find_exit(reset->room, reset->command))) { mudlog("RESET_UPDATE: no exit found for reset#%li",reset->id); break; } exit->door = reset->loaded; break; } min--; } } add_reset(orig); } }
bool LX::ConvertLXNToIGC(const void *_data, size_t _length, FILE *file) { const uint8_t *data = (const uint8_t *)_data, *end = data + _length; Context context; char ch; unsigned l; while (data < end) { union LXN::Packet packet = { data }; unsigned packet_length; switch ((LXN::Command)*packet.cmd) { case LXN::EMPTY: packet_length = 0; while (data < end && *data == LXN::EMPTY) { ++packet_length; ++data; } fprintf(file, "LFILEMPTY%u\r\n", packet_length); break; case LXN::END: return true; case LXN::VERSION: data += sizeof(*packet.version); if (data > end) return false; fprintf(file, "HFRFWFIRMWAREVERSION:%3.1f\r\n" "HFRHWHARDWAREVERSION:%3.1f\r\n", packet.version->software / 10., packet.version->hardware / 10.); break; case LXN::START: data += sizeof(*packet.start); if (data > end || memcmp(packet.start->streraz, "STReRAZ", 8) != 0) return false; context.flight_no = packet.start->flight_no; break; case LXN::ORIGIN: data += sizeof(*packet.origin); if (data > end) return false; context.origin_time = FromBE32(packet.origin->time); context.origin_latitude = (int32_t)FromBE32(packet.origin->latitude); context.origin_longitude = (int32_t)FromBE32(packet.origin->longitude); fprintf(file, "L%.*sORIGIN%02d%02d%02d" "%02d%05d%c" "%03d%05d%c\r\n", (int)sizeof(context.vendor), context.vendor, context.origin_time / 3600, context.origin_time % 3600 / 60, context.origin_time % 60, abs(context.origin_latitude) / 60000, abs(context.origin_latitude) % 60000, context.origin_latitude >= 0 ? 'N' : 'S', abs(context.origin_longitude) / 60000, abs(context.origin_longitude) % 60000, context.origin_longitude >= 0 ? 'E' : 'W'); break; case LXN::SECURITY_OLD: data += sizeof(*packet.security_old); if (data > end) return false; fprintf(file, "G%22.22s\r\n", packet.security_old->foo); break; case LXN::SERIAL: data += sizeof(*packet.serial); if (data > end) return false; if (!ValidString(packet.serial->serial, sizeof(packet.serial->serial))) return false; fprintf(file, "A%sFLIGHT:%u\r\nHFDTE%s\r\n", packet.serial->serial, context.flight_no, context.date); break; case LXN::POSITION_OK: case LXN::POSITION_BAD: data += sizeof(*packet.position); if (data > end) return false; HandlePosition(file, context, *packet.position); break; case LXN::SECURITY: data += sizeof(*packet.security); if (data > end || packet.security->length > sizeof(packet.security->foo)) return false; if (packet.security->type == LXN::SECURITY_HIGH) ch = '2'; else if (packet.security->type == LXN::SECURITY_MED) ch = '1'; else if (packet.security->type == LXN::SECURITY_LOW) ch = '0'; else return false; fprintf(file, "G%c", ch); for (unsigned i = 0; i < packet.security->length; ++i) fprintf(file, "%02X", packet.security->foo[i]); fprintf(file, "\r\n"); break; case LXN::SECURITY_7000: data += sizeof(*packet.security_7000); if (data > end || packet.security_7000->x40 != 0x40) return false; fprintf(file, "G3"); for (auto ch : packet.security_7000->line1) fprintf(file, "%02X", ch); fprintf(file, "\r\nG"); for (auto ch : packet.security_7000->line2) fprintf(file, "%02X", ch); fprintf(file, "\r\nG"); for (auto ch : packet.security_7000->line3) fprintf(file, "%02X", ch); fprintf(file, "\r\n"); break; case LXN::COMPETITION_CLASS: data += sizeof(*packet.competition_class); if (data > end) return false; if (!ValidString(packet.competition_class->class_id, sizeof(packet.competition_class->class_id))) return false; if (context.flight_info.competition_class_id == 7) fprintf(file, "HFFXA%03d\r\n" "HFPLTPILOT:%s\r\n" "HFGTYGLIDERTYPE:%s\r\n" "HFGIDGLIDERID:%s\r\n" "HFDTM%03dGPSDATUM:%s\r\n" "HFCIDCOMPETITIONID:%s\r\n" "HFCCLCOMPETITIONCLASS:%s\r\n" "HFGPSGPS:%s\r\n", context.flight_info.fix_accuracy, context.flight_info.pilot, context.flight_info.glider, context.flight_info.registration, context.flight_info.gps_date, LXN::FormatGPSDate(context.flight_info.gps_date), context.flight_info.competition_class, packet.competition_class->class_id, context.flight_info.gps); break; case LXN::TASK: data += sizeof(*packet.task); if (data > end) return false; context.time = FromBE32(packet.task->time); // from a valid IGC file read with LXe: // C 11 08 11 14 11 18 11 08 11 0001 -2 fprintf(file, "C%02d%02d%02d%02d%02d%02d" "%02d%02d%02d" "%04d%02d\r\n", packet.task->day, packet.task->month, packet.task->year, context.time / 3600, context.time % 3600 / 60, context.time % 60, packet.task->day2, packet.task->month2, packet.task->year2, FromBE16(packet.task->task_id), packet.task->num_tps); for (unsigned i = 0; i < sizeof(packet.task->usage); ++i) { if (packet.task->usage[i]) { int latitude = (int32_t)FromBE32(packet.task->latitude[i]); int longitude = (int32_t)FromBE32(packet.task->longitude[i]); if (!ValidString(packet.task->name[i], sizeof(packet.task->name[i]))) return false; fprintf(file, "C%02d%05d%c" "%03d%05d%c" "%s\r\n", abs(latitude) / 60000, abs(latitude) % 60000, latitude >= 0 ? 'N' : 'S', abs(longitude) / 60000, abs(longitude) % 60000, longitude >= 0 ? 'E' : 'W', packet.task->name[i]); } } break; case LXN::EVENT: data += sizeof(*packet.event); if (data > end || !ValidString(packet.event->foo, sizeof(packet.event->foo))) return false; context.event = *packet.event; context.is_event = true; break; case LXN::B_EXT: data += sizeof(*packet.b_ext) + context.b_ext.num * sizeof(packet.b_ext->data[0]); if (data > end) return false; for (unsigned i = 0; i < context.b_ext.num; ++i) fprintf(file, "%0*u", (int)context.b_ext.extensions[i].width, FromBE16(packet.b_ext->data[i])); fprintf(file, "\r\n"); break; case LXN::K_EXT: data += sizeof(*packet.k_ext) + context.k_ext.num * sizeof(packet.k_ext->data[0]); if (data > end) return false; l = context.time + packet.k_ext->foo; fprintf(file, "K%02d%02d%02d", l / 3600, l % 3600 / 60, l % 60); for (unsigned i = 0; i < context.k_ext.num; ++i) fprintf(file, "%0*u", context.k_ext.extensions[i].width, FromBE16(packet.k_ext->data[i])); fprintf(file, "\r\n"); break; case LXN::DATE: data += sizeof(*packet.date); if (data > end || packet.date->day > 31 || packet.date->month > 12) return false; snprintf(context.date, sizeof(context.date), "%02d%02d%02d", packet.date->day % 100, packet.date->month % 100, FromBE16(packet.date->year)); break; case LXN::FLIGHT_INFO: data += sizeof(*packet.flight_info); if (data > end || !ValidString(packet.flight_info->pilot, sizeof(packet.flight_info->pilot)) || !ValidString(packet.flight_info->glider, sizeof(packet.flight_info->glider)) || !ValidString(packet.flight_info->registration, sizeof(packet.flight_info->registration)) || !ValidString(packet.flight_info->competition_class, sizeof(packet.flight_info->competition_class)) || !ValidString(packet.flight_info->gps, sizeof(packet.flight_info->gps))) return false; if (packet.flight_info->competition_class_id > 7) return false; if (packet.flight_info->competition_class_id < 7) fprintf(file, "HFFXA%03d\r\n" "HFPLTPILOT:%s\r\n" "HFGTYGLIDERTYPE:%s\r\n" "HFGIDGLIDERID:%s\r\n" "HFDTM%03dGPSDATUM:%s\r\n" "HFCIDCOMPETITIONID:%s\r\n" "HFCCLCOMPETITIONCLASS:%s\r\n" "HFGPSGPS:%s\r\n", packet.flight_info->fix_accuracy, packet.flight_info->pilot, packet.flight_info->glider, packet.flight_info->registration, packet.flight_info->gps_date, LXN::FormatGPSDate(packet.flight_info->gps_date), packet.flight_info->competition_class, LXN::FormatCompetitionClass(packet.flight_info->competition_class_id), packet.flight_info->gps); context.flight_info = *packet.flight_info; break; case LXN::K_EXT_CONFIG: data += sizeof(*packet.ext_config); if (data > end) return false; HandleExtConfig(file, *packet.ext_config, context.k_ext, 'J', 8); break; case LXN::B_EXT_CONFIG: data += sizeof(*packet.ext_config); if (data > end) return false; HandleExtConfig(file, *packet.ext_config, context.b_ext, 'I', 36); break; #ifdef __clang__ #pragma GCC diagnostic ignored "-Wcovered-switch-default" #endif default: if (*packet.cmd < 0x40) { data += sizeof(*packet.string); if (data > end) return false; data += packet.string->length; if (data > end) return false; fprintf(file, "%.*s\r\n", (int)packet.string->length, packet.string->value); if (packet.string->length >= 12 + sizeof(context.vendor) && memcmp(packet.string->value, "HFFTYFRTYPE:", 12) == 0) memcpy(context.vendor, packet.string->value + 12, sizeof(context.vendor)); } else return false; } } return false; }
/////////////// // FUNCTIONS // /////////////// void interpret(CREATURE *crit, char *buf) { CREATURE *xcrit=0; OBJECT *obj=0; SOCIAL *social=0; EXIT *exit=0; ROOM *room=0; char command[MAX_BUFFER]; char temp[MAX_BUFFER]; char *pbuf = command; char **arguments; char **editargs; long i = 0, x = 0; long string = 0; bool found = 0; bool command_ok = 0; bool social_ok = 0; strcpy(temp,buf); while( isspace(*buf) ) buf++; // check for one character commands without spaces to // seperate arguments. - i.e. chat yo = .yo | pip if(ispunct(*buf)) *pbuf++ = *buf++; else { while( !isspace(*buf) && *buf != '\0' ) *pbuf++ = *buf++; } *pbuf = '\0'; while( isspace(*buf) ) buf++; // moved exits before other commands - pip. // insert full exit name for abbreviated one. for( i = 0; directions[i].abbr; i++) { if (directions[i].abbr[0] != '\0' && !strcasecmp(command,directions[i].abbr)) { sprintf(command,"%s",directions[i].name); break; } } if(!IsDisabled(crit)) { for(exit = crit->in_room->exits; exit; exit = exit->next ) { if( !strindex(exit->name, command) ) { if((room = hashfind_room(exit->to_vnum)) == 0) { sendcrit(crit,"That exit enters into a domain far too powerful for you to handle."); mudlog("exit(%s) in room(%s:%d) has bad to_vnum(%d)!", exit->name, crit->in_room->name, crit->in_room->vnum, exit->to_vnum); continue; } if (exit->door >= DOOR_CLOSED && !IsImmortal(crit)) { sendcritf(crit,"The %s door is closed.",exit->name); return; } if (crit->rider) { sendcritf(crit,"You can't move on your own until %s dismounts you.",crit->rider->name); return; } // adding mounts! if (crit->mount) message("$n ride$x $p on $N.",crit,crit->mount,exit->name); else message("$n leave$x $p.",crit,0,exit->name); trans(crit,room); if (crit->mount) { trans(crit->mount,crit); message("$n arrive$x riding $N.",crit,crit->mount,crit->in_room); } message("$n $v arrived.",crit,crit->in_room,0); interpret(crit,"look"); return; } } } // check if they in editor and get a successful return (edited something) // otherwise let them use normal commands if(IsEditing(crit)) { if(crit->socket->string) { if(!(string = string_editor(crit,temp))) return; str_dup(&(*crit->socket->variable), crit->socket->string); DeleteObject(crit->socket->string) return; } else temp[0] = '\0'; if(!ValidString(command)) strcat(temp,""); else sprintf(temp,"%s %s",command,buf); editargs = make_arguments(temp); if(editor(crit,editargs)) { free_arguments(editargs); return; } free_arguments(editargs); }