#ifndef MSI_H #define MSI_H #include "config.h" #include <sys/types.h> #include <netinet/in.h> #include <time.h> #ifndef NOCOMPRESS #include <zlib.h> #endif #include "ident.h" #include "charset.h" #include "base.h" #include "colour.h" #include "commandhandler.h" class Socket; //! MSI: the Mud's telnet Stack. namespace msi { enum Thingy { tNone = 0, tNormal = 1, tMono = 2, tWebmake = 17, }; //! a telnet stack/connection class player { private: void blank(); #define SMALL_BUFSIZE 500 #ifndef NOCOMPRESS z_stream *deflate; Bytef small_outbuf[SMALL_BUFSIZE]; #endif int esc; string escstr; int secure; // Did we get an MXP secure mode escape sequence? void datah(unsigned char data, commandhandler *); void tstack(unsigned char data, commandhandler *); void handle_naws(commandhandler *, const string &); void handle_ttype(commandhandler *, const string &); string outbuffer; public: //! The socket associated with this Socket *socket; //! The buffer of text recieved so far on this socket. string buffer; int trunc; //! The cursor position within the buffer. int cursor; //! What socket is this object from? Thingy thingy_from; //! Whether this connection has agreed to be sent IAC EOR at the end of every prompt. int do_eor; //! Whether this connection is being sent MXP. int mxp; int secure_locked; // Is MXP secure mode locked? //! The auto-detected new line character for this connection. char newlinechar; //! The number of rows on this connection (per NAWS) int row; //! The number of columns on this connection (per NAWS) int col; //! 1 to indicate this isn't a telnet connection, but a webmake connection or some other internet protocol. int rawmode; //! The time the last IAC NOP (keepalive) packet was sent. time_t last_keepalive; //! The terminal type as identifed by TTYPE. string term; //! Whether the remote end is echoing at the moment or not. int last_noecho; //! The state the remote ends colour parser should be in. colstate_t colstate; #ifndef NOCOMPRESS //! Whether the other end has agreed to compression (MCCP) int will_compress; //! Whether compression is actually in effect. int compress; #endif //! Telnet net subnegiation in progress int se_mode; //! Telnet state int mode; //! Telnet subnegotiation buffer string se_str; //! Whether other end has agreed to telnet multiplexing. int mplex; //! The titlebar the other end is displaying string titlebar; //! The returned version of MXP string mxp_version; #ifndef NOCOMPRESS //! the number of uncompressed bytes we've sent long long rawbytes; //! the number of bytes we've sent (before compresssion) long long uncbytes; //! the number of bytes we've sent (after compression) long long combytes; #endif //! whether we are providing a line editor at our end int lineeditor; //! is it ok to send stuff to this socket? int nosend; //! do the initial telnet requests void ask_things(); #ifndef NOCOMPRESS //! turn compression on void compress_on(); //! turn compression off void compress_off(); #endif //! eor void eor(); //! echo void noecho(bool); //! create a new (empty) connection player(); public: //! create a connection and latch onto the given fd player(int fd); ~player(); //! format the string taking into account given colour preferences, and send it to the player void write(const char *, const colourinfo_t &); //! send the raw bytes given void rawsend(const string &); //! send the raw bytes given void rawsend(const char *data, size_t s); //! read data, and call methods on the commandhandler as appropriate int read(commandhandler *); string get_ip() const; string get_hostname() const; int get_port() const; //! send an IAC NOP packet if applicable void keepalive(); //! choose which mplex subwindow to address void mplex_choose(int); //! show an mplex subwindow void mplex_show(int); //! hide an mplex subwindow void mplex_hide(int); //! set the size of an mplex subwindow void mplex_setsize(int, int, int); //! accept and create a connection static player *accept(fd_set *fdset); //! serialise the telnet state and return it string serialise() const; //! deserialise the telnet state void deserialise(const string &s); //! actually flush void flush(); }; //! set base port /port/ void set_port(int port); //! open up all the ports, with base port port void init(int port); //! open ports void init(); //! close all the ports. void done(); //! return the current port int port(); } class PersonState; string serialise_personstate(PersonState *ps); void deserialise_personstate(PersonState *ps, string); #endif