[ScryMUD] SVN Commit Info r893 - trunk/mud/grrmud/server

scrymud at wanfear.com scrymud at wanfear.com
Sun Feb 25 00:06:45 PST 2007


Author: eroper
Date: 2007-02-25 00:06:44 -0800 (Sun, 25 Feb 2007)
New Revision: 893

Modified:
   trunk/mud/grrmud/server/command4.cc
   trunk/mud/grrmud/server/critter.cc
   trunk/mud/grrmud/server/critter.h
   trunk/mud/grrmud/server/grrmud.cc
   trunk/mud/grrmud/server/login.cc
   trunk/mud/grrmud/server/misc.cc
   trunk/mud/grrmud/server/parse.cc
   trunk/mud/grrmud/server/telnet_handler.cc
Log:
Logging off during login will no longer issue you another prompt prior to
letting you go.

Telnet Handlers now default to not echoing, thus asking clients to do it
initially. We turn it on for password prompts and then off again. It's worth
noting that not all MUD clients support telnet echo. (the good ones do ;)

Changed a prefix incrementor in decrease_timed_affecting_pcs in order to
prevent potential short-circuiting with some optimizing compilers. The
increment was previously being done in a complex conditional evaluation.

Linkdead players should be detected immediately in the event they abruptly
close their (well-behaved) client. We should no longer have to wait until the
next write() failure to discover them.

Linkdead players are now disconnected after 2 ticks as opposed to 30 ticks
before. Previously this left linkdead players vulnerable to aoe spells and
attacks, even when the aggressor had no the link-dead victim was present. It
is intentional that they should remain somewhat vulnerable to prevent
abrupt-disconnects from allowing players to escape impending doom.

Linkdead players were previously (eventually) transistioned into
MODE_QUIT_ME_PLEASE by log_out(). They will now be transistioned to
MODE_LOG_OFF_LINKDEAD_PLEASE by the same mechanism.

ticks_till_freedom will no longer decrease indefinitely.
decrementTicksTillFreedom() conditionally decrements down to 0 now.

Moved some socket error handling out of grrmud.cc and added
pc_data::SocketProblem() which will properly transistion the various pc_data
states and log odd socket errors which occur when they shouldn't.

Yet again repositioned the delete calls for ProtocolHandler's. I've tested
several hundred times with combinations of login-process-logouts, full on
logouts, link deaths, link death reconnections, live reconnection /
replacements, etc. I have failed to cause any further segfaults. According to
"dsys" we aren't leaking any *Handlers anymore either.

You may now log in as "who" in order to see who's online. Immediately
following the current player list, you will be disconnected.


Modified: trunk/mud/grrmud/server/command4.cc
===================================================================
--- trunk/mud/grrmud/server/command4.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/command4.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -545,8 +545,15 @@
    }
 
    pc.save();
-   pc.setMode(MODE_QUIT_ME_PLEASE);
 
+   //If they're link-dead we logout a bit differently. I'm not sure if this is
+   //just for "accounting" reasons, or if maybe there is some other reason.
+   if ( pc.getMode() == MODE_GO_LINKDEAD_PLEASE ) {
+      pc.setMode(MODE_LOG_OFF_LINKDEAD_PLEASE);
+   } else {//normal quit or idle timeout
+      pc.setMode(MODE_QUIT_ME_PLEASE);
+   }
+
    show("Cya later.\n", pc);
    emote("has left the game.\n", pc, ROOM, TRUE);
    return 0;

Modified: trunk/mud/grrmud/server/critter.cc
===================================================================
--- trunk/mud/grrmud/server/critter.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/critter.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -1346,6 +1346,7 @@
    snooping = NULL;
    imm_data = NULL;
    w_eye_obj = NULL;
+   client = NO_CLIENT;
    Clear();
 }//constructor
 
@@ -1357,6 +1358,7 @@
    snooping = NULL;
    imm_data = NULL;
    w_eye_obj = NULL;
+   client = NO_CLIENT;
    *this = source;
 }//constructor
 
@@ -1735,7 +1737,48 @@
    ofile.getline(tmp, 80); //grabs extra line/comment
 }//Read()       
 
+//This gets called when we have a socket problem and need to transistion to
+//some other state.
+void pc_data::SocketProblem() {
 
+   switch ( link_condition ) {
+
+      case 1://CON_PLAYING
+         link_condition = 2;
+      break;
+
+      case 2://CON_LINKDEAD
+         mudlog << "Already linkdead but getting more socket errors." << endl;
+      break;
+
+      case 3://CON_LOGGING_IN
+         link_condition = 2;
+      break;
+   };
+
+   switch ( mode ) {
+
+      case MODE_LOGGING_IN:// safe to go bye bye from here
+         mode = MODE_LOGOFF_NEWBIE_PLEASE;
+      break;
+
+      case MODE_QUIT_ME_PLEASE:
+      case MODE_LOGOFF_NEWBIE_PLEASE:
+         mudlog << "Got socket errors while awaiting logoff." << endl;
+      break;
+
+      case MODE_GO_LINKDEAD_PLEASE:
+         mudlog << "Already in MODE_GO_LINKDEAD_PLEASE and received socket errors." << endl;
+      break;
+
+      default:
+         mode = MODE_GO_LINKDEAD_PLEASE;
+
+   }
+
+}//pc_data::SocketProblem()
+
+
 //*************************************************************//
 ///*********************  critter  ***************************///
 

Modified: trunk/mud/grrmud/server/critter.h
===================================================================
--- trunk/mud/grrmud/server/critter.h	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/critter.h	2007-02-25 08:06:44 UTC (rev 893)
@@ -501,7 +501,7 @@
    void incrementTicksOld() { ticks_old++; }
    int getTicksTillFreedom() const { return ticks_till_freedom; }
    void setTicksTillFreedom(int i) { ticks_till_freedom = i; }
-   void decrementTicksTillFreedom() { ticks_till_freedom--; }
+   void decrementTicksTillFreedom() { if ( ticks_till_freedom > 0 ) { ticks_till_freedom--; } }
    void setDisolvable(int val) { mob_data_flags.set(9, val); }
    int isDisolvable() const { return mob_data_flags.get(9); }
 
@@ -644,6 +644,7 @@
    void Clear();
    void Write(ofstream& ofile);
    void Read(critter* parent, ifstream& ofile);
+   void SocketProblem();
    static int getInstanceCount() { return _cnt; }
 
    int client;

Modified: trunk/mud/grrmud/server/grrmud.cc
===================================================================
--- trunk/mud/grrmud/server/grrmud.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/grrmud.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -864,6 +864,7 @@
             tmp_ptr = pc_ptr;
             pc_ptr = pc_list.lose(pc_cell);
             tmp_ptr->doLogOffNewLogin();
+            delete tmp_ptr->pc->p_handler;
             delete tmp_ptr;
          }//if
          else if (pc_ptr->getMode() == MODE_QUIT_ME_PLEASE)  {
@@ -876,6 +877,7 @@
             else {
                tmp_ptr->doLogOffActive();
             }
+            delete tmp_ptr->pc->p_handler;
             delete tmp_ptr;
          }//else
          else {
@@ -897,6 +899,7 @@
             else {
                tmp_ptr->doLogOffInactive();
             }
+            delete tmp_ptr->pc->p_handler;
             delete tmp_ptr;
          }//else
          else {
@@ -1000,27 +1003,19 @@
             FD_CLR(pc_ptr->getDescriptor(), &input_set);
             FD_CLR(pc_ptr->getDescriptor(), &output_set);
             mudlog << "WARNING:  pc -:" << pc_ptr->getName() << " going linkdead because of exc_set.\n";
-            pc_ptr->setMode(MODE_GO_LINKDEAD_PLEASE);
+            pc_ptr->pc->SocketProblem();
          }//if
       }//while
 
-        //log("Get input.\n");
-                        /* get input */
+      //log("Get input.\n");
+      /* get input */
       pc_list.head(pc_cell);
       while ((pc_ptr = pc_cell.next())) {
          if ((pc_ptr->MODE != MODE_GO_LINKDEAD_PLEASE) &&
-             (pc_ptr->MODE != MODE_LOGOFF_NEWBIE_PLEASE) &&
-             (pc_ptr->MODE != MODE_QUIT_ME_PLEASE)) {
-              if (FD_ISSET(pc_ptr->getDescriptor(), &input_set)) {
-               if (pc_ptr->readInput() < 0) { 
-                  mudlog.log(DBG, "Kicked out by negative get_input.\n");
-                  if (pc_ptr->pc->link_condition == CON_LOGGING_IN) {
-                     pc_ptr->setMode(MODE_LOGOFF_NEWBIE_PLEASE);
-                  }
-                  else {
-                     pc_ptr->setMode(MODE_GO_LINKDEAD_PLEASE);
-                  }
-               }//if
+               (pc_ptr->MODE != MODE_LOGOFF_NEWBIE_PLEASE) &&
+               (pc_ptr->MODE != MODE_QUIT_ME_PLEASE)) {
+            if (FD_ISSET(pc_ptr->getDescriptor(), &input_set)) {
+               pc_ptr->readInput();
             }//if
          }//if
       }//while
@@ -1164,8 +1159,7 @@
              (pc_ptr->MODE != MODE_LOGOFF_NEWBIE_PLEASE) &&
              (pc_ptr->MODE != MODE_QUIT_ME_PLEASE)) {
             if (pc_ptr->writeOutput() < 0) { 
-               mudlog.log(DBG, "Kicked out by negative write_output.\n");
-               pc_ptr->setMode(MODE_GO_LINKDEAD_PLEASE);
+               pc_ptr->pc->SocketProblem();
             }//if
          }//if
       }//while
@@ -1451,6 +1445,7 @@
    mudlog.log(TRC, "In createWithDescriptor\n");
 
    if ((desc = new_connection(s)) < 0) {
+      delete newd->pc->p_handler;
       delete newd;
       return -1;
    }//if
@@ -1462,6 +1457,7 @@
       write(desc, str, strlen(str)); 
       mudlog.log(WRN, "WARNING:  the mud was full.\n");
       close(desc);
+      delete newd->pc->p_handler;
       delete newd;
       return -1;
    }//if
@@ -1509,6 +1505,7 @@
       Sprintf(buf2, "WARNING:  Connection attempt denied from [%S]", 
               &(newd->pc->host));
       mudlog.log(WRN, buf2);
+      delete newd->pc->p_handler;
       delete newd;
       return -1;
    }//if
@@ -1622,37 +1619,42 @@
       } else {
          return(0);
       }
+   } else if ( read_bytes == 0 ) {// the other end performed an orderly shutdown
+      return(-2);
    }
+      
    return(read_bytes);
 }
 
-   int critter::readInput()  {
+int critter::readInput()  {
 
-      if (!pc) {
-         return -1;
-      }
+   if (!pc) {
+      mudlog << "(in critter::readInput) Critter: " << getName()
+         << " does not have pc_data." << endl;
+      return -1;
+   }
 
-      errno = 0;
-      //ret = pc->input.Read(pc->descriptor, MAX_INPUT_LEN);
+   errno = 0;
 
-      char input_buf[4096];
-      ssize_t read_bytes = netread(pc->descriptor, input_buf, 4096);
-      ssize_t ret = read_bytes;
+   char input_buf[4096];
+   ssize_t read_bytes = netread(pc->descriptor, input_buf, 4096);
 
-      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;
+      pc->SocketProblem();
+      return(0);
+   }
 
-      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);
-      }
+   if (mudlog.ofLevel(TRC)) {
+      mudlog << "End of get_input, here it is:\n" << pc->input << ":-  ret: " << read_bytes << endl;
+   }
 
-      return read_bytes;  //valid input added to input buffer, can go parse it now.
-   }//get_input
+   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);
@@ -1811,12 +1813,6 @@
       return -1;
    }
 
-   // no need of a protocol handler when they're D/C'ed.
-   if ( pc->p_handler ) {
-      delete pc->p_handler;
-      pc->p_handler = NULL;
-   }
-
    if (mudlog.ofLevel(DBG)) {
       mudlog << "In doGoLinkDead, critter name:  " <<  *(getName())
          << "  room:  " << getCurRoomNum() << "  addr:  " << this
@@ -1878,12 +1874,6 @@
       return -1;
    }
 
-   // remove the protocol handler
-   if ( pc->p_handler ) {
-      delete pc->p_handler;
-      pc->p_handler = NULL;
-   }
-
    if (mudlog.ofLevel(DBG)) {
       mudlog << "In doLogOffNewLogin, critter name:  " <<  *(getName())
          << "  room:  " << getCurRoomNum() << "  addr:  " << this

Modified: trunk/mud/grrmud/server/login.cc
===================================================================
--- trunk/mud/grrmud/server/login.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/login.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -40,6 +40,7 @@
 #include "Filters.h"
 #include "clients.h"
 #include "telnet_handler.h"
+#include "command3.h"
 
 
 extern List<critter*> new_pc_list;
@@ -101,6 +102,15 @@
          case 0:  /* get the name.. */
             string = pc->input.Get_Command(eos, term_by_period);
 
+            //if someone logs in as "who", show them who's on and hang up on
+            //them
+            if (string == "who") {
+               SEE_BIT = 1024;
+               who(*this);
+               setMode(MODE_LOGOFF_NEWBIE_PLEASE);
+               break;
+            }
+
             if (string == "__HEGEMON__") {
                using_client(*this);
                setClient(HEGEMON);
@@ -508,15 +518,15 @@
                      //  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.
-                     if ( old_ptr->pc->p_handler ) {
-                        delete old_ptr->pc->p_handler;
-                     }
+                     ProtocolHandler* tmp_p_handler = old_ptr->pc->p_handler;
                      old_ptr->pc->p_handler = pc->p_handler;
                      old_ptr->pc->p_handler->newCritter(old_ptr);
-                     // set the current protocol_handler to NULL so it doesn't
-                     // get deleted (we're going to use it in old_ptr)
-                     pc->p_handler = NULL;
+                     pc->p_handler = tmp_p_handler;
 
+                     //for good measure, make sure they get to see what they
+                     //type.
+                     old_ptr->pc->p_handler->set_echo(false);
+
                      old_ptr->cur_stats[0] &= ~32;      //make em visable again
                      old_ptr->pc->link_condition = CON_PLAYING;
                      old_ptr->pc->index = 0;
@@ -925,6 +935,8 @@
 
    pc.save(); //make sure they have a Pfile
 
+   pc.pc->p_handler->set_echo(false);
+
    return 0;
 }//quit_do_login_new()
  

Modified: trunk/mud/grrmud/server/misc.cc
===================================================================
--- trunk/mud/grrmud/server/misc.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/misc.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -1275,23 +1275,33 @@
    stat_spell_cell* sp_ptr;
    String buf(100);
 
+   //log anyone who isn't isn't >= IMM level 2 off after 30 ticks of
+   //inactivity.
    while ((crit_ptr = crit_cell.next())) {
-      if ((++(crit_ptr->pc->idle_ticks) > 30) && 
-          (!crit_ptr->pc->imm_data || (crit_ptr->IMM_LEVEL < 2))) {
+
+      //This used to be a prefix increment in the conditional, but that means
+      //that it could be short-circuited depending on the compiler.
+      crit_ptr->pc->idle_ticks++;
+
+      if (
+            (crit_ptr->pc->idle_ticks > 30)
+            && ( (!crit_ptr->pc->imm_data) || (crit_ptr->IMM_LEVEL < 2) )
+         ) {
+
          if (mudlog.ofLevel(DBG)) {
-            mudlog << "Logging off player in decrease_timed_affecting_pcs,"
-                   << " name:  " << *(name_of_crit(*crit_ptr, ~0)) 
-                   << "  address:  " << crit_ptr << "  ticks:  "
-                   << crit_ptr->pc->idle_ticks << endl;
+            mudlog << "Logging off player in decrease_timed_affecting_pcs," << " name:  " <<
+               *(name_of_crit(*crit_ptr, ~0)) << "  address:  "
+               << crit_ptr << " ticks:  " << crit_ptr->pc->idle_ticks << endl;
          }
+
          log_out(*crit_ptr);
-      }//if
+      }
 
       if (TRUE /*crit_ptr->pc->mode == MODE_NORMAL*/) {
          crit_ptr->affected_by.head(sp_cell);
          sp_ptr = sp_cell.next();
          while (sp_ptr) {
-               if (sp_ptr->bonus_duration != -1)
+            if (sp_ptr->bonus_duration != -1)
                sp_ptr->bonus_duration--;
             if (sp_ptr->bonus_duration == 0) {
                rem_effects_crit(sp_ptr->stat_spell, *crit_ptr, TRUE, sp_ptr->bonus_value);
@@ -1317,7 +1327,7 @@
 
          if (crit_ptr->MODE == MODE_NORMAL) {
             if (crit_ptr->HUNGER == 0)
-                     crit_ptr->show("You are famished.\n");
+               crit_ptr->show("You are famished.\n");
             if (crit_ptr->THIRST == 0)
                crit_ptr->show("You are thirsty.\n");
             if (crit_ptr->DRUGGED == 0) {
@@ -1326,26 +1336,26 @@
             }//if
          }//if
 
-                /* check for lights about to go out */
+         /* check for lights about to go out */
          if (crit_ptr->EQ[11]) {
             if (!crit_ptr->EQ[11]->IN_LIST) {
                crit_ptr->EQ[11] = obj_to_sobj(*(crit_ptr->EQ[11]), 
-                                              &(crit_ptr->inv), crit_ptr->getCurRoomNum());
+                     &(crit_ptr->inv), crit_ptr->getCurRoomNum());
             }//if
             if (crit_ptr->EQ[11]->extras[0] == 1) {
                Sprintf(buf, "%S flickers.\n", 
-                       long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
+                     long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
                buf.Cap();
                crit_ptr->show(buf);
             }//if
          }//if
 
-                /* check for lights gone out */
+         /* check for lights gone out */
          if (crit_ptr->EQ[11]) {
             if (crit_ptr->EQ[11]->extras[0] == 0) {
                crit_ptr->EQ[11]->extras[0] = -2;
                Sprintf(buf, "%S dims and glows its last.\n", 
-                       long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
+                     long_name_of_obj(*(crit_ptr->EQ[11]), crit_ptr->SEE_BIT));
                buf.Cap();
                crit_ptr->show(buf);
                crit_ptr->crit_flags.turn_off(USING_LIGHT_SOURCE);
@@ -1372,7 +1382,7 @@
    String buf(100);
 
    while ((crit_ptr = crit_cell.next())) {
-      if (++(crit_ptr->pc->idle_ticks) > 30) {
+      if (++(crit_ptr->pc->idle_ticks) > 2) {
          mudlog << "Logging off player in decrease_timed_affecting_lds,"
                 << " name:  " << *(name_of_crit(*crit_ptr, ~0)) 
                 << "  address:  " << crit_ptr << endl;

Modified: trunk/mud/grrmud/server/parse.cc
===================================================================
--- trunk/mud/grrmud/server/parse.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/parse.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -269,7 +269,7 @@
       if (MODE == MODE_LOGGING_IN) {
          doLogin();
          //log("Do login finished...\n");
-         if (MODE != MODE_NORMAL) {
+         if ( ( MODE != MODE_NORMAL) && ( MODE != MODE_LOGOFF_NEWBIE_PLEASE) ) {
             show(login_prompts[pc->index]);
             show(pc->p_handler->end_of_record());
             // turn on server side echoing for password blanking when appropriate

Modified: trunk/mud/grrmud/server/telnet_handler.cc
===================================================================
--- trunk/mud/grrmud/server/telnet_handler.cc	2007-02-25 03:01:14 UTC (rev 892)
+++ trunk/mud/grrmud/server/telnet_handler.cc	2007-02-25 08:06:44 UTC (rev 893)
@@ -48,6 +48,7 @@
 
    my_option_states[TELOPT_EOR] = true;
    send(WILL,TELOPT_EOR);
+   send(WONT,TELOPT_ECHO);
 
 }//Constructor: TelnetHandler
 




More information about the ScryMUD mailing list