예제 #1
0
파일: Stream.cs 프로젝트: vhsoaresr/Dota2
        private void ReadChunkHeader(Bitstream stream)
        {
            header = new ChunkedHeader();

            header.IsFile = stream.ReadBool();
            if (header.IsFile)
            {
                var filenameLength = stream.ReadUInt32();
                var filename = new byte[filenameLength + 1]; // semantically wrong. should be
                // 0x104
                stream.Read(filename, 0, (int) filenameLength); // and then read to end of string
                filename[filenameLength] = 0; // whatever 
                header.Filename = Encoding.UTF8.GetString(filename);
                throw new NotImplementedException();
            }

            header.IsCompressed = stream.ReadBool();
            if (header.IsCompressed)
            {
                header.DecompressedLength = stream.ReadBits(26);
            }

            header.ByteLength = stream.ReadBits(26);
            header.ChunkCount =
                (header.ByteLength + DotaGameConnection.BYTES_PER_CHUNK - 1)/
                DotaGameConnection.BYTES_PER_CHUNK;

            Receiving = true;
            dataIn = new byte[header.ByteLength];
            dataReceived = new bool[header.ChunkCount];
            countReceived = 0;
        }
예제 #2
0
        private UpdateFlag ReadHeader(ref uint id, Bitstream stream)
        {
            var value = stream.ReadBits(6);

            if ((value & 0x30) > 0)
            {
                var a = (value >> 4) & 3;
                var b = (uint) ((a == 3) ? 16 : 0);

                value = (stream.ReadBits((byte) (4*a + b)) << 4) | (value & 0xF);
            }

            id = unchecked(id + value + 1);

            var flags = UpdateFlag.None;

            if (!stream.ReadBool())
            {
                if (stream.ReadBool())
                {
                    flags |= UpdateFlag.EnterPvs;
                }
            }
            else
            {
                flags |= UpdateFlag.LeavePvs;

                if (stream.ReadBool())
                {
                    flags |= UpdateFlag.Delete;
                }
            }

            return flags;
        }
예제 #3
0
        private string ReadKeyIfIncluded(Bitstream stream, List<string> keyHistory)
        {
            var has_key = stream.ReadBool();

            if (!has_key)
            {
                return null;
            }

            var is_substring = stream.ReadBool();

            string key;

            if (!is_substring)
            {
                key = stream.ReadString();
            }
            else
            {
                var fromIndex = (int) stream.ReadBits(5);
                var fromLength = (int) stream.ReadBits(5);
                key = keyHistory[fromIndex].Substring(0, fromLength);

                key += stream.ReadString();
            }

            if (keyHistory.Count == KEY_HISTORY_SIZE)
            {
                keyHistory.RemoveAt(0);
            }

            keyHistory.Add(key);

            return key;
        }
예제 #4
0
파일: Stream.cs 프로젝트: vhsoaresr/Dota2
        public Message? Receive(Bitstream stream)
        {
            var hasData = stream.ReadBool();

            if (!hasData)
            {
                return null;
            }

            if (stream.ReadBool())
            {
                return ReadChunk(stream);
            }
            return ReadSingle(stream);
        }
예제 #5
0
        public float UnpackFloat(PropertyInfo info, Bitstream stream)
        {
            var flags = info.Flags;

            if (flags.HasFlag(PropertyInfo.MultiFlag.Coord))
            {
                return UnpackFloatCoord(stream);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CoordMp))
            {
                return UnpackFloatCoordMp(stream, FloatType.None);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CoordMpLowPrecision))
            {
                return UnpackFloatCoordMp(stream, FloatType.LowPrecision);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CoordMpIntegral))
            {
                return UnpackFloatCoordMp(stream, FloatType.Integral);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.NoScale))
            {
                return UnpackFloatNoScale(stream);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.Normal))
            {
                return UnpackFloatNormal(stream);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CellCoord))
            {
                return UnpackFloatCellCoord(info, stream, FloatType.None);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CellCoordLowPrecision))
            {
                return UnpackFloatCellCoord(info, stream, FloatType.LowPrecision);
            }
            if (flags.HasFlag(PropertyInfo.MultiFlag.CellCoordIntegral))
            {
                return UnpackFloatCellCoord(info, stream, FloatType.Integral);
            }
            var dividend = stream.ReadBits(info.NumBits);
            var divisor = (uint) (1 << info.NumBits) - 1;

            var f = ((float) dividend)/divisor;
            var range = info.HighValue - info.LowValue;

            return f*range + info.LowValue;
        }
예제 #6
0
파일: Stream.cs 프로젝트: vhsoaresr/Dota2
        private Message? ReadChunk(Bitstream stream)
        {
            var offset = stream.ReadBits(18);
            var count = stream.ReadBits(3);

            if (offset == 0)
            {
                ReadChunkHeader(stream);
            }

            var byteOffset = offset*DotaGameConnection.BYTES_PER_CHUNK;

            uint byteCount;
            if (offset + count < header.ChunkCount)
            {
                byteCount = count*DotaGameConnection.BYTES_PER_CHUNK;
            }
            else
            {
                byteCount = header.ByteLength - byteOffset;
            }

            stream.Read(dataIn, (int) byteOffset, (int) byteCount);

            for (var i = offset;
                i < offset + count;
                ++i)
            {
                if (!dataReceived[i])
                {
                    dataReceived[i] = true;
                    ++countReceived;
                }
            }

            if (countReceived == header.ChunkCount)
            {
                Receiving = false;
                return new Message
                {
                    IsCompressed = header.IsCompressed,
                    DecompressedLength = header.DecompressedLength,
                    Data = dataIn
                };
            }
            return null;
        }
예제 #7
0
        public void Update(Bitstream stream, uint baseline, bool updateBaseline, uint updated, bool isDelta)
        {
            var id = uint.MaxValue;
            uint found = 0;

            while (found < updated)
            {
                var flags = ReadHeader(ref id, stream);

                if (flags.HasFlag(UpdateFlag.EnterPvs))
                {
                    ReadEnterPvs(id, baseline, updateBaseline, stream);
                }
                else if (flags.HasFlag(UpdateFlag.LeavePvs))
                {
                    if (flags.HasFlag(UpdateFlag.Delete))
                    {
                        Delete(id);
                    }
                }
                else
                {
                    ReadUpdate(id, stream);
                }

                ++found;
            }

            if (isDelta)
            {
                while (stream.ReadBool())
                {
                    id = stream.ReadBits(11);
                    Delete(id);
                }
            }
        }
예제 #8
0
        public uint UnpackInt(PropertyInfo info, Bitstream stream)
        {
            var flags = info.Flags;

            if (flags.HasFlag(PropertyInfo.MultiFlag.EncodedAgainstTickcount))
            {
                if (flags.HasFlag(PropertyInfo.MultiFlag.Unsigned))
                {
                    return stream.ReadVarUInt();
                }
                var value = stream.ReadVarUInt();
                return unchecked((uint) ((-(value & 1)) ^ (value >> 1)));
            }

            var numBits = info.NumBits;

            var isUnsigned = Convert.ToUInt32(flags.HasFlag(PropertyInfo.MultiFlag.Unsigned));
            var signer = (0x80000000 >> (32 - numBits)) & unchecked((isUnsigned - 1));

            {
                var value = stream.ReadBits(numBits) ^ signer;
                return value - signer;
            }
        }
예제 #9
0
        public string UnpackString(PropertyInfo info, Bitstream stream)
        {
            var length = stream.ReadBits(9);

            var buffer = new byte[length];
            stream.Read(buffer, 0, (int) length);

            return new string((from byte b in buffer select (char) b).ToArray<char>());
        }
예제 #10
0
 public VectorXy UnpackVectorXy(PropertyInfo info, Bitstream stream)
 {
     var x = UnpackFloat(info, stream);
     var y = UnpackFloat(info, stream);
     return new VectorXy(x, y);
 }
예제 #11
0
        public Vector UnpackVector(PropertyInfo info, Bitstream stream)
        {
            var x = UnpackFloat(info, stream);
            var y = UnpackFloat(info, stream);
            float z;

            if (info.Flags.HasFlag(PropertyInfo.MultiFlag.Normal))
            {
                var sign = stream.ReadBool();

                var f = x*x + y*y;

                if (1 >= f)
                {
                    z = 0;
                }
                else
                {
                    z = (float) Math.Sqrt(1 - f);
                }

                if (sign)
                {
                    z *= -1;
                }
            }
            else
            {
                z = UnpackFloat(info, stream);
            }

            return new Vector(x, y, z);
        }
예제 #12
0
        private float UnpackFloatCellCoord(PropertyInfo info, Bitstream stream, FloatType type)
        {
            var value = stream.ReadBits(info.NumBits);
            float f = value;

            if ((value >> 31) > 0)
            {
                f *= -1;
            }

            if (type == FloatType.None)
            {
                var fraction = stream.ReadBits(5);

                return f + 0.03125f*fraction;
            }
            if (type == FloatType.LowPrecision)
            {
                var fraction = stream.ReadBits(3);

                return f + 0.125f*fraction;
            }
            if (type == FloatType.Integral)
            {
                return f;
            }
            throw new InvalidOperationException("Unknown float type");
        }
예제 #13
0
        private float UnpackFloatNormal(Bitstream stream)
        {
            var sign = stream.ReadBool();
            var value = stream.ReadBits(NORMAL_FRACTIONAL_BITS);

            var f = (float) (value*NORMAL_RESOLUTION);

            if (sign)
            {
                f *= -1;
            }

            return f;
        }
예제 #14
0
        private uint ReadFieldNumber(uint lastField, Bitstream stream)
        {
            if (stream.ReadBool())
            {
                return unchecked(lastField + 1);
            }
            var value = stream.ReadVarUInt();

            if (value == 0x3FFF)
            {
                return uint.MaxValue;
            }
            return unchecked(lastField + value + 1);
        }
예제 #15
0
        private float UnpackFloatCoord(Bitstream stream)
        {
            var hasInteger = stream.ReadBool();
            var hasFraction = stream.ReadBool();

            if (hasInteger || hasFraction)
            {
                var sign = stream.ReadBool();

                uint integer = 0;
                if (hasInteger)
                {
                    integer = stream.ReadBits(COORD_INTEGER_BITS) + 1;
                }

                uint fraction = 0;
                if (hasFraction)
                {
                    fraction = stream.ReadBits(COORD_FRACTIONAL_BITS);
                }

                var f = (float) (integer + fraction*COORD_RESOLUTION);

                if (sign)
                {
                    f *= -1;
                }

                return f;
            }
            return 0;
        }
예제 #16
0
        private byte[] ReadValueIfIncluded(Bitstream stream, bool userDataFixedSize,
            uint userDataSizeBits)
        {
            var has_value = stream.ReadBool();

            if (!has_value)
            {
                return null;
            }

            uint length;
            uint bitLength;

            if (userDataFixedSize)
            {
                length = (userDataSizeBits + 7)/8;
                bitLength = userDataSizeBits;
            }
            else
            {
                length = stream.ReadBits(14);
                bitLength = 8*length;
            }

            return stream.ReadManyBits(bitLength);
        }
예제 #17
0
        private void ReadEnterPvs(uint id, uint baseline, bool update_baseline, Bitstream stream)
        {
            var clazz = state.Classes[(int) stream.ReadBits(ClassBitLength)];
            var serial = stream.ReadBits(10);

            Create(id, clazz, baseline);
            ReadAndUnpackFields(state.Slots[id].Entity, stream);

            if (update_baseline)
            {
                state.Slots[id].Baselines[1 - baseline] = state.Slots[id].Entity.Copy();
            }
        }
예제 #18
0
 private void ReadUpdate(uint id, Bitstream stream)
 {
     var entity = state.Slots[id].Entity;
     ReadAndUnpackFields(entity, stream);
 }
예제 #19
0
파일: Stream.cs 프로젝트: vhsoaresr/Dota2
        private Message ReadSingle(Bitstream stream)
        {
            var isCompressed = stream.ReadBool();

            if (isCompressed)
            {
                var uncompressed_length = stream.ReadBits(26);
                var length = stream.ReadBits(18);

                var data = new byte[length];
                stream.Read(data, 0, (int) length);

                return new Message
                {
                    IsCompressed = false,
                    Data = new SnappyDecompressor().Decompress(data, 0, data.Length)
                };
            }
            else
            {
                var length = stream.ReadBits(18);

                var data = new byte[length];
                stream.Read(data, 0, (int) length);

                return new Message
                {
                    IsCompressed = false,
                    Data = data
                };
            }
        }
예제 #20
0
        private void ReadAndUnpackFields(Entity entity, Bitstream stream)
        {
            var fields = ReadFieldList(stream);

            foreach (var field in fields)
            {
                entity.Properties[(int) field].Update(state.ClientTick, unpacker, stream);
            }
        }
예제 #21
0
        public void UnpackArray(uint tick, List<Property> elements, PropertyInfo info, Bitstream stream)
        {
            var countBits = MiscMath.Log2(info.NumElements + 1);
            var count = stream.ReadBits(countBits);

            if (elements.Count > count)
            {
                elements.RemoveRange(0, elements.Count - (int) count);
            }
            else
            {
                while (elements.Count < count)
                {
                    elements.Add(Property.For(info.ArrayProp));
                }
            }

            foreach (var element in elements)
            {
                element.Update(tick, this, stream);
            }
        }
예제 #22
0
 private float UnpackFloatCoordMp(Bitstream stream, FloatType type)
 {
     throw new NotImplementedException();
 }
예제 #23
0
        public ulong UnpackInt64(PropertyInfo info, Bitstream stream)
        {
            if (info.Flags.HasFlag(PropertyInfo.MultiFlag.EncodedAgainstTickcount))
            {
                return stream.ReadVarUInt();
            }
            var negate = false;
            var secondBits = (byte) (info.NumBits - 32);

            if (!info.Flags.HasFlag(PropertyInfo.MultiFlag.Unsigned))
            {
                --secondBits;

                if (stream.ReadBool())
                {
                    negate = true;
                }
            }

            ulong a = stream.ReadBits(32);
            ulong b = stream.ReadBits(secondBits);
            var value = (b << 32) | a;

            if (negate)
            {
                value = unchecked((ulong) ((long) value*-1));
            }

            return value;
        }
예제 #24
0
 private float UnpackFloatNoScale(Bitstream stream)
 {
     var data = stream.ReadManyBits(32);
     return BitConverter.ToSingle(data, 0);
 }
예제 #25
0
        private void WriteUserCmd(UserCmd cmd, UserCmd last, Bitstream stream)
        {
            if (cmd.Command != last.Command + 1)
            {
                stream.WriteBool(true);
                stream.WriteUInt32(cmd.Command);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.Tick != last.Tick + 1)
            {
                stream.WriteBool(true);
                stream.WriteUInt32(cmd.Tick);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ViewAngles.X != last.ViewAngles.X)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.ViewAngles.X);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ViewAngles.X != last.ViewAngles.X)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.ViewAngles.X);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ViewAngles.Z != last.ViewAngles.Z)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.ViewAngles.Z);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ForwardMove != last.ForwardMove)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.ForwardMove);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.SideMove != last.SideMove)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.SideMove);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.UpMove != last.UpMove)
            {
                stream.WriteBool(true);
                stream.WriteFloat(cmd.UpMove);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.Buttons != last.Buttons)
            {
                stream.WriteBool(true);
                stream.WriteUInt32(cmd.Buttons);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.Impulse != last.Impulse)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.Impulse);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.CrosshairTrace != last.CrosshairTrace)
            {
                stream.WriteBool(true);
                stream.WriteBitVec3Coord(cmd.CrosshairTrace);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.CursorUnitEntIndex != last.CursorUnitEntIndex)
            {
                stream.WriteBool(true);
                stream.WriteBits(cmd.CursorUnitEntIndex, 11);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.QueryEntIndex != last.QueryEntIndex)
            {
                stream.WriteBool(true);
                stream.WriteBits(cmd.QueryEntIndex, 11);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.CursorUnitEntIndex != last.CursorUnitEntIndex)
            {
                stream.WriteBool(true);
                stream.WriteBits(cmd.CursorUnitEntIndex, 11);

                if (cmd.QueryEntIndex != last.QueryEntIndex)
                {
                    stream.WriteBool(true);
                    stream.WriteBits(cmd.QueryEntIndex, 11);
                }
                else
                {
                    stream.WriteBool(false);
                }
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.MouseDx != last.MouseDx)
            {
                stream.WriteBool(true);
                stream.WriteUInt16(cmd.MouseDx);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.MouseDy != last.MouseDy)
            {
                stream.WriteBool(true);
                stream.WriteUInt16(cmd.MouseDy);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.Offset3c != last.Offset3c)
            {
                stream.WriteBool(true);
                stream.WriteUInt16(cmd.Offset3c);
            }
            else
            {
                stream.WriteBool(false);
            }

            // 0x44 to 0x74 inclusive
            if (cmd.OrderId != last.OrderId)
            {
                stream.WriteBool(true);
                stream.WriteInt16(cmd.OrderId);
                stream.WriteInt16((short) cmd.Order.Value.SelectedUnits.Length);

                foreach (var entity in cmd.Order.Value.SelectedUnits)
                {
                    stream.WriteBits(entity, 11);
                }

                stream.WriteInt16(cmd.Order.Value.OrderType);
                stream.WriteInt16(cmd.Order.Value.EntityIndex1);
                stream.WriteBitVec3Coord(cmd.Order.Value.PreparedOrderPoint);
                stream.WriteBits(cmd.Order.Value.BaseNpcHandle, 11);
                stream.WriteBool(cmd.Order.Value.QueueOrder);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.CameraX != last.CameraX || cmd.CameraY != last.CameraY)
            {
                stream.WriteBool(true);
                stream.WriteUInt16(cmd.CameraX);
                stream.WriteUInt16(cmd.CameraY);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ClickBehavior != last.ClickBehavior)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.ClickBehavior);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.SpectatorStatsSomething != last.SpectatorStatsSomething)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.SpectatorStatsSomething);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.ShopModeSomething != last.ShopModeSomething)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.ShopModeSomething);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.HudStatsDropdownCategoryIndex != last.HudStatsDropdownCategoryIndex)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.HudStatsDropdownCategoryIndex);
            }
            else
            {
                stream.WriteBool(false);
            }

            if (cmd.HudStatsDropdownSortMethod != last.HudStatsDropdownSortMethod)
            {
                stream.WriteBool(true);
                stream.WriteByte(cmd.HudStatsDropdownSortMethod);
            }
            else
            {
                stream.WriteBool(false);
            }
        }
예제 #26
0
        private List<uint> ReadFieldList(Bitstream stream)
        {
            var fields = new List<uint>();

            var field = uint.MaxValue;
            field = ReadFieldNumber(field, stream);

            while (field != uint.MaxValue)
            {
                fields.Add(field);

                field = ReadFieldNumber(field, stream);
            }

            return fields;
        }