📄 session.cc
字号:
// Sesssion.cc// This defines a Session structure which communicates with a MUD#include <ctype.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#include <sys/time.h>#include <sys/types.h>#include <arpa/telnet.h>#include "mcl.h"#include "cui.h"#include "Session.h"#include "Interpreter.h"#include "Action.h"#include "Alias.h"#include "Curses.h"#include "Chat.h"const int connectTimeout = 30;// Network windowclass NetworkStateWindow : public Window { public: NetworkStateWindow (Session& _ses) : Window(screen, 19,1, None, -18, 1), ses(_ses) {} private: virtual void redraw(); virtual bool keypress(int key); Session& ses;};enum show_t {show_clock, show_clock_sec, show_timer, show_timer_sec, max_show_t };int timer_show [8][max_show_t] = { {1,1,1,1}, {1,0,1,1}, {1,0,1,0}, {1,1,0,0}, {1,0,0,0}, {0,0,1,1}, {0,0,1,0}, {-1,-1,-1,-1}};// Convert to X, xK, xM, xGconst char* csBytes(int n) { int letter = ' '; double f = n; if (f > 1024) { f /= 1024; letter = 'k'; } if (f > 1024) { f /= 1024; letter = 'm'; } if (letter == ' ' ) return Sprintf("%.0f", f); else return Sprintf("%.1f%c", f, letter);}class StatWindow : public Window {public: StatWindow(Session &_ses) : Window(screen, 15, 1, None, -15, 3), ses(_ses), last_bytes_written(-1), last_bytes_read(-1) { } virtual void idle() { if (last_bytes_written != ses.stats.bytes_written || last_bytes_read != ses.stats.bytes_read) { force_update(); } } virtual void redraw() { set_color(config->getOption(opt_statcolor)); clear(); gotoxy(0,0); printf("%7s/%7s", csBytes(ses.stats.bytes_read), csBytes(ses.stats.bytes_written)); last_bytes_written = ses.stats.bytes_written; last_bytes_read = ses.stats.bytes_read; dirty = false; } private: Session& ses; int last_bytes_written, last_bytes_read;};class TimerWindow : public Window { public: TimerWindow(Session &_ses) :Window (screen, 17, 1, None, -17, 2 ), ses(_ses), state(config->getOption(opt_timerstate)) {} private: Session& ses; virtual void redraw(); virtual void idle(); virtual bool keypress(int key); time_t last_update; int state, last_state;};void TimerWindow::idle() { if (last_update != current_time) force_update();}void TimerWindow::redraw () { last_state = state; gotoxy (0, 0); set_color (config->getOption (opt_timercolor)); // Adjust dimensions based on what we have to show height = 1; width = 0; if (timer_show[state][show_clock]) width += 5; if (timer_show[state][show_clock_sec]) width += 3; if (timer_show[state][show_timer]) width += 6; if (timer_show[state][show_timer_sec]) width += 3; if (timer_show[state][show_clock] && timer_show[state][show_timer]) width++; resize(width, height); move(parent->width - width, parent_y); clear (); last_update = current_time; if (timer_show[state][show_clock]) { struct tm *tm = localtime (¤t_time); printf ("%02d:%02d", tm->tm_hour, tm->tm_min); if (timer_show[state][show_clock_sec]) printf (":%02d", tm->tm_sec); } if (timer_show[state][show_clock] && timer_show[state][show_timer]) print (" "); if (timer_show[state][show_timer]) { int difference = int (difftime (current_time, ses.stats.dial_time)); printf ("%03d:", difference / (60 * 60)); difference -= (difference / (60 * 60)) * 60 * 60; printf ("%02d", difference / 60); if (timer_show[state][show_timer_sec]) printf (":%02d", difference % 60); } dirty = false;}bool TimerWindow::keypress(int key) { if (key == key_ctrl_t) { dirty = true; // Die if we reach the end of the table if (timer_show[++state][show_clock] < 0) { ses.timer = NULL; die(); } return true; } else return false;}void NetworkStateWindow::redraw () { int tx_queue, rx_queue; int timer, retrans; set_color(config->getOption(opt_statcolor)); clear (); gotoxy(0,0); if (mudcompress_compressing(ses.mcinfo)) printf("C "); else printf(" "); if (ses.state == disconnected) printf ("Offline"); // Hmm, this cannot really happen else if (ses.get_connection_stats (tx_queue, rx_queue, timer, retrans)) printf ("%4d %2d %5.1f/%2d", tx_queue, rx_queue, timer/100.0, retrans); dirty = false;}bool NetworkStateWindow::keypress(int key) { if (key == key_alt_s) { ses.statWindow->die(); ses.statWindow = NULL; ses.nsw = NULL; die(); return true; } else return false;}Session::Session(MUD& _mud, Window *_window, int _fd) : Socket(_fd), state(disconnected),mud(_mud), window(_window), pos(0),nsw(NULL), timer(NULL), statWindow(NULL), last_nsw_update(0){ input_buffer[0] = NUL; prompt[0] = NUL; memset(&stats,0,sizeof(stats)); if (config->getOption(opt_autostatwin)) show_nsw(); if (config->getOption(opt_autotimerwin)) show_timer(); mcinfo = mudcompress_new(); if (!mud.loaded) { mud.loaded = true; embed_interp->load_file(mud.name, true); } embed_interp->set("mud", mud.name); embed_interp->run_quietly("sys/connect", "", NULL); if (_fd != -1) { stats.dial_time = current_time; establishConnection(true); }}Session::~Session() { close(); if (nsw) nsw->die(); if (timer) timer->die(); if (statWindow) statWindow->die(); unsigned long comp, uncomp; mudcompress_stats(mcinfo, &comp, &uncomp); globalStats.comp_read += comp; globalStats.uncomp_read += uncomp; mudcompress_delete(mcinfo); set_title("mcl - unconnected");}// Write to whatever we are connected to// Also log, if logging is active?void Session::print (const char *s) { if (window) window->print(s);}// Try to connect to mudbool Session::open() { int res = connect(mud.getHostname(), mud.getPort(), true); if (res != errNoError && res != EINPROGRESS) { status->setf ("%s - error ocurred: %s", mud.getFullName(), getErrorText()); return false; } status->setf ("Connecting to %s", mud.getFullName()); state = connecting; stats.dial_time = current_time; set_title(Sprintf("mcl - connecting to %s", mud.getFullName())); return true;}// Disconnect from mudbool Session::close() { if (state > disconnected) { // Closing a closed session has no effect state = disconnected; embed_interp->run_quietly("sys/loselink", "", NULL); } embed_interp->set("mud", ""); return true;}void Session::writeMUD(const char *s) { writeLine(s); globalStats.bytes_written += strlen(s); stats.bytes_written += strlen(s);}// Do various time updatesvoid Session::idle() { if (state == connecting) { int time_left = stats.dial_time - current_time + connectTimeout; if (time_left <= 0) { close(); status->setf ("Connection to %s timed out", mud.getFullName()); } else { static char filled_string[64]; static char empty_string[64]; char buf[256]; if (!filled_string[0]) { for (unsigned int i = 0; i < sizeof(filled_string)-1; i++) { filled_string[i] = special_chars[sc_filled_box]; empty_string[i] = special_chars[sc_half_filled_box]; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -