示例#1
0
 /// <summary>
 /// Tries reading a single packet from this stream. To read multiple available
 /// packets, repeatedly call this method until it returns <c>null</c>.
 /// </summary>
 /// <returns>
 /// A read packet, if one was available.
 /// </returns>
 /// <exception cref="System.IO.IOException">If the underlying stream fails.</exception>
 public IReadablePacket Read()
 {
     using (var packet = _stream.Read())
     {
         if (packet != null)
         {
             var compressed = packet.ReadBoolean();
             var data       = packet.ReadByteArray();
             if (compressed)
             {
                 data = SimpleCompression.Decompress(data);
             }
             return(new Packet(data, false));
         }
     }
     return(null);
 }
示例#2
0
        /// <summary>Parse received data to check if it's a message we can handle, and parse it.</summary>
        /// <param name="message">the data to parse.</param>
        /// <returns>
        ///     the data parsed from the message, or <c>null</c> on failure.
        /// </returns>
        private IReadablePacket ParseMessage(byte[] message)
        {
            // Check the header.
            if (IsHeaderValid(message))
            {
                // Get message length plus compressed bit.
                var info   = BitConverter.ToUInt32(message, _header.Length);
                var length = (int)(info & ~CompressedMask);
                var flag   = (info & CompressedMask) > 0;

                // OK, get the decrypted packet.
                var data = Crypto.Decrypt(message, _header.Length + sizeof(uint), length);

                // Is this a compressed message?
                if (flag)
                {
                    data = SimpleCompression.Decompress(data);
                }

                // Return result as a packet.
                return(new Packet(data, false));
            }
            return(null);
        }
示例#3
0
        /// <summary>
        ///     Loads this profile from disk. If loading fails this will default to a new profile with the fall-back character
        ///     class.
        /// </summary>
        /// <exception cref="ArgumentException">Profile name is invalid.</exception>
        public void Load(string name)
        {
            if (InvalidCharPattern.IsMatch(name))
            {
                throw new ArgumentException(@"Invalid profile name, contains invalid character.", "name");
            }

            // Figure out the path, check if it's valid.
            Reset();
            Name = name;
            var profilePath = GetFullProfilePath();

            if (!File.Exists(profilePath))
            {
                throw new ArgumentException(@"Invalid profile name, no such file.", "name");
            }

            try
            {
                // Load the file contents, which are encrypted and compressed.
                var encrypted  = File.ReadAllBytes(profilePath);
                var compressed = Crypto.Decrypt(encrypted);
                var plain      = SimpleCompression.Decompress(compressed);

                // Now we have the plain data, handle it as a packet to read our
                // data from it.
                using (var packet = new Packet(plain, false))
                {
                    // Get file header.
                    if (!CheckHeader(packet.ReadByteArray()))
                    {
                        Logger.Error("Failed loading profile, invalid header, using default.");
                        return;
                    }

                    // Get the hash the data had when writing.
                    var hash = packet.ReadInt32();

                    // Get the player class.
                    var playerClass = (PlayerClassType)packet.ReadByte();

                    // And the actual data.
                    var data = packet.ReadPacketizable <Packet>();

                    // Check if the hash matches.
                    var hasher = new Hasher();
                    hasher.Write((byte)playerClass);
                    if (data != null)
                    {
                        hasher.Write(data);
                    }
                    if (hasher.Value == hash)
                    {
                        // All is well, keep the data, drop our old data, if any.
                        PlayerClass = playerClass;
                        _data       = data;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Failed loading profile, using default.", ex);
            }
        }