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); } } }