Exemplo n.º 1
0
        public void Write(PacketLogEntry entry)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            if (!Servers.ContainsKey(entry.ServerId))
            {
                throw new ArgumentException("Invalid server ID.", nameof(entry));
            }

            if (!Messages.Game.OpCodeToName.ContainsKey(entry.OpCode))
            {
                throw new ArgumentException("Invalid opcode.", nameof(entry));
            }

            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            _writer.WriteInt64(new DateTimeOffset(entry.Timestamp).ToUnixTimeMilliseconds());
            _writer.WriteInt32(entry.ServerId);
            _writer.WriteByte((byte)entry.Direction);
            _writer.WriteUInt16(entry.OpCode);
            _writer.WriteUInt16((ushort)entry.Payload.Count);
            _writer.WriteBytes(entry.Payload.ToArray());
        }
Exemplo n.º 2
0
        bool HandleSpawnMe(GameClient client, Direction direction, RawPacket packet)
        {
            // Automatically join a chat channel when logging in.

            _log.Info("Making client {0} join chat channel {1} with password {2}",
                      client.EndPoint, ChatChannelName, ChatChannelPassword);

            using (var writer = new TeraBinaryWriter())
            {
                writer.WriteUInt16((ushort)(PacketHeader.HeaderSize +
                                            sizeof(ushort) * 2));
                writer.WriteUInt16(ChatChannelPassword);
                writer.WriteString(ChatChannelName);

                client.SendToServer(new RawPacket("C_JOIN_PRIVATE_CHANNEL")
                {
                    Payload = writer.ToArray()
                });
            }

            // Let's request an absurdly low visibility range.

            _log.Info("Setting visibility range for client {0} to {1}",
                      client.EndPoint, VisibilityRange);

            client.SendToServer(new CSetVisibleRangePacket
            {
                Range = VisibilityRange
            });

            return(true);
        }
Exemplo n.º 3
0
        internal static void WriteHeader(PacketHeader header, byte[] buffer)
        {
            using var writer = new TeraBinaryWriter(buffer);

            writer.WriteUInt16((ushort)(header.Length + PacketHeader.HeaderSize));
            writer.WriteUInt16(header.OpCode);
        }
Exemplo n.º 4
0
        public PacketLogWriter(MessageTables messages, ServerInfo[] servers,
                               string directory, string fileNameFormat, bool compress)
        {
            if (servers == null)
            {
                throw new ArgumentNullException(nameof(servers));
            }

            if (servers.Any(x => x == null))
            {
                throw new ArgumentException("A null server was given.",
                                            nameof(servers));
            }

            if (fileNameFormat == null)
            {
                throw new ArgumentNullException(nameof(fileNameFormat));
            }

            IsCompressed = compress;
            Messages     = messages ?? throw new ArgumentNullException(nameof(messages));
            Servers      = servers.ToDictionary(x => x.Id);

            Directory.CreateDirectory(directory);

            Stream stream = File.Open(
                Path.Combine(directory, DateTime.Now.ToString(fileNameFormat) + ".pkt"),
                FileMode.Create, FileAccess.Write);

            var magic = PacketLogEntry.Magic.ToArray();

            stream.Write(magic, 0, magic.Length);
            stream.WriteByte((byte)(compress ? 6 : 0));

            if (compress)
            {
                stream = new DeflateStream(stream, CompressionLevel.Optimal);
            }

            _writer = new TeraBinaryWriter(stream);

            _writer.WriteUInt32(Version);
            _writer.WriteByte((byte)messages.Region);
            _writer.WriteUInt32(messages.Game.Version);
            _writer.WriteUInt32((uint)servers.Length);

            foreach (var server in servers)
            {
                _writer.WriteInt32(server.Id);
                _writer.WriteString(server.Name);
                _writer.WriteBoolean(server.RealEndPoint.AddressFamily ==
                                     AddressFamily.InterNetworkV6);
                _writer.WriteBytes(server.RealEndPoint.Address.GetAddressBytes());
                _writer.WriteUInt16((ushort)server.RealEndPoint.Port);
                _writer.WriteBytes(server.ProxyEndPoint.Address.GetAddressBytes());
                _writer.WriteUInt16((ushort)server.ProxyEndPoint.Port);
            }
        }
Exemplo n.º 5
0
        void SerializeObject(TeraBinaryWriter writer, object source)
        {
            var fields  = GetPacketFields <ReflectionPacketFieldInfo>(source.GetType());
            var offsets = new List <(ReflectionPacketFieldInfo, int)>();

            foreach (var info in fields)
            {
                if (info.IsByteArray)
                {
                    offsets.Add((info, writer.Position));
                    writer.WriteUInt16(0);
                    writer.WriteUInt16((ushort)((List <byte>)info.Property
                                                .GetValue(source)).Count);
                }
                else if (info.IsArray)
                {
                    writer.WriteUInt16(
                        (ushort)((IList)info.Property.GetValue(source)).Count);
                    offsets.Add((info, writer.Position));
                    writer.WriteUInt16(0);
                }
                else if (info.IsString)
                {
                    offsets.Add((info, writer.Position));
                    writer.WriteUInt16(0);
                }
                else
                {
                    info.PrimitiveSerializer(writer, info.Property.GetValue(source));
                }
            }

            foreach (var(info, offset) in offsets)
            {
                if (info.IsByteArray)
                {
                    var list = (List <byte>)info.Property.GetValue(source);

                    if (list.Count == 0)
                    {
                        continue;
                    }

                    writer.Seek(offset, (w, op) => w.WriteOffset(op));
                    writer.WriteBytes(list.ToArray());
                }
                else if (info.IsArray)
                {
                    var list = (IList)info.Property.GetValue(source);

                    if (list.Count == 0)
                    {
                        continue;
                    }

                    writer.Seek(offset, (w, op) => w.WriteOffset(op));

                    for (var i = 0; i < list.Count; i++)
                    {
                        var pos = writer.Position;

                        writer.WriteOffset(pos);
                        writer.WriteUInt16(0);

                        SerializeObject(writer, list[i]);

                        if (i != list.Count - 1)
                        {
                            writer.Seek(pos + sizeof(ushort), (w, op) => w.WriteOffset(op));
                        }
                    }
                }
                else
                {
                    writer.Seek(offset, (w, op) => w.WriteOffset(op));
                    writer.WriteString((string)info.Property.GetValue(source) ?? string.Empty);
                }
            }
        }
Exemplo n.º 6
0
        static void SerializePrimitive(TeraBinaryWriter writer, object value)
        {
            var type = value.GetType();

            if (type.IsEnum)
            {
                type = type.GetEnumUnderlyingType();
            }

            if (type == typeof(bool))
            {
                writer.WriteBoolean((bool)value);
            }
            else if (type == typeof(byte))
            {
                writer.WriteByte((byte)value);
            }
            else if (type == typeof(sbyte))
            {
                writer.WriteSByte((sbyte)value);
            }
            else if (type == typeof(ushort))
            {
                writer.WriteUInt16((ushort)value);
            }
            else if (type == typeof(short))
            {
                writer.WriteInt16((short)value);
            }
            else if (type == typeof(uint))
            {
                writer.WriteUInt32((uint)value);
            }
            else if (type == typeof(int))
            {
                writer.WriteInt32((int)value);
            }
            else if (type == typeof(ulong))
            {
                writer.WriteUInt64((ulong)value);
            }
            else if (type == typeof(long))
            {
                writer.WriteInt64((long)value);
            }
            else if (type == typeof(float))
            {
                writer.WriteSingle((float)value);
            }
            else if (type == typeof(Vector3))
            {
                writer.WriteVector3((Vector3)value);
            }
            else if (type == typeof(EntityId))
            {
                writer.WriteEntityId((EntityId)value);
            }
            else if (type == typeof(SkillId))
            {
                writer.WriteSkillId((SkillId)value);
            }
            else if (type == typeof(Angle))
            {
                writer.WriteAngle((Angle)value);
            }
            else
            {
                throw Assert.Unreachable();
            }
        }
Exemplo n.º 7
0
        void SerializeObject(TeraBinaryWriter writer, object source)
        {
            var fields  = GetPacketFields(source.GetType());
            var counts  = new Dictionary <string, int>();
            var offsets = new Dictionary <string, int>();

            foreach (var info in fields.Where(x => x.IsPrimitive))
            {
                if (info.IsCount)
                {
                    counts.Add(info.Property.Name, writer.Position);
                }
                else if (info.IsOffset)
                {
                    offsets.Add(info.Property.Name, writer.Position);
                }

                if (info.IsCount || info.IsOffset)
                {
                    writer.WriteUInt16(0);
                }
                else
                {
                    SerializePrimitive(writer, info.Property.GetValue(source));
                }
            }

            foreach (var info in fields.Where(x => !x.IsPrimitive))
            {
                var type     = info.Property.PropertyType;
                var value    = info.Property.GetValue(source);
                var array    = value as Array;
                var noOffset = array != null && array.Length == 0;

                writer.Seek(offsets[info.Property.Name + OffsetNameSuffix],
                            (w, op) => w.WriteUInt16((ushort)(noOffset ?
                                                              0 : op + PacketHeader.HeaderSize)));

                if (type.IsArray)
                {
                    writer.Seek(counts[info.Property.Name + CountNameSuffix],
                                (w, op) => w.WriteUInt16((ushort)array.Length));

                    var elemType = type.GetElementType();

                    if (elemType.IsEnum)
                    {
                        elemType = elemType.GetEnumUnderlyingType();
                    }

                    var markers = new Stack <int>();

                    for (var i = 0; i < array.Length; i++)
                    {
                        var isLast = i == array.Length - 1;

                        if (!IsByte(elemType))
                        {
                            writer.WriteUInt16((ushort)(writer.Position +
                                                        PacketHeader.HeaderSize));

                            if (!isLast)
                            {
                                markers.Push(writer.Position);
                            }

                            writer.WriteUInt16(0);
                        }

                        var elem = array.GetValue(i);

                        if (elemType.IsPrimitive)
                        {
                            SerializePrimitive(writer, elem);
                        }
                        else
                        {
                            SerializeObject(writer, elem);
                        }

                        if (!IsByte(elemType) && !isLast)
                        {
                            markers.Push(writer.Position);
                        }
                    }

                    if (!IsByte(elemType))
                    {
                        for (var i = 0; i < markers.Count / 2; i++)
                        {
                            var afterElemPos = markers.Pop();
                            var nextPos      = markers.Pop();

                            writer.Seek(nextPos, (w, op) =>
                                        w.WriteUInt16((ushort)(afterElemPos +
                                                               PacketHeader.HeaderSize)));
                        }
                    }
                }
                else
                {
                    writer.WriteString((string)value);
                }
            }
        }