RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

MOTD Crash

LadyGaGa

Wanderer
http://www.runuo.com/community/threads/runuo-2-0-message-of-the-day.86469/
This happens when I try to use a craft gump macro on this gump.

Code:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Joeku.MOTD.MOTD_Gump.AddTitle() in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 56
   at Joeku.MOTD.MOTD_Gump..ctor(Mobile user, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 36
   at Joeku.MOTD.MOTD_Utility.SendGump(Mobile mob, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Utility.cs:line 64
   at Joeku.MOTD.MOTD_Gump.OnResponse(NetState sender, RelayInfo info) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 176
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
 

Jeff

Lord
In OnResponse there is the following code for the default switch case
Code:
                    MOTD_Utility.SendGump( mob, this.Help, button-10 );

The problem is, the gump macro is created by recording packets. The packets being recorded are the results of button clicks. So when the user clicks button 15 on the craft gump, it sends a packet to the server stating that button 15 was pressed. Razor emulates this by manually just sending the packet (it doesn't really click the button). This gump is crashing because its assuming the only way it could have come to this point is if a user clicked the proper button (when in fact you don't have to thanks to Razor).

I believe (I've not studied the scripts in their entirety..) you can fix this by adding an If statement above the suspect line

Code:
                default: // Page Forward/Back
                    if(Index <= MOTD_Main.Info - 1)
                         MOTD_Utility.SendGump( mob, this.Help, button-10 );
                    break;
Something like the above code.
 

LadyGaGa

Wanderer
So if I understand what you are saying, most custom gumps can be crashed by razor?

Also I get an error:
operator "-" cannot be applied to operand of type MOTD_Info[] and int
 

Jeff

Lord
MOTD_Main.Info.Length sorry.
And no, not most, only ones poorly written. If the creator doesnt put in checks like this, yes they will crash.. Also, most gumps don't have a dynamic button index like this one, so it is a rare circumstance.
 

LadyGaGa

Wanderer
Oh yeah I figured that Length after I posted. Anyways I tried a few ways and still get the crash when I run the razor macro.

Code:
Exception:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Joeku.MOTD.MOTD_Gump.AddTitle() in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 56
   at Joeku.MOTD.MOTD_Gump..ctor(Mobile user, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 36
   at Joeku.MOTD.MOTD_Utility.SendGump(Mobile mob, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Utility.cs:line 64
   at Joeku.MOTD.MOTD_Gump.OnResponse(NetState sender, RelayInfo info) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 181
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)
 

Jeff

Lord
You need to add the same check for HelpInfo
Code:
                    if((Help && Index <= MOTD_Main.HelpInfo.Length - 1) || (!Help && Index <= MOTD_Main.Info.Length - 1))
                        MOTD_Utility.SendGump( mob, this.Help, button-10 );
 

Jeff

Lord
Ok, lets try another approach... lets not let them continue if the button isn't within the range we want, use this OnResponse:
Code:
        public override void OnResponse( NetState sender, RelayInfo info )
        {
            Mobile mob = sender.Mobile;
            int button = info.ButtonID;

            if (Help)
            {
                if (pageBack < 0 || pageForward >= MOTD_Main.Info.Length)
                    return;
            }
            else
            {
                if (pageBack < 0 || pageForward >= MOTD_Main.Info.Length)
                    return;
            }

            switch( button )
            {
                case 0:    // Close
                    if( this.Help )
                        MOTD_Utility.SendGump( mob );
                    break;
                case 1: // Help
                    if( !this.Help )
                        MOTD_Utility.SendGump( mob, true );
                    else
                    {
                        MOTD_Utility.ToggleLogin( this.User.Account );
                        MOTD_Utility.SendGump( mob, true, this.Index );
                    }
                    break;
                default: // Page Forward/Back
                    MOTD_Utility.SendGump( mob, this.Help, button-10 );
                    break;
            }
        }
 

LadyGaGa

Wanderer
Couldn't run this because it didn't recognize pageback and forward.
I added this inside to compile it:
Code:
                    int pageBack = this.Index-1, pageForward = this.Index+1;
                    if( pageBack < 0 )
                        pageBack = MOTD_Main.Info.Length-1;
                    if( pageForward == MOTD_Main.Info.Length )
                        pageForward = 0;
and then I get the same crash :(

Code:
Exception:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at Joeku.MOTD.MOTD_Gump.AddTitle() in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 56
   at Joeku.MOTD.MOTD_Gump..ctor(Mobile user, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 36
   at Joeku.MOTD.MOTD_Utility.SendGump(Mobile mob, Boolean help, Int32 index) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Utility.cs:line 64
   at Joeku.MOTD.MOTD_Gump.OnResponse(NetState sender, RelayInfo info) in c:\Documents and Settings\Administrator\Desktop\Test Server\Scripts\XX Custom\PlayerCommands\MOTD\Gump.cs:line 186
   at Server.Network.PacketHandlers.DisplayGumpResponse(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns)
   at Server.Network.MessagePump.Slice()
   at Server.Core.Main(String[] args)

Could there still be a problem on the other parts? It always ends at "MOTD_Utility.SendGump( mob, this.Help, button-10 );" line. But starts at other parts of the code? Or is there a similiar gump script like this where we can study the code?
 

Jeff

Lord
Code:
  public override void OnResponse( NetState sender, RelayInfo info )
        {
            Mobile mob = sender.Mobile;
            int button = info.ButtonID;

            if (Help)
            {
                if (button< 0 || button>= MOTD_Main.Info.Length)
                    return;
            }
            else
            {
                if (button< 0 || button>= MOTD_Main.Info.Length)
                    return;
            }

            switch( button )
            {
                case 0:    // Close
                    if( this.Help )
                        MOTD_Utility.SendGump( mob );
                    break;
                case 1: // Help
                    if( !this.Help )
                        MOTD_Utility.SendGump( mob, true );
                    else
                    {
                        MOTD_Utility.ToggleLogin( this.User.Account );
                        MOTD_Utility.SendGump( mob, true, this.Index );
                    }
                    break;
                default: // Page Forward/Back
                    MOTD_Utility.SendGump( mob, this.Help, button-10 );
                    break;
            }
        }
Sorry meant to replace those with 'button' try the above... you might need to debug this with console writelines to see the values for what is acceptably and what you are getting.
 

Lichtblitz

Sorceror
Check out the link in my signature for a tutorial on debugging. Alternatively you could add some lines like
PHP:
Console.WriteLine( "button ID = {0}", button );
To see what values are actually received on the server end or lines like
PHP:
default: // Page Forward/Back
    MOTD_Utility.SendGump( mob, this.Help, button-10 );
    Console.WriteLine( "Page Forward/Back clicked" );
    break;

To see if a condition has actually been met or not.
 
Top