[ScryMUD] SVN Commit Info r890 - trunk/mud/grrmud/server
scrymud at wanfear.com
scrymud at wanfear.com
Sat Feb 24 17:21:13 PST 2007
Author: eroper
Date: 2007-02-24 17:21:12 -0800 (Sat, 24 Feb 2007)
New Revision: 890
Modified:
trunk/mud/grrmud/server/Makefile
trunk/mud/grrmud/server/command5.cc
trunk/mud/grrmud/server/const.cc
trunk/mud/grrmud/server/critter.cc
trunk/mud/grrmud/server/critter.h
trunk/mud/grrmud/server/grrmud.cc
trunk/mud/grrmud/server/hegemon_handler.cc
trunk/mud/grrmud/server/hegemon_handler.h
trunk/mud/grrmud/server/login.cc
trunk/mud/grrmud/server/parse.cc
trunk/mud/grrmud/server/protocol_handler.h
trunk/mud/grrmud/server/telnet_handler.cc
trunk/mud/grrmud/server/telnet_handler.h
Log:
We are now using HegemonHandler's and TelnetHandler's.
Modified: trunk/mud/grrmud/server/Makefile
===================================================================
--- trunk/mud/grrmud/server/Makefile 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/Makefile 2007-02-25 01:21:12 UTC (rev 890)
@@ -21,7 +21,7 @@
ez_skll.o social2.o cr_skll.o ar_skll.o pet_spll.o vehicle.o const.o \
script.o SkillSpell.o zone.o rm_parse.o rm_cmds.o obj_parse.o \
obj_cmds.o BuildInfo.o BugEntry.o MudStats.o clients.o ServerConfig.o \
-mapper.o regex.o
+mapper.o regex.o protocol_handler.o telnet_handler.o hegemon_handler.o
grrmud_TARG = grrmud
GEN_SPEC = gen_cmds.spec
Modified: trunk/mud/grrmud/server/command5.cc
===================================================================
--- trunk/mud/grrmud/server/command5.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/command5.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -48,6 +48,8 @@
#include "clients.h"
#include "vehicle.h"
#include "regex.h"
+#include "telnet_handler.h"
+#include "hegemon_handler.h"
int test(critter& pc) {
String buf;
@@ -2522,6 +2524,9 @@
Sprintf(buf, "[%i]%P10 RoomScript %P30[%i] %P42 BugCollection\n",
RoomScript::getInstanceCount(), BugCollection::getInstanceCount());
pc.show(buf);
+ Sprintf(buf, "[%i]%P10 TelnetHandler %P30[%i] %P42 HegemonHandler\n",
+ TelnetHandler::getInstanceCount(), HegemonHandler::getInstanceCount());
+ pc.show(buf);
Sprintf(buf, "\nSize (length) of:\n\tembattled_rooms: %i \t affected_doors: %i\n",
embattled_rooms.size(), affected_doors.size());
Modified: trunk/mud/grrmud/server/const.cc
===================================================================
--- trunk/mud/grrmud/server/const.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/const.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -616,9 +616,9 @@
//"\n\x9B\x4D\x31\x32\x68\nChoose a Password: ",
//"\n\x9B\x4D\x31\x32\x68\nEnter your password again for verification: ",
- "\nChoose a Password (Will be Echoed): ",
+ "\nChoose a Password (may be echoed): ",
"\nEnter your password again for verification: ",
- "(M)ale, (F)emale, or (N)euter: ",
+ "\n(M)ale, (F)emale, or (N)euter: ",
"\n\nSelection of Classes: \n\n"
" Your class may affect your stats and will have an influence on\n"
" the skills you are able to acquire.\n"
Modified: trunk/mud/grrmud/server/critter.cc
===================================================================
--- trunk/mud/grrmud/server/critter.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/critter.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -42,6 +42,8 @@
#include "battle.h"
#include <stdarg.h>
#include "clients.h"
+#include "telnet_handler.h"
+#include "hegemon_handler.h"
const char* PcPositionStrings[] = {"stand", "sit", "rest", "sleep", "meditate",
"stun", "dead", "prone"};
@@ -1338,6 +1340,7 @@
pc_data::pc_data() {
_cnt++;
+ p_handler = NULL;
post_msg = NULL;
snoop_by = NULL;
snooping = NULL;
@@ -1348,6 +1351,7 @@
pc_data::pc_data(const pc_data& source) {
_cnt++;
+ p_handler = NULL;
post_msg = NULL;
snoop_by = NULL;
snooping = NULL;
@@ -1358,6 +1362,7 @@
pc_data::~pc_data() {
_cnt--;
+
Clear();
}//destructor
@@ -1419,6 +1424,7 @@
last_login_time = 0; //in seconds, since 1970 etc...
total_time_online = 0; //in seconds
lines_on_page = 20;
+ columns_on_page = 80;
if (w_eye_obj) {
w_eye_obj->obj_proc->w_eye_owner = NULL;
w_eye_obj = NULL;
@@ -1461,6 +1467,7 @@
imm_data = new immort_data(*(source.imm_data));
mode = source.mode;
lines_on_page = source.lines_on_page;
+ columns_on_page = source.columns_on_page;
index = source.index;
hunger = source.hunger;
thirst = source.thirst;
@@ -3732,6 +3739,7 @@
pc = new pc_data;
}//if
pc->Read(this, ofile);
+
pc->file_format_version = format_version;
}//if
else { //its a mob
@@ -4292,13 +4300,6 @@
return;
}
- char go_ahead_str[] =
- {
- (char) IAC,
- (char) GA,
- (char) 0
- };
-
// for visible exits
Cell<door*> cll(getCurRoom()->doors);
door* dr_ptr;
@@ -4448,9 +4449,7 @@
targ.Append(tmp);
}
- if (! isUsingClient()) {
- targ.Append(go_ahead_str);
- }
+ targ.Append(pc->p_handler->end_of_record());
show(targ);
@@ -4591,11 +4590,31 @@
}//whichClient
bool critter::setClient(int which) {
- if (NUM_CLIENTS < which)
+
+ if (NUM_CLIENTS < which) {
return false;
- if(!pc->pc_data_flags.get(5))
+ }
+
+ if ( pc->client == which ) {
return false;
+ }
+
pc->client = which;
+
+ switch ( which ) {
+
+ case HEGEMON:
+ delete pc->p_handler;
+ pc->p_handler = new HegemonHandler(this);
+ break;
+
+ case NO_CLIENT:
+ delete pc->p_handler;
+ pc->p_handler = new TelnetHandler(this);
+ break;
+
+ };
+
return true;
}
Modified: trunk/mud/grrmud/server/critter.h
===================================================================
--- trunk/mud/grrmud/server/critter.h 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/critter.h 2007-02-25 01:21:12 UTC (rev 890)
@@ -40,6 +40,7 @@
#include "const.h"
#include "lang_strings.h"
#include "battle.h"
+#include "protocol_handler.h"
///******************** temp crit data *****************************///
@@ -552,6 +553,7 @@
static int _cnt;
public:
+ ProtocolHandler* p_handler;
String password;
String input;
String output;
@@ -581,6 +583,7 @@
short rent_year; //year of last rent
short rent_day; //day of last rent
short lines_on_page; //used to page output
+ short columns_on_page; //will be used to format output better
int age;
String host;
short link_condition; //1 CON_PLAYING, 2 CON_LINKDEAD, 3 CON_LOGGING_IN
Modified: trunk/mud/grrmud/server/grrmud.cc
===================================================================
--- trunk/mud/grrmud/server/grrmud.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/grrmud.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -79,6 +79,7 @@
#include <new>
#include "telnet.h"
+#include "telnet_handler.h"
#define MAX_HOSTNAME 256
@@ -1032,69 +1033,12 @@
(pc_ptr->MODE != MODE_LOGOFF_NEWBIE_PLEASE) &&
(pc_ptr->MODE != MODE_QUIT_ME_PLEASE)) {
- /* Yes I need a better place for this, it has to happen before
- * snooping and has to be able to put crap in the output buffer
- */
- {
- String tmp;
- int i;
- int imax;
- unsigned char telnet_cmd = '\0';
-
- // Process telnet protocol commands
-
- /* window size negotinations:
- * (client) IAC WILL NAWS
- * (server) IAC DO NAWS
- * (client) IAC SB NAWS WIDTH[1] WIDTH[0] HEIGHT[1] HEIGHT[0] IAC SE
- * < 16 bit value > < 16 bit value >
- * For now though, I'm going to be lazy ;)
- * (client) IAC WILL NAWS
- * (server) IAC DON'T NAWS
- */
-
- imax = pc_ptr->getInput()->Strlen();
- tmp.Clear();
- for(i=0;i<imax;i++) {
- if ( pc_ptr->getInput()->charAt(i) == (char)IAC ) {
- if ( i+1 < imax )
- telnet_cmd = pc_ptr->getInput()->charAt(++i);
-
- switch ( telnet_cmd ) {
- case WILL:
- if ( i+1 < imax ) {
- telnet_cmd = pc_ptr->getInput()->charAt(++i);
- switch ( telnet_cmd ) {
- /*
- case TELOPT_NAWS:
- pc_ptr->pc->output.append((char)IAC);
- pc_ptr->pc->output.append((char)DO);
- pc_ptr->pc->output.append((char)telnet_cmd);
- break;
- */
- default:
- pc_ptr->pc->output.append((char)IAC);
- pc_ptr->pc->output.append((char)DONT);
- pc_ptr->pc->output.append((char)telnet_cmd);
- }
- }
- break;
- }
- } //if telnet cmd
- else {
- tmp.append(pc_ptr->getInput()->charAt(i));
- }
- } //for
- pc_ptr->getInput()->Clear();
- pc_ptr->getInput()->append(tmp);
- } // telnet parser
-
len = pc_ptr->getInput()->Strlen();
if (len && ((pc_ptr->getInput()->charAt(len - 1) == '\n') ||
- pc_ptr->getInput()->Contains('\n')) || (len >= MAX_INPUT_LEN)) {
+ pc_ptr->getInput()->Contains('\n')) || (len >= MAX_INPUT_LEN)) {
if (mudlog.ofLevel(DBG)) {
mudlog << "processing input for: " << *(pc_ptr->getName())
- << ", cmd -:" << *(pc_ptr->getInput()) << ":- " << endl;
+ << ", cmd -:" << *(pc_ptr->getInput()) << ":- " << endl;
}
critter* snooper;
@@ -1102,7 +1046,7 @@
mudlog.log(TRC, "Within snoop if\n");
String buf2(100);
Sprintf(buf2, "SNOOP_IN: %S: %S\n",
- pc_ptr->getName(snooper->SEE_BIT), pc_ptr->getInput());
+ pc_ptr->getName(snooper->SEE_BIT), pc_ptr->getInput());
snooper->show(buf2);
}//if snoop
@@ -1123,10 +1067,10 @@
}//if
else {
pc_ptr->possessing->processInput(*(pc_ptr->getInput()),
- FALSE, TRUE);
+ FALSE, TRUE);
if (mudlog.ofLevel(DBG)) {
mudlog << "input after processInput: " << *(pc_ptr->getInput())
- << endl;
+ << endl;
}//if
//pc_ptr->setDoPrompt(TRUE);
}
@@ -1502,6 +1446,8 @@
newd->pc = new pc_data;
newd->CRITTER_TYPE = 0; //change default of MOB to PC
+ newd->pc->p_handler = new TelnetHandler(newd);
+
mudlog.log(TRC, "In createWithDescriptor\n");
if ((desc = new_connection(s)) < 0) {
@@ -1664,28 +1610,49 @@
#endif
+// This is temporarily here for now as we need to be able to handle binary
+// data for telnet option negotiations. String::Read() assumes that we only
+// ever deal in \n terminated printable strings.
+ssize_t netread(int fd, char* input_buf, size_t max_read) {
+ ssize_t read_bytes;
+ read_bytes = recv(fd, input_buf, max_read, 0);
+ if ( read_bytes < 0 ) {
+ if ( errno != EAGAIN ) {
+ return(-1);
+ } else {
+ return(0);
+ }
+ }
+ return(read_bytes);
+}
+ int critter::readInput() {
-int critter::readInput() {
- if (!pc)
- return -1;
+ if (!pc) {
+ return -1;
+ }
- errno = 0;
- int ret;
- ret = pc->input.Read(pc->descriptor, MAX_INPUT_LEN);
+ errno = 0;
+ int ret;
+ //ret = pc->input.Read(pc->descriptor, MAX_INPUT_LEN);
- if (mudlog.ofLevel(TRC)) {
- mudlog << "End of get_input, here it is:\n" << pc->input << ":- ret: " << ret << endl;
- }
-
- if (ret < 0) {
- mudlog << "Critter: " << getName() << " Read Error: " << strerror(errno) << endl;
- }
+ char input_buf[4096];
+ ssize_t read_bytes = netread(pc->descriptor, input_buf, 4096);
- return ret; //valid input added to input buffer, can go parse it now.
-}//get_input
+ if (mudlog.ofLevel(TRC)) {
+ mudlog << "End of get_input, here it is:\n" << pc->input << ":- ret: " << ret << endl;
+ }
+ if (read_bytes < 0) {
+ mudlog << "Critter: " << getName() << " Read Error: " << strerror(errno) << endl;
+ } else if ( read_bytes > 0 ) {
+ pc->p_handler->parse(input_buf, read_bytes);
+ }
+ return read_bytes; //valid input added to input buffer, can go parse it now.
+ }//get_input
+
+
void close_sockets(int mother) {
Cell<critter*> cell;
pc_list.head(cell);
@@ -1713,10 +1680,10 @@
if (mudlog.ofLevel(DBG)) {
mudlog << "In doLoseLink, critter name: " << *(getName())
- << " room: " << getCurRoomNum() << " addr: " << this
- << endl << flush;
+ << " room: " << getCurRoomNum() << " addr: " << this
+ << endl << flush;
mudlog << " link condition: " << pc->link_condition
- << endl;
+ << endl;
}
if (pc->link_condition != CON_PLAYING) {
@@ -1741,7 +1708,7 @@
if (mudlog.ofLevel(DBG)) {
mudlog << "doLogOffInactive, critter: " << *(getName())
- << " size of PETS: " << PETS.size() << endl;
+ << " size of PETS: " << PETS.size() << endl;
}
doUngroup(1, &NULL_STRING); //take em out of their group, if in it.
@@ -1751,7 +1718,7 @@
while ((pet_ptr = pet_cll.next())) {
if (mudlog.ofLevel(DBG)) {
mudlog << "PETS: Has a pet: " << *(pet_ptr->getName())
- << " ptr_address: " << pet_ptr << endl;
+ << " ptr_address: " << pet_ptr << endl;
}
}//while
@@ -1762,7 +1729,7 @@
while ((pet_ptr = pet_cll.next())) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Tmp_List: Has a pet: " << *(pet_ptr->getName())
- << " ptr_address: " << pet_ptr << endl;
+ << " ptr_address: " << pet_ptr << endl;
}
}//while
@@ -1774,7 +1741,7 @@
while ((pet_ptr = pet_cll.next())) {
if (mudlog.ofLevel(DBG)) {
mudlog << "Found a pet: " << *(pet_ptr->getName())
- << endl << flush;
+ << endl << flush;
}
pet_ptr->show("Your master has left the game.\n");
pet_ptr->doBecomeNonPet();
@@ -1783,7 +1750,7 @@
if (PETS.size() > 0) {
mudlog << "ERROR: PETS.size() > 0 in doLogOffInactive: "
- << PETS.size() << endl << flush;
+ << PETS.size() << endl << flush;
PETS.clear();
}
@@ -1812,21 +1779,21 @@
}
doShowList(this, Selectors::instance().CC_gets_info_allow,
- Selectors::instance().CC_none, pc_list,
- CS_PLAYER_OFF_LD_LIST_INFO,
- getName());
+ Selectors::instance().CC_none, pc_list,
+ CS_PLAYER_OFF_LD_LIST_INFO,
+ getName());
if (MASTER) {
doBecomeNonPet();
}
-
+
emote("has left the game.");
leave_room_effects(*(getCurRoom()), *this, FALSE);
breakEarthMeld();
doLeaveRoom();
-
+
recursive_init_unload(*this); //take eq out of circulation
return 1;
@@ -1844,12 +1811,16 @@
return -1;
}
+ // no need of a protocol handler when they're D/C'ed.
+ delete pc->p_handler;
+ pc->p_handler = NULL;
+
if (mudlog.ofLevel(DBG)) {
mudlog << "In doGoLinkDead, critter name: " << *(getName())
- << " room: " << getCurRoomNum() << " addr: " << this
- << endl << flush;
+ << " room: " << getCurRoomNum() << " addr: " << this
+ << endl << flush;
mudlog << " link condition: " << pc->link_condition
- << endl;
+ << endl;
}
if (SNOOPED_BY) {
@@ -1864,10 +1835,10 @@
}
doShowList(this, Selectors::instance().CC_gets_info_allow,
- Selectors::instance().CC_none, pc_list,
- CS_PLAYER_LOST_CON_INFO,
- getName());
-
+ Selectors::instance().CC_none, pc_list,
+ CS_PLAYER_LOST_CON_INFO,
+ getName());
+
if (MASTER) {
Sprintf(buf, "%S has lost link.\n", getName());
buf.Cap();
@@ -1880,12 +1851,12 @@
writeOutput();
if (close(pc->descriptor) < 0) {
mudlog << "ERROR: close_socket, close: " << strerror(errno)
- << endl;
+ << endl;
}//if
else {
sockets_connected--;
}
-
+
pc->descriptor = -1;
}//if
@@ -1905,12 +1876,15 @@
return -1;
}
+ // remove the protocol handler
+ delete pc->p_handler;
+
if (mudlog.ofLevel(DBG)) {
mudlog << "In doLogOffNewLogin, critter name: " << *(getName())
- << " room: " << getCurRoomNum() << " addr: " << this
- << endl << flush;
+ << " room: " << getCurRoomNum() << " addr: " << this
+ << endl << flush;
mudlog << " link condition: " << pc->link_condition
- << endl;
+ << endl;
}
if (pc->descriptor != -1) {
Modified: trunk/mud/grrmud/server/hegemon_handler.cc
===================================================================
--- trunk/mud/grrmud/server/hegemon_handler.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/hegemon_handler.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -24,3 +24,80 @@
#include "hegemon_handler.h"
int HegemonHandler::_cnt = 0;
+
+HegemonHandler::HegemonHandler(critter* c_ptr) {
+
+ _cnt++;
+ my_critter = c_ptr;
+ current_text_state = ST_NORM;
+
+}//HegemonHandler::HegemonHandler()
+
+bool HegemonHandler::parse(const char* input_buf, size_t len) {
+ size_t i = 0;
+ const char* p;
+ bool parsed_full_command = false;
+
+ while ( i < len ) {
+
+ p = input_buf+i;
+
+ switch ( current_text_state ) {
+ case ST_NORM:
+ switch ( *p ) {
+
+ case 0x08://backspace
+ if ( out_buf.size() > 0 ) {
+ out_buf.resize(out_buf.size()-1);
+ }
+ break;
+
+ case 0x0D://carriage return
+ //do nothing, we don't like \r's around here.
+ break;
+
+ case 0x0A://newline
+ out_buf += *p;
+ my_critter->pc->input += out_buf.c_str();
+ out_buf.clear();
+ parsed_full_command = true;
+ break;
+
+ case ';':
+ current_text_state = ST_SEMICOLON;
+ break;
+
+ default:
+ out_buf += *p;
+ break;
+ };
+ break;
+
+ case ST_SEMICOLON:
+ switch ( *p ) {
+
+ case ';':
+ out_buf += ';';
+ break;
+
+ case 0x08://backspace
+ if ( out_buf.size() > 0 ) {
+ out_buf.resize(out_buf.size()-1);
+ }
+ current_text_state = ST_NORM;
+ break;
+
+ default:
+ out_buf += '\n';
+ out_buf += *p;
+ break;
+
+ };
+ break;
+ };//switch(current_text_state)
+
+ i++;
+ }//while there's more input
+
+ return(parsed_full_command);
+}
Modified: trunk/mud/grrmud/server/hegemon_handler.h
===================================================================
--- trunk/mud/grrmud/server/hegemon_handler.h 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/hegemon_handler.h 2007-02-25 01:21:12 UTC (rev 890)
@@ -31,16 +31,22 @@
protected:
static int _cnt;
+ enum text_state { ST_NORM, ST_SEMICOLON };
+
+ text_state current_text_state;
+ std::string out_buf;
critter* my_critter;
public:
static int getInstanceCount() { return _cnt; }
- HegemonHandler(critter *c_ptr) : my_critter(c_ptr) { HegemonHandler::_cnt++; };
+ HegemonHandler(critter *c_ptr);
~HegemonHandler() { _cnt--; };
- void parse(const char* input_buf) { my_critter->pc->input += input_buf; }
+ void newCritter(critter* c_ptr) { my_critter = c_ptr; };
+
+ bool parse(const char* input_buf, size_t len);
void set_echo(bool on_off) { }
const char* end_of_record() const { return(""); }
};
Modified: trunk/mud/grrmud/server/login.cc
===================================================================
--- trunk/mud/grrmud/server/login.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/login.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -39,6 +39,7 @@
#include "const.h"
#include "Filters.h"
#include "clients.h"
+#include "telnet_handler.h"
extern List<critter*> new_pc_list;
@@ -64,6 +65,7 @@
pc->input = NULL_STRING; //null out input
show(get_page("./opening")); //opening page
show(login_prompts[0]);
+ show(pc->p_handler->end_of_record());
mudlog.log(TRC, "Done w/start_login.\n");
}//start_login
@@ -189,6 +191,7 @@
// log("All done w/case 0.\n");
break;
case 1: //password for new player
+
string = pc->input.Get_Command(eos, term_by_period);
if (string == "__HEGEMON__") {
@@ -231,6 +234,7 @@
if (!isUsingClient())
show(ANSI_ECHO_ON); //echo ON
string = pc->input.Get_Command(eos, term_by_period);
+ pc->p_handler->set_echo(false);//stop echoing for the client
if (pc->password == string) {
pc->password = crypt((const char*)(pc->password), "bg");
pc->index = 3; //go choose male/female/neuter
@@ -384,6 +388,8 @@
if (!isUsingClient())
show(ANSI_ECHO_ON); //echo ON
+
+ ProtocolHandler* tmp_p_handler = pc->p_handler;
int tmp_int = pc->descriptor;
int tmp_index = pc->index;
tmp_host = pc->host;
@@ -413,6 +419,7 @@
}//if
fileRead(rfile, TRUE);
+
break;
}
@@ -451,6 +458,7 @@
setClient(HEGEMON);
}
+ pc->p_handler = tmp_p_handler;
pc->descriptor = tmp_int;
pc->host = tmp_host;
pc->index = tmp_index;
@@ -497,7 +505,12 @@
old_ptr->pc->descriptor = pc->descriptor;
pc->descriptor = tmp_old_desc;
- /* set old player back in action */
+ // set old player back in action
+ // stick our current protocol handler into the old critter
+ // and let our protocol handler know that it has been moved.
+ old_ptr->pc->p_handler = pc->p_handler;
+ old_ptr->pc->p_handler->newCritter(old_ptr);
+
old_ptr->cur_stats[0] &= ~32; //make em visable again
old_ptr->pc->link_condition = CON_PLAYING;
old_ptr->pc->index = 0;
@@ -970,6 +983,10 @@
update_skills(pc); //sync them up, does not necessarly add new ones
pc.PC_FLAGS.turn_off(33); //make sure they aren't marked as afk
+ //make sure they echo for themselves
+
+ pc.pc->p_handler->set_echo(false);
+
pc.show(get_page("./motd")); //message of the day
pc.show("Welcome back!!\n\n");
Modified: trunk/mud/grrmud/server/parse.cc
===================================================================
--- trunk/mud/grrmud/server/parse.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/parse.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -271,6 +271,17 @@
//log("Do login finished...\n");
if (MODE != MODE_NORMAL) {
show(login_prompts[pc->index]);
+ // turn on server side echoing for password blanking when appropriate
+ switch ( pc->index ) {
+ case 1://password for new player
+ case 2://confirm new player password
+ case 5://password for existing player
+ pc->p_handler->set_echo(true);
+ break;
+
+ default:
+ break;
+ }
}//if
return 0;
}//if logging in
Modified: trunk/mud/grrmud/server/protocol_handler.h
===================================================================
--- trunk/mud/grrmud/server/protocol_handler.h 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/protocol_handler.h 2007-02-25 01:21:12 UTC (rev 890)
@@ -47,9 +47,12 @@
virtual ~ProtocolHandler() { };
+ // for reassociating ourself with a new critter.
+ virtual void newCritter(critter* c_ptr) = 0;
+
// do any necessary parsing, stick the resulting data (if any) in the pc's
// input buffer.
- virtual void parse(const char* input_buf) = 0;
+ virtual bool parse(const char* input_buf, size_t len) = 0;
// toggle server-side echoing of input
virtual void set_echo(bool on_off) = 0;
@@ -68,10 +71,12 @@
static int getInstanceCount() { return NullHandler::_cnt; }
- NullHandler(critter *c_ptr) : my_critter(c_ptr) { my_critter = c_ptr; NullHandler::_cnt++; };
+ NullHandler(critter* c_ptr) { my_critter = c_ptr; NullHandler::_cnt++; };
~NullHandler() { NullHandler::_cnt--; };
- void parse(const char* input_buf);
+ void newCritter(critter* c_ptr) { my_critter = c_ptr; };
+
+ bool parse(const char* input_buf, size_t len);
void set_echo(bool on_off) { return; }
const char* end_of_record() const { return(""); }
};//class NullHandler
Modified: trunk/mud/grrmud/server/telnet_handler.cc
===================================================================
--- trunk/mud/grrmud/server/telnet_handler.cc 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/telnet_handler.cc 2007-02-25 01:21:12 UTC (rev 890)
@@ -30,6 +30,7 @@
extern LogStream mudlog;
int TelnetHandler::_cnt = 0;
+const char TelnetHandler::eor_str[2] = { IAC, EOR };
TelnetHandler::TelnetHandler(critter* c_ptr) {
@@ -37,16 +38,17 @@
my_critter = c_ptr;
current_state = ST_TEXT;
+ current_text_state = ST_NORM;
//memset is probably faster, but oh well.
for(unsigned int i=0;i<sizeof(my_want_states);my_want_states[i++]=false);
for(unsigned int i=0;i<sizeof(my_option_states);my_option_states[i++]=false);
- //This is sort of a hack. We're assuming that we will only be instantiated
- //immediately preceeding the login password prompt.
- set_echo(true);
send(DO,TELOPT_NAWS);
+ my_option_states[TELOPT_EOR] = true;
+ send(WILL,TELOPT_EOR);
+
}//Constructor: TelnetHandler
void TelnetHandler::send(int action, int option) {
@@ -62,11 +64,13 @@
}//TelnetHandler::send()
//handle DOs
-void TelnetHandler::rcv_do(const int opt) {
+void TelnetHandler::rcv_do(int opt) {
bool need_to_respond = false;
bool will = false;
+ mudlog << "TelnetHandler::rcv_do received: IAC DO " << opt << endl;
+
//If we are already doing what they're asking for, we just ignore that they
//asked. this is the behaviour required by the rfc.
if ( ! my_option_states[opt] ) {
@@ -109,9 +113,11 @@
}//TelnetHandler::rcv_do()
//handle DONTs
-void TelnetHandler::rcv_dont(const int opt) {
+void TelnetHandler::rcv_dont(int opt) {
bool need_to_respond = false;
+ mudlog << "TelnetHandler::rcv_dont received: IAC DONT " << opt << endl;
+
//the rfc requires that we never refuse to turn off a feature and that we
//be willing to drop down to basics.
@@ -129,26 +135,30 @@
}//TelnetHandler::rcv_dont()
//handle WILLs
-void TelnetHandler::rcv_will(const int opt) {
+void TelnetHandler::rcv_will(int opt) {
// I don't expect to have to deal with these, but for now I'll log them to
// find out if I'm wrong.
mudlog << "TelnetHandler::rcv_will received: IAC WILL " << opt << endl;
}//TelnetHandler::rcv_will()
//handle WONTs
-void TelnetHandler::rcv_wont(const int opt) {
+void TelnetHandler::rcv_wont(int opt) {
// The only thing that might come back to us here is NAWS as I don't plan
// on asking the client to do much more than that. so for now, just log the
// fact that they said they wouldn't do something.
mudlog << "TelnetHandler::rcv_wont received: IAC WONT " << opt << endl;
}//TelnetHandler::rcv_wont()
-void TelnetHandler::parse(const char* input_buf) {
+bool TelnetHandler::parse(const char* input_buf, size_t len) {
- const char* p = input_buf;
+ size_t i=0;
+ const char* p;
+ bool parsed_full_command = false;
- while ( *p ) {
+ while ( i < len ) {
+ p = input_buf+i;
+
switch ( current_state ) {
case ST_TEXT:
@@ -159,16 +169,75 @@
break;
default:
- my_critter->pc->input += *p;
+ // we don't directly append to the pc's buf as the command
+ // parser isn't currently smart enough to deal with
+ // incomplete commands. We also need to handle backspace,
+ // etc. These things were previously dealt with in
+ // String::Read()
+ switch ( current_text_state ) {
+ case ST_NORM:
+ switch ( *p ) {
+
+ case 0x08://backspace
+ if ( out_buf.size() > 0 ) {
+ out_buf.resize(out_buf.size()-1);
+ }
+ break;
+
+ case 0x0D://carriage return
+ //do nothing, we don't like \r's around here.
+ break;
+
+ case 0x0A://newline
+ out_buf += *p;
+ my_critter->pc->input += out_buf.c_str();
+ out_buf.clear();
+ parsed_full_command = true;
+ break;
+
+ case ';':
+ current_text_state = ST_SEMICOLON;
+ break;
+
+ default:
+ out_buf += *p;
+ break;
+ };
+ break;
+
+ case ST_SEMICOLON:
+ switch ( *p ) {
+
+ case ';':
+ out_buf += ';';
+ break;
+
+ case 0x08://backspace
+ if ( out_buf.size() > 0 ) {
+ out_buf.resize(out_buf.size()-1);
+ }
+ current_text_state = ST_NORM;
+ break;
+
+ default:
+ out_buf += '\n';
+ out_buf += *p;
+ break;
+
+ };
+ current_text_state = ST_NORM;
+ break;
+
+ }//switch(current_text_state)
break;
- };
- break;
+ };//ST_TEXT: switch(*p)
+ break;//end ST_TEXT
case ST_IAC:
switch (*p) {
case IAC://escaped IAC.
- my_critter->pc->input += *p;
+ out_buf += *p;
break;
case DO:
@@ -192,24 +261,30 @@
break;
default:
+ //invalid transistion
+ current_state = ST_TEXT;
break;
};
break;
case ST_DO:
rcv_do(*p);
+ current_state = ST_TEXT;
break;
case ST_DONT:
rcv_dont(*p);
+ current_state = ST_TEXT;
break;
case ST_WILL:
rcv_will(*p);
+ current_state = ST_TEXT;
break;
case ST_WONT:
rcv_wont(*p);
+ current_state = ST_TEXT;
break;
case ST_SB://processing a sub-option datastream
@@ -223,7 +298,7 @@
sb_buf += *p;
// sanity check this to prevent resource exhaustion from a
// rogue client
- if ( sb_buf.Strlen() > 256 ) {
+ if ( sb_buf.size() > 256 ) {
sb_buf.clear();
current_state = ST_TEXT;
}
@@ -236,6 +311,7 @@
case IAC://escaped IAC character.
sb_buf += *p;
+ current_state = ST_SB;
break;
case SE://end of sub-option data
@@ -255,9 +331,11 @@
};//switch ( telnet_state )
- p++;
+ i++;
}//while there's more input
+ return(parsed_full_command);
+
}//TelnetHandler::parse()
bool TelnetHandler::should_echo() const {
@@ -294,37 +372,35 @@
//for now we ignore everything but NAWS, and even then just spew some log
//information about it as we haven't established a place to store it in the
//pcdata yet.
- if ( sb_buf.Strlen() == 0 ) {
+ if ( sb_buf.size() == 0 ) {
return;
}
- switch ( sb_buf[0] ) {
+
+ const char* p = sb_buf.data();
+
+ switch ( *p ) {
case TELOPT_NAWS: {
short width, height;
- union
- {
- short s;
- char a;
- char b;
- } i_tmp;
width = height = -1;
- if ( sb_buf.Strlen() != 5 ) {
+ if ( sb_buf.size() != 5 ) {
//NAWS should be: NAWS WIDTH[1] WIDTH[0] HEIGHT[1] HEIGHT[0]
mudlog
<< "TelnetHandler::process_subopt() received malformed NAWS of len "
- << sb_buf.Strlen()
+ << sb_buf.size()
<< endl;
break;
}
- i_tmp.a = sb_buf[1];
- i_tmp.b = sb_buf[2];
- width = ntohs(i_tmp.s);
+ width = *(short *)(p+1);
+ height = *(short *)(p+3);
- i_tmp.a = sb_buf[3];
- i_tmp.b = sb_buf[4];
- height = ntohs(i_tmp.s);
+ width = ntohs(width);
+ height = ntohs(height);
+ my_critter->pc->lines_on_page = height;
+ my_critter->pc->columns_on_page = width;
+
mudlog << "TelnetHandler::process_subopt() received NAWS "
<< "width: " << width << " height: " << height << endl;
}//TELOPT_NAWS
@@ -338,3 +414,17 @@
sb_buf.clear();
}//TelnetHandler::process_subopt()
+
+const char* TelnetHandler::end_of_record() const {
+
+ if ( my_option_states[TELOPT_EOR] ) {
+ return(TelnetHandler::eor_str);
+ } else {
+ return("");
+ }
+
+}//TelnetHandler::end_of_record()
+
+void TelnetHandler::newCritter(critter* c_ptr) {
+ my_critter = c_ptr;
+}//TelnetHandler::newCritter()
Modified: trunk/mud/grrmud/server/telnet_handler.h
===================================================================
--- trunk/mud/grrmud/server/telnet_handler.h 2007-02-24 09:41:40 UTC (rev 889)
+++ trunk/mud/grrmud/server/telnet_handler.h 2007-02-25 01:21:12 UTC (rev 890)
@@ -32,12 +32,15 @@
protected:
static int _cnt;
+ static const char eor_str[2];
enum state { ST_TEXT, ST_IAC, ST_DO, ST_DONT, ST_WILL, ST_WONT, ST_SB, ST_SB_IAC };
+ enum text_state { ST_NORM, ST_SEMICOLON };
state current_state;
- String sb_buf;
- String eor_str;
+ text_state current_text_state;
+ std::string sb_buf;
+ std::string out_buf;
critter* my_critter;
bool my_want_states[256]; //things I've requested or offered.
@@ -49,19 +52,23 @@
void rcv_wont(int opt);
void process_subopt();
+ void process_out_buf();
//inserts IAC action option into my_critter's outbuf.
void send(int action, int option);
+ bool should_echo() const;
+
public:
+ static int getInstanceCount() { return _cnt; }
+
TelnetHandler(critter* c_ptr);
~TelnetHandler() { _cnt--; };
- void parse(const char* input_buf);
-
+ void newCritter(critter* c_ptr);
+ bool parse(const char* input_buf, size_t len);
void set_echo(bool on_off);
- bool should_echo() const;
- const char* end_of_record() const { return( (const char*)eor_str ); }
+ const char* end_of_record() const;
};
More information about the ScryMUD
mailing list