예제 #1
0
        public GetHeadersMessage(
            IEnumerable <Header> headerLocator,
            uint versionProtocol)
            : base("getheaders")
        {
            HeaderLocator = headerLocator;
            StopHash      =
                ("00000000000000000000000000000000" +
                 "00000000000000000000000000000000").ToBinary();

            List <byte> payload = new List <byte>();

            payload.AddRange(BitConverter.GetBytes(versionProtocol));
            payload.AddRange(VarInt.GetBytes(HeaderLocator.Count()));

            for (int i = 0; i < HeaderLocator.Count(); i++)
            {
                payload.AddRange(
                    HeaderLocator.ElementAt(i).Hash);
            }

            payload.AddRange(StopHash);

            Payload = payload.ToArray();
        }
예제 #2
0
    public static byte[] GetBytes(string data)
    {
        List <byte> builder = new List <byte>();

        byte[] strRaw = Encoding.UTF8.GetBytes(data);
        builder.AddRange(VarInt.GetBytes(strRaw.Length));
        builder.AddRange(strRaw);
        return(builder.ToArray());
    }
예제 #3
0
        void SerializePayload()
        {
            var payload = new List <byte>();

            payload.AddRange(VarInt.GetBytes(Headers.Count));

            foreach (Header header in Headers)
            {
                payload.AddRange(header.GetBytes());
                payload.Add(0);
            }

            Payload = payload.ToArray();
        }
예제 #4
0
        public InvMessage(List <Inventory> inventories)
            : base("inv")
        {
            Inventories = inventories;

            List <byte> payload = new List <byte>();

            payload.AddRange(VarInt.GetBytes(inventories.Count));

            Inventories.ForEach(
                i => payload.AddRange(i.GetBytes()));

            Payload = payload.ToArray();
        }
예제 #5
0
    /// <summary>
    /// Sends a packet to the server
    /// </summary>
    /// <param name="p"></param>
    public void WritePacket(Packet p)
    {
        lock (_streamWriteLock)
        {
            List <byte> buffer = new List <byte>();

            // check if compression enabled
            if (_compressionThreshold >= 0)
            {
                List <byte> uncompressedBody = new List <byte>(VarInt.GetBytes(p.PacketID));
                uncompressedBody.AddRange(p.Payload);

                if (uncompressedBody.Count >= _compressionThreshold)
                {
                    // compress data
                    byte[] compressedBody = ZlibStream.CompressBuffer(uncompressedBody.ToArray());

                    // add the packet payload data first, and we will insert the length of the data at the beginning of the packet
                    buffer.AddRange(VarInt.GetBytes(uncompressedBody.Count));
                    buffer.AddRange(compressedBody);
                    buffer.InsertRange(0, VarInt.GetBytes(buffer.Count));
                }
                else
                {
                    // data length below compression threshold
                    buffer.AddRange(VarInt.GetBytes(uncompressedBody.Count + 1)); // add one for length of data length
                    buffer.Add(0);                                                // 0 data length for uncompressed payload
                    buffer.AddRange(uncompressedBody);
                }
            }
            else
            {
                // no compression
                buffer.AddRange(VarInt.GetBytes(p.Length));
                buffer.AddRange(VarInt.GetBytes(p.PacketID));
                buffer.AddRange(p.Payload);
            }

            WriteBytes(buffer.ToArray(), 0, buffer.Count);
            if (_encrypted)
            {
                _aesStream.Flush();
            }
            else
            {
                Client.GetStream().Flush();
            }
        }
    }
예제 #6
0
        public GetDataMessage(List <Inventory> inventories)
            : base("getdata")
        {
            Inventories = inventories;

            List <byte> payload = new List <byte>();

            payload.AddRange(VarInt.GetBytes(Inventories.Count()));

            for (int i = 0; i < Inventories.Count(); i++)
            {
                payload.AddRange(Inventories.ElementAt(i).GetBytes());
            }

            Payload = payload.ToArray();
        }
예제 #7
0
        /// <summary>
        /// 生成发送给服务端的包
        /// </summary>
        /// <param name="compress">数据包压缩的阚值</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public virtual List <byte> ToList(int compress = -1)
        {
            if (Empty)
            {
                throw new PacketException("Packet is empty");
            }

            List <byte> PacketData = new List <byte>();

            PacketData.Capacity = Length;
            if (compress > 0)
            {
                if (Data.Count >= compress)
                {
                    PacketData.AddRange(VarInt.GetBytes(Length));
                    int    IdLength = VarInt.GetLength(ID);
                    byte[] buffer   = new byte[IdLength + Data.Count];
                    Array.Copy(VarInt.GetBytes(ID), 0, buffer, 0, IdLength);
                    Data.CopyTo(buffer, IdLength);
                    PacketData.AddRange(ZlibUtils.Compress(buffer));
                    PacketData.InsertRange(0, VarInt.GetBytes(PacketData.Count));
                }
                else
                {
                    PacketData.AddRange(VarInt.GetBytes(Length + 1));
                    PacketData.Add(0);
                    PacketData.AddRange(VarInt.GetBytes(ID));
                    PacketData.AddRange(Data);
                }
            }
            else
            {
                PacketData.AddRange(VarInt.GetBytes(Length));
                PacketData.AddRange(VarInt.GetBytes(ID));
                PacketData.AddRange(Data);
            }
            return(PacketData);
        }
        public override byte[] ToBytes(int compress = -1)
        {
            byte[] channel = Encoding.UTF8.GetBytes(Channel);
            byte[] PacketData;
            //14w31a: The length prefix on the payload of Plugin Message has been removed (Both ways)
            if (_protocolVersion <= ProtocolVersionNumbers.V14w31a)
            {
                if (HasForge)
                {
                    PacketData = ProtocolHandler.ConcatBytes(VarInt.GetBytes(channel.Length), channel, VarShort.GetBytes(Data.Count), Data.ToArray());
                }
                else
                {
                    PacketData = ProtocolHandler.ConcatBytes(VarInt.GetBytes(channel.Length), channel, ProtocolHandler.GetBytes((short)Data.Count), Data.ToArray());
                }
            }
            else
            {
                PacketData = ProtocolHandler.ConcatBytes(VarInt.GetBytes(channel.Length), channel, Data.ToArray());
            }
            int DataLength = PacketData.Length;

            PacketData = ProtocolHandler.ConcatBytes(VarInt.GetBytes(ID), PacketData);

            if (compress > 0)
            {
                if (DataLength >= compress)
                {
                    PacketData = ProtocolHandler.ConcatBytes(VarInt.GetBytes(PacketData.Length), ZlibUtils.Compress(PacketData));
                }
                else
                {
                    PacketData = ProtocolHandler.ConcatBytes(new byte[] { 0 }, PacketData);
                }
            }
            return(ProtocolHandler.ConcatBytes(VarInt.GetBytes(PacketData.Length), PacketData));
        }
예제 #9
0
 public virtual void WriteVarInt(int value)
 {
     WriteBytes(VarInt.GetBytes(value));
 }
예제 #10
0
 /// <summary>
 /// Writes a VarInt to the given BinaryWriter
 /// </summary>
 /// <param name="writer">The writer to use</param>
 /// <param name="value">The VarInt value to write</param>
 public static void WriteVarInt(BinaryWriter writer, int value)
 {
     writer.Write(VarInt.GetBytes(value));
 }
            public override void BackupImage(string path)
            {
                string directoryPath = Path.Combine(path, Label);

                Directory.CreateDirectory(directoryPath);

                var byteList = new List <byte>();

                foreach (KeyValuePair <int, uint[]> keyValuePair in PrimaryTable)
                {
                    byteList.AddRange(BitConverter.GetBytes(keyValuePair.Key));
                    int byteLength = keyValuePair.Value.Length << 2;
                    byteList.AddRange(VarInt.GetBytes(byteLength));

                    byte[] byteArray = new byte[byteLength];

                    Buffer.BlockCopy(
                        keyValuePair.Value,
                        0,
                        byteArray,
                        0,
                        byteArray.Length);

                    byteList.AddRange(byteArray);
                }

                byte[] bytes = byteList.ToArray();

                using (FileStream stream = new FileStream(
                           Path.Combine(directoryPath, "PrimaryTable"),
                           FileMode.Create,
                           FileAccess.Write,
                           FileShare.None))
                {
                    stream.Write(bytes, 0, bytes.Length);
                }

                byteList.Clear();

                foreach (KeyValuePair <byte[], uint[]> keyValuePair in CollisionTable)
                {
                    byteList.AddRange(keyValuePair.Key);
                    int byteLength = keyValuePair.Value.Length << 2;
                    byteList.AddRange(VarInt.GetBytes(byteLength));

                    byte[] byteArray = new byte[keyValuePair.Value.Length << 2];
                    Buffer.BlockCopy(keyValuePair.Value, 0, byteArray, 0, byteArray.Length);
                    byteList.AddRange(byteArray);
                }

                bytes = byteList.ToArray();

                using (FileStream stream = new FileStream(
                           Path.Combine(directoryPath, "CollisionTable"),
                           FileMode.Create,
                           FileAccess.Write,
                           FileShare.None))
                {
                    stream.Write(bytes, 0, bytes.Length);
                }
            }
예제 #12
0
 public static byte[] GetBytes(string value)
 {
     byte[] str = Encoding.UTF8.GetBytes(value);
     return(ConcatBytes(VarInt.GetBytes(str.Length), str));
 }
예제 #13
0
    /// <summary>
    /// Gets the next packet from the server
    /// </summary>
    /// <returns></returns>
    public PacketData ReadNextPacket()
    {
        int packetId;

        byte[] payload;

        lock (_streamReadLock)
        {
            int         length = VarInt.ReadNext(ReadBytes);
            List <byte> buffer = new List <byte>();

            // check if data is compressed
            if (_compressionThreshold >= 0)
            {
                int dataLength = VarInt.ReadNext(ReadBytes);
                length -= VarInt.GetBytes(dataLength).Length;                   // remove size of data length from rest of packet length
                if (dataLength != 0)
                {
                    byte[] compressedBuffer = ReadBytes(length);
                    buffer.AddRange(ZlibStream.UncompressBuffer(compressedBuffer));
                }
                else
                {
                    buffer.AddRange(ReadBytes(length));
                }
            }
            else
            {
                buffer.AddRange(ReadBytes(length));
            }

            packetId = VarInt.ReadNext(buffer);
            payload  = buffer.ToArray();
        }

        // handles some stuff during login phase
        if (State == ProtocolState.LOGIN)
        {
            // handle compression packet
            if (packetId == (int)ClientboundIDs.LogIn_SetCompression)
            {
                _compressionThreshold = VarInt.ReadNext(new List <byte>(payload));
                return(ReadNextPacket());
            }

            // handle protocol encryption packet
            if (packetId == (int)ClientboundIDs.LogIn_EncryptionRequest)
            {
                var encRequestPkt = new EncryptionRequestPacket()
                {
                    Payload = payload
                };

                var aesSecret = CryptoHandler.GenerateSharedSecret();
                var authHash  = CryptoHandler.SHAHash(Encoding.ASCII.GetBytes(encRequestPkt.ServerID).Concat(aesSecret, encRequestPkt.PublicKey));

                Debug.Log($"Sending hash to Mojang servers: {authHash}");

                // check session with mojang
                if (!MojangAPI.JoinServer(authHash))
                {
                    throw new UnityException("Invalid session. (Try restarting game or relogging into Minecraft account)");
                }

                // use pub key to encrypt shared secret
                using (var rsaProvider = CryptoHandler.DecodeRSAPublicKey(encRequestPkt.PublicKey))
                {
                    byte[] encSecret = rsaProvider.Encrypt(aesSecret, false);
                    byte[] encToken  = rsaProvider.Encrypt(encRequestPkt.VerifyToken, false);

                    // respond to server with private key
                    var responsePkt = new EncryptionResponsePacket()
                    {
                        SharedSecret = encSecret,
                        VerifyToken  = encToken
                    };
                    WritePacket(responsePkt);


                    // enable aes encryption
                    _aesStream = new AesStream(Client.GetStream(), aesSecret);
                    _encrypted = true;

                    // read the next packet
                    return(ReadNextPacket());
                }
            }
        }

        return(new PacketData
        {
            ID = packetId,
            Payload = payload
        });
    }
예제 #14
0
 public virtual void WriteString(string value)
 {
     byte[] str = Encoding.UTF8.GetBytes(value);
     Write(VarInt.GetBytes(str.Length));
     Write(str);
 }