/// <summary>
        /// Sends a CharacterCreate packet to a CityServer.
        /// </summary>
        /// <param name="LoginArgs">Arguments used to log onto the CityServer.</param>
        /// <param name="Character">The character to create on the CityServer.</param>
        public static void SendCharacterCreateCity(LoginArgsContainer LoginArgs, TSOClient.VM.Sim Character)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_CREATE_CITY, 0);

            Packet.WriteHeader();

            byte[]       EncryptionKey = LoginArgs.Enc.GetDecryptionArgsContainer().ARC4DecryptArgs.EncryptionKey;
            MemoryStream PacketData    = new MemoryStream();
            BinaryWriter Writer        = new BinaryWriter(PacketData);

            Writer.Write((byte)LoginArgs.Username.Length);
            Writer.Write(Encoding.ASCII.GetBytes(LoginArgs.Username), 0, Encoding.ASCII.GetBytes(LoginArgs.Username).Length);

            //LoginArgs password is set to PlayerAccount.Hash for relogging to the cityserver.
            byte[] HashBuf = Convert.FromBase64String(LoginArgs.Password);
            Writer.Write((byte)HashBuf.Length);
            Writer.Write(HashBuf, 0, HashBuf.Length);

            Writer.Write((byte)EncryptionKey.Length);
            Writer.Write(EncryptionKey);
            Writer.Write(PlayerAccount.CityToken);
            Writer.Write(Character.Timestamp);
            Writer.Write(Character.Name);
            Writer.Write(Character.Sex);
            Writer.Write(Character.Description);
            Writer.Write((ulong)Character.HeadOutfitID);
            Writer.Write((ulong)Character.BodyOutfitID);
            Writer.Write((byte)Character.AppearanceType);

            Packet.WriteUInt16((ushort)((ushort)PacketHeaders.UNENCRYPTED + PacketData.Length));
            Packet.WriteBytes(PacketData.ToArray());
            Writer.Close();

            LoginArgs.Client.Send(Packet.ToArray());
        }
        public static void SendLoginRequest(LoginArgsContainer Args)
        {
            //Variable length...
            PacketStream Packet = new PacketStream((byte)PacketType.LOGIN_REQUEST, 0);

            Packet.WriteByte(0x00);

            SaltedHash Hash = new SaltedHash(new SHA512Managed(), Args.Username.Length);

            MemoryStream MemStream = new MemoryStream();

            DecryptionArgsContainer DecryptionArgs = Args.Enc.GetDecryptionArgsContainer();

            MemStream.WriteByte((byte)Args.Username.Length);
            MemStream.Write(Encoding.ASCII.GetBytes(Args.Username), 0, Encoding.ASCII.GetBytes(Args.Username).Length);

            byte[] HashBuf = Hash.ComputePasswordHash(Args.Username, Args.Password);
            PlayerAccount.Hash = HashBuf;

            MemStream.WriteByte((byte)HashBuf.Length);
            MemStream.Write(HashBuf, 0, HashBuf.Length);

            Packet.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + MemStream.ToArray().Length + 4));
            Packet.WriteBytes(MemStream.ToArray());

            string[] Version = GlobalSettings.Default.ClientVersion.Split('.');

            Packet.WriteByte((byte)int.Parse(Version[0])); //Version 1
            Packet.WriteByte((byte)int.Parse(Version[1])); //Version 2
            Packet.WriteByte((byte)int.Parse(Version[2])); //Version 3
            Packet.WriteByte((byte)int.Parse(Version[3])); //Version 4

            Args.Client.Send(Packet.ToArray());
        }
        /// <summary>
        /// Sends a CharacterRetirement packet to the LoginServer, retiring a specific character.
        /// </summary>
        /// <param name="Character">The character to retire.</param>
        public static void SendCharacterRetirement(UISim Character)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.RETIRE_CHARACTER, 0);

            Packet.WritePascalString(PlayerAccount.Username);
            Packet.WritePascalString(Character.GUID.ToString());
            PlayerAccount.Client.SendEncrypted((byte)PacketType.RETIRE_CHARACTER, Packet.ToArray());
        }
        /// <summary>
        /// Requests a token from the LoginServer, that can be used to log into a CityServer.
        /// </summary>
        /// <param name="Client">A NetworkClient instance.</param>
        public static void RequestCityToken(NetworkClient Client, Sim SelectedCharacter)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.REQUEST_CITY_TOKEN, 0);

            Packet.WritePascalString(Client.ClientEncryptor.Username);
            Packet.WritePascalString(SelectedCharacter.ResidingCity.UUID);
            Packet.WritePascalString(SelectedCharacter.GUID.ToString());
            Client.SendEncrypted((byte)PacketType.REQUEST_CITY_TOKEN, Packet.ToArray());
        }
        /// <summary>
        /// Sends a packet to create a SimulationObject on ter server.
        /// Assumes the player is on a lot that he owns.
        /// </summary>
        /// <param name="CreatedObject">The SimulationObject to create.</param>
        public static void SendCreatedSimulationObject(SimulationObject CreatedObject)
        {
            //TODO: Change this ID!
            PacketStream CreateSimulationObjectPacket = new PacketStream(0x11, 0);

            BinaryFormatter BinFormatter = new BinaryFormatter();
            BinFormatter.Serialize(CreateSimulationObjectPacket, CreatedObject);

            PlayerAccount.Client.Send(FinalizePacket(0x11, new DESCryptoServiceProvider(),
                CreateSimulationObjectPacket.ToArray()));
        }
        /// <summary>
        /// Sends a packet to create a SimulationObject on ter server.
        /// Assumes the player is on a lot that he owns.
        /// </summary>
        /// <param name="CreatedObject">The SimulationObject to create.</param>
        public static void SendCreatedSimulationObject(SimulationObject CreatedObject)
        {
            //TODO: Change this ID!
            PacketStream CreateSimulationObjectPacket = new PacketStream(0x11, 0);

            BinaryFormatter BinFormatter = new BinaryFormatter();

            BinFormatter.Serialize(CreateSimulationObjectPacket, CreatedObject);

            PlayerAccount.Client.Send(FinalizePacket(0x11, new DESCryptoServiceProvider(),
                                                     CreateSimulationObjectPacket.ToArray()));
        }
        /// <summary>
        /// LoginServer sent information about the player's characters.
        /// </summary>
        /// <param name="Packet">The packet that was received.</param>
        public static void OnCharacterInfoResponse(ProcessedPacket Packet, NetworkClient Client)
        {
            //If the decrypted length == 1, it means that there were 0
            //characters that needed to be updated, or that the user
            //hasn't created any characters on his/her account yet.
            //Since the Packet.Length property is equal to the length
            //of the encrypted data, it cannot be used to get the length
            //of the decrypted data.
            if (Packet.DecryptedLength > 1)
            {
                byte         NumCharacters = (byte)Packet.ReadByte();
                List <UISim> FreshSims     = new List <UISim>();

                for (int i = 0; i < NumCharacters; i++)
                {
                    int CharacterID = Packet.ReadInt32();

                    UISim FreshSim = new UISim(Packet.ReadString(), false);
                    FreshSim.CharacterID       = CharacterID;
                    FreshSim.Timestamp         = Packet.ReadString();
                    FreshSim.Name              = Packet.ReadString();
                    FreshSim.Sex               = Packet.ReadString();
                    FreshSim.Description       = Packet.ReadString();
                    FreshSim.HeadOutfitID      = Packet.ReadUInt64();
                    FreshSim.BodyOutfitID      = Packet.ReadUInt64();
                    FreshSim.Avatar.Appearance = (AppearanceType)Packet.ReadByte();
                    FreshSim.ResidingCity      = new CityInfo(Packet.ReadString(), "", Packet.ReadUInt64(), Packet.ReadString(),
                                                              Packet.ReadUInt64(), Packet.ReadString(), Packet.ReadInt32());

                    FreshSims.Add(FreshSim);
                }

                if (NumCharacters < 3)
                {
                    FreshSims = Cache.LoadCachedSims(FreshSims);
                }
                NetworkFacade.Avatars = FreshSims;
                Cache.CacheSims(FreshSims);
            }
            else
            {
                NetworkFacade.Avatars = Cache.LoadAllSims();
            }

            PacketStream CityInfoRequest = new PacketStream(0x06, 0);

            CityInfoRequest.WriteByte(0x00); //Dummy

            Client.SendEncrypted((byte)PacketType.CITY_LIST, CityInfoRequest.ToArray());
        }
        public static void SendCharacterInfoRequest(string TimeStamp)
        {
            PacketStream Packet = new PacketStream(0x05, 0);
            //If this timestamp is newer than the server's timestamp, it means
            //the client doesn't have a charactercache. If it's older, it means
            //the cache needs to be updated. If it matches, the server sends an
            //empty responsepacket.
            //Packet.WriteString(TimeStamp);
            Packet.WriteByte((byte)TimeStamp.Length);
            Packet.WriteBytes(Encoding.ASCII.GetBytes(TimeStamp));

            byte[] PacketData = Packet.ToArray();

            PlayerAccount.Client.Send(FinalizePacket(0x05, new DESCryptoServiceProvider(), PacketData));
        }
        public static void SendCharacterInfoRequest(string TimeStamp)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_LIST, 0);

            //If this timestamp is newer than the server's timestamp, it means
            //the client doesn't have a charactercache. If it's older, it means
            //the cache needs to be updated. If it matches, the server sends an
            //empty responsepacket.
            //Packet.WriteString(TimeStamp);
            Packet.WritePascalString(TimeStamp);

            byte[] PacketData = Packet.ToArray();

            //PlayerAccount.Client.Send(FinalizePacket(0x05, new DESCryptoServiceProvider(), PacketData));
            PlayerAccount.Client.SendEncrypted((byte)PacketType.CHARACTER_LIST, PacketData);
        }
        public static void SendLoginRequest(NetworkClient Client, string Username, string Password)
        {
            //Variable length...
            PacketStream Packet = new PacketStream(0x00, 0);

            Packet.WriteByte(0x00);

            SaltedHash Hash = new SaltedHash(new SHA512Managed(), Username.Length);

            byte[] HashBuf = new byte[Encoding.ASCII.GetBytes(Password).Length +
                                      Encoding.ASCII.GetBytes(Username).Length];

            MemoryStream MemStream = new MemoryStream();

            PasswordDeriveBytes Pwd = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(Password),
                                                              Encoding.ASCII.GetBytes("SALT"), "SHA1", 10);

            byte[] EncKey = Pwd.GetBytes(8);
            PlayerAccount.EncKey = EncKey;

            MemStream.WriteByte((byte)Username.Length);
            MemStream.Write(Encoding.ASCII.GetBytes(Username), 0, Encoding.ASCII.GetBytes(Username).Length);

            HashBuf            = Hash.ComputePasswordHash(Username, Password);
            PlayerAccount.Hash = HashBuf;

            MemStream.WriteByte((byte)HashBuf.Length);
            MemStream.Write(HashBuf, 0, HashBuf.Length);

            MemStream.WriteByte((byte)EncKey.Length);
            MemStream.Write(EncKey, 0, EncKey.Length);

            Packet.WriteByte((byte)(2 + MemStream.ToArray().Length + 4));
            Packet.WriteBytes(MemStream.ToArray());
            //TODO: Change this to write a global client version.
            Packet.WriteByte(0x00); //Version 1
            Packet.WriteByte(0x00); //Version 2
            Packet.WriteByte(0x00); //Version 3
            Packet.WriteByte(0x01); //Version 4

            Client.Send(Packet.ToArray());
        }
示例#11
0
        /// <summary>
        /// LoginServer sent information about the player's characters.
        /// </summary>
        /// <param name="Packet">The packet that was received.</param>
        public static void OnCharacterInfoResponse(PacketStream Packet, NetworkClient Client)
        {
            byte Opcode          = (byte)Packet.ReadByte();
            byte Length          = (byte)Packet.ReadByte();
            byte DecryptedLength = (byte)Packet.ReadByte();

            Packet.DecryptPacket(PlayerAccount.EncKey, new DESCryptoServiceProvider(), DecryptedLength);

            //If the decrypted length == 1, it means that there were 0
            //characters that needed to be updated, or that the user
            //hasn't created any characters on his/her account yet.
            //Since the Packet.Length property is equal to the length
            //of the encrypted data, it cannot be used to get the length
            //of the decrypted data.
            if (DecryptedLength > 1)
            {
                byte       NumCharacters = (byte)Packet.ReadByte();
                List <Sim> FreshSims     = new List <Sim>();

                for (int i = 0; i < NumCharacters; i++)
                {
                    int CharacterID = Packet.ReadInt32();

                    Sim FreshSim = new Sim(Packet.ReadString());
                    FreshSim.CharacterID = CharacterID;
                    FreshSim.Timestamp   = Packet.ReadString();
                    FreshSim.Name        = Packet.ReadString();
                    FreshSim.Sex         = Packet.ReadString();

                    FreshSims.Add(FreshSim);
                }

                NetworkFacade.Avatars = FreshSims;
                CacheSims(FreshSims);
            }

            PacketStream CityInfoRequest = new PacketStream(0x06, 0);

            CityInfoRequest.WriteByte(0x00); //Dummy

            Client.SendEncrypted(0x06, CityInfoRequest.ToArray());
        }
        /// <summary>
        /// Sends a token to a CityServer, as received by a LoginServer.
        /// </summary>
        /// <param name="Client">A NetworkClient instance.</param>
        public static void SendCityToken(NetworkClient Client)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CITY_TOKEN, 0);

            Packet.WriteHeader();

            MemoryStream PacketData = new MemoryStream();
            BinaryWriter Writer     = new BinaryWriter(PacketData);

            Writer.Write((byte)PlayerAccount.Hash.Length);
            Writer.Write(PlayerAccount.Hash, 0, PlayerAccount.Hash.Length);

            Writer.Write(PlayerAccount.CityToken);

            Packet.WriteUInt16((ushort)((ushort)PacketHeaders.UNENCRYPTED + PacketData.Length));
            Packet.WriteBytes(PacketData.ToArray());
            Writer.Close();

            Client.Send(Packet.ToArray());
        }
        /// <summary>
        /// LoginServer sent information about the player's characters.
        /// </summary>
        /// <param name="Packet">The packet that was received.</param>
        public static void OnCharacterInfoResponse(PacketStream Packet, NetworkClient Client)
        {
            byte Opcode = (byte)Packet.ReadByte();
            byte Length = (byte)Packet.ReadByte();
            byte DecryptedLength = (byte)Packet.ReadByte();

            Packet.DecryptPacket(PlayerAccount.EncKey, new DESCryptoServiceProvider(), DecryptedLength);

            //If the decrypted length == 1, it means that there were 0
            //characters that needed to be updated, or that the user
            //hasn't created any characters on his/her account yet.
            //Since the Packet.Length property is equal to the length
            //of the encrypted data, it cannot be used to get the length
            //of the decrypted data.
            if (DecryptedLength > 1)
            {
                byte NumCharacters = (byte)Packet.ReadByte();
                List<Sim> FreshSims = new List<Sim>();

                for (int i = 0; i < NumCharacters; i++)
                {
                    int CharacterID = Packet.ReadInt32();

                    Sim FreshSim = new Sim(Packet.ReadString());
                    FreshSim.CharacterID = CharacterID;
                    FreshSim.Timestamp = Packet.ReadString();
                    FreshSim.Name = Packet.ReadString();
                    FreshSim.Sex = Packet.ReadString();

                    FreshSims.Add(FreshSim);
                }

                NetworkFacade.Avatars = FreshSims;
                CacheSims(FreshSims);
            }

            PacketStream CityInfoRequest = new PacketStream(0x06, 0);
            CityInfoRequest.WriteByte(0x00); //Dummy

            Client.SendEncrypted(0x06, CityInfoRequest.ToArray());
        }
        /// <summary>
        /// Sends a CharacterCreate packet to the LoginServer.
        /// </summary>
        /// <param name="Character">The character to create.</param>
        /// <param name="TimeStamp">The timestamp of when this character was created.</param>
        public static void SendCharacterCreate(TSOClient.VM.Sim Character, string TimeStamp)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CHARACTER_CREATE, 0);

            Packet.WritePascalString(PlayerAccount.Client.ClientEncryptor.Username);
            Packet.WritePascalString(TimeStamp);
            Packet.WritePascalString(Character.Name);
            Packet.WritePascalString(Character.Sex);
            Packet.WritePascalString(Character.Description);
            Packet.WriteUInt64(Character.HeadOutfitID);
            Packet.WriteUInt64(Character.BodyOutfitID);
            Packet.WriteByte((byte)Character.AppearanceType);

            Packet.WritePascalString(Character.ResidingCity.Name);
            Packet.WriteUInt64(Character.ResidingCity.Thumbnail);
            Packet.WritePascalString(Character.ResidingCity.UUID);
            Packet.WriteUInt64(Character.ResidingCity.Map);
            Packet.WritePascalString(Character.ResidingCity.IP);
            Packet.WriteInt32(Character.ResidingCity.Port);

            byte[] PacketData = Packet.ToArray();
            PlayerAccount.Client.SendEncrypted((byte)PacketType.CHARACTER_CREATE, PacketData);
        }
        /// <summary>
        /// Sends a token to a CityServer, as received by a LoginServer.
        /// </summary>
        /// <param name="Client">A NetworkClient instance.</param>
        public static void SendCityToken(NetworkClient Client)
        {
            PacketStream Packet = new PacketStream((byte)PacketType.CITY_TOKEN, 0);

            Packet.WriteHeader();

            byte[]       EncryptionKey = Client.ClientEncryptor.GetDecryptionArgsContainer().ARC4DecryptArgs.EncryptionKey;
            MemoryStream PacketData    = new MemoryStream();
            BinaryWriter Writer        = new BinaryWriter(PacketData);

            Writer.Write((byte)PlayerAccount.Hash.Length);
            Writer.Write(PlayerAccount.Hash, 0, PlayerAccount.Hash.Length);

            Writer.Write((byte)EncryptionKey.Length);
            Writer.Write(EncryptionKey);
            Writer.Write(PlayerAccount.CityToken);

            Packet.WriteUInt16((ushort)((ushort)PacketHeaders.UNENCRYPTED + PacketData.Length));
            Packet.WriteBytes(PacketData.ToArray());
            Writer.Close();

            Client.Send(Packet.ToArray());
        }
        private void ReceiveCallback(IAsyncResult AR)
        {
            try
            {
                Socket Sock = (Socket)AR.AsyncState;
                int NumBytesRead = Sock.EndReceive(AR);

                Log.LogThis("Received: " + NumBytesRead + " bytes!", eloglevel.info);

                byte[] TmpBuf = new byte[NumBytesRead];
                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead);

                //The packet is given an ID of 0x00 because its ID is currently unknown.
                PacketStream TempPacket = new PacketStream(0x00, NumBytesRead, TmpBuf);
                byte ID = TempPacket.PeekByte(0);
                int PacketLength = 0;

                bool FoundMatchingID = false;

                FoundMatchingID = FindMatchingPacketID(ID);

                if (FoundMatchingID)
                {
                    PacketLength = m_PacketIDs[ID];

                    Log.LogThis("PacketLength: " + PacketLength, eloglevel.info);
                    Log.LogThis("Found matching PacketID (" + ID + ")!\r\n\r\n", eloglevel.info);

                    if (NumBytesRead == PacketLength)
                    {
                        Log.LogThis("Got packet - exact length!\r\n\r\n", eloglevel.info);
                        m_RecvBuf = new byte[11024];

                        OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()));
                    }
                    else if (NumBytesRead < PacketLength)
                    {
                        m_TempPacket = new PacketStream(ID, PacketLength);
                        byte[] TmpBuffer = new byte[NumBytesRead];

                        //Store the number of bytes that were read in the temporary buffer.
                        Log.LogThis("Got data, but not a full packet - stored " +
                            NumBytesRead.ToString() + "bytes!\r\n\r\n", eloglevel.info);
                        Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead);
                        m_TempPacket.WriteBytes(TmpBuffer);

                        //And reset the buffers!
                        m_RecvBuf = new byte[11024];
                        TmpBuffer = null;
                    }
                    else if (PacketLength == 0)
                    {
                        Log.LogThis("Received variable length packet!\r\n", eloglevel.info);

                        if (NumBytesRead > 2)
                        {
                            PacketLength = TempPacket.PeekByte(1);

                            if (NumBytesRead == PacketLength)
                            {
                                Log.LogThis("Received exact number of bytes for packet!\r\n", eloglevel.info);

                                m_RecvBuf = new byte[11024];
                                m_TempPacket = null;
                                OnReceivedData(new PacketStream(ID, PacketLength, TempPacket.ToArray()));
                            }
                            else if (NumBytesRead < PacketLength)
                            {
                                Log.LogThis("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n",
                                    eloglevel.info);

                                TempPacket.SetLength(PacketLength);
                                m_TempPacket = TempPacket;
                                m_RecvBuf = new byte[11024];
                            }
                            else if (NumBytesRead > PacketLength)
                            {
                                Log.LogThis("Received more bytes than needed for packet. Excess: " +
                                    (NumBytesRead - PacketLength) + "\r\n", eloglevel.info);

                                byte[] TmpBuffer = new byte[NumBytesRead - PacketLength];
                                Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length);
                                m_TempPacket = new PacketStream(TmpBuffer[0], NumBytesRead - PacketLength,
                                    TmpBuffer);

                                byte[] PacketBuffer = new byte[PacketLength];
                                Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length);

                                m_RecvBuf = new byte[11024];
                                OnReceivedData(new PacketStream(ID, PacketLength, PacketBuffer));
                            }
                        }
                    }
                }
                else
                {
                    if (m_TempPacket != null)
                    {
                        if (m_TempPacket.Length < m_TempPacket.BufferLength)
                        {
                            //Received the exact number of bytes needed to complete the stored packet.
                            if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                            {
                                byte[] TmpBuffer = new byte[NumBytesRead];
                                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead);

                                m_RecvBuf = new byte[11024];
                                TmpBuffer = null;
                            }
                            //Received more than the number of bytes needed to complete the packet!
                            else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                            {
                                int Target = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                byte[] TmpBuffer = new byte[Target];

                                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, Target);
                                m_TempPacket.WriteBytes(TmpBuffer);

                                //Now we have a full packet, so call the received event!
                                OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                    (int)m_TempPacket.Length, m_TempPacket.ToArray()));

                                //Copy the remaining bytes in the receiving buffer.
                                TmpBuffer = new byte[NumBytesRead - Target];
                                Buffer.BlockCopy(m_RecvBuf, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                ID = TempPacket.PeekByte(0);

                                //This SHOULD be an existing ID, but let's sanity-check it...
                                if (FindMatchingPacketID(ID))
                                {
                                    m_TempPacket = new PacketStream(ID, m_PacketIDs[ID], TempPacket.ToArray());

                                    //Congratulations, you just received another packet!
                                    if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                    {
                                        OnReceivedData(new PacketStream(m_TempPacket.PacketID,
                                            (int)m_TempPacket.Length, m_TempPacket.ToArray()));

                                        //No more data to store on this read, so reset everything...
                                        m_TempPacket = null;
                                        TmpBuffer = null;
                                        m_RecvBuf = new byte[11024];
                                    }
                                }
                                else
                                {
                                    //Houston, we have a problem (this should never occur)!
                                }
                            }
                        }
                    }
                }

                m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveCallback), m_Sock);
            }
            catch (SocketException E)
            {
                Log.LogThis("SocketException: " + E.ToString(), eloglevel.info);
                Disconnect();
            }
        }
示例#17
0
        private void ReceiveCallback(IAsyncResult AR)
        {
            try
            {
                Socket Sock         = (Socket)AR.AsyncState;
                int    NumBytesRead = Sock.EndReceive(AR);

                /** Cant do anything with this! **/
                if (NumBytesRead == 0)
                {
                    return;
                }

                Log.LogThis("Received: " + NumBytesRead + " bytes!", eloglevel.info);

                byte[] TmpBuf = new byte[NumBytesRead];
                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuf, 0, NumBytesRead);

                //The packet is given an ID of 0x00 because its ID is currently unknown.
                PacketStream TempPacket = new PacketStream(0x00, NumBytesRead, TmpBuf);
                byte         ID         = TempPacket.PeekByte(0);

                int PacketLength = 0;
                var handler      = FindPacketHandler(ID);

                if (handler != null)
                {
                    PacketLength = handler.Length;

                    Log.LogThis("PacketLength: " + PacketLength, eloglevel.info);
                    Log.LogThis("Found matching PacketID (" + ID + ")!\r\n\r\n", eloglevel.info);

                    if (NumBytesRead == PacketLength)
                    {
                        Log.LogThis("Got packet - exact length!\r\n\r\n", eloglevel.info);
                        m_RecvBuf = new byte[11024];

                        OnPacket(new PacketStream(ID, PacketLength, TempPacket.ToArray()), handler);
                    }
                    else if (NumBytesRead < PacketLength)
                    {
                        m_TempPacket = new PacketStream(ID, PacketLength);
                        byte[] TmpBuffer = new byte[NumBytesRead];

                        //Store the number of bytes that were read in the temporary buffer.
                        Log.LogThis("Got data, but not a full packet - stored " +
                                    NumBytesRead.ToString() + "bytes!\r\n\r\n", eloglevel.info);
                        Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead);
                        m_TempPacket.WriteBytes(TmpBuffer);

                        //And reset the buffers!
                        m_RecvBuf = new byte[11024];
                        TmpBuffer = null;
                    }
                    else if (PacketLength == 0)
                    {
                        Log.LogThis("Received variable length packet!\r\n", eloglevel.info);

                        if (NumBytesRead > (int)PacketHeaders.UNENCRYPTED) //Header is 3 bytes.
                        {
                            PacketLength = TempPacket.PeekUShort(1);

                            if (NumBytesRead == PacketLength)
                            {
                                Log.LogThis("Received exact number of bytes for packet!\r\n", eloglevel.info);

                                m_RecvBuf    = new byte[11024];
                                m_TempPacket = null;
                                OnPacket(new PacketStream(ID, PacketLength, TempPacket.ToArray()), handler);
                            }
                            else if (NumBytesRead < PacketLength)
                            {
                                Log.LogThis("Didn't receive entire packet - stored: " + PacketLength + " bytes!\r\n",
                                            eloglevel.info);

                                TempPacket.SetLength(PacketLength);
                                m_TempPacket = TempPacket;
                                m_RecvBuf    = new byte[11024];
                            }
                            else if (NumBytesRead > PacketLength)
                            {
                                Log.LogThis("Received more bytes than needed for packet. Excess: " +
                                            (NumBytesRead - PacketLength) + "\r\n", eloglevel.info);

                                byte[] TmpBuffer = new byte[NumBytesRead - PacketLength];
                                Buffer.BlockCopy(TempPacket.ToArray(), 0, TmpBuffer, 0, TmpBuffer.Length);
                                m_TempPacket = new PacketStream(TmpBuffer[0], NumBytesRead - PacketLength,
                                                                TmpBuffer);

                                byte[] PacketBuffer = new byte[PacketLength];
                                Buffer.BlockCopy(TempPacket.ToArray(), 0, PacketBuffer, 0, PacketBuffer.Length);

                                m_RecvBuf = new byte[11024];
                                OnPacket(new PacketStream(ID, PacketLength, PacketBuffer), handler);
                            }
                        }
                    }
                }
                else
                {
                    if (m_TempPacket != null)
                    {
                        if (m_TempPacket.Length < m_TempPacket.BufferLength)
                        {
                            //Received the exact number of bytes needed to complete the stored packet.
                            if ((m_TempPacket.BufferLength + NumBytesRead) == m_TempPacket.Length)
                            {
                                byte[] TmpBuffer = new byte[NumBytesRead];
                                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, NumBytesRead);

                                m_RecvBuf = new byte[11024];
                                TmpBuffer = null;
                            }
                            //Received more than the number of bytes needed to complete the packet!
                            else if ((m_TempPacket.BufferLength + NumBytesRead) > m_TempPacket.Length)
                            {
                                int    Target    = (int)((m_TempPacket.BufferLength + NumBytesRead) - m_TempPacket.Length);
                                byte[] TmpBuffer = new byte[Target];

                                Buffer.BlockCopy(m_RecvBuf, 0, TmpBuffer, 0, Target);
                                m_TempPacket.WriteBytes(TmpBuffer);

                                //Now we have a full packet, so call the received event!
                                OnPacket(new PacketStream(m_TempPacket.PacketID,
                                                          (int)m_TempPacket.Length, m_TempPacket.ToArray()), handler);

                                //Copy the remaining bytes in the receiving buffer.
                                TmpBuffer = new byte[NumBytesRead - Target];
                                Buffer.BlockCopy(m_RecvBuf, Target, TmpBuffer, 0, (NumBytesRead - Target));

                                //Give the temporary packet an ID of 0x00 since we don't know its ID yet.
                                TempPacket = new PacketStream(0x00, NumBytesRead - Target, TmpBuffer);
                                ID         = TempPacket.PeekByte(0);
                                handler    = FindPacketHandler(ID);

                                //This SHOULD be an existing ID, but let's sanity-check it...
                                if (handler != null)
                                {
                                    m_TempPacket = new PacketStream(ID, handler.Length, TempPacket.ToArray());

                                    //Congratulations, you just received another packet!
                                    if (m_TempPacket.Length == m_TempPacket.BufferLength)
                                    {
                                        OnPacket(new PacketStream(m_TempPacket.PacketID,
                                                                  (int)m_TempPacket.Length, m_TempPacket.ToArray()), handler);

                                        //No more data to store on this read, so reset everything...
                                        m_TempPacket = null;
                                        TmpBuffer    = null;
                                        m_RecvBuf    = new byte[11024];
                                    }
                                }
                                else
                                {
                                    //Houston, we have a problem (this should never occur)!
                                }
                            }
                        }
                    }
                }

                m_Sock.BeginReceive(m_RecvBuf, 0, m_RecvBuf.Length, SocketFlags.None,
                                    new AsyncCallback(ReceiveCallback), m_Sock);
            }
            catch (SocketException E)
            {
                Log.LogThis("SocketException: " + E.ToString(), eloglevel.info);
                Disconnect();
            }
        }
        public static void SendLoginRequest(NetworkClient Client, string Username, string Password)
        {
            //Variable length...
            PacketStream Packet = new PacketStream(0x00, 0);
            Packet.WriteByte(0x00);

            SaltedHash Hash = new SaltedHash(new SHA512Managed(), Username.Length);
            byte[] HashBuf = new byte[Encoding.ASCII.GetBytes(Password).Length +
                Encoding.ASCII.GetBytes(Username).Length];

            MemoryStream MemStream = new MemoryStream();

            PasswordDeriveBytes Pwd = new PasswordDeriveBytes(Encoding.ASCII.GetBytes(Password),
                Encoding.ASCII.GetBytes("SALT"), "SHA1", 10);
            byte[] EncKey = Pwd.GetBytes(8);
            PlayerAccount.EncKey = EncKey;

            MemStream.WriteByte((byte)Username.Length);
            MemStream.Write(Encoding.ASCII.GetBytes(Username), 0, Encoding.ASCII.GetBytes(Username).Length);

            HashBuf = Hash.ComputePasswordHash(Username, Password);
            PlayerAccount.Hash = HashBuf;

            MemStream.WriteByte((byte)HashBuf.Length);
            MemStream.Write(HashBuf, 0, HashBuf.Length);

            MemStream.WriteByte((byte)EncKey.Length);
            MemStream.Write(EncKey, 0, EncKey.Length);

            Packet.WriteByte((byte)(2 + MemStream.ToArray().Length + 4));
            Packet.WriteBytes(MemStream.ToArray());
            //TODO: Change this to write a global client version.
            Packet.WriteByte(0x00); //Version 1
            Packet.WriteByte(0x00); //Version 2
            Packet.WriteByte(0x00); //Version 3
            Packet.WriteByte(0x01); //Version 4

            Client.Send(Packet.ToArray());
        }