Welcome to the Builder Academy

Question Crash - need help

More
07 Mar 2018 18:03 - 07 Mar 2018 18:09 #7668 by JTP
spells.c
Code:
/* Used by the locate object spell to check the alias list on objects */ int isname_obj(char *search, char *list) { char *found_in_list; /* But could be something like 'ring' in 'shimmering.' */ char searchname[128]; char namelist[MAX_STRING_LENGTH]; int found_pos = -1; int found_name=0; /* found the name we're looking for */ int match = 1; int i; /* Force to lowercase for string comparisons */ sprintf(searchname, "%s", search); for (i = 0; searchname[i]; i++) searchname[i] = LOWER(searchname[i]); sprintf(namelist, "%s", list); <<<--- line 239 for (i = 0; namelist[i]; i++) namelist[i] = LOWER(namelist[i]); /* see if searchname exists any place within namelist */ found_in_list = strstr(namelist, searchname); if (!found_in_list) { return 0; } ASPELL(spell_locate_object) { struct obj_data *i; char name[MAX_INPUT_LENGTH]; int j; if (!obj) { send_to_char(ch, "You sense nothing.\r\n"); return; } /* added a global var to catch 2nd arg. */ sprintf(name, "%s", cast_arg2); j = GET_LEVEL(ch) / 2; /* # items to show = twice char's level */ for (i = object_list; i && (j > 0); i = i->next) { if (!isname_obj(name, i->name)) <<<---287 continue; send_to_char(ch, "%c%s", UPPER(*i->short_description), i->short_description + 1); if (i->carried_by) send_to_char(ch, " is being carried by %s.\r\n", PERS(i->carried_by, ch)); else if (IN_ROOM(i) != NOWHERE) send_to_char(ch, " is in %s.\r\n", world[IN_ROOM(i)].name); else if (i->in_obj) send_to_char(ch, " is in %s.\r\n", i->in_obj->short_description); else if (i->worn_by) send_to_char(ch, " is being worn by %s.\r\n", PERS(i->worn_by, ch)); else send_to_char(ch, "'s location is uncertain.\r\n"); j--; } }
Last edit: 07 Mar 2018 18:09 by JTP.

Please Log in or Create an account to join the conversation.

More
07 Mar 2018 18:14 #7669 by JTP
spell_parser.c
Code:
if (IS_SET(SINFO.routines, MAG_MANUAL)) switch (spellnum) { case SPELL_CHARM: MANUAL_SPELL(spell_charm); break; case SPELL_CREATE_WATER: MANUAL_SPELL(spell_create_water); break; case SPELL_DETECT_POISON: MANUAL_SPELL(spell_detect_poison); break; case SPELL_ENCHANT_WEAPON: MANUAL_SPELL(spell_enchant_weapon); break; case SPELL_IDENTIFY: MANUAL_SPELL(spell_identify); break; case SPELL_LOCATE_OBJECT: MANUAL_SPELL(spell_locate_object); break; <<<---289 int cast_spell(struct char_data *ch, struct char_data *tch, struct obj_data *tobj, int spellnum) { if (spellnum < 0 || spellnum > TOP_SPELL_DEFINE) { log("SYSERR: cast_spell trying to call spellnum %d/%d.", spellnum, TOP_SPELL_DEFINE); return (0); } if (GET_POS(ch) < SINFO.min_position) { switch (GET_POS(ch)) { case POS_SLEEPING: send_to_char(ch, "You dream about great magical powers.\r\n"); break; case POS_RESTING: send_to_char(ch, "You cannot concentrate while resting.\r\n"); break; case POS_SITTING: send_to_char(ch, "You can't do this sitting!\r\n"); break; case POS_FIGHTING: send_to_char(ch, "Impossible! You can't concentrate enough!\r\n"); break; default: send_to_char(ch, "You can't do much of anything like this!\r\n"); break; } return (0); } if (AFF_FLAGGED(ch, AFF_CHARM) && (ch->master == tch)) { send_to_char(ch, "You are afraid you might hurt your master!\r\n"); return (0); } if ((tch != ch) && IS_SET(SINFO.targets, TAR_SELF_ONLY)) { send_to_char(ch, "You can only cast this spell upon yourself!\r\n"); return (0); } if ((tch == ch) && IS_SET(SINFO.targets, TAR_NOT_SELF)) { send_to_char(ch, "You cannot cast this spell upon yourself!\r\n"); return (0); } if (IS_SET(SINFO.routines, MAG_GROUPS) && !GROUP(ch)) { send_to_char(ch, "You can't cast this spell if you're not in a group!\r\n"); return (0); } send_to_char(ch, "%s", CONFIG_OK); say_spell(ch, spellnum, tch, tobj, (GET_CLASS(ch) == CLASS_BARD ? SCMD_SONG : SCMD_CAST)); return (call_magic(ch, tch, tobj, spellnum, GET_LEVEL(ch), CAST_SPELL)); <<<---513 } } else { /* cast spell returns 1 on success; subtract mana & set waitstate */ if (cast_spell(ch, tch, tobj, spellnum)) { <<<---668 WAIT_STATE(ch, PULSE_VIOLENCE); if (mana > 0) GET_MANA(ch) = MAX(0, MIN(GET_MAX_MANA(ch), GET_MANA(ch) - mana)); } } }

Please Log in or Create an account to join the conversation.

More
07 Mar 2018 18:17 #7670 by JTP
interpreter.c
Code:
/* Only apply levenshtein counts if the command is not a trigger command. */ if ( (levenshtein_distance(arg, cmd_info[cmd].command) <= 2) && (cmd_info[cmd].minimum_level >= 0) ) { if (!found) { send_to_char(ch, "\r\nDid you mean:\r\n"); found = 1; } send_to_char(ch, " %s\r\n", cmd_info[cmd].command); } } } else if (!IS_NPC(ch) && PLR_FLAGGED(ch, PLR_FROZEN) && GET_LEVEL(ch) < LVL_IMPL) send_to_char(ch, "You try, but the mind-numbing cold prevents you...\r\n"); else if (complete_cmd_info[cmd].command_pointer == NULL) send_to_char(ch, "Sorry, that command hasn't been implemented yet.\r\n"); else if (IS_NPC(ch) && complete_cmd_info[cmd].minimum_level >= LVL_IMMORT) send_to_char(ch, "You can't use immortal commands while switched.\r\n"); else if (GET_POS(ch) < complete_cmd_info[cmd].minimum_position) switch (GET_POS(ch)) { case POS_DEAD: send_to_char(ch, "Lie still; you are DEAD!!! :-(\r\n"); break; case POS_INCAP: case POS_MORTALLYW: send_to_char(ch, "You are in a pretty bad shape, unable to do anything!\r\n"); break; case POS_STUNNED: send_to_char(ch, "All you can do right now is think about the stars!\r\n"); break; case POS_SLEEPING: send_to_char(ch, "In your dreams, or what?\r\n"); break; case POS_RESTING: send_to_char(ch, "Nah... You feel too relaxed to do that..\r\n"); break; case POS_SITTING: send_to_char(ch, "Maybe you should get on your feet first?\r\n"); break; case POS_FIGHTING: send_to_char(ch, "No way! You're fighting for your life!\r\n"); break; } else if (no_specials || !special(ch, cmd, line)) ((*complete_cmd_info[cmd].command_pointer) (ch, line, cmd, complete_cmd_info[cmd].subcmd)); <<<---671 }

Please Log in or Create an account to join the conversation.

More
07 Mar 2018 18:22 #7671 by JTP
comm.c
Code:
if (d->character) { /* Reset the idle timer & pull char back from void if necessary */ d->character->char_specials.timer = 0; if (STATE(d) == CON_PLAYING && GET_WAS_IN(d->character) != NOWHERE) { if (IN_ROOM(d->character) != NOWHERE) char_from_room(d->character); char_to_room(d->character, GET_WAS_IN(d->character)); GET_WAS_IN(d->character) = NOWHERE; act("$n has returned.", TRUE, d->character, 0, 0, TO_ROOM); } GET_WAIT_STATE(d->character) = 1; } d->has_prompt = FALSE; if (d->showstr_count) /* Reading something w/ pager */ show_string(d, comm); else if (d->str) /* Writing boards, mail, etc. */ string_add(d, comm); else if (STATE(d) != CON_PLAYING) /* In menus, etc. */ nanny(d, comm); else { /* else: we're playing normally. */ if (aliased) /* To prevent recursive aliases. */ d->has_prompt = TRUE; /* To get newline before next cmd output. */ else if (perform_alias(d, comm, sizeof(comm))) /* Run it through aliasing system */ get_from_q(&d->input, comm, &aliased); command_interpreter(d->character, comm); /* Send it to interpreter */ <<<---892 } } /* If we made it this far, we will be able to restart without problem. */ remove(KILLSCRIPT_FILE); if (fCopyOver) /* reload players */ copyover_recover(); log("Entering game loop."); game_loop(mother_desc); <<<--- 536 /* Moved here to distinguish command line options and to show up * in the log if stderr is redirected to a file. */ log("Loading configuration."); log("%s", tbamud_version); if (chdir(dir) < 0) { perror("SYSERR: Fatal error changing to data directory"); exit(1); } log("Using %s as data directory.", dir); if (scheck) boot_world(); else { log("Running game on port %d.", port); init_game(port); <<<---356 } log("Clearing game world."); destroy_db();

Please Log in or Create an account to join the conversation.

More
07 Mar 2018 18:38 #7672 by JTP
Hope you can spot what is wrong

Please Log in or Create an account to join the conversation.

More
07 Mar 2018 21:25 #7673 by thomas

JTP wrote: Hope you can spot what is wrong

Go to this frame (the command, once you're in gdb is "up"):

JTP wrote:

Code:
ASPELL(spell_locate_object) { struct obj_data *i; char name[MAX_INPUT_LENGTH]; int j; if (!obj) { send_to_char(ch, "You sense nothing.\r\n"); return; } /* added a global var to catch 2nd arg. */ sprintf(name, "%s", cast_arg2); j = GET_LEVEL(ch) / 2; /* # items to show = twice char's level */ for (i = object_list; i && (j > 0); i = i->next) { if (!isname_obj(name, i->name)) <<<---287 continue;

And, when there, print the i object with "print *i".

My guess is that you'll see that it is a corpse, because you've been asking about changes to the corpse code lately.

Here, obviously, the object "i" has a NULL name pointer (the "list" parameter to the innermost frame).
And this causes all sorts of trouble.

So, there are two ways of fixing this:
  1. You can guard against this possibility in isname_obj. Simply add a null check for the list somewhere near the beginning. This will make sure that you don't crash. However, you'd never be able to find the object or pick it up or look at it, because the name is NULL.
  2. You can make sure no objects are created with a NULL name. This means making sure that whenever you CREATE an object_data, you initialize the name to something. This is done already in the distribution code , but I'm afraid you might have removed it in your version.

Please Log in or Create an account to join the conversation.

Time to create page: 0.266 seconds