Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
parse description bug
Dec 15, 2017, 10:08 pm
By Remcon
Couple bugs
Dec 12, 2017, 5:42 pm
By Remcon
Bug in disarm( )
Nov 12, 2017, 6:54 pm
By GatewaySysop
Bug in will_fall( )
Oct 23, 2017, 1:35 am
By GatewaySysop
Bug in do_zap( ), do_brandish( )
Oct 18, 2017, 1:52 pm
By GatewaySysop
LOP 1.45
Author: Remcon
Submitted by: Remcon
LOP Heroes Edition
Author: Vladaar
Submitted by: Vladaar
Heroes sound extras
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.3
Author: Vladaar
Submitted by: Vladaar
Memwatch
Author: Johan Lindh
Submitted by: Vladaar
Users Online
CommonCrawl, Majestic-12, Yahoo!, Google, DotBot

Members: 0
Guests: 13
Stats
Files
Topics
Posts
Members
Newest Member
477
3,706
19,240
608
LAntorcha
Today's Birthdays
There are no member birthdays today.
Related Links
» SmaugMuds.org » Bugfix Lists » AFKMud Bugfix List » AFKMud Bug Archive » [Bug] Exit creation stumbles ...
Forum Rules | Mark all | Recent Posts

[Bug] Exit creation stumbles on flags in the argument
< Newer Topic :: Older Topic > AFKMud 1.77

Pages:<< prev 1 next >>
Post is unread #1 Dec 2, 2006, 4:53 pm   Last edited Dec 2, 2006, 4:53 pm by Samson
Go to the top of the page
Go to the bottom of the page

Samson
Black Hand
GroupAdministrators
Posts3,639
JoinedJan 1, 2002

Bug: Exit creation stumbles on flags in the argument
Danger: Low - Ending up with partly broken exits makes more work for people to fix.
Discovered in: AFKMud 1.77
Found by: pstone
Fixed by: Samson

---

build.c, do_redit

Locate:
   if( !str_cmp( arg, "exit" ) )
   {
      bool addexit, numnotdir;

      argument = one_argument( argument, arg2 );
      argument = one_argument( argument, arg3 );
      if( !arg2 || arg2[0] == '\0' )
      {
         send_to_char( "Create, change or remove an exit.\n\r", ch );
         send_to_char( "Usage: redit exit <dir> [room] [flags] [key] [keywords] \n\r", ch );
         return;
      }
      addexit = numnotdir = FALSE;
      switch ( arg2[0] )
      {
         default:
            edir = get_dir( arg2 );
            break;
         case '+':
            edir = get_dir( arg2 + 1 );
            addexit = TRUE;
            break;
         case '#':
            edir = atoi( arg2 + 1 );
            numnotdir = TRUE;
            break;
      }
      if( !arg3 || arg3[0] == '\0' )
         evnum = 0;
      else
         evnum = atoi( arg3 );
      if( numnotdir )
      {
         if( ( xit = get_exit_num( location, edir ) ) != NULL )
            edir = xit->vdir;
      }
      else
         xit = get_exit( location, edir );
      if( !evnum )
      {
         if( xit )
         {
            extract_exit( location, xit );
            send_to_char( "Exit removed.\n\r", ch );
            return;
         }
         send_to_char( "No exit in that direction.\n\r", ch );
         return;
      }
      if( evnum < 1 || evnum > ( sysdata.maxvnum - 1 ) )
      {
         send_to_char( "Invalid room number.\n\r", ch );
         return;
      }
      if( ( tmp = get_room_index( evnum ) ) == NULL )
      {
         if( evnum < ch->pcdata->low_vnum || evnum > ch->pcdata->hi_vnum )
         {
            ch_printf( ch, "Room #%d does not exist.\n\r", evnum );
            return;
         }
         tmp = make_room( evnum, ch->pcdata->area );
         if( !tmp )
         {
            bug( "%s: make_room failed", __FUNCTION__ );
            return;
         }
      }
      if( addexit || !xit )
      {
         if( numnotdir )
         {
            send_to_char( "Cannot add an exit by number, sorry.\n\r", ch );
            return;
         }
         if( addexit && xit && get_exit_to( location, edir, tmp->vnum ) )
         {
            send_to_char( "There is already an exit in that direction leading to that location.\n\r", ch );
            return;
         }
         xit = make_exit( location, tmp, edir );
         xit->key = -1;
         xCLEAR_BITS( xit->exit_info );
         act( AT_IMMORT, "$n reveals a hidden passage!", ch, NULL, NULL, TO_ROOM );
      }
      else
         act( AT_IMMORT, "Something is different...", ch, NULL, NULL, TO_ROOM );
      if( xit->to_room != tmp )
      {
         xit->to_room = tmp;
         xit->vnum = evnum;
         texit = get_exit_to( xit->to_room, rev_dir[edir], location->vnum );
         if( texit )
         {
            texit->rexit = xit;
            xit->rexit = texit;
         }
      }
      argument = one_argument( argument, arg3 );
      if( arg3 && arg3[0] != '\0' )
      {
         int fl;

         fl = get_exflag( arg3 );

         if( fl < 0 || fl > MAX_BITS )
            send_to_char( "Bad exit flag!\n\r", ch );
         else
            SET_EXIT_FLAG( xit, fl );
      }
      if( argument && argument[0] != '\0' )
      {
         one_argument( argument, arg3 );
         ekey = atoi( arg3 );
         if( ekey != 0 || arg3[0] == '0' )
         {
            argument = one_argument( argument, arg3 );
            xit->key = ekey;
         }
         if( argument && argument[0] != '\0' )
         {
            STRFREE( xit->keyword );
            xit->keyword = STRALLOC( argument );
         }
      }
      send_to_char( "New exit added.\n\r", ch );
      return;
   }


Change to:
   if( !str_cmp( arg, "exit" ) )
   {
      bool addexit, numnotdir;

      argument = one_argument( argument, arg2 );
      argument = one_argument( argument, arg3 );
      if( !arg2 || arg2[0] == '\0' )
      {
         send_to_char( "Create, change or remove an exit.\r\n", ch );
         send_to_char( "Usage: redit exit <dir> [room] [key] [keyword] [flags]\r\n", ch );
         return;
      }

      // Pick a direction. Variable edir assumes this value once set.
      addexit = numnotdir = FALSE;
      switch( arg2[0] )
      {
         default:
            edir = get_dir( arg2 );
            break;
         case '+':
            edir = get_dir( arg2 + 1 );
            addexit = TRUE;
            break;
         case '#':
            edir = atoi( arg2 + 1 );
            numnotdir = TRUE;
            break;
      }

      // Pick a target room number for the exit. Set to 0 if not found.
      if( !arg3 || arg3[0] == '\0' )
         evnum = 0;
      else
         evnum = atoi( arg3 );

      if( numnotdir )
      {
         if( ( xit = get_exit_num( location, edir ) ) != NULL )
            edir = xit->vdir;
      }
      else
         xit = get_exit( location, edir );

      // If the evnum value is 0, delete this exit and ignore all other arguments to the command.
      if( !evnum )
      {
         if( xit )
         {
            extract_exit( location, xit );
            send_to_char( "Exit removed.\r\n", ch );
            return;
         }
         send_to_char( "No exit in that direction.\r\n", ch );
         return;
      }

      // Validate the target room vnum is within allowable maximums.
      if( evnum < 1 || evnum > ( sysdata.maxvnum - 1 ) )
      {
         send_to_char( "Invalid room number.\r\n", ch );
         return;
      }

      // Check for existing target room....
      if( !( tmp = get_room_index( evnum ) ) )
      {
         // If outside the person's vnum range, bail out. FIXME: Check for people who can edit globally.
         if( evnum < ch->pcdata->low_vnum || evnum > ch->pcdata->hi_vnum )
         {
            ch_printf( ch, "Room #%d does not exist.\r\n", evnum );
            return;
         }

         // Create the target room if the vnum did not exist yet.
         tmp = make_room( evnum, ch->pcdata->area );
         if( !tmp )
         {
            bug( "%s: make_room failed", __FUNCTION__ );
            return;
         }
      }

      // Actually add or change the exit affected.
      if( addexit || !xit )
      {
         if( numnotdir )
         {
            send_to_char( "Cannot add an exit by number, sorry.\r\n", ch );
            return;
         }
         if( addexit && xit && get_exit_to( location, edir, tmp->vnum ) )
         {
            send_to_char( "There is already an exit in that direction leading to that location.\r\n", ch );
            return;
         }
         xit = make_exit( location, tmp, edir );
         xit->key = -1;
         xCLEAR_BITS( xit->exit_info );
         act( AT_IMMORT, "$n reveals a hidden passage!", ch, NULL, NULL, TO_ROOM );
      }
      else
         act( AT_IMMORT, "Something is different...", ch, NULL, NULL, TO_ROOM );

      // A sanity check to make sure it got sent to the proper place.
      if( xit->to_room != tmp )
      {
         xit->to_room = tmp;
         xit->vnum = evnum;
         texit = get_exit_to( xit->to_room, rev_dir[edir], location->vnum );
         if( texit )
         {
            texit->rexit = xit;
            xit->rexit = texit;
         }
      }

      // Set the vnum of the key required to unlock this exit.
      argument = one_argument( argument, arg3 );
      if( arg3 && arg3[0] != '\0' )
      {
         ekey = atoi( arg3 );
         if( ekey != 0 || arg3[0] == '0' )
            xit->key = ekey;
      }

      // Set a keyword on this exit. "door", "gate", etc. Only accepts *ONE* keyword.
      argument = one_argument( argument, arg3 );
      if( arg3 && arg3[0] != '\0' )
      {
         STRFREE( xit->keyword );
         xit->keyword = STRALLOC( arg3 );
      }

      // And finally set any flags which have been specified.
      if( argument && argument[0] != '\0' )
      {
         while( argument[0] != '\0' )
         {
            argument = one_argument( argument, arg3 );
            value = get_exflag( arg3 );
            if( value < 0 || value > MAX_BITS )
               ch_printf( ch, "Unknown exit flag: %s\r\n", arg3 );
            else
               xTOGGLE_BIT( xit->exit_info, value );
         }
      }

      // WOO! Finally done. Inform the user.
      send_to_char( "New exit added.\r\n", ch );
      return;
   }


As written in the code, the redit command has a flaw which will not properly permit the creation of exit flags when generating a new exit. It boils down to "redit exit <dir> ..." trying to allow too much at once to be done. Thus this fix reorganizes the code section responsible for it to make it work as it was intended.

It was also suggested that putting single quotes around the flags was the best way to fix this, but it still leaves it open for mistakes by users who forget to do this. But I personally see being forced to use single quotes around a set of arguments as a flaw in design, and will seek to correct those as time permits.
       
Pages:<< prev 1 next >>