do_commands

  • Fizban
  • Topic Author
  • Offline
  • Administrator
  • Administrator
More
5 years 8 months ago - 5 years 8 months ago #7437 by Fizban
do_commands was created by Fizban
do_commands is showing corrupted info when the wizhelp subcommand is used with a mortal as its argument.

It doesn't appear to be an issue with do_commands itself, it seems to be an issue with the string being passed to column_list already having info in it when it is being substantiated. When you use social or commands, the pre-existing information in the string is being overwritten and thus hidden from view, but because mortals don't have any access to immortal commands, nothing is being added to the string when wizhelp is called as the subcommand so it's showing whatever content it had still stored in it.

On a brand new character wizhelp <name> shows nothing.

If the mortal uses the socials or commands, commands, then wizhelp <mortal> then shows you the info they most recently saw. If however the mortals most recent commands were something entirely different then it often shows corrupted nonsensical info, such as the name of mobs from zones the mortal has never been to, or random characters.
ACMD(do_commands)
{
  int no, i, cmd_num;
  int wizhelp = 0, socials = 0;
  struct char_data *vict;
  char arg[MAX_INPUT_LENGTH];
  char buf[MAX_STRING_LENGTH];
  const char *commands[1000];
  int overflow = sizeof(commands) / sizeof(commands[0]);

  if (!ch->desc)
    return;

  one_argument(argument, arg);

  if (*arg) {
    if (!(vict = get_char_vis(ch, arg, NULL, FIND_CHAR_WORLD)) || IS_NPC(vict)) {
      send_to_char(ch, "Who is that?\r\n");
      return;
    }
  } else
    vict = ch;

  if (subcmd == SCMD_SOCIALS)
    socials = 1;
  else if (subcmd == SCMD_WIZHELP)
    wizhelp = 1;

  sprintf(buf, "The following %s%s are available to %s:\r\n",
          wizhelp ? "privileged " : "",
          socials ? "socials" : "commands",
          vict == ch ? "you" : GET_NAME(vict));

  /* cmd_num starts at 1, not 0, to remove 'RESERVED' */
  for (no = 0, cmd_num = 1;
       complete_cmd_info[cmd_sort_info[cmd_num]].command[0] != '\n';
       ++cmd_num) {

    i = cmd_sort_info[cmd_num];

    if (complete_cmd_info[i].minimum_level < 0 || GET_LEVEL(vict) < complete_cmd_info[i].minimum_level)
      continue;

    if ((complete_cmd_info[i].minimum_level >= LVL_IMMORT) != wizhelp)
      continue;

    if (!wizhelp && socials != (complete_cmd_info[i].command_pointer == do_action))
      continue;

    if (wizhelp && complete_cmd_info[i].command_pointer == do_action)
      continue;

    if (--overflow < 0)
      continue;

    /* matching command: copy to commands list */
    commands[no++] = complete_cmd_info[i].command;
  }

  /* display commands list in a nice columnized format */
  column_list(ch, 0, commands, no, FALSE);
}

The only issue I see with do_commands itself is there's a completely useless buf char created, that has info put inside of it, but is never actually sent anywhere. I'd just remove the buf and send the string via send_to_char, but that part really isn't important as it's not related to the corrupted info winding up inside of commands.
Last edit: 5 years 8 months ago by Fizban.

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

  • Fizban
  • Topic Author
  • Offline
  • Administrator
  • Administrator
More
5 years 8 months ago #7438 by Fizban
Replied by Fizban on topic do_commands
void column_list(struct char_data *ch, int num_cols, const char **list, int list_length, bool show_nums)
{
   size_t max_len = 0, len = 0, temp_len;
   int num_per_col, col_width, r, c, i, offset = 0;
   char buf[MAX_STRING_LENGTH];

   /* Work out the longest list item */
   for (i=0; i<list_length; i++)
     if (max_len < strlen(list[i]))
       max_len = strlen(list[i]);

   /* auto columns case */
   if (num_cols == 0) {
	   num_cols = (IS_NPC(ch) ? 80 : GET_SCREEN_WIDTH(ch)) / (max_len + (show_nums ? 5 : 1));
   }

   /* Ensure that the number of columns is in the range 1-10 */
   num_cols = MIN(MAX(num_cols,1), 10);

   /* Work out the longest list item */
   for (i=0; i<list_length; i++)
     if (max_len < strlen(list[i]))
       max_len = strlen(list[i]);

   /* Calculate the width of each column */
   if (IS_NPC(ch))   col_width = 80 / num_cols;
   else              col_width = (GET_SCREEN_WIDTH(ch)) / num_cols;

   if (show_nums) col_width-=4;

   if (col_width < 0 || (size_t)col_width < max_len)
     log("Warning: columns too narrow for correct output to %s in simple_column_list (utils.c)", GET_NAME(ch));

   /* Calculate how many list items there should be per column */
   num_per_col = (list_length / num_cols) + ((list_length % num_cols) ? 1 : 0);

   /* Fill 'buf' with the columnised list */
   for (r=0; r<num_per_col; r++)
   {
     for (c=0; c<num_cols; c++)
     {
       offset = (c*num_per_col)+r;
       if (offset < list_length)
       {
         if (show_nums)
           temp_len = snprintf(buf+len, sizeof(buf) - len, "%2d) %-*s", offset+1, col_width, list[(offset)]);
         else
           temp_len = snprintf(buf+len, sizeof(buf) - len, "%-*s", col_width, list[(offset)]);
         len += temp_len;
       }
     }
     temp_len = snprintf(buf+len, sizeof(buf) - len, "\r\n");
     len += temp_len;
   }

   if (len >= sizeof(buf))
     snprintf((buf + MAX_STRING_LENGTH) - 22, 22, "\r\n*** OVERFLOW ***\r\n");

   /* Send the list to the player */
   page_string(ch->desc, buf, TRUE);
}

Here's sample output:

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

More
5 years 8 months ago #7439 by thomas
Replied by thomas on topic do_commands
Does adding this work?
   char buf[MAX_STRING_LENGTH];
  
+    *buf='\0';
   /* Work out the longest list item */

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

  • Fizban
  • Topic Author
  • Offline
  • Administrator
  • Administrator
More
5 years 8 months ago #7440 by Fizban
Replied by Fizban on topic do_commands
That does fix the output, but isn't that just fixing the symptom rather than the actual cause?

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

More
5 years 8 months ago #7441 by WhiskyTest
Replied by WhiskyTest on topic do_commands
That fixes the problem for me

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

More
5 years 8 months ago #7442 by thomas
Replied by thomas on topic do_commands

Fizban wrote: That does fix the output, but isn't that just fixing the symptom rather than the actual cause?

No. The cause is that buf is allocated on calling the function. But while the memory is made ready to use on the stack, it isn't cleared. So, if you don't write anything to it, you get what's in it.

The correct solution is to add a NULL as the first byte before starting to treat it like a (null-terminated) string. Which this does.
The following user(s) said Thank You: WhiskyTest

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

More
5 years 8 months ago - 5 years 8 months ago #7443 by JTP
Replied by JTP on topic do_commands
You type wizhelp playername ?

Mine Seem to look ok
Last edit: 5 years 8 months ago by JTP.

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

  • Fizban
  • Topic Author
  • Offline
  • Administrator
  • Administrator
More
5 years 8 months ago - 5 years 8 months ago #7444 by Fizban
Replied by Fizban on topic do_commands
It only looks okay if that player is an immortal, if they're not it sends garbage.
Last edit: 5 years 8 months ago by Fizban.

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

More
5 years 8 months ago #7445 by JTP
Replied by JTP on topic do_commands
This is wizh on an immortal, so appear to once have worked ?
Attachments:

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

More
5 years 8 months ago #7446 by JTP
Replied by JTP on topic do_commands
If i try to type: wizh mortalplayername.

It just returns, no output. Mortals should not have Any wiz commands

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

More
5 years 8 months ago #7447 by Sascha
Replied by Sascha on topic do_commands
I tried it on mine. I had my tester do nothing, and I typed 'wizhelp (charactername)' and there was no return. Then I had my tester do a social, and typed 'wizhelp (charactername)' again. This is the output:

i1 510H 110M 92V >
wizhelp vivtest
￘ツヘᄄ1
i1 510H 110M 92V >


Thanks for the catch, I'll be making the change this afternoon.

Will you stand against the coming Storm? After the Breaking: STORMRIDERS MUD - atbmud.dune.net port 4000

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

More
5 years 8 months ago #7448 by JTP
Replied by JTP on topic do_commands
So its a bug on latest tba version ?

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

More
5 years 8 months ago #7449 by JTP
Replied by JTP on topic do_commands
Ah ok now it did to on mine, just had to try a few times

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

More
5 years 8 months ago #7466 by JTP
Replied by JTP on topic do_commands
Anyone who found a fix for this ?

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

  • Fizban
  • Topic Author
  • Offline
  • Administrator
  • Administrator
More
5 years 8 months ago #7467 by Fizban
Replied by Fizban on topic do_commands
Welcor posted a fix earlier in the thread. Though in stock wizhelp has since been removed from do_commands completely and replaced with a do_wizhelp command that sorts commands by their level.

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

More
5 years 8 months ago #7468 by JTP
Replied by JTP on topic do_commands
On my mud doing wizhelp testchar, it return with no output.

Until i have typed wizhelp myownname...and Then If i again type wizhelp testchar, Then it shows my wiz commands ?

Where when i try on tbamud, wizhelp testchar, it from the first time shows wiz commands, but its a level 1 i tried on...but at the very end of the wizcommands it Then writes: peacThe Propagandist

Now where did that Come from.

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

Time to create page: 0.181 seconds