Welcome to the Builder Academy

Question Snippet Help: Hemote

More
16 Apr 2018 11:52 #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:
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
16 Apr 2018 13:39 #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!
Code:
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?
Code:
/* 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.

More
16 Apr 2018 14:25 #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
16 Apr 2018 14:45 - 16 Apr 2018 14:46 #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?
Code:
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: 16 Apr 2018 14:46 by lacrc.
The following user(s) said Thank You: Chime

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

More
16 Apr 2018 15:07 #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
16 Apr 2018 15:21 - 16 Apr 2018 15:22 #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)
Code:
/* 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: 16 Apr 2018 15:22 by lacrc.
The following user(s) said Thank You: Chime

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

Time to create page: 0.632 seconds