Login
User Name:

Password:



Register
Forgot your password?
Vote for Us!
tintin++ ogg sound player script for linux
Author: Robert Smith
Submitted by: Vladaar
6Dragons ogg Soundpack
Author: Vladaar
Submitted by: Vladaar
6Dragons 4.4
Author: Vladaar
Submitted by: Vladaar
LoP 1.46
Author: Remcon
Submitted by: Remcon
LOP 1.45
Author: Remcon
Submitted by: Remcon
Users Online
CommonCrawl, Bing

Members: 0
Guests: 7
Stats
Files
Topics
Posts
Members
Newest Member
481
3,740
19,396
629
DarrenPayn
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,644
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 >>