At the risk of sounding crazy for chattering to myself, here is my working albeit not final solution. Things finally clicked when I found KaViR's explanation for MSDPTableSet in protocols.h, I can't believe I has missed it so often! I will probably alter the following code in the future.
Code:
/*
* Find all the exits in the room and display them and the VNUMS of the connecting
* rooms through the MSDP_ROOM_EXITS interface.
* Pre: a valid pointer to the MUD PC.
*/
const char *find_exits(struct char_data *ch)
{
int door, elen = 150; /* elen a bit larger than the number of chars needed for all exits and VNUMS. */
char *msdp_exits, *buf;
msdp_exits = calloc(DIR_COUNT * 2, sizeof(char*)); /* Must be free'd by msdp_update(). */
buf = calloc(DIR_COUNT * 2, sizeof(char*));
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;
sprintf(buf, "%c%s%c%d", (char)MSDP_VAR, dirs[door], (char)MSDP_VAL, GET_ROOM_VNUM(EXIT(ch, door)->to_room));
/* *BSD specific, not exactly the most portable. */
(void)strlcat(msdp_exits, buf, elen);
}
free(buf);
return (msdp_exits);
}
In msdp_update().
Code:
char buf[MAX_STRING_LENGTH], *buf2;
.
.
.
buf2 = find_exits(ch);
MSDPSetTable( d, eMSDP_ROOM_EXITS, buf2 );
.
.
.
MSDPUpdate( d );
}
free(buf2);
Again, pointers and comments welcome.
Addendum:
free in msdp_updates() is in the wrong spot. Causes undefined behavior when an uninitialized pointer is free'd. Might cause a crash on login if not some other point. Place free immediately after the MSDPSetTable or, better yet, use tba's STRFREE macro immediately after.
Addendum 2:
According to the MSDP spec, exit directions are supposed to be abbreviated. Changed dirs[door] to autoexits[door].
tintin.sourceforge.net/msdp/