示例#1
0
        public static void DecodeBundledPacket(NetState state, PacketReader pvSrc)
        {
            int packetID = pvSrc.ReadByte();

            PacketHandler ph = GetHandler(packetID);

            if (ph != null)
            {
                if (ph.Ingame && state.Mobile == null)
                {
                    Utility.PushColor(ConsoleColor.DarkRed);
                    Console.WriteLine("Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID);
                    Utility.PopColor();
                    state.Dispose();
                }
                else if (ph.Ingame && state.Mobile.Deleted)
                {
                    state.Dispose();
                }
                else
                {
                    ph.OnReceive(state, pvSrc);
                }
            }
        }
        public void RejectNoEncryption(NetState ns)
        {
            // Log it on the console
            Console.WriteLine("Client: {0}: Unencrypted client detected, disconnected", ns);

            // Send the client the typical "Bad communication" packet and also a sysmessage stating the error
            ns.Send(new AsciiMessage(Server.Serial.MinusOne, -1, MessageType.Label, 0x35, 3, "System", "Unencrypted connections are not allowed on this server."));
            ns.Send(new AccountLoginRej(ALRReason.BadComm));

            // Disconnect the client
            ns.Dispose(true);
        }
        public static void DecodeBundledPacket( NetState state, PacketReader pvSrc )
        {
            int packetID = pvSrc.ReadByte();

            PacketHandler ph = GetHandler( packetID );

            if ( ph != null )
            {
                if ( ph.Ingame && state.Mobile == null )
                {
                    log.Warn(String.Format("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 );
                }
            }
        }
		public static void EncodedCommand( NetState state, PacketReader pvSrc )
		{
			IEntity e = World.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 );
			}
		}
		public static void AccountLogin_ReplyAck( NetState state )
		{
			ServerListEventArgs e = new ServerListEventArgs( state, state.Account );

			EventSink.InvokeServerList( e );

			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 ) );
			}
		}
		public static void LoginServerSeed( NetState 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 );
		}
		public static void GameLogin( NetState 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( "Login: {0}: Invalid client detected, disconnecting", state );
				state.Dispose();
				return;
			}
			
			if ( state.m_AuthID != 0 && authID != state.m_AuthID )
			{
				Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state );
				state.Dispose();
				return;
			}
			else if ( state.m_AuthID == 0 && authID != state.m_Seed )
			{
				Console.WriteLine( "Login: {0}: Invalid client detected, disconnecting", state );
				state.Dispose();
				return;
			}

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

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

			EventSink.InvokeGameLogin( e );

			if ( e.Accepted )
			{
				state.CityInfo = e.CityInfo;
				state.CompressionEnabled = true;

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

				if ( state.NewCharacterList ) {
					state.Send( new CharacterList( state.Account, state.CityInfo ) );
				} else {
					state.Send( new CharacterListOld( state.Account, state.CityInfo ) );
				}
			}
			else
			{
				state.Dispose();
			}
		}
		public static void PlayCharacter( NetState state, PacketReader pvSrc )
		{
			pvSrc.ReadInt32(); // 0xEDEDEDED

			string name = pvSrc.ReadString( 30 );

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

			if ( FeatureProtection.DisabledFeatures != 0 && ThirdPartyAuthCallback != null )
			{
				bool authOK = false;

				ulong razorFeatures = (((ulong)pvSrc.ReadUInt32())<<32) | ((ulong)pvSrc.ReadUInt32());

				if ( razorFeatures == (ulong)FeatureProtection.DisabledFeatures )
				{
					bool match = true;
					for ( int i=0; match && i < m_ThirdPartyAuthKey.Length; i++ )
						match = match && pvSrc.ReadByte() == m_ThirdPartyAuthKey[i];
						
					if ( match )
						authOK = true;
				}
                else
                {
                    pvSrc.Seek( 16, SeekOrigin.Current );
                }

				ThirdPartyAuthCallback( state, authOK );
			}
			else
			{
				pvSrc.Seek( 24, SeekOrigin.Current );
			}

			if ( ThirdPartyHackedCallback != null )
			{
				pvSrc.Seek( -2, SeekOrigin.Current );
				if ( pvSrc.ReadUInt16() == 0xDEAD )
					ThirdPartyHackedCallback( state, true );
			}

			if ( !state.Running )
				return;

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

			IAccount a = state.Account;

			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.NetState != null )
						m.NetState.Dispose();

					NetState.ProcessDisposedQueue();

					state.Send( new ClientVersionReq() );

					state.BlockAllPackets = true;

					state.Flags = (ClientFlags)flags;

					state.Mobile = m;
					m.NetState = state;

					new LoginTimer( state, m ).Start();
				}
			}
		}
		public static void DisplayGumpResponse( NetState 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 ) {
						state.WriteConsole( "Invalid gump response, disconnecting..." );
						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 ) {
						state.WriteConsole( "Invalid gump response, disconnecting..." );
						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 ) {
							state.WriteConsole( "Invalid gump response, disconnecting..." );
							state.Dispose();
							return;
						}

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

					state.RemoveGump( gump );

					GumpProfile prof = GumpProfile.Acquire( gump.GetType() );

					if ( prof != null ) {
						prof.Start();
					}

					gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) );

					if ( prof != null ) {
						prof.Finish();
					}

					return;
				}
			}

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

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

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

					if ( beheld != null ) {
						EventSink.InvokeVirtueItemRequest( new VirtueItemRequestEventArgs( state.Mobile, beheld, buttonID ) );
					}
				}
			}
		}
        // Try to decrypt incoming data.
        public void DecodeIncomingPacket(NetState from, ref byte[] buffer, ref int length)
        {
            #region m_Encryption != null
            if (m_Encryption != null)
            {
                // If we're decrypting using LoginCrypt and we've already been relayed,
                // only decrypt a single packet using logincrypt and then disable it
                if (m_AlreadyRelayed && m_Encryption is LoginEncryption)
                {
                    uint newSeed = ((((LoginEncryption)(m_Encryption)).Key1 + 1) ^ ((LoginEncryption)(m_Encryption)).Key2);

                    // Swap the seed
                    newSeed = ((newSeed >> 24) & 0xFF) | ((newSeed >> 8) & 0xFF00) | ((newSeed << 8) & 0xFF0000) | ((newSeed << 24) & 0xFF000000);

                    // XOR it with the old seed
                    newSeed ^= m_Seed;

                    IClientEncryption newEncryption = new GameEncryption(newSeed);

                    // Game Encryption comes first
                    newEncryption.clientDecrypt(ref buffer, length);

                    // The login encryption is still used for this one packet
                    m_Encryption.clientDecrypt(ref buffer, length);

                    // Swap the encryption schemes
                    m_Encryption = newEncryption;
                    m_Seed = newSeed;

                    return;
                }

                m_Encryption.clientDecrypt(ref buffer, length);
                return;
            }
            #endregion

            #region Port Scan
            //11JUN2008 GOW SVN fix ** START ***
            // If the client did not connect on the game server port,
            // it's not our business to handle encryption for it
            //if (((IPEndPoint)from.Socket.LocalEndPoint).Port != Listener.Port) 
            //{
            //    m_Encryption = new NoEncryption();
            //    return;
            //}
            bool handle = false;

            for (int i = 0; i < Listener.EndPoints.Length; i++)
            {
                IPEndPoint ipep = (IPEndPoint)Listener.EndPoints[i];

                if (((IPEndPoint)from.Socket.LocalEndPoint).Port == ipep.Port)
                    handle = true;
            }

            if (!handle)
            {
                m_Encryption = new NoEncryption();
                return;
            }
            #endregion

            #region !m_Seeded
            // For simplicities sake, enqueue what we just received as long as we're not initialized
            m_Buffer.Enqueue(buffer, 0, length);
            // Clear the array
            length = 0;

            // If we didn't receive the seed yet, queue data until we can read the seed
            //if (!m_Seeded) 
            //{
            //    // Now check if we have at least 4 bytes to get the seed
            //    if (m_Buffer.Length >= 4) 
            //    {
            //        byte[] m_Peek = new byte[m_Buffer.Length];
            //        m_Buffer.Dequeue( m_Peek, 0, m_Buffer.Length ); // Dequeue everything
            //        m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
            //        m_Seeded = true;

            //        Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
            //        length = 4;
            //    } 
            //    else 
            //    {
            //        return;
            //    }
            //}
            //http://uodev.de/viewtopic.php?t=5097&postdays=0&postorder=asc&start=15&sid=dfb8e6c73b9e3eb95c1634ca3586e8a7
            //if (!m_Seeded)
            //{
            //    int seed_length = m_Buffer.GetSeedLength();

            //    if (m_Buffer.Length >= seed_length)
            //    {
            //        byte[] m_Peek = new byte[m_Buffer.Length];
            //        m_Buffer.Dequeue(m_Peek, 0, seed_length);

            //        if (seed_length == 4)
            //            m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
            //        else if (seed_length == 21)
            //            m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);

            //        m_Seeded = true;

            //        Buffer.BlockCopy(m_Peek, 0, buffer, 0, seed_length);
            //        length = seed_length;
            //    }
            //    else
            //    {
            //        return;
            //    }
            //}

            //11JUN2008 My Version

            if (!m_Seeded)
            {
                if (m_Buffer.Length <= 3) //Short Length, try again.
                {
                    Console.WriteLine("Encryption: Failed - Short Lenght");
                    return;
                }
                //else if ((m_Buffer.Length == 83) && (m_Buffer.GetPacketID() == 239)) //New Client
                //{
                //    byte[] m_Peek = new byte[21];
                //    m_Buffer.Dequeue(m_Peek, 0, 21);

                //    m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                //    m_Seeded = true;

                //    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);
                //    length = 21;

                //    Console.WriteLine("Encryption: Passed - New Client");
                //}

                //05MAR2009 Smjert's fix for double log in.  *** START ***
                else if ((m_Buffer.Length == 83 || m_Buffer.Length == 21) && (m_Buffer.GetPacketID() == 239)) //New Client
                {
                    length = m_Buffer.Length;
                    byte[] m_Peek = new byte[21];
                    m_Buffer.Dequeue(m_Peek, 0, 21);

                    m_Seed = (uint)((m_Peek[1] << 24) | (m_Peek[2] << 16) | (m_Peek[3] << 8) | m_Peek[4]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 21);


                    Console.WriteLine("Encryption: Passed - New Client");

                    // We need to wait the next packet
                    if (length == 21)
                        return;

                    length = 21;
                }

                else if (m_Buffer.Length >= 4) //Old Client
                //05MAR2009 Smjert's fix for double log in.  *** END ***
                {
                    byte[] m_Peek = new byte[4];
                    m_Buffer.Dequeue(m_Peek, 0, 4);

                    m_Seed = (uint)((m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3]);
                    m_Seeded = true;

                    Buffer.BlockCopy(m_Peek, 0, buffer, 0, 4);
                    length = 4;

                    Console.WriteLine("Encryption: Passed - Old Client");
                }
                else //It should never reach here.
                {
                    Console.WriteLine("Encryption: Failed - It should never reach here");
                    return;
                }
            }
            #endregion

            // If the context isn't initialized yet, that means we haven't decided on an encryption method yet
            #region m_Encryption == null
            if (m_Encryption == null)
            {
                int packetLength = m_Buffer.Length;
                int packetOffset = length;
                m_Buffer.Dequeue(buffer, length, packetLength); // Dequeue everything
                length += packetLength;

                // This is special handling for the "special" UOG packet
                if (packetLength >= 3)
                {
                    if (buffer[packetOffset] == 0xf1 && buffer[packetOffset + 1] == ((packetLength >> 8) & 0xFF) && buffer[packetOffset + 2] == (packetLength & 0xFF))
                    {
                        m_Encryption = new NoEncryption();
                        return;
                    }
                }

                // Check if the current buffer contains a valid login packet (62 byte + 4 byte header)
                // Please note that the client sends these in two chunks. One 4 byte and one 62 byte.
                if (packetLength == 62)
                {
                    Console.WriteLine("Checking packetLength 62 == " + packetLength);
                    // Check certain indices in the array to see if the given data is unencrypted
                    if (buffer[packetOffset] == 0x80 && buffer[packetOffset + 30] == 0x00 && buffer[packetOffset + 60] == 0x00)
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                            return;
                        }
                    }
                    else
                    {
                        LoginEncryption encryption = new LoginEncryption();
                        if (encryption.init(m_Seed, buffer, packetOffset, packetLength))
                        {
                            Console.WriteLine("Client: {0}: Encrypted client detected, using keys of client {1}", from, encryption.Name);
                            m_Encryption = encryption;
                            Console.WriteLine("Encryption: Check 1");
                            byte[] packet = new byte[packetLength];
                            Console.WriteLine("Encryption: Check 2");
                            Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                            Console.WriteLine("Encryption: Check 3");
                            encryption.clientDecrypt(ref packet, packet.Length);
                            Console.WriteLine("Encryption: Check 4");
                            Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                            Console.WriteLine("Encryption: Check 5");
                            //return; //Just throwing this in.
                        }
                        else
                        {
                            Console.WriteLine("Detected an unknown client.");
                        }
                    }
                }
                else if (packetLength == 65)
                {
                    Console.WriteLine("Checking packetLength 65 == " + packetLength);
                    // If its unencrypted, use the NoEncryption class
                    if (buffer[packetOffset] == '\x91' && buffer[packetOffset + 1] == ((m_Seed >> 24) & 0xFF) && buffer[packetOffset + 2] == ((m_Seed >> 16) & 0xFF) && buffer[packetOffset + 3] == ((m_Seed >> 8) & 0xFF) && buffer[packetOffset + 4] == (m_Seed & 0xFF))
                    {
                        if (Configuration.AllowUnencryptedClients)
                        {
                            m_Encryption = new NoEncryption();
                        }
                        else
                        {
                            RejectNoEncryption(from);
                            from.Dispose();
                        }
                    }
                    else
                    {
                        // If it's not an unencrypted packet, simply assume it's encrypted with the seed
                        m_Encryption = new GameEncryption(m_Seed);

                        byte[] packet = new byte[packetLength];
                        Buffer.BlockCopy(buffer, packetOffset, packet, 0, packetLength);
                        m_Encryption.clientDecrypt(ref packet, packet.Length);
                        Buffer.BlockCopy(packet, 0, buffer, packetOffset, packetLength);
                    }
                }

                // If it's still not initialized, copy the data back to the queue and wait for more
                if (m_Encryption == null)
                {
                    Console.WriteLine("Encryption: Check - Waiting");
                    m_Buffer.Enqueue(buffer, packetOffset, packetLength);
                    length -= packetLength;
                    return;
                }
            }
            #endregion
        }
		public static bool VerifyGC( NetState state )
		{
			if ( state.Mobile == null || state.Mobile.AccessLevel <= AccessLevel.Counselor )
			{
				if ( state.Running )
					log.WarnFormat("Player {0} using godclient, disconnecting",
								   state);

				state.Dispose();
				return false;
			}
			else
			{
				return true;
			}
		}
示例#12
0
            public override void OnResponse( NetState sender, RelayInfo info )
            {
                PlayerMobile pm = m_Entry.Player;

                m_CloseTimer.Stop();

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

                if ( info.ButtonID == 1 && 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 );
            }
示例#13
0
        public bool HandleReceive(NetState ns)
        {
            ByteQueue     queue1;
            int           num1;
            int           num2;
            int           num3;
            PacketHandler handler1;

            byte[] buffer1;
            int    num4;
            ThrottlePacketCallback callback1;
            PacketProfile          profile1;
            DateTime     time1;
            PacketReader reader1;
            NetState     state1 = ns;

            lock (ns)
            {
                queue1 = ns.Buffer;
                if (queue1 == null)
                {
                    return(true);
                }
                num1 = queue1.Length;
                if (ns.Seeded)
                {
                    goto Label_0250;
                }
                if (num1 >= 4)
                {
                    queue1.Dequeue(this.m_Peek, 0, 4);
                    num2 = ((((this.m_Peek[0] << 24) | (this.m_Peek[1] << 16)) | (this.m_Peek[2] << 8)) | this.m_Peek[3]);
                    if (num2 == 0)
                    {
                        Console.WriteLine("Login: {0}: Invalid client detected, disconnecting", ns);
                        ns.Dispose();
                        return(false);
                    }
                    ns.m_Seed = num2;
                    ns.Seeded = true;
                }
                return(true);

Label_009D:
                queue1.Peek(this.m_Peek, 0, 1);
                num3 = this.m_Peek[0];
                if (((!ns.SentFirstPacket && (num3 != 241)) && ((num3 != 207) && (num3 != 128))) && ((num3 != 145) && (num3 != 164)))
                {
                    Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns);
                    ns.Dispose();
                    goto Label_0269;
                }
                handler1 = PacketHandlers.GetHandler(num3);
                if (handler1 == null)
                {
                    buffer1 = queue1.Dequeue(num1);
                    new PacketReader(buffer1, 0).Trace(ns);
                    goto Label_0269;
                }
                num4 = handler1.Length;
                if (num4 <= 0)
                {
                    if (num1 < 3)
                    {
                        goto Label_0269;
                    }
                    queue1.Peek(this.m_Peek, 0, 3);
                    num4 = ((this.m_Peek[1] << 8) | this.m_Peek[2]);
                    if (num4 < 3)
                    {
                        ns.Dispose();
                        goto Label_0269;
                    }
                }
                if (num1 < num4)
                {
                    goto Label_0269;
                }
                if (handler1.Ingame && (ns.Mobile == null))
                {
                    Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, num3);
                    ns.Dispose();
                    goto Label_0269;
                }
                if (handler1.Ingame && ns.Mobile.Deleted)
                {
                    ns.Dispose();
                    goto Label_0269;
                }
                callback1 = handler1.ThrottleCallback;
                if ((callback1 != null) && !callback1.Invoke(ns))
                {
                    this.m_Throttled.Enqueue(ns);
                    return(false);
                }
                profile1 = PacketProfile.GetIncomingProfile(num3);
                time1    = ((profile1 == null) ? DateTime.MinValue : DateTime.Now);
                reader1  = new PacketReader(queue1.Dequeue(num4), (handler1.Length != 0));
                handler1.OnReceive(ns, reader1);
                num1 = queue1.Length;
                if (profile1 != null)
                {
                    profile1.Record(num4, ((TimeSpan)(DateTime.Now - time1)));
                }
Label_0250:
                if (num1 > 0)
                {
                    if (ns.Running)
                    {
                        goto Label_009D;
                    }
                }
            }
Label_0269:
            return(true);
        }
示例#14
0
        public void HandleReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return;
            }

            lock (buffer)
            {
                if (!ns.Seeded && !HandleSeed(ns, buffer))
                {
                    return;
                }

                int length = buffer.Length;

                while (length > 0 && ns.Running)
                {
                    int packetID = buffer.GetPacketID();

                    if (CheckEncrypted(ns, packetID))
                    {
                        return;
                    }

                    PacketHandler handler = ns.GetHandler(packetID);

                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);
                        new PacketReader(data, length, false).Trace(ns);
                        return;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                return;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }

                    if (length < packetLength)
                    {
                        return;
                    }

                    if (handler.Ingame)
                    {
                        if (ns.Mobile == null)
                        {
                            Utility.PushColor(ConsoleColor.Red);
                            Console.WriteLine("Client: {0}: Packet (0x{1:X2}) Requires State Mobile", ns, packetID);
                            Utility.PopColor();

                            ns.Dispose();
                            return;
                        }

                        if (ns.Mobile.Deleted)
                        {
                            Utility.PushColor(ConsoleColor.Red);
                            Console.WriteLine("Client: {0}: Packet (0x{1:X2}) Ivalid State Mobile", ns, packetID);
                            Utility.PopColor();

                            ns.Dispose();
                            return;
                        }
                    }

                    ThrottlePacketCallback throttler = handler.ThrottleCallback;

                    if (throttler != null)
                    {
                        if (!throttler(ns, out bool drop))
                        {
                            if (!drop)
                            {
                                m_Throttled.Enqueue(ns);
                            }
                            else
                            {
                                buffer.Dequeue(new byte[packetLength], 0, packetLength);
                            }

                            return;
                        }
                    }

                    PacketReceiveProfile prof = null;

                    if (Core.Profiling)
                    {
                        prof = PacketReceiveProfile.Acquire(packetID);
                    }

                    if (prof != null)
                    {
                        prof.Start();
                    }

                    byte[] packetBuffer;

                    if (BufferSize >= packetLength)
                    {
                        packetBuffer = m_Buffers.AcquireBuffer();
                    }
                    else
                    {
                        packetBuffer = new byte[packetLength];
                    }

                    packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                    if (packetBuffer != null && packetBuffer.Length > 0 && packetLength > 0)
                    {
                        PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                        handler.OnReceive(ns, r);

                        if (BufferSize >= packetLength)
                        {
                            m_Buffers.ReleaseBuffer(packetBuffer);
                        }
                    }

                    if (prof != null)
                    {
                        prof.Finish(packetLength);
                    }

                    length = buffer.Length;
                }
            }
        }
示例#15
0
        public bool HandleReceive(NetState ns)
        {
            lock ( ns )
            {
                ByteQueue buffer = ns.Buffer;

                if (buffer == null)
                {
                    return(true);
                }

                int length = buffer.Length;

                if (!ns.Seeded)
                {
                    if (length >= 4)
                    {
                        buffer.Dequeue(m_Peek, 0, 4);

                        int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3];

                        //Console.WriteLine( "Login: {0}: Seed is 0x{1:X8}", ns, seed );

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

                        ns.m_Seed = seed;
                        ns.Seeded = true;
                    }

                    return(true);
                }

                //Console.WriteLine( "{" );

                while (length > 0 && ns.Running)
                {
                    int packetID = buffer.GetPacketID();

                    if (!ns.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xBF)
                    {
                        Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns);
                        ns.Dispose();
                        break;
                    }

                    PacketHandler handler = PacketHandlers.GetHandler(packetID);

                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);

                        new PacketReader(data, length, false).Trace(ns);

                        break;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length >= packetLength)
                    {
                        if (handler.Ingame && ns.Mobile == null)
                        {
                            Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID);
                            ns.Dispose();
                            break;
                        }
                        else if (handler.Ingame && ns.Mobile.Deleted)
                        {
                            ns.Dispose();
                            break;
                        }
                        else
                        {
                            ThrottlePacketCallback throttler = handler.ThrottleCallback;

                            if (throttler != null && !throttler(ns))
                            {
                                m_Throttled.Enqueue(ns);
                                //Console.WriteLine( "}" );
                                return(false);
                            }

                            //Console.WriteLine( handler.OnReceive.Method.Name );

                            PacketProfile profile = PacketProfile.GetIncomingProfile(packetID);
                            DateTime      start   = (profile == null ? DateTime.MinValue : DateTime.Now);

                            byte[] packetBuffer;

                            if (BufferSize >= packetLength)
                            {
                                packetBuffer = m_Buffers.AquireBuffer();
                            }
                            else
                            {
                                packetBuffer = new byte[packetLength];
                            }

                            packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                            PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                            try {
                                handler.OnReceive(ns, r);
                            } catch (Exception e) {
                                Console.WriteLine("Exception disarmed in HandleReceive from {0}: {1}",
                                                  ns.Address, e);
                            }

                            length = buffer.Length;

                            if (BufferSize >= packetLength)
                            {
                                m_Buffers.ReleaseBuffer(packetBuffer);
                            }

                            if (profile != null)
                            {
                                profile.Record(packetLength, DateTime.Now - start);
                            }

                            //Console.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", ns, packetID );
                            //Utility.FormatBuffer( Console.Out, new System.IO.MemoryStream( r.Buffer ), r.Buffer.Length );
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                //Console.WriteLine( "}" );
            }

            return(true);
        }
示例#16
0
        public bool HandleReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return(true);
            }

            lock ( buffer )
            {
                int length = buffer.Length;

                if (!ns.Seeded)
                {
                    if (buffer.GetPacketID() == 0xEF)
                    {
                        // new packet in client	6.0.5.0	replaces the traditional seed method with a	seed packet
                        // 0xEF	= 239 =	multicast IP, so this should never appear in a normal seed.	 So	this is	backwards compatible with older	clients.
                        ns.Seeded = true;
                    }
                    else if (buffer.Length >= 4)
                    {
                        buffer.Dequeue(m_Peek, 0, 4);

                        int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3];

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

                        ns.m_Seed = seed;
                        ns.Seeded = true;

                        length = buffer.Length;
                    }
                    else
                    {
                        return(true);
                    }
                }

                while (length > 0 && ns.Running)
                {
                    int packetID = buffer.GetPacketID();

                    if (!ns.SentFirstPacket && packetID != 0xF0 && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 && packetID != 0xEF)
                    {
                        Console.WriteLine("Client: {0}: Encrypted client detected, disconnecting", ns);
                        ns.Dispose();
                        break;
                    }

                    PacketHandler handler = ns.GetHandler(packetID);

                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);

                        new PacketReader(data, length, false).Trace(ns);

                        break;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length >= packetLength)
                    {
                        if (handler.Ingame && ns.Mobile == null)
                        {
                            Console.WriteLine("Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID);
                            ns.Dispose();
                            break;
                        }
                        else if (handler.Ingame && ns.Mobile.Deleted)
                        {
                            ns.Dispose();
                            break;
                        }
                        else
                        {
                            ThrottlePacketCallback throttler = handler.ThrottleCallback;

                            if (throttler != null && !throttler(ns))
                            {
                                m_Throttled.Enqueue(ns);
                                return(false);
                            }

                            PacketReceiveProfile prof = PacketReceiveProfile.Acquire(packetID);

                            if (prof != null)
                            {
                                prof.Start();
                            }

                            byte[] packetBuffer;

                            if (BufferSize >= packetLength)
                            {
                                packetBuffer = m_Buffers.AcquireBuffer();
                            }
                            else
                            {
                                packetBuffer = new byte[packetLength];
                            }

                            packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                            PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                            handler.OnReceive(ns, r);
                            length = buffer.Length;

                            if (BufferSize >= packetLength)
                            {
                                m_Buffers.ReleaseBuffer(packetBuffer);
                            }

                            if (prof != null)
                            {
                                prof.Finish(packetLength);
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return(true);
        }
示例#17
0
        public static void DisplayGumpResponse(NetState state, CircularBufferReader reader)
        {
            var serial   = reader.ReadUInt32();
            var typeID   = reader.ReadInt32();
            var buttonID = reader.ReadInt32();

            foreach (var gump in state.Gumps)
            {
                if (gump.Serial != serial || gump.TypeID != typeID)
                {
                    continue;
                }

                var buttonExists = buttonID == 0; // 0 is always 'close'

                if (!buttonExists)
                {
                    foreach (var e in gump.Entries)
                    {
                        if (e is GumpButton button && button.ButtonID == buttonID)
                        {
                            buttonExists = true;
                            break;
                        }

                        if (e is GumpImageTileButton tileButton && tileButton.ButtonID == buttonID)
                        {
                            buttonExists = true;
                            break;
                        }
                    }
                }

                if (!buttonExists)
                {
                    state.WriteConsole("Invalid gump response, disconnecting...");
                    state.Dispose();
                    return;
                }

                var switchCount = reader.ReadInt32();

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

                var switches = new int[switchCount];

                for (var j = 0; j < switches.Length; ++j)
                {
                    switches[j] = reader.ReadInt32();
                }

                var textCount = reader.ReadInt32();

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

                var textEntries = new TextRelay[textCount];

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

                    if (textLength > 239)
                    {
                        state.WriteConsole("Invalid gump response, disconnecting...");
                        state.Dispose();
                        return;
                    }

                    var text = reader.ReadBigUniSafe(textLength);
                    textEntries[j] = new TextRelay(entryID, text);
                }

                state.RemoveGump(gump);

                var prof = GumpProfile.Acquire(gump.GetType());

                prof?.Start();

                gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries));

                prof?.Finish();

                return;
            }

            if (typeID == 461)
            {
                // Virtue gump
                var switchCount = reader.ReadInt32();

                if (buttonID == 1 && switchCount > 0)
                {
                    var beheld = World.FindMobile(reader.ReadUInt32());

                    if (beheld != null)
                    {
                        EventSink.InvokeVirtueGumpRequest(state.Mobile, beheld);
                    }
                }
                else
                {
                    var beheld = World.FindMobile(serial);

                    if (beheld != null)
                    {
                        EventSink.InvokeVirtueItemRequest(state.Mobile, beheld, buttonID);
                    }
                }
            }
        }
        public void HandleReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return;
            }

            lock (buffer)
            {
                if (!ns.Seeded)
                {
                    if (!HandleSeed(ns, buffer))
                    {
                        return;
                    }
                }

                int length = buffer.Length;

                while (length > 0 && ns.Running)
                {
                    int packetID = buffer.GetPacketID();

                    if (CheckEncrypted(ns, packetID))
                    {
                        break;
                    }

                    PacketHandler handler = ns.GetHandler(packetID);

                    if (handler == null)
                    {
                        var data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);
                        new PacketReader(data, length, false).Trace(ns);
                        break;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length >= packetLength)
                    {
                        if (handler.Ingame)
                        {
                            if (ns.Mobile == null)
                            {
                                Utility.PushColor(ConsoleColor.DarkRed);
                                Console.WriteLine(
                                    "Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID);
                                Utility.PopColor();
                                ns.Dispose();
                                break;
                            }
                            else if (ns.Mobile.Deleted)
                            {
                                ns.Dispose();
                                break;
                            }
                        }

                        ThrottlePacketCallback throttler = handler.ThrottleCallback;

                        if (throttler != null && !throttler(ns))
                        {
                            m_Throttled.Enqueue(ns);
                            return;
                        }

                        PacketReceiveProfile prof = null;

                        if (Core.Profiling)
                        {
                            prof = PacketReceiveProfile.Acquire(packetID);
                        }

                        if (prof != null)
                        {
                            prof.Start();
                        }

                        byte[] packetBuffer;

                        if (BufferSize >= packetLength)
                        {
                            packetBuffer = m_Buffers.AcquireBuffer();
                        }
                        else
                        {
                            packetBuffer = new byte[packetLength];
                        }

                        packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                        PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                        handler.OnReceive(ns, r);
                        length = buffer.Length;

                        if (BufferSize >= packetLength)
                        {
                            m_Buffers.ReleaseBuffer(packetBuffer);
                        }

                        if (prof != null)
                        {
                            prof.Finish(packetLength);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            #region Enhance Client
            // Would be nicer to detect the enhanced client in clientversion.cs
            // It seems that UOKR-EH sends a version number bigger 66.0.0.0, UOSA-EH bigger 67.0.0.0
            try
            {
                if (ns.Version.Major > 8)
                {
                    ns.IsKRClient = true;
                }
            }
            //Standard classic client does not display version this early, so we can rule SA enhanced client out
            catch
            {
                ns.IsKRClient = false;
            }
            return;

            #endregion
        }
示例#19
0
        public void HandleReceive(NetState ns)
        {
            ByteQueue buffer = ns.Buffer;

            if (buffer == null || buffer.Length <= 0)
            {
                return;
            }

            lock (buffer)
            {
                if (!ns.Seeded)
                {
                    if (!HandleSeed(ns, buffer))
                    {
                        return;
                    }
                }

                int length = buffer.Length;

                while (length > 0 && ns.Running)
                {
                    int packetID = buffer.GetPacketID();

                    if (CheckEncrypted(ns, packetID))
                    {
                        break;
                    }

                    PacketHandler handler = ns.GetHandler(packetID);

                    if (handler == null)
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue(data, 0, length);
                        new PacketReader(data, length, false).Trace(ns);
                        break;
                    }

                    int packetLength = handler.Length;

                    if (packetLength <= 0)
                    {
                        if (length >= 3)
                        {
                            packetLength = buffer.GetPacketLength();

                            if (packetLength < 3)
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (length >= packetLength)
                    {
                        if (handler.Ingame)
                        {
                            if (ns.Mobile == null)
                            {
                                Utility.WriteConsole(ConsoleColor.Yellow, "Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID);
                                ns.Dispose();
                                break;
                            }
                            else if (ns.Mobile.Deleted)
                            {
                                ns.Dispose();
                                break;
                            }
                        }

                        ThrottlePacketCallback throttler = handler.ThrottleCallback;

                        if (throttler != null && !throttler(ns))
                        {
                            m_Throttled.Enqueue(ns);
                            return;
                        }

                        PacketReceiveProfile prof = null;

                        if (Core.Profiling)
                        {
                            prof = PacketReceiveProfile.Acquire(packetID);
                        }

                        if (prof != null)
                        {
                            prof.Start();
                        }

                        byte[] packetBuffer;

                        if (BufferSize >= packetLength)
                        {
                            packetBuffer = m_Buffers.AcquireBuffer();
                        }
                        else
                        {
                            packetBuffer = new byte[packetLength];
                        }

                        packetLength = buffer.Dequeue(packetBuffer, 0, packetLength);

                        PacketReader r = new PacketReader(packetBuffer, packetLength, handler.Length != 0);

                        handler.OnReceive(ns, r);
                        length = buffer.Length;

                        if (BufferSize >= packetLength)
                        {
                            m_Buffers.ReleaseBuffer(packetBuffer);
                        }

                        if (prof != null)
                        {
                            prof.Finish(packetLength);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        public static void AccountLogin( NetState 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.InvokeAccountLogin(e);
            } catch (Exception ex) {
                Console.WriteLine("Exception disarmed in AccountLogin {0}: {1}",
                                  username, ex);
            }

            if ( e.Accepted )
                AccountLogin_ReplyAck( state );
            else
                AccountLogin_ReplyRej( state, e.RejectReason );
        }
		public static void DisplayGumpResponse( NetState 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 )
					{
						log.InfoFormat("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 )
					{
						log.InfoFormat("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 );
					}

					state.RemoveGump( gump );

					try {
						gump.OnResponse( state, new RelayInfo( buttonID, switches, textEntries ) );
					} catch (Exception e) {
						log.Fatal(String.Format("Exception disarmed in gump response of {0}",
												gump), e);
					}

					return;
				}
			}

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

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

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

					if ( beheld != null )
						EventSink.InvokeVirtueItemRequest( new VirtueItemRequestEventArgs( state.Mobile, beheld, buttonID ) );
				}
			}
		}
		public static void PlayCharacter( NetState 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();
			/*int clientIP = */pvSrc.ReadInt32();

			IAccount a = state.Account;

			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 )
					{
						log.InfoFormat("Login: {0}: Account in use", state);
						state.Send( new PopupMessage( PMMessage.CharInWorld ) );
						return;
					}
				}

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

					NetState.ProcessDisposedQueue();

					state.Send( new ClientVersionReq() );

					state.BlockAllPackets = true;

					state.Flags = flags;

					state.Mobile = m;
					m.NetState = state;

					new LoginTimer( state, m ).Start();
				}
			}
		}
示例#23
0
        public bool HandleReceive( NetState ns )
        {
            lock ( ns )
            {
                ByteQueue buffer = ns.Buffer;

                if ( buffer == null )
                    return true;

                int length = buffer.Length;

                if ( !ns.Seeded )
                {
                    if ( length >= 4 )
                    {
                        buffer.Dequeue( m_Peek, 0, 4 );

                        int seed = (m_Peek[0] << 24) | (m_Peek[1] << 16) | (m_Peek[2] << 8) | m_Peek[3];

                        //Console.WriteLine( "Login: {0}: Seed is 0x{1:X8}", ns, seed );

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

                        ns.m_Seed = seed;
                        ns.Seeded = true;
                    }

                    return true;
                }

                //Console.WriteLine( "{" );

                while ( length > 0 && ns.Running )
                {
                    int packetID = buffer.GetPacketID();

                    if ( !ns.SentFirstPacket && packetID != 0xF1 && packetID != 0xCF && packetID != 0x80 && packetID != 0x91 && packetID != 0xA4 )
                    {
                        Console.WriteLine( "Client: {0}: Encrypted client detected, disconnecting", ns );
                        ns.Dispose();
                        break;
                    }

                    PacketHandler handler = PacketHandlers.GetHandler( packetID );

                    if ( handler == null )
                    {
                        byte[] data = new byte[length];
                        length = buffer.Dequeue( data, 0, length );

                        new PacketReader( data, length, false ).Trace( ns );

                        break;
                    }

                    int packetLength = handler.Length;

                    if ( packetLength <= 0 )
                    {
                        if ( length >= 3 )
                        {
                            packetLength = buffer.GetPacketLength();

                            if ( packetLength < 3 )
                            {
                                ns.Dispose();
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }

                    if ( length >= packetLength )
                    {
                        if ( handler.Ingame && ns.Mobile == null )
                        {
                            Console.WriteLine( "Client: {0}: Sent ingame packet (0x{1:X2}) before having been attached to a mobile", ns, packetID );
                            ns.Dispose();
                            break;
                        }
                        else if ( handler.Ingame && ns.Mobile.Deleted )
                        {
                            ns.Dispose();
                            break;
                        }
                        else
                        {
                            ThrottlePacketCallback throttler = handler.ThrottleCallback;

                            if ( throttler != null && !throttler( ns ) )
                            {
                                m_Throttled.Enqueue( ns );
                                //Console.WriteLine( "}" );
                                return false;
                            }

                            //Console.WriteLine( handler.OnReceive.Method.Name );

                            PacketProfile profile = PacketProfile.GetIncomingProfile( packetID );
                            DateTime start = ( profile == null ? DateTime.MinValue : DateTime.Now );

                            byte[] packetBuffer;

                            if ( BufferSize >= packetLength )
                                packetBuffer = m_Buffers.AquireBuffer();
                            else
                                packetBuffer = new byte[packetLength];

                            packetLength = buffer.Dequeue( packetBuffer, 0, packetLength );

                            PacketReader r =  new PacketReader( packetBuffer, packetLength, handler.Length != 0 );

                            handler.OnReceive( ns, r );
                            length = buffer.Length;

                            if ( BufferSize >= packetLength )
                                m_Buffers.ReleaseBuffer( packetBuffer );

                            if ( profile != null )
                                profile.Record( packetLength, DateTime.Now - start );

                            //Console.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", ns, packetID );
                            //Utility.FormatBuffer( Console.Out, new System.IO.MemoryStream( r.Buffer ), r.Buffer.Length );
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                //Console.WriteLine( "}" );
            }

            return true;
        }
		public static void CreateCharacter( NetState 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 );

			bool female = pvSrc.ReadByte() > 0 ? true : false;
			/*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 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();
			/*int clientIP = */pvSrc.ReadInt32();
			int shirtHue = pvSrc.ReadInt16();
			int pantsHue = pvSrc.ReadInt16();

			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 )
					{
						log.InfoFormat("Login: {0}: Account in use", state);
						state.Send( new PopupMessage( PMMessage.CharInWorld ) );
						return;
					}
				}

				state.Flags = flags;

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

				state.Send( new ClientVersionReq() );

				state.BlockAllPackets = true;

				try {
					EventSink.InvokeCharacterCreated(args);
				} catch (Exception ex) {
					log.Fatal(String.Format("Exception disarmed in CharacterCreated {0}",
											name), ex);
				}

				Mobile m = args.Mobile;

				if ( m != null )
				{
					state.Mobile = m;
					m.NetState = state;
					new LoginTimer( state, m ).Start();
				}
				else
				{
					state.BlockAllPackets = false;
					state.Dispose();
				}
			}
		}
示例#25
0
		public static void ExtendedCommand( NetState 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 );
			}
		}
		private static void GameLoginInternal(NetState state, string username, string password,
											  bool compressionEnabled)
		{
			GameLoginEventArgs e = new GameLoginEventArgs( state, username, password );

			try {
				EventSink.InvokeGameLogin(e);
			} catch (Exception ex) {
				log.Fatal(String.Format("Exception disarmed in GameLogin {0}",
										username), ex);
			}

			if ( e.Accepted )
			{
				if (state.Account == null) {
					log.ErrorFormat("BUG: GameLogin state.Account==null (username {0})",
									username);
					state.Dispose();
					return;
				}

				state.CityInfo = e.CityInfo;
				state.CompressionEnabled = compressionEnabled;

				if ( Core.AOS )
					state.Send( SupportedFeatures.Instantiate( state.Account ) );

				state.Send( new CharacterList( state.Account, state.CityInfo ) );
			}
			else
			{
				state.Dispose();
			}
		}
示例#27
0
		public static void CreateCharacter70160( NetState 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();
			int clientIP = pvSrc.ReadInt32();
			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;

			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;
					}
				}

				state.Flags = (ClientFlags)flags;

				CharacterCreatedEventArgs args = new CharacterCreatedEventArgs(
					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.Send( new ClientVersionReq() );

				state.BlockAllPackets = true;

				EventSink.InvokeCharacterCreated( args );

				Mobile m = args.Mobile;

				if ( m != null )
				{
					state.Mobile = m;
					m.NetState = state;
					new LoginTimer( state, m ).Start();
				}
				else
				{
					state.BlockAllPackets = false;
					state.Dispose();
				}
			}
		}
		public static void GameLogin( NetState state, PacketReader pvSrc )
		{
			if ( state.SentFirstPacket )
			{
				state.Dispose();
				return;
			}

			state.SentFirstPacket = true;

			int authID = pvSrc.ReadInt32();

			if (Core.Config.Login.IgnoreAuthID)
				AddAuthID(authID);

			if ( !IsValidAuthID( authID ) )
			{
				log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state);
				state.Dispose();
				return;
			}
			else if ( state.m_AuthID != 0 && authID != state.m_AuthID )
			{
				log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state);
				state.Dispose();
				return;
			}
			else if ( state.m_AuthID == 0 && authID != state.m_Seed )
			{
				log.WarnFormat("Login: {0}: Invalid client detected, disconnecting", state);
				state.Dispose();
				return;
			}

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

			GameLoginInternal(state, username, password, true);
		}
示例#29
0
		public static void PlayServer( NetState 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 ) );
			}
		}
		public static void PlayServer( NetState 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];

				if (state.Username != null && state.Password != null &&
					Core.Config.Features["quick-local-connect"] &&
					si.Address.ToString() == state.Socket.LocalEndPoint.ToString()) {
					/* local connect to this game server which is
					   login server at the same time: re-use this
					   connection, emulate a GameLogin packet */
					GameLoginInternal(state, state.Username, state.Password, false);
					return;
				}

				// send relay packet to client

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

				state.SentFirstPacket = false;
				state.Send( new PlayServerAck( si ) );
			}
		}
示例#31
0
		public static void AccountLogin( NetState 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 );

			EventSink.InvokeAccountLogin( e );

			if ( e.Accepted )
				AccountLogin_ReplyAck( state );
			else
				AccountLogin_ReplyRej( state, e.RejectReason );
		}
		public static void AccountLogin( NetState 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.InvokeAccountLogin(e);
			} catch (Exception ex) {
				log.Fatal(String.Format("Exception disarmed in AccountLogin {0}",
										username), ex);
			}

			if (e.Accepted && Core.Config.Features["quick-local-connect"]) {
				/* we have to remember username+password, because it
				   is required to emulate a GameLogin packet */
				state.Username = username;
				state.Password = password;
			}

			if ( e.Accepted )
				AccountLogin_ReplyAck( state );
			else
				AccountLogin_ReplyRej( state, e.RejectReason );
		}
示例#33
0
		public static void AccountLogin_ReplyRej( NetState state, ALRReason reason )
		{
			state.Send( new AccountLoginRej( reason ) );
			state.Dispose();
		}
		public static void AccountLogin_ReplyAck( NetState state )
		{
			ServerListEventArgs e = new ServerListEventArgs( state, state.Account );

			try {
				EventSink.InvokeServerList(e);
			} catch (Exception ex) {
				log.Fatal("Exception disarmed in ServerList", ex);
				e.Rejected = true;
			}

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

				state.ServerInfo = info;

				state.Send( new AccountLoginAck( info ) );
			}
		}
示例#35
0
		public static bool VerifyGC( NetState state )
		{
			if ( state.Mobile == null || state.Mobile.AccessLevel <= AccessLevel.Counselor )
			{
				if ( state.Running )
					Console.WriteLine( "Warning: {0}: Player using godclient, disconnecting", state );

				state.Dispose();
				return false;
			}
			else
			{
				return true;
			}
		}
		private static void OnAddAuthID( NetState state, PacketReader pvSrc ) {
			if (!state.Super) {
				log.WarnFormat("Client {0} attempted to inject an AuthID",
							   state);
				state.Dispose(false);
				return;
			}

			int authID = pvSrc.ReadInt32();
			/*String username =*/ pvSrc.ReadString(30);
			AddAuthID(authID);

			state.Send(new AddAuthIDAck(authID));
		}
        public static void DisplayGumpResponse(NetState state, PacketReader pvSrc)
        {
            int serial = pvSrc.ReadInt32();
            int typeID = pvSrc.ReadInt32();
            int buttonID = pvSrc.ReadInt32();

            List<Gump> gumps = state.Gumps;

            for (int i = 0; i < gumps.Count; ++i)
            {
                Gump gump = gumps[i];

                if (gump.Serial == serial && gump.TypeID == typeID)
                {
                    int switchCount = pvSrc.ReadInt32();

                    if (switchCount < 0)
                    {
                        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)
                    {
                        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);
                    }

                    state.RemoveGump(i);

                    if (!CheckResponse(gump, state.Mobile, buttonID))
                        return;

                    gump.OnResponse(state, new RelayInfo(buttonID, switches, textEntries));

                    return;
                }
            }

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

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

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

                    if (beheld != null)
                        EventSink.InvokeVirtueItemRequest(new VirtueItemRequestEventArgs(state.Mobile, beheld, buttonID));
                }
            }
        }
 public static void AccountLogin_ReplyRej(NetState state, ALRReason reason)
 {
     state.Send(new AccountLoginRej(reason));
     state.Dispose();
 }