muds_player_init(player) {
libtelnet_init(&player->telnet);
libtelnet_send_negotiate(&player->telnet, WILL, EOR, player);
…
}
muds_flush_code(player) {
libtelnet_send_data(&player->telnet, player->prompt, strlen(player->prompt), player);
if (player->flags.use_eor)
libtelnet_send_command(&player->telnet, EOR, player);
flush_sock();
}
muds_read_code(player) {
buffer[size];
length = read_socket(buffer, size, player->descriptor);
libtelnet_push_buffer(&player->telnet, buffer, length, player);
}
libtelnet_negotiate_cb(telnet, cmd, opt, user_data) {
player = (player*)user_data;
if (opt == EOR) {
if (cmd == DO)
player->flags.use_eor = 1;
else if (cmd == DONT)
player->flags.use_eor = 0;
}
}
libtelnet_input_cb(telnet, byte, user_data) {
player = (player*)user_data;
append_to_line_buffer(player, byte);
process_buffer_if_has_line();
}
libtelnet_output_cb(telnet, buffer, size, user_data) {
player = (player*)user_data;
write_to_descriptor(player, buffer, size);
}
SERVER IAC 251 25
SERVER IAC 251 93
SERVER IAC 253 39
SERVER IAC 253 24
SERVER IAC 253 31
SERVER INPUT: <1B>
SERVER IAC 251 25
SERVER IAC 251 93
SERVER IAC 253 39
SERVER IAC 253 24
SERVER IAC 253 31
SERVER INPUT: <1B>[2J<1B>[H<0D><0A>
—-===[ Source MUD V0.26.20081030 ]===—-<0D><0A>
<0D><0A>
Source MUD Copyright (C) 2000-2005 Sean Middleditch<0D><0A>
Visit http://www.sourcemud.org for more details.<0D><0A>
<1B>[36mBuild<1B>[0m - V0.26.20081030, Mar 5 2009 21:32:25<0D><0A>
<1B>[36mUptime<1B>[0m - 0 days, 0 hours, 1 minute, 32 seconds<0D><0A>
<1B>[36mHost<1B>[0m - localhost.localdomain<0D><0A>
<1B>[36mPlayers<1B>[0m - 0<0D><0A>
<0D><0A>
Enter your account name and password to login. To create a new <0D><0A>
account, simply type <1B>[0;33mnew<1B>[0m.<0D><0A>
<0D><0A>
Enter thy name:
CLIENT IAC 254 25
CLIENT IAC 254 93
CLIENT IAC 251 39
CLIENT IAC 251 24
CLIENT IAC 251 31
CLIENT SUBREQ 31: <00>P<00><18>
SERVER SUBREQ 39: <01><00>SYSTEMTYPE
SERVER SUBREQ 24: <01>
CLIENT SUBREQ 39: <00><00>SYSTEMTYPE
CLIENT SUBREQ 24: <00>XTERM
SERVER INPUT: <1B>]2;Source MUD<07>
CLIENT INPUT: quit<0D><0A>
[/code]
Oh, do note that you will currently need to disable MCCP2 if both the server and client support it: telnet-proxy will happily forward the negotiation/subrequests for MCCP2 through and then get stuck looking at a gzip stream it can't understand. libtelnet itself is not actually compatible with MCCP2 at the moment, as handling that either requires byte-at-a-time API or giving libtelnet the ability to decode the gzip stream. That is of course on the todo list. :)
CLIENT IAC WILL 31 (NAWS)
CLIENT SUB 31 (NAWS): <00>@<00><14>
CLIENT IAC DO 86 (COMPRESS2)
SERVER IAC WILL 25 (EOR)
SERVER SUB 93 (ZMP): zmp.ident<00>Source MUD<00>0.26.20081030<00>Powerful C++ MUD server software<00>
SERVER SUB 93 (ZMP): zmp.check<00>net.sourcemud.<00>
SERVER SUB 93 (ZMP): zmp.check<00>color.define<00>
SERVER SUB 24 (TTYPE): <01>
SERVER SUB 86 (COMPRESS2)
CLIENT COMPRESSION ON
SERVER COMPRESSION ON
CLIENT DATA: <FF> <– why are you there? I do not know and it makes Sean a sad boy.
CLIENT SUB 93 (ZMP): zmp.ident<00>gnome-mud<00>0.11.2<00>A mud client written for the GNOME environment.<00>
CLIENT SUB 93 (ZMP): zmp.no-support<00>net.sourcemud.<00>
CLIENT SUB 93 (ZMP): zmp.no-support<00>color.define<00>
CLIENT SUB 24 (TTYPE): <00>gnome-mud
It deals only with the protocol parsing bits of TELNET. It doesn't automatically handle negotiation or any other features. Those remain the application's job.
The code can be found here: http://github.com/elanthis/libtelnet/tre...
Note that the code right now won't even compile, but it's a preview of where I'm going with the API and general implementation. Some half-finished docs are available too. I'm going to be splicing it into tbaMUD once I have the basics nailed down, which will include a pair of small test programs to make sure it's doing everything right. Aside from a few typos I've already spotted, the only major change I can think of left is to make sure the subrequest buffering is correct and efficient. It also shouldn't allocate a buffer at all if the subrequest is "empty" like it is for MCCP2 (no data after the request type byte), as only a small handful of MUD-related TELNET features even need a buffer. ZMP, MSSP, and ENVIRON are all that come to mind.
Any feedback on the general API (keep in mind its purpose as a block box "easy to splice in" code) or implementation would be awesome.