Example #1
0
        public static void OnReceive( GameClient state, PacketReader pvSrc )
        {
            if ( pvSrc.ReadByte() == 0xFF )
                state.Send( new UOGInfo( String.Format( ", Name={0}, Age={1}, Clients={2}, Items={3}, Chars={4}, Mem={5}K", Environment.Config.ServerName, (int) ( DateTime.Now - Server.Items.Clock.ServerStart ).TotalHours, GameServer.Instance.ClientCount, World.Instance.ItemCount, World.Instance.MobileCount, (int) ( System.GC.GetTotalMemory( false ) / 1024 ) ) ) );

            state.Dispose();
        }
Example #2
0
        public static void DecodeBundledPacket( GameClient state, PacketReader pvSrc )
        {
            int packetID = pvSrc.ReadByte();

            PacketHandler ph = GetHandler( packetID );

            if ( ph != null )
            {
                if ( ph.Ingame && state.Mobile == null )
                {
                    Console.WriteLine( "Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID );
                    state.Dispose();
                }
                else if ( ph.Ingame && state.Mobile.Deleted )
                {
                    state.Dispose();
                }
                else
                {
                    ph.OnReceive( state, pvSrc );
                }
            }
        }
Example #3
0
        public void CreateCharacterNew( GameClient state, PacketReader pvSrc )
        {
            /*int unk1 = */
            pvSrc.ReadInt32();
            /*int unk2 = */
            pvSrc.ReadInt32();
            /*int unk3 = */
            pvSrc.ReadByte();
            string name = pvSrc.ReadString( 30 );

            pvSrc.Seek( 2, SeekOrigin.Current );
            int flags = pvSrc.ReadInt32();
            pvSrc.Seek( 8, SeekOrigin.Current );
            int prof = pvSrc.ReadByte();
            pvSrc.Seek( 15, SeekOrigin.Current );

            int genderRace = pvSrc.ReadByte();

            int str = pvSrc.ReadByte();
            int dex = pvSrc.ReadByte();
            int intl = pvSrc.ReadByte();
            int is1 = pvSrc.ReadByte();
            int vs1 = pvSrc.ReadByte();
            int is2 = pvSrc.ReadByte();
            int vs2 = pvSrc.ReadByte();
            int is3 = pvSrc.ReadByte();
            int vs3 = pvSrc.ReadByte();
            int is4 = pvSrc.ReadByte();
            int vs4 = pvSrc.ReadByte();
            int hue = pvSrc.ReadUInt16();
            int hairVal = pvSrc.ReadInt16();
            int hairHue = pvSrc.ReadInt16();
            int hairValf = pvSrc.ReadInt16();
            int hairHuef = pvSrc.ReadInt16();
            pvSrc.ReadByte();
            int cityIndex = pvSrc.ReadByte();
            /*int charSlot = */
            pvSrc.ReadInt32();
            uint clientIP = pvSrc.ReadUInt32();
            int shirtHue = pvSrc.ReadInt16();
            int pantsHue = pvSrc.ReadInt16();

            /*
            0x00, 0x01
            0x02, 0x03 -> Human Male, Human Female
            0x04, 0x05 -> Elf Male, Elf Female
            0x05, 0x06 -> Gargoyle Male, Gargoyle Female
            */

            bool female = ( ( genderRace % 2 ) != 0 );

            Race race = null;

            byte raceId = (byte) ( genderRace < 4 ? 0 : ( ( genderRace / 2 ) - 1 ) );
            race = Race.Races[raceId];

            if ( race == null )
                race = Race.DefaultRace;

            clientIP = (uint) IPAddress.NetworkToHostOrder( (int) clientIP );

            state.ClientAddress = new IPAddress( (long) clientIP );

            CityInfo[] info = state.CityInfo;
            IAccount a = state.Account;

            if ( Utility.IsUsingMulticlient( state, Environment.Config.Login.MaxLoginsPerPC ) )
            {
                Console.WriteLine( "Login: {0}: Multiclient detected, disconnecting...", state );
                state.Send( new PopupMessage( PMMessage.LoginSyncError ) );
                state.Dispose();
                return;
            }

            if ( info == null || a == null || cityIndex < 0 || cityIndex >= info.Length )
            {
                state.Dispose();
            }
            else
            {
                // Check if anyone is using this account
                for ( int i = 0; i < a.Length; ++i )
                {
                    Mobile check = a[i];

                    if ( check != null && check.Map != Map.Internal )
                    {
                        Console.WriteLine( "Login: {0}: Account in use", state );
                        state.Send( new PopupMessage( PMMessage.CharInWorld ) );
                        return;
                    }
                }

                state.Flags = flags;

                CreateCharRequestEventArgs args = new CreateCharRequestEventArgs(
                    state, a,
                    name, female, hue,
                    str, dex, intl,
                    info[cityIndex],
                    new SkillNameValue[4]
                    {
                        new SkillNameValue( (SkillName)is1, vs1 ),
                        new SkillNameValue( (SkillName)is2, vs2 ),
                        new SkillNameValue( (SkillName)is3, vs3 ),
                        new SkillNameValue( (SkillName)is4, vs4 ),
                    },
                    shirtHue, pantsHue,
                    hairVal, hairHue,
                    hairValf, hairHuef,
                    prof,
                    race
                    );

                state.BlockAllPackets = true;

                try
                {
                    EventSink.Instance.InvokeCreateCharRequest( args );
                }
                catch ( Exception ex )
                {
                    Logger.Error( "Exception disarmed in CreateCharRequest {0}: {1}", name, ex );
                }

                Mobile m = args.Mobile;

                if ( m != null )
                {
                    state.Mobile = m;
                    m.Client = state;

                    state.BlockAllPackets = false;

                    try
                    {
                        EventSink.Instance.InvokeCharacterCreated( new CharacterCreatedEventArgs( m ) );
                    }
                    catch ( Exception ex )
                    {
                        Logger.Error( "Exception disarmed in CharacterCreated {0}: {1}", m, ex );
                    }

                    DoLogin( state, m );
                }
                else
                {
                    state.BlockAllPackets = false;
                    state.Dispose();
                }
            }
        }
Example #4
0
        public void CreateCharacterEnhanced( GameClient state, PacketReader pvSrc )
        {
            pvSrc.ReadInt32(); // 0xEDEDEDED

            /*int charSlot = */
            pvSrc.ReadInt32();

            string name = pvSrc.ReadString( 30 );

            pvSrc.Seek( 30, SeekOrigin.Current );

            int prof = pvSrc.ReadByte();
            int cityIndex = pvSrc.ReadByte();
            int genderId = pvSrc.ReadByte();
            int raceId = pvSrc.ReadByte();

            int str = pvSrc.ReadByte();
            int dex = pvSrc.ReadByte();
            int intl = pvSrc.ReadByte();

            int hue = pvSrc.ReadUInt16();

            pvSrc.Seek( 8, SeekOrigin.Current );

            int is1 = pvSrc.ReadByte();
            int vs1 = pvSrc.ReadByte();
            int is2 = pvSrc.ReadByte();
            int vs2 = pvSrc.ReadByte();
            int is3 = pvSrc.ReadByte();
            int vs3 = pvSrc.ReadByte();
            int is4 = pvSrc.ReadByte();
            int vs4 = pvSrc.ReadByte();

            pvSrc.Seek( 25, SeekOrigin.Current );

            pvSrc.ReadByte(); // 0x0B
            int hairHue = pvSrc.ReadInt16();
            int hairVal = pvSrc.ReadInt16();

            pvSrc.ReadByte(); // 0x0C
            int pantsHue = pvSrc.ReadInt16();
            /*int pantsVal = */
            pvSrc.ReadInt16();

            pvSrc.ReadByte(); // 0x0D
            int shirtHue = pvSrc.ReadInt16();
            /*int shirtVal = */
            pvSrc.ReadInt16();

            pvSrc.ReadByte(); // 0x0F
            /*int faceHue = */
            pvSrc.ReadInt16();
            /*int faceVal = */
            pvSrc.ReadInt16();

            pvSrc.ReadByte(); // 0x10
            int hairValf = pvSrc.ReadInt16();
            int hairHuef = pvSrc.ReadInt16();

            // male=0, female=1
            bool female = ( genderId == 1 );

            // human=0, elf=1, gargoyle=2
            raceId = raceId - 1; // convert to zero-based
            if ( raceId < 0 )
                raceId = 0;
            if ( raceId >= Race.Races.Length )
                raceId = Race.Races.Length;

            Race race = Race.Races[raceId];
            if ( race == null )
                race = Race.DefaultRace;

            CityInfo[] info = state.CityInfo;
            IAccount a = state.Account;

            if ( info == null || a == null || cityIndex < 0 || cityIndex >= info.Length )
            {
                state.Dispose();
            }
            else
            {
                // Check if anyone is using this account
                for ( int i = 0; i < a.Length; ++i )
                {
                    Mobile check = a[i];

                    if ( check != null && check.Map != Map.Internal )
                    {
                        Console.WriteLine( "Login: {0}: Account in use", state );
                        state.Send( new PopupMessage( PMMessage.CharInWorld ) );
                        return;
                    }
                }

                CreateCharRequestEventArgs args = new CreateCharRequestEventArgs(
                    state, a,
                    name, female, hue,
                    str, dex, intl,
                    info[cityIndex],
                    new SkillNameValue[4]
                    {
                        new SkillNameValue( (SkillName)is1, vs1 ),
                        new SkillNameValue( (SkillName)is2, vs2 ),
                        new SkillNameValue( (SkillName)is3, vs3 ),
                        new SkillNameValue( (SkillName)is4, vs4 ),
                    },
                    shirtHue, pantsHue,
                    hairVal, hairHue,
                    hairValf, hairHuef,
                    prof,
                    race
                    );

                state.BlockAllPackets = true;

                try
                {
                    EventSink.Instance.InvokeCreateCharRequest( args );
                }
                catch ( Exception ex )
                {
                    Logger.Error( "Exception disarmed in CreateCharRequest {0}: {1}", name, ex );
                }

                Mobile m = args.Mobile;

                if ( m != null )
                {
                    state.Mobile = m;
                    m.Client = state;

                    state.BlockAllPackets = false;

                    try
                    {
                        EventSink.Instance.InvokeCharacterCreated( new CharacterCreatedEventArgs( m ) );
                    }
                    catch ( Exception ex )
                    {
                        Logger.Error( "Exception disarmed in CharacterCreated {0}: {1}", m, ex );
                    }

                    DoLogin( state, m );
                }
                else
                {
                    state.BlockAllPackets = false;
                    state.Dispose();
                }
            }
        }
Example #5
0
 public void AccountLogin_ReplyRej( GameClient state, ALRReason reason )
 {
     state.Send( new AccountLoginRej( reason ) );
     state.Dispose();
 }
Example #6
0
 public bool VerifyGC( GameClient state )
 {
     if ( state.Mobile == null || state.Mobile.AccessLevel <= AccessLevel.Counselor )
     {
         Console.WriteLine( "Warning: {0}: Player using godclient, disconnecting", state );
         state.Dispose();
         return false;
     }
     else
     {
         return true;
     }
 }
Example #7
0
        public void AccountLogin_ReplyAck( GameClient state )
        {
            ServerListEventArgs e = new ServerListEventArgs( state, state.Account );

            try
            {
                EventSink.Instance.InvokeServerList( e );
            }
            catch ( Exception ex )
            {
                Logger.Error( "Exception disarmed in ServerList: {0}", ex );
                e.Rejected = true;
            }

            if ( e.Rejected )
            {
                state.Account = null;
                state.Send( new AccountLoginRej( ALRReason.BadComm ) );
                state.Dispose();
            }
            else
            {
                ServerInfo[] info = e.Servers.ToArray();

                state.ServerInfo = info;

                state.Send( new AccountLoginAck( info ) );
            }
        }
Example #8
0
        public void EncodedCommand( GameClient state, PacketReader pvSrc )
        {
            IEntity e = World.Instance.FindEntity( pvSrc.ReadInt32() );
            int packetID = pvSrc.ReadUInt16();

            EncodedPacketHandler ph = GetEncodedHandler( packetID );

            if ( ph != null )
            {
                if ( ph.Ingame && state.Mobile == null )
                {
                    Console.WriteLine( "Client: {0}: Sent ingame packet (0xD7x{1:X2}) before having been attached to a mobile", state, packetID );
                    state.Dispose();
                }
                else if ( ph.Ingame && state.Mobile.Deleted )
                {
                    state.Dispose();
                }
                else
                {
                    ph.OnReceive( state, e, new EncodedReader( pvSrc ) );
                }
            }
            else
            {
                pvSrc.Trace( state );
            }
        }
Example #9
0
        public void TargetResponse( GameClient state, PacketReader pvSrc )
        {
            int type = pvSrc.ReadByte();
            /*int targetID = */
            pvSrc.ReadInt32();
            /*int flags = */
            pvSrc.ReadByte();
            Serial serial = pvSrc.ReadInt32();
            int x = pvSrc.ReadInt16(), y = pvSrc.ReadInt16(), z = pvSrc.ReadInt16();
            int graphic = pvSrc.ReadInt16();

            Mobile from = state.Mobile;

            Target t = from.Target;

            if ( t == null )
            {
                state.NullTargets++;

                if ( state.NullTargets > GameClient.MaxNullTargets )
                {
                    state.Dispose();
                    return;
                }
            }
            else
            {
                state.NullTargets = 0;

                if ( x == -1 && y == -1 && !serial.IsValid )
                {
                    // User pressed escape
                    t.Cancel( from, TargetCancelType.Canceled );
                }
                else
                {
                    object toTarget;

                    if ( type == 1 )
                    {
                        if ( graphic == 0 )
                        {
                            toTarget = new LandTarget( new Point3D( x, y, z ), from.Map );
                        }
                        else
                        {
                            Map map = from.Map;

                            if ( map == null || map == Map.Internal )
                            {
                                t.Cancel( from, TargetCancelType.Canceled );
                                return;
                            }
                            else
                            {
                                Tile[] tiles = map.Tiles.GetStaticTiles( x, y, !t.DisallowMultis );

                                bool valid = false;

                                for ( int i = 0; !valid && i < tiles.Length; ++i )
                                {
                                    bool surface = ( TileData.ItemTable[tiles[i].ID & TileData.MaxItemValue].Flags & TileFlag.Surface ) != 0;
                                    int zOffset = surface ? tiles[i].Height : 0;

                                    if ( ( tiles[i].Z + zOffset ) == z && ( tiles[i].ID & TileData.MaxItemValue ) == ( graphic & TileData.MaxItemValue ) )
                                    {
                                        valid = true;
                                        z -= zOffset;
                                    }
                                }

                                if ( !valid )
                                {
                                    t.Cancel( from, TargetCancelType.Canceled );
                                    return;
                                }
                                else
                                {
                                    toTarget = new StaticTarget( new Point3D( x, y, z ), graphic );
                                }
                            }
                        }
                    }
                    else if ( serial.IsMobile )
                    {
                        toTarget = World.Instance.FindMobile( serial );
                    }
                    else if ( serial.IsItem )
                    {
                        toTarget = World.Instance.FindItem( serial );
                    }
                    else
                    {
                        t.Cancel( from, TargetCancelType.Canceled );
                        return;
                    }

                    try
                    {
                        t.Invoke( from, toTarget );
                    }
                    catch ( Exception e )
                    {
                        Logger.Error( "Exception disarmed in target {0} > {1} > {2}: {3}", from, t, toTarget, e );
                    }
                }
            }
        }
Example #10
0
        public void PlayServer( GameClient state, PacketReader pvSrc )
        {
            int index = pvSrc.ReadInt16();

            ServerInfo[] info = state.ServerInfo;
            IAccount a = state.Account;

            if ( info == null || a == null || index < 0 || index >= info.Length )
            {
                state.Dispose();
            }
            else
            {
                ServerInfo si = info[index];

                state.m_AuthID = PlayServerAck.m_AuthID = GenerateAuthID( state );

                state.SentFirstPacket = false;
                state.Send( new PlayServerAck( si ) );

                // Close the connection, since they will be redirected to the game server.
                state.Dispose();
            }
        }
Example #11
0
        public void PlayCharacter( GameClient state, PacketReader pvSrc )
        {
            pvSrc.ReadInt32(); // 0xEDEDEDED

            /*string name = */
            pvSrc.ReadString( 30 );

            pvSrc.Seek( 2, SeekOrigin.Current );
            int flags = pvSrc.ReadInt32();
            pvSrc.Seek( 24, SeekOrigin.Current );

            int charSlot = pvSrc.ReadInt32();
            uint clientIP = pvSrc.ReadUInt32();

            clientIP = (uint) IPAddress.NetworkToHostOrder( (int) clientIP );
            state.ClientAddress = new IPAddress( (long) clientIP );

            IAccount a = state.Account;

            if ( Utility.IsUsingMulticlient( state, Environment.Config.Login.MaxLoginsPerPC ) )
            {
                Console.WriteLine( "Login: {0}: Multiclient detected, disconnecting...", state );
                state.Send( new PopupMessage( PMMessage.LoginSyncError ) );
                state.Dispose();
                return;
            }

            if ( a == null || charSlot < 0 || charSlot >= a.Length )
            {
                state.Dispose();
            }
            else
            {
                Mobile m = a[charSlot];

                // Check if anyone is using this account
                for ( int i = 0; i < a.Length; ++i )
                {
                    Mobile check = a[i];

                    if ( check != null && check.Map != Map.Internal && check != m )
                    {
                        Console.WriteLine( "Login: {0}: Account in use", state );
                        state.Send( new PopupMessage( PMMessage.CharInWorld ) );
                        return;
                    }
                }

                if ( m == null )
                {
                    state.Dispose();
                }
                else
                {
                    if ( m.Client != null )
                        m.Client.Dispose();

                    GameServer.Instance.ProcessDisposedQueue();

                    state.BlockAllPackets = true;

                    state.Flags = flags;

                    state.Mobile = m;
                    m.Client = state;

                    state.BlockAllPackets = false;
                    DoLogin( state, m );
                }
            }
        }
Example #12
0
        public void LoginServerSeed( GameClient state, PacketReader pvSrc )
        {
            state.m_Seed = pvSrc.ReadInt32();
            state.Seeded = true;

            if ( state.m_Seed == 0 )
            {
                Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state );
                state.Dispose();
                return;
            }

            int clientMaj = pvSrc.ReadInt32();
            int clientMin = pvSrc.ReadInt32();
            int clientRev = pvSrc.ReadInt32();
            int clientPat = pvSrc.ReadInt32();

            state.Version = new ClientVersion( clientMaj, clientMin, clientRev, clientPat );
        }
Example #13
0
        public void GameLogin( GameClient state, PacketReader pvSrc )
        {
            if ( state.SentFirstPacket )
            {
                state.Dispose();
                return;
            }

            state.SentFirstPacket = true;

            int authID = pvSrc.ReadInt32();

            if ( m_AuthIDWindow.ContainsKey( authID ) )
            {
                AuthIDPersistence ap = m_AuthIDWindow[authID];
                m_AuthIDWindow.Remove( authID );

                state.Version = ap.Version;
            }
            else if ( m_ClientVerification )
            {
                Console.WriteLine( "GameLogin: {0}: Invalid auth ID, disconnecting", state );
                state.Dispose();
                return;
            }

            if ( state.m_AuthID != 0 && authID != state.m_AuthID )
            {
                Console.WriteLine( "GameLogin: {0}: Invalid auth ID, disconnecting", state );
                state.Dispose();
                return;
            }
            else if ( state.m_AuthID == 0 && state.m_Seed != -1 && authID != state.m_Seed )
            {
                Console.WriteLine( "GameLogin: {0}: Invalid auth ID, disconnecting", state );
                state.Dispose();
                return;
            }

            string username = pvSrc.ReadString( 30 );
            string password = pvSrc.ReadString( 30 );

            GameLoginEventArgs e = new GameLoginEventArgs( state, username, password );

            try
            {
                EventSink.Instance.InvokeGameLogin( e );
            }
            catch ( Exception ex )
            {
                Logger.Error( "Exception disarmed in GameLogin {0}: {1}", username, ex );
            }

            if ( e.Accepted )
            {
                if ( state.Account == null )
                {
                    state.Dispose();
                    return;
                }

                state.CityInfo = e.CityInfo;
                state.CompressionEnabled = true;

                state.Send( SupportedFeatures.Instantiate( state ) );

                if ( state.Version != null && ( state.Version >= CV.Client70130 || state.Version.IsEnhanced ) )
                    state.Send( new CharacterListHS( state.Account, state.CityInfo ) );
                else
                    state.Send( new CharacterList( state.Account, state.CityInfo ) );
            }
            else
            {
                state.Dispose();
            }
        }
Example #14
0
        public void ExtendedCommand( GameClient state, PacketReader pvSrc )
        {
            int packetId = pvSrc.ReadUInt16();

            PacketHandler ph = GetExtendedHandler( packetId );

            if ( ph != null )
            {
                if ( ph.Ingame && state.Mobile == null )
                {
                    Console.WriteLine( "Client: {0}: Sent ingame packet (0xBFx{1:X2}) before having been attached to a mobile", state, packetId );
                    state.Dispose();
                }
                else if ( ph.Ingame && state.Mobile.Deleted )
                {
                    state.Dispose();
                }
                else
                {
                    ph.OnReceive( state, pvSrc );
                }
            }
            else
            {
                pvSrc.Trace( state );
            }
        }
Example #15
0
        public void AccountLogin( GameClient state, PacketReader pvSrc )
        {
            if ( state.SentFirstPacket )
            {
                state.Dispose();
                return;
            }

            state.SentFirstPacket = true;

            string username = pvSrc.ReadString( 30 );
            string password = pvSrc.ReadString( 30 );

            AccountLoginEventArgs e = new AccountLoginEventArgs( state, username, password );

            try
            {
                EventSink.Instance.InvokeAccountLogin( e );
            }
            catch ( Exception ex )
            {
                Logger.Error( "Exception disarmed in AccountLogin {0}: {1}", username, ex );
            }

            if ( e.Accepted )
                AccountLogin_ReplyAck( state );
            else
                AccountLogin_ReplyRej( state, e.RejectReason );
        }
Example #16
0
            public override void OnResponse( GameClient sender, RelayInfo info )
            {
                PlayerMobile pm = m_Entry.Player;

                m_CloseTimer.Stop();

                if ( Campfire.GetEntry( pm ) != m_Entry )
                    return;

                if ( info.ButtonID == 2 && m_Entry.Safe && m_Bedroll.Parent == null && m_Bedroll.IsAccessibleTo( pm )
                    && m_Bedroll.VerifyMove( pm ) && m_Bedroll.Map == pm.Map && pm.InRange( m_Bedroll, 2 ) )
                {
                    pm.PlaceInBackpack( m_Bedroll );

                    pm.BedrollLogout = true;
                    sender.Dispose();
                }

                Campfire.RemoveEntry( m_Entry );
            }
Example #17
0
        public void DisplayGumpResponse( GameClient state, PacketReader pvSrc )
        {
            int serial = pvSrc.ReadInt32();
            int typeID = pvSrc.ReadInt32();
            int buttonID = pvSrc.ReadInt32();

            foreach ( Gump gump in state.Gumps )
            {
                if ( gump.Serial == serial && gump.TypeID == typeID )
                {
                    int switchCount = pvSrc.ReadInt32();

                    if ( switchCount < 0 || switchCount > gump.m_Switches )
                    {
                        Console.WriteLine( "Client: {0}: Invalid gump response, disconnecting...", state );
                        state.Dispose();
                        return;
                    }

                    int[] switches = new int[switchCount];

                    for ( int j = 0; j < switches.Length; ++j )
                        switches[j] = pvSrc.ReadInt32();

                    int textCount = pvSrc.ReadInt32();

                    if ( textCount < 0 || textCount > gump.m_TextEntries )
                    {
                        Console.WriteLine( "Client: {0}: Invalid gump response, disconnecting...", state );
                        state.Dispose();
                        return;
                    }

                    TextRelay[] textEntries = new TextRelay[textCount];

                    for ( int j = 0; j < textEntries.Length; ++j )
                    {
                        int entryID = pvSrc.ReadUInt16();
                        int textLength = pvSrc.ReadUInt16();

                        if ( textLength > 239 )
                            return;

                        string text = pvSrc.ReadUnicodeStringSafe( textLength );
                        textEntries[j] = new TextRelay( entryID, text );
                    }

                    try
                    {
                        gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) );
                    }
                    catch ( Exception e )
                    {
                        Logger.Error( "Exception disarmed in gump response of {0}: {1}", gump, e );
                    }

                    state.RemoveGump( gump );
                    return;
                }
            }

            if ( typeID == 461 )
            { // Virtue gump
                int switchCount = pvSrc.ReadInt32();

                if ( buttonID == 1 && switchCount > 0 )
                {
                    Mobile beheld = World.Instance.FindMobile( pvSrc.ReadInt32() );

                    if ( beheld != null )
                        EventSink.Instance.InvokeVirtueGumpRequest( new VirtueGumpRequestEventArgs( state.Mobile, beheld ) );
                }
                else if ( buttonID == 1971 )
                {
                    EventSink.Instance.InvokeVirtueGumpRequest( new VirtueGumpRequestEventArgs( state.Mobile, state.Mobile ) );
                }
                else
                {
                    Mobile beheld = World.Instance.FindMobile( serial );

                    if ( beheld != null )
                        EventSink.Instance.InvokeVirtueItemRequest( new VirtueItemRequestEventArgs( state.Mobile, beheld, buttonID ) );
                }
            }
        }