Beispiel #1
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);
            }
        }
Beispiel #2
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);
            }
        }
Beispiel #3
0
        public HMessage(byte[] data, HDestination destination)
            : this()
        {
            Destination = destination;
            IsCorrupted = (data.Length < 6 ||
                           (BigEndian.ToInt32(data, 0) != data.Length - 4));

            if (!IsCorrupted)
            {
                Header = BigEndian.ToUInt16(data, 4);

                _bodyBuffer = new byte[data.Length - 6];
                Buffer.BlockCopy(data, 6, _bodyBuffer, 0, data.Length - 6);
            }
            else
            {
                _bodyBuffer = data;
            }
            _body.AddRange(_bodyBuffer);
        }
Beispiel #4
0
        public static byte[] GetBytes(params object[] values)
        {
            var buffer = new List <byte>();

            foreach (object value in values)
            {
                switch (Type.GetTypeCode(value.GetType()))
                {
                case TypeCode.Byte: buffer.Add((byte)value); break;

                case TypeCode.Boolean: buffer.Add(Convert.ToByte((bool)value)); break;

                case TypeCode.Int32: buffer.AddRange(BigEndian.GetBytes((int)value)); break;

                case TypeCode.UInt16: buffer.AddRange(BigEndian.GetBytes((ushort)value)); break;

                default:
                case TypeCode.String:
                {
                    byte[] data = value as byte[];
                    if (data == null)
                    {
                        string stringValue = value.ToString()
                                             .Replace("\\a", "\a").Replace("\\b", "\b")
                                             .Replace("\\f", "\f").Replace("\\n", "\n")
                                             .Replace("\\r", "\r").Replace("\\t", "\t")
                                             .Replace("\\v", "\v").Replace("\\0", "\0");

                        data = BigEndian.GetBytes(stringValue);
                    }
                    buffer.AddRange(data);
                    break;
                }
                }
            }
            return(buffer.ToArray());
        }
Beispiel #5
0
        public static byte[] ToBytes(string value)
        {
            value = value.Replace("{b:}", "[0]")
                    .Replace("{u:}", "[0][0]")
                    .Replace("{s:}", "[0][0]")
                    .Replace("{i:}", "[0][0][0][0]");

            for (int i = 0; i <= 13; i++)
            {
                value = value.Replace(
                    "[" + i + "]", ((char)i).ToString());
            }

            string objectValue = string.Empty;

            while (!string.IsNullOrWhiteSpace(
                       objectValue = value.GetChild("{b:").GetParent("}")))
            {
                char byteChar = objectValue.ToLower()[0];

                byte byteValue = (byte)(byteChar == 't' ||
                                        (byteChar == '1' && objectValue.Length == 1) ? 1 : 0);

                if (byteChar != 'f' && byteValue != 1 &&
                    !byte.TryParse(objectValue.ToLower(), out byteValue))
                {
                    break;
                }

                string byteParam = $"{{b:{objectValue}}}";
                value = value.Replace(byteParam, ((char)byteValue).ToString());
            }

            while (!string.IsNullOrWhiteSpace(
                       objectValue = value.GetChild("{u:").GetParent("}")))
            {
                ushort shortValue = 0;
                if (!ushort.TryParse(objectValue, out shortValue))
                {
                    break;
                }

                byte[] ushortData  = BigEndian.GetBytes(shortValue);
                string ushortParam = $"{{u:{objectValue}}}";

                value = value.Replace(ushortParam,
                                      Encoding.Default.GetString(ushortData));
            }

            while (!string.IsNullOrWhiteSpace(
                       objectValue = value.GetChild("{i:").GetParent("}")))
            {
                int intValue = 0;
                if (!int.TryParse(objectValue, out intValue))
                {
                    break;
                }

                byte[] intData  = BigEndian.GetBytes(intValue);
                string intParam = $"{{i:{objectValue}}}";

                value = value.Replace(intParam,
                                      Encoding.Default.GetString(intData));
            }

            while (!string.IsNullOrWhiteSpace(
                       objectValue = value.GetChild("{s:").GetParent("}")))
            {
                byte[] stringData  = BigEndian.GetBytes(objectValue);
                string stringParam = $"{{s:{objectValue}}}";

                value = value.Replace(stringParam,
                                      Encoding.Default.GetString(stringData));
            }

            if (value.StartsWith("{l}") && value.Length >= 5)
            {
                byte[] lengthData = BigEndian.GetBytes(value.Length - 3);
                value = Encoding.Default.GetString(lengthData) + value.Substring(3);
            }
            return(Encoding.Default.GetBytes(value));
        }
Beispiel #6
0
 public void WriteString(string value, int position)
 {
     byte[] encoded = BigEndian.GetBytes(value);
     WriteObject(encoded, value, position);
 }
Beispiel #7
0
 public void WriteBoolean(bool value, int position)
 {
     byte[] encoded = BigEndian.GetBytes(value);
     WriteObject(encoded, value, position);
 }
Beispiel #8
0
 public void WriteShort(ushort value, int position)
 {
     byte[] encoded = BigEndian.GetBytes(value);
     WriteObject(encoded, value, position);
 }
Beispiel #9
0
 public void WriteInteger(int value, int position)
 {
     byte[] encoded = BigEndian.GetBytes(value);
     WriteObject(encoded, value, position);
 }
Beispiel #10
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());
            }
        }
Beispiel #11
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);
            }
        }
Beispiel #12
0
        public static byte[] Construct(ushort Header, HDestinations Destination, HProtocols Protocol, params object[] Chunks)
        {
            if (Protocol == HProtocols.Unknown)
            {
                throw new Exception("You must specify a supported HProtocols value for this method. ( Ancient / Modern )");
            }
            if (Protocol == HProtocols.Ancient && Destination == HDestinations.Unknown)
            {
                throw new Exception("Cannot construct the body of an Ancient type packet without a valid HDestinations value. ( Client / Server )");
            }

            List <byte> Buffer    = new List <byte>();
            bool        IsAncient = Protocol == HProtocols.Ancient;

            if (IsAncient && Destination == HDestinations.Server)
            {
                Buffer.Add(64);
            }
            Buffer.AddRange(IsAncient ? Ancient.CypherShort(Header) : BigEndian.CypherShort(Header));

            Buffer.AddRange(ConstructBody(Destination, Protocol, Chunks));

            if (!IsAncient || Destination == HDestinations.Server)
            {
                Buffer.InsertRange(IsAncient ? 1 : 0, IsAncient ? Ancient.CypherShort((ushort)(Buffer.Count - 1)) : BigEndian.CypherInt(Buffer.Count));
            }
            else if (Buffer[Buffer.Count - 1] != 1)
            {
                Buffer.Add(1);
            }

            return(Buffer.ToArray());
        }
Beispiel #13
0
        public static byte[] ConstructBody(HDestinations Destination, HProtocols Protocol, params object[] Chunks)
        {
            if (Protocol == HProtocols.Unknown)
            {
                throw new Exception("You must specify a supported HProtocols value for this method. ( Ancient / Modern )");
            }
            if (Protocol == HProtocols.Ancient && Destination == HDestinations.Unknown)
            {
                throw new Exception("Cannot construct the body of an Ancient type packet without a valid HDestinations value. ( Client / Server )");
            }

            List <byte> Buffer    = new List <byte>();
            bool        IsAncient = Protocol == HProtocols.Ancient;

            for (int i = 0; i < Chunks.Length; i++)
            {
                object Chunk = Chunks[i];
                if (Chunk == null)
                {
                    throw new NullReferenceException(string.Format("Unable to encode a null object. {{ Index = {0} }}", i));
                }

                if (Chunk is byte[])
                {
                    Buffer.AddRange((byte[])Chunk);
                }
                else
                {
                    switch (Type.GetTypeCode(Chunk.GetType()))
                    {
                    case TypeCode.Int32:
                    {
                        int Value = (int)Chunk;
                        Buffer.AddRange(IsAncient ? Ancient.CypherInt(Value) : BigEndian.CypherInt(Value));
                        break;
                    }

                    default:
                    case TypeCode.String:
                    {
                        string Value = Chunk.ToString();
                        if (!IsAncient || Destination == HDestinations.Server)
                        {
                            Buffer.AddRange(IsAncient ? Ancient.CypherShort((ushort)Value.Length) : BigEndian.CypherShort((ushort)Value.Length));
                            Buffer.AddRange(Encoding.Default.GetBytes(Value));
                        }
                        else
                        {
                            Buffer.AddRange(Encoding.Default.GetBytes(Value));
                            Buffer.Add(2);
                        }
                        break;
                    }

                    case TypeCode.Boolean:
                    {
                        bool Value = (bool)Chunk;
                        Buffer.Add(IsAncient ? (byte)(Value ? 73 : 72) : Convert.ToByte(Value));
                        break;
                    }

                    case TypeCode.Byte:
                    {
                        byte Value = (byte)Chunk;
                        Buffer.Add(Value);
                        break;
                    }
                    }
                }
            }
            return(Buffer.ToArray());
        }
Beispiel #14
0
        public static byte[] ToBytes(string packet)
        {
            for (int i = 0; i <= 13; i++)
            {
                packet = packet.Replace(
                    "[" + i + "]", ((char)i).ToString());
            }

            MatchCollection matches = _valueGrabber.Matches(packet);

            foreach (Match match in matches)
            {
                string type  = match.Groups["type"].Value;
                string value = match.Groups["value"].Value;

                byte[] data = null;
                #region Switch: type
                switch (type)
                {
                case "s":
                {
                    data = BigEndian.GetBytes(value);
                    break;
                }

                case "u":
                {
                    ushort uValue = 0;
                    ushort.TryParse(value, out uValue);
                    data = BigEndian.GetBytes(uValue);
                    break;
                }

                case "i":
                {
                    int iValue = 0;
                    int.TryParse(value, out iValue);
                    data = BigEndian.GetBytes(iValue);
                    break;
                }

                case "b":
                {
                    byte bValue = 0;
                    if (!byte.TryParse(value, out bValue))
                    {
                        data = BigEndian.GetBytes(
                            (value.ToLower() == "true"));
                    }
                    else
                    {
                        data = new byte[] { bValue }
                    };
                    break;
                }
                }
                #endregion

                packet = packet.Replace(match.Value,
                                        Encoding.Default.GetString(data));
            }
            if (packet.StartsWith("{l}") && packet.Length >= 5)
            {
                byte[] lengthData = BigEndian.GetBytes(packet.Length - 3);
                packet = Encoding.Default.GetString(lengthData) + packet.Substring(3);
            }
            return(Encoding.Default.GetBytes(packet));
        }