예제 #1
0
        public HMessage(byte[] data, HDestination destination)
            : this()
        {
            if (data == null)
            {
                throw new NullReferenceException();
            }
            if (data.Length < 6)
            {
                throw new Exception("Insufficient data, minimum length is '6'(Six). [Length{4}][Header{2}]");
            }

            Destination = destination;
            IsCorrupted = (BigEndian.DecypherInt(data) != data.Length - 4);
            if (!IsCorrupted)
            {
                Header = BigEndian.DecypherShort(data, 4);

                _body.AddRange(data);
                _body.RemoveRange(0, 6);

                Reconstruct();
            }
            else
            {
                Length        = data.Length;
                _toBytesCache = data;
            }
        }
예제 #2
0
        public virtual int ReadInt(ref int index)
        {
            if (index >= Body.Length || index + 4 > Body.Length)
            {
                throw new Exception("Not enough data at the current position to begin reading a Int32 type object.");
            }

            int value = BigEndian.DecypherInt(Body[index++], Body[index++], Body[index++], Body[index++]);

            AddToRead(value);

            return(value);
        }
예제 #3
0
        public static IList <byte[]> Split(ref byte[] cache, byte[] data, bool shouldSplit)
        {
            if (!shouldSplit)
            {
                return new[] { data }
            }
            ;

            lock (_splitLock)
            {
                if (cache != null)
                {
                    data  = Merge(cache, data);
                    cache = null;
                }

                var chunks = new List <byte[]>();

                int length = BigEndian.DecypherInt(data);
                if (length == data.Length - 4)
                {
                    chunks.Add(data);
                }
                else
                {
                    do
                    {
                        if (length > data.Length - 4)
                        {
                            cache = data; break;
                        }
                        chunks.Add(CutBlock(ref data, 0, length + 4));

                        if (data.Length >= 4)
                        {
                            length = BigEndian.DecypherInt(data);
                        }
                    }while (data.Length != 0);
                }
                return(chunks);
            }
        }
예제 #4
0
        public int ReadInt(ref int Index)
        {
            if (IsCorrupted)
            {
                return(0);
            }
            switch (Protocol)
            {
            case HProtocols.Modern: return(BigEndian.DecypherInt(Body[Index++], Body[Index++], Body[Index++], Body[Index++]));

            case HProtocols.Ancient:
            {
                int Value = Ancient.DecypherInt(Body, Index);
                Index += Ancient.CypherInt(Value).Length;
                return(Value);
            }

            default: return(0);
            }
        }
예제 #5
0
        public static byte[][] Split(ref byte[] Cache, byte[] Data, HDestinations Destination, HProtocols Protocol)
        {
            lock (SplitLock)
            {
                if (Cache != null)
                {
                    Data  = Merge(Cache, Data);
                    Cache = null;
                }

                List <byte[]> Chunks = new List <byte[]>();
                if (Protocol == HProtocols.Ancient && Destination == HDestinations.Client)
                {
                    if (!Data.Contains((byte)1))
                    {
                        Cache = Data;
                    }
                    else
                    {
                        List <byte> Buffer = new List <byte>();
                        foreach (byte Value in Data)
                        {
                            Buffer.Add(Value);
                            if (Value == 1)
                            {
                                Chunks.Add(Buffer.ToArray());
                                Buffer.Clear();
                            }
                        }
                        if (Buffer.Count > 0)
                        {
                            Cache = Buffer.ToArray();
                        }
                    }
                }
                else
                {
                    bool IsAncient = Protocol == HProtocols.Ancient;
                    int  Offset    = IsAncient ? 3 : 4;
                    int  Length    = IsAncient ? Ancient.DecypherShort(Data, 1) : BigEndian.DecypherInt(Data);
                    if (Length == Data.Length - Offset)
                    {
                        Chunks.Add(Data);
                    }
                    else
                    {
                        do
                        {
                            if (Length > Data.Length - Offset)
                            {
                                Cache = Data; break;
                            }
                            Chunks.Add(CutBlock(ref Data, 0, Length + Offset));
                            if (Data.Length >= Offset)
                            {
                                Length = IsAncient ? Ancient.DecypherShort(Data, 1) : BigEndian.DecypherInt(Data);
                            }
                        }while (Data.Length != 0);
                    }
                }
                return(Chunks.ToArray());
            }
        }
예제 #6
0
        public HMessage(byte[] Data, HDestinations Destination)
            : this()
        {
            if (Data == null)
            {
                throw new NullReferenceException();
            }
            if (Data.Length < 1)
            {
                throw new Exception("The minimum amount of bytes required to initialize an HMessage instance is 1(One). If the amount of bytes passed is < 3(Three), and >= 1(One), it will be immediately be identified as a corrupted packet. { IsCorrupted = true }");
            }

            this.Destination = Destination;
            bool HasByteZero     = Data.Contains(byte.MinValue);
            bool IsAncientHeader = !HasByteZero && Data.Length == 2 && Data[1] != 1;

            if (!IsAncientHeader && Data.Length >= 6 && BigEndian.DecypherInt(Data) == Data.Length - 4)
            {
                Protocol = HProtocols.Modern;

                _Header = BigEndian.DecypherShort(Data, 4);
                Append(ByteUtils.CopyBlock(Data, 4, Data.Length - 4));

                if (Data.Length == 6)
                {
                    LogWriting = true;
                }
            }
            else if ((Destination == HDestinations.Server && IsAncientHeader) || (!HasByteZero && Data.Length >= 5 && Ancient.DecypherShort(Data, 1) == Data.Length - 3))
            {
                this.Destination = HDestinations.Server;
                Protocol         = HProtocols.Ancient;

                _Header = Ancient.DecypherShort(Data, IsAncientHeader ? 0 : 3);
                Append(IsAncientHeader ? Data : ByteUtils.CopyBlock(Data, 3, Data.Length - 3));

                if (Data.Length == 5 || IsAncientHeader)
                {
                    LogWriting = true;
                }
            }
            else if (IsAncientHeader || (!HasByteZero && Data.Length >= 3 && Data[Data.Length - 1] == 1))
            {
                this.Destination = HDestinations.Client;
                Protocol         = HProtocols.Ancient;

                if (IsAncientHeader)
                {
                    Data = new byte[3] {
                        Data[0], Data[1], 1
                    }
                }
                ;
                _Header = Ancient.DecypherShort(Data);
                Append(Data);

                if (Data.Length == 3 || IsAncientHeader)
                {
                    LogWriting = true;
                }
            }
            else
            {
                Body        = Data;
                BCache      = Data;
                IsCorrupted = true;
                Length      = Data.Length;
                Buffer.AddRange(Data);
                SCache = ToString(Data);
            }
        }