Snippet Help: Hemote

  • Chime
  • Chime's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
3 years 4 weeks ago #7926 by Chime
Snippet Help: Hemote was created by Chime
This the pemote snippet on www.circlemud.org/, with just some minor little edits to get it to compile (the usual stuff!).

As of now it's cleanly compiling, but this happens when I test the command:

hemote Maker performs a hidden emote to Maker. | performs a public emote to the room.
Chime pera hidde hidden emote to maker.


Totally mangled. The recipient sees the same mangled bit.

I've done some tinkering to see if I could puzzle out what the trouble is, but with no luck. If someone else might be willing to give it a peek, I'd be grateful.

The code:
int parse_hemote(char *argument, char *vict_arg, char *room_arg);

ACMD(do_hemote)
{
  struct char_data *vict;
  char buf[MAX_STRING_LENGTH];
  char buf1[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  
  // Check for ch in character
  if (GET_LEVEL(ch) < LVL_GOD) {
    send_to_char(ch,"Hemotes cannot be done with Staff.\r\n");
    return;
  }

  skip_spaces(&argument);

  if (!*argument) {
    send_to_char(ch,"Usage: hemote <target> <private emote> | <public emote>\r\n");
    return;
  }
  
  half_chop(argument, buf1, argument);

  if (!(vict = get_char_vis(ch, buf1, NULL, FIND_CHAR_ROOM))) {
    send_to_char(ch,"There is no one here by that name.");
    return;
  }

  if (!(parse_hemote(argument, buf1, buf2))) {
    send_to_char(ch,"Usage: hemote <victim> <to-vict message> | <to-room message>\r\n");
    return;
  } else {
    sprintf(buf, "$n %s", buf1);
    act(buf, FALSE, ch, 0, vict, TO_VICT); // Send out the to_vict message
    act(buf, FALSE, ch, 0, vict, TO_CHAR); // Send the to_vict also to char
    sprintf(buf, "$n %s", buf2);
    act(buf, FALSE, ch, 0, vict, TO_NOTVICT); // Send out the to_room message
  }
}

/* from one_argument, pipe (|) delimited text */
int parse_hemote(char *argument, char *vict_arg, char *room_arg)
{
  char *begin_vict = vict_arg;
  char *begin_room = room_arg;
  char *tester = argument;
  int found = 0;

  // Check to make sure this is really pipe delimited text
  for ( ; *tester; tester++) {
    if (*tester == '|')
      found = 1;
  }

  if (!found) return 0;

  // get the to_vict argument
	do {
		skip_spaces(&argument);

    if (!*argument) return 0;

		vict_arg = begin_vict;

			while (*argument && *argument != '|') {
				*(vict_arg++) = *argument;
				argument++;
			}
			argument++;

		*vict_arg = '\0';
	} while (fill_word(begin_vict));

  /* skip that pipe */
  if (*argument == '|') argument++;  //which it *should* at this point

  /* get the to_room argument */
	do {
		skip_spaces(&argument);

    if (!*argument) return 0;

		room_arg = begin_room;

			while (*argument) {
				*(room_arg++) = *argument;
				argument++;
			}
			argument++;

		*room_arg = '\0';
	} while (fill_word(begin_room));

  return 1;
}

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

More
3 years 4 weeks ago #7931 by lacrc
Replied by lacrc on topic Snippet Help: Hemote
Hmm that's odd, I just put the same code you provided in latest version of TBA stock and it worked!
hemote peace performs a hidden emote to Peacekeeper. | performs a public emote to the room.
Ashver performs a hidden emote to Peacekeeper. 

I used it on a mob tho, since I don't have any friends :'( (added drama)

Anyway, I think you might having an issue when the strings are being copied, I don't fully understand why that is happening but it might be because of an older version of the fill_word() function maybe? You could try find out why and debug with with GDB or by adding log() calls to each word being copied.

From what I can tell (and from the comment) the snippet based itself on the one_arg() implementation to copy word by word of the emote, can you check if this other implementation works?
/* Splits pipe (|) delimited text into two strings to be send to chars */
int parse_hemote(char *argument, char *vict_arg, char *room_arg)
{
  char *tester = argument;
  int found = 0;

  // Check to make sure this is really pipe delimited text
  for ( ; *tester; tester++) {
    if (*tester == '|')
      found = 1;
  }

  if (!found) return 0;

  skip_spaces(&argument);

  /* copying vict_arg */
  while (*argument && *argument != '|') {
    *(vict_arg++) = *argument;
    argument++;
  }
  *vict_arg = '\0'; /* terminating is healthy! */

  /* skip that pipe */
  if (*argument == '|') argument++;  //which it *should* at this point

  /* copying room_arg */
  while (*argument) {
    *(room_arg++) = *argument;
    argument++;
  }
  *room_arg = '\0';

  return 1;
}
It is kinda simpler and doesn't rely on fill_word(). I tested it a bit (only with mobs :/ ) and it seemed to work fine.
The following user(s) said Thank You: Chime

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

  • Chime
  • Chime's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
3 years 4 weeks ago #7933 by Chime
Replied by Chime on topic Snippet Help: Hemote
This is absolutely bizarre!

I went to a random mobile to test, and it worked with the original parse_hemote:

hemote merchant does a private sort of emote. | does a public sort of emote.
Chime does a private sort of emote.


I copied in your updated function, and it worked with the same mobile:

hemote merchant does a private sort of emote. | does a public sort of emote.
Chime does a private sort of emote.


However... I tried it on another random mob, and it mangled it with both the old and new parse_hemote function:

Old:
hemote postal does a private sort of emote. | does a public sort of emote.
Chime doivate sivate sort of emote.

New:
hemote postal does a private sort of emote. | does a public sort of emote.
Chime doivate sivate sort of emote.


It mangles it with my tester player (Maker) with both the old and new function, and it seems completely random which mobile it'll work on and which it won't...

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

More
3 years 4 weeks ago - 3 years 4 weeks ago #7934 by lacrc
Replied by lacrc on topic Snippet Help: Hemote
I tested in more mobs on my local server and it seems to be working fine :/
On those cases I add logs everywhere to try and see where the mangling is occurring. Can you try that?
ACMD(do_hemote)
{
  struct char_data *vict;
  char buf[MAX_STRING_LENGTH];
  char buf1[MAX_STRING_LENGTH];
  char buf2[MAX_STRING_LENGTH];
  
  // Check for ch in character
  if (GET_LEVEL(ch) < LVL_GOD) {
    send_to_char(ch,"Hemotes cannot be done with Staff.\r\n");
    return;
  }

  skip_spaces(&argument);

  if (!*argument) {
    send_to_char(ch,"Usage: hemote <target> <private emote> | <public emote>\r\n");
    return;
  }
  
  half_chop(argument, buf1, argument);
  log("HALFCHOP: %s", argument); /* <--- added log here */

  if (!(vict = get_char_vis(ch, buf1, NULL, FIND_CHAR_ROOM))) {
    send_to_char(ch,"There is no one here by that name.");
    return;
  }

  if (!(parse_hemote(argument, buf1, buf2))) {
    send_to_char(ch,"Usage: hemote <victim> <to-vict message> | <to-room message>\r\n");
    return;
  } else {
    sprintf(buf, "$n %s", buf1);
    log("TOVICT: %s", buf); /* <--- added log here */
    act(buf, FALSE, ch, 0, vict, TO_VICT); // Send out the to_vict message
    act(buf, FALSE, ch, 0, vict, TO_CHAR); // Send the to_vict also to char
    sprintf(buf, "$n %s", buf2);
    log("TO_NOTVICT: %s", buf); /* <--- added log here */
    act(buf, FALSE, ch, 0, vict, TO_NOTVICT); // Send out the to_room message
  }
}
I'm guessing it's either the half_chop() or the sprintf()s that are mangling the text. Add more logs if you have more suspicions lol
Last edit: 3 years 4 weeks ago by lacrc.
The following user(s) said Thank You: Chime

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

  • Chime
  • Chime's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
3 years 4 weeks ago #7935 by Chime
Replied by Chime on topic Snippet Help: Hemote
I noticed something interesting while testing with GDB. Using the mob's full keyword works. Using an abbreviated version mangles the output:

hemote albatross does a private sort of emote. | does a public sort of emote.
Chime does a private sort of emote.

hemote alb does a private sort of emote. | does a public sort of emote.
Chime does ivate ste sort of emote.


Anyway! With logging:

Apr 16 08:09:06 ▒▒▒ :: HALFCHOP: does a private sort of emote. | does a public sort of emote.
Apr 16 08:09:06 :: TOVICT: $n does a private sort of emote.
Apr 16 08:09:06 :: TO_NOTVICT: $n does a public sort of emote.
Apr 16 08:09:10 :: HALFCHOP: does ivate ste sort of emote. | does a public sort of emote.
Apr 16 08:09:10 :: TOVICT: $n does ivate ste sort of emote.
Apr 16 08:09:10 :: TO_NOTVICT: $n does a public sort of emote.

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

More
3 years 4 weeks ago - 3 years 4 weeks ago #7936 by lacrc
Replied by lacrc on topic Snippet Help: Hemote
It might be better for someone else to pitch in about this but, I had an issue with half_chop() in a (very) old codebase, not sure what cause it, and it only happened on a specific comm channel, can you check if it works for you? (It's in interpreter.c)
/* Return first space-delimited token in arg1; remainder of string in arg2.
 * NOTE: Requires sizeof(arg2) >= sizeof(string) */
void half_chop(char *string, char *arg1, char *arg2) {
    char *temp;

    temp = any_one_arg(string, arg1);
    skip_spaces(&temp);
    //strcpy(arg2, temp);	/* strcpy: OK (documentation) */
    //for some reason strcpy messed up the arg2 string
    int i;
    for (i = 0; i < strlen(temp); i++) {
        arg2[i] = temp[i];
    }
    arg2[i] = '\0';
}
I needed a quick fix, so I replaced the strcpy() with a manual copy of the string, and it worked lol.
Last edit: 3 years 4 weeks ago by lacrc.
The following user(s) said Thank You: Chime

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

  • Chime
  • Chime's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
3 years 4 weeks ago #7937 by Chime
Replied by Chime on topic Snippet Help: Hemote
I don't know why or how, but that completely resolved the mangling. Tested with mobiles using full keyword, abbreviated keyword, and a player tester. All work fine now. I'm baffled, but not complaining one bit!

Thanks a ton Iacrc, truly much appreciated.
The following user(s) said Thank You: lacrc

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

More
3 years 4 weeks ago #7938 by lacrc
Replied by lacrc on topic Snippet Help: Hemote
Glad to help and to know it worked!
But now I'm even more curious as to why that worked for us hahaha, or why strcpy() mangled the strings like that, I remember that, in my case, it only occurred with strings that were smaller then a specific length like 20 ou 30 chars.
Maybe someone can clarify for us later! :)

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

  • Chime
  • Chime's Avatar Topic Author
  • Offline
  • Senior Member
  • Senior Member
More
3 years 4 weeks ago #7940 by Chime
Replied by Chime on topic Snippet Help: Hemote
I know right? I'm so confused, lol. Content, but confused. Fingers crossed for a later explanation!

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

Time to create page: 0.117 seconds