Welcome to the Builder Academy

Question Custom Auto Exits Issue. I must be missing something.

More
06 Nov 2022 02:49 #10215 by Bodhi
ISSUE:
In file act.informative.c:
look_at_room function calls the do_auto_exits function.
After I copy and paste this code from ACMD(do_exits) into do_auto_exits(): 
Code:
{     int door, len = 0;   if (AFF_FLAGGED(ch, AFF_BLIND) && GET_LEVEL(ch) < LVL_IMMORT)   {     send_to_char(ch, "You can't see a damned thing, you're blind!\r\n");     return;   }   send_to_char(ch, "%s", CCGRN(ch, C_NRM));   send_to_char(ch, "Exits:\r\n");   for (door = 0; door < DIR_COUNT; door++)   {     if (!EXIT(ch, door) || EXIT(ch, door)->to_room == NOWHERE)       continue;     if (EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED) && !CONFIG_DISP_CLOSED_DOORS)       continue;     if (EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) && !PRF_FLAGGED(ch, PRF_HOLYLIGHT))       continue;     len++;     if (!IS_NPC(ch) && PRF_FLAGGED(ch, PRF_SHOWVNUMS) && !EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))     {       send_to_char(ch, "%-5s -[%5d]%s %s\r\n", dirs[door], GET_ROOM_VNUM(EXIT(ch, door)->to_room),         EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? "[HIDDEN]" : "", world[EXIT(ch, door)->to_room].name);     }     else if (CONFIG_DISP_CLOSED_DOORS && EXIT_FLAGGED(EXIT(ch, door), EX_CLOSED))     {       /*But we tell them the door is closed */       send_to_char(ch, "%-5s - The %s is closed%s\r\n", dirs[door],         (EXIT(ch, door)->keyword) ? fname(EXIT(ch, door)->keyword) : "opening",         EXIT_FLAGGED(EXIT(ch, door), EX_HIDDEN) ? " and hidden." : ".");     }     else     {       send_to_char(ch, "%-5s - %s\r\n", dirs[door], IS_DARK(EXIT(ch, door)->to_room) &&         !CAN_SEE_IN_DARK(ch) ? "Too dark to tell." : world[EXIT(ch, door)->to_room].name);     }   }     if (!len)       send_to_char(ch, " None.\r\n"); }
It causes the server to report:
Code:
:: SCRIPT ERROR: Room 55571 :: wdoor: invalid direction :: SCRIPT ERROR: Room 55577 :: wdoor: invalid direction :: SCRIPT ERROR: Room 55569 :: wdoor: invalid direction :: SCRIPT ERROR: Room 55624 :: wdoor: invalid direction :: SCRIPT ERROR: Room 55618 :: wdoor: invalid direction :: SCRIPT ERROR: Mob (Hazel, the wellmaster, VNum 109):: mdoor: invalid direction
These rooms are:
55571 Yew Forest
55577 Yew Forest
55569 Yew Forest
55624 The Whirlpool
55618 The Whirlpool

Each of these rooms use a trigger script to "shift" their exits to create maze. For some reason, the copied code causes the server to "monitor" when these scripts "shift" exits and "report" those script errors. Using the redit command to detach those triggers for each room resolves the issue, but isn't exactly a solution to the root problem.

As for Hazel the wellmaster, a trigger script causes her to unlock a door, open a door, then close that door and lock it again. The opening and closing of that door causes the server to report that respective script error. Again, detaching her trigger resolves the issue, but isn't exactly a solution to the root problem.

Something in this "new" do_auto_exits() code doesn't play nice with trigger scripts opening, closing, or shifting doors. Each time we get a pulse and the trigger scripts have opened, closed, or "shifted" any door, it causes the server to report those script errors. However, there are no genuine errors. This is just a notification that trigger scripts have fired and altered door states.

So, I investigate and locate the code that produces the SCRIPT ERROR message:

FILE:
dg_scripts.c

IN FUNCTION:
Code:
void script_vlog(const char *format, va_list args) {   char output[MAX_STRING_LENGTH];   struct descriptor_data *i;   /* parse the args, making the error message */   vsnprintf(output, sizeof(output) - 2, format, args);   /* Save to the syslog file */   basic_mud_log("SCRIPT ERROR: %s", output);   /* And send to imms */   for (i = descriptor_list; i; i = i->next) {     if (STATE(i) != CON_PLAYING || IS_NPC(i->character)) /* switch */       continue;     if (GET_LEVEL(i->character) < LVL_BUILDER)       continue;     if (PLR_FLAGGED(i->character, PLR_WRITING))       continue;     if (NRM > (PRF_FLAGGED(i->character, PRF_LOG1) ? 1 : 0) + (PRF_FLAGGED(i->character, PRF_LOG2) ? 2 : 0))       continue;     send_to_char(i->character, "%s[ %s ]%s\r\n", CCGRN(i->character, C_NRM), output, CCNRM(i->character, C_NRM));   } }
FILE:
dg_wldcmd.c

IN COMMAND:
Code:
WCMD(do_wdoor) {     char target[MAX_INPUT_LENGTH], direction[MAX_INPUT_LENGTH];     char field[MAX_INPUT_LENGTH], *value;     room_data *rm;     struct room_direction_data *newexit;     int dir, fd, to_room;     const char *door_field[] = {         "purge",         "description",         "flags",         "key",         "name",         "room",         "\n"     };     argument = two_arguments(argument, target, direction);     value = one_argument(argument, field);     skip_spaces(&value);     if (!*target || !*direction || !*field) {         wld_log(room, "wdoor called with too few args");         return;     }     if ((rm = get_room(target)) == NULL) {         wld_log(room, "wdoor: invalid target");         return;     }     if ((dir = search_block(direction, dirs, FALSE)) == -1) {         wld_log(room, "wdoor: invalid direction");         return;     }     if ((fd = search_block(field, door_field, FALSE)) == -1) {         wld_log(room, "wdoor: invalid field");         return;     }     newexit = rm->dir_option[dir];     /* purge exit */     if (fd == 0) {         if (newexit) {             if (newexit->general_description)                 free(newexit->general_description);             if (newexit->keyword)                 free(newexit->keyword);             free(newexit);             rm->dir_option[dir] = NULL;         }     }     else {         if (!newexit) {             CREATE(newexit, struct room_direction_data, 1);             rm->dir_option[dir] = newexit;         }         switch (fd) {         case 1:  /* description */             if (newexit->general_description)                 free(newexit->general_description);             CREATE(newexit->general_description, char, strlen(value) + 3);             strcpy(newexit->general_description, value);             strcat(newexit->general_description, "\r\n");             break;         case 2:  /* flags       */             newexit->exit_info = (sh_int)asciiflag_conv(value);             break;         case 3:  /* key         */             newexit->key = atoi(value);             break;         case 4:  /* name        */             if (newexit->keyword)                 free(newexit->keyword);             CREATE(newexit->keyword, char, strlen(value) + 1);             strcpy(newexit->keyword, value);             break;         case 5:  /* room        */             if ((to_room = real_room(atoi(value))) != NOWHERE)                 newexit->to_room = to_room;             else                 wld_log(room, "wdoor: invalid door target");             break;         }     } }
Now, I see "what" produces those script error messages. Unfortunately, I still don't understand "why". I must be missing something. Why is that copy and pasted code in do_auto_exits() causing the server to "monitor" and "report" trigger scripts altering door states?

If I don't understand why it happens, I can't prevent it from happening. 

What am I missing?

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

More
06 Nov 2022 17:03 - 06 Nov 2022 17:05 #10216 by Vatiken
On a clean compile of tbaMUD I have blindly replace ACMD(do_exits) into do_auto_exits() and I have no errors to report.

I don't see how this change could possibly have the affect you are describing. Experience tells me there is another change you have done that has caused the issue.

However, tbaMUD could be a lot more helpful if it provided much better debug information in these errors. I will open an issue on github and look addressing it in the next week or so.

In the meantime, assuming you have a stock do_wdoor replace it with the code below and report back your errors again.
Code:
WCMD(do_wdoor) {     char target[MAX_INPUT_LENGTH], direction[MAX_INPUT_LENGTH];     char field[MAX_INPUT_LENGTH], *value;     room_data *rm;     struct room_direction_data *newexit;     int dir, fd, to_room, i;     const char *door_field[] = {         "purge",         "description",         "flags",         "key",         "name",         "room",         "\n"     };     argument = two_arguments(argument, target, direction);     value = one_argument(argument, field);     skip_spaces(&value);     if (!*target || !*direction || !*field) {         wld_log(room, "wdoor called with too few args");         return;     }     if ((rm = get_room(target)) == NULL) {         wld_log(room, "wdoor: invalid target (arg = %s)", target);         return;     }     if ((dir = search_block(direction, dirs, FALSE)) == -1) {       char error_log[MAX_STRING_LENGTH];       sprintf(error_log, "wdoor: invalid direction (arg == %s) not found in:\n  [ ", direction);       for (i = 0; i < NUM_OF_DIRS; i++)         sprintf(error_log + strlen(error_log), "%s ", dirs[i]);       sprintf(error_log + strlen(error_log), "]");       wld_log(room, error_log);       return;     }     if ((fd = search_block(field, door_field, FALSE)) == -1) {         wld_log(room, "wdoor: invalid field (arg == %s)", field);         return;     }     newexit = rm->dir_option[dir];     /* purge exit */     if (fd == 0) {         if (newexit) {             if (newexit->general_description)                 free(newexit->general_description);             if (newexit->keyword)                 free(newexit->keyword);             free(newexit);             rm->dir_option[dir] = NULL;         }     }     else {         if (!newexit) {             CREATE(newexit, struct room_direction_data, 1);             rm->dir_option[dir] = newexit;         }         switch (fd) {         case 1:  /* description */             if (newexit->general_description)                 free(newexit->general_description);             CREATE(newexit->general_description, char, strlen(value) + 3);             strcpy(newexit->general_description, value);             strcat(newexit->general_description, "\r\n");             break;         case 2:  /* flags       */             newexit->exit_info = (sh_int)asciiflag_conv(value);             break;         case 3:  /* key         */             newexit->key = atoi(value);             break;         case 4:  /* name        */             if (newexit->keyword)                 free(newexit->keyword);             CREATE(newexit->keyword, char, strlen(value) + 1);             strcpy(newexit->keyword, value);             break;         case 5:  /* room        */             if ((to_room = real_room(atoi(value))) != NOWHERE)                 newexit->to_room = to_room;             else                 wld_log(room, "wdoor: invalid door target (arg == %s)", value);             break;         }     } }

The result should look something like this:
Code:
Nov 06 12:56:31 2022 :: SCRIPT ERROR: Room 8500 :: wdoor: invalid direction (arg == sooth) not found in:   [ north east south west up down northwest northeast southeast southwest ] Nov 06 12:56:31 2022 :: SCRIPT ERROR: Room 8500 :: wdoor: invalid door target (arg == 8501)

 

tbaMUD developer/programmer
Last edit: 06 Nov 2022 17:05 by Vatiken.
The following user(s) said Thank You: Bodhi

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

More
06 Nov 2022 22:36 - 06 Nov 2022 22:48 #10217 by Bodhi
You're quite right! It was the result of a seperate code change. 

FILE:
constants.c

IN ARRAY:
const char *dirs

ALTERATION:
Code:
const char *dirs = {   "north",   "east",   "south",   "west",   "up",   "down",   "northwest", /* Diagonals only used if CONFIG_DIAGONAL_DIRS is set */   "northeast",   "southeast",   "southwest",   "\n" };

TO:
Code:
const char *dirs = {   "North",   "East",   "South",   "West",   "Up",   "Down",      // directions capitalized for improved aesthetics   "Northwest", /* Diagonals only used if CONFIG_DIAGONAL_DIRS is set */   "Northeast",   "Southeast",   "Southwest",   "\n" };

RATIONALE:
Capitalize the first letter of directions for improved aesthetics for use with auto exits.
​​​​​​​
It makes perfect sense this would cause issues with trigger scripts expecting lowercase elements from the array! Since I made this alteration simultaneously with the auto exits alteration, it slipped my mind. Man, thanks for helping me hunt this down! 

Now, I can work on a solution forcing the do_auto_exits() to output the dir names with capital first letters.

However, tbaMUD could be a lot more helpful if it provided much better debug information in these errors. I will open an issue on github and look addressing it in the next week or so.

Quite right! I was thinking the same thing. In fact, adding the file name to all SYSERR messages in every single file that produces them is on my todo list. tbaMUD contains a great deal of code in many files. For newbs like me, it's very helpful to know where each error message originates. Compiling a list all @todo from each file is also on my list.

I attempted using the git @todo app as a means of automating the process, but I use a Linux OS, which complicates the matter, as the git-hub Linux desktop app is not an official one. Tried installing windows desktop app in a virtual machine running windows 7. That had installation issues. Didn't want to take the time to mess with fixing the issues for either option. Hence, I'm compiling the @todo list manually, since I'm going through every single file anyway.
Last edit: 06 Nov 2022 22:48 by Bodhi. Reason: misplaced code tags

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

More
06 Nov 2022 23:36 #10218 by Vatiken
You could build a todo list in the projects tab on your github page.

The messages are unique enough that you should be able to just copy&paste it into your IDE and find it instantly and thus not require adding file names to the syserr messages.

I've already got the new messages added in my fork so I should have it out shortly, or you can grab it from my github page. It's the development branch.

I'm going to do some more testing and then I'll do a pull request on the tbamud master.

tbaMUD developer/programmer
The following user(s) said Thank You: Bodhi

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

More
07 Nov 2022 06:39 - 07 Nov 2022 06:41 #10219 by Bodhi

The messages are unique enough that you should be able to just copy&paste it into your IDE and find it instantly and thus not require adding file names to the syserr messages.

Oh, duh! I use Atom as my code editor. So, I can simply use "Find in Project". The same goes for @todo. That's pretty slick! Thank You!

I've already got the new messages added in my fork so I should have it out shortly, or you can grab it from my github page. It's the development branch.

So, it's probably best practice to make pull requests to your github page as the development branch, not tbaMUD-master?
Last edit: 07 Nov 2022 06:41 by Bodhi.

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

Time to create page: 0.289 seconds