d->intop += translate_telopts(d, bufin, nRead, d->inbuf + d->intop);
if (IS_SET(d->comm_flags, COMM_FLAG_REMOTEECHO))
{
for (nSkip = nCurr ; nSkip < d->intop ; nSkip++)
{
switch (d->inbuf[nSkip])
{
case 8:
case 127:
d->inbuf[nSkip] = '\b';
write(d->descriptor, "\b \b", 3);
break;
case '\n':
write(d->descriptor, "\n\r", 2);
break;
default:
write(d->descriptor, d->inbuf + nSkip, 1);
break;
}
}
}
A further extension to this problem is that if you use cyclic TTYPE on windows telnet, it ends up using the VTNT terminal type, which effectively causes the client to freeze completely, for reasons described here by Kaz.
Following donky's proposal, I therefore implemented the following:
Step 1: After the client connects, I wait 1 second to see if it initiates negotiation. If it does, I assume it's PuTTY.
Step 2: If the client didn't initiate negotiation, I send it "\033: If the client didn't initiate negotiation, I send it "\033[0c". If I get a response, I immediately follow up by sending "\033[0x". Windows telnet can be identified by the response to the second escape sequence.
[b]Step 3[/b]: If I didn't detect windows telnet after the 2nd second, I attempt to negotiate TTYPE. If the client either accepts or declines TTYPE, I negotiate all of the remaining protocols. If TTYPE is accepted, I perform a cyclic TTYPE query to look for extended colour support.
[b]Step 4[/b]: On the 3rd second, I display the welcome screen and allow the user to enter input.
This works fine for me*, however I've also had a couple of people ask if I could add it to my protocol snippet, and I'm wondering how that'll work in conjunction with MSSP.
MSSP crawlers connecting to my mud only ever seem to use the plain text version (I support both) - they don't like to wait. But my snippet doesn't support the plain text version (yet at least).
Because most muds switch off echo (with the "password" prompt) the moment you enter your name, it would be necessary to block/delay input for a few seconds until the negotiation was complete. However every crawler I've encountered seems to drop its connection almost instantly.
One possibility would be to have a separate state during negotiation which prevents you from logging on, but does allow other input. However that would also prevent clients from autoconnecting, as it would be necessary to parse the input rather than pause - and as I discovered first hand, players can get grumpy when their autoconnect stops working.
The only way around it that I can think of is to queue up the input [i]unless[/i] it's "MSSP-REQUEST". That would require some changes to the way input worked, and I'm not sure how easy it would be without a codebase-specific solution - something I really want to avoid for my snippet.
I suppose the other way would be to try and persuade the crawlers to wait a few seconds. But would they bother, if it was just a handful of muds using this approach? Probably not.
[i]* Although TinTin++ sometimes adds the escape code response to the input buffer instead of sending it to the mud - it appears to be related to the use of linewrap.[/i]