Make LegacyPeer::writeSocketData() private

No longer used outside of this class.
Introduce the DataStreamProtocol

This is going to be a streamlined version of the LegacyProtocol, still
using QDataStream serialization, but with some of the overhead removed
from the message formats and not supporting stuff that's deprecated.
The DataStreamProtocol will be automatically selected if both client
and core support it.

This commit simply adds a copy of the LegacyProtocol with the necessary
changes to make it compile. The optimizations are going to be in separate
commits so that the changes can be easier tracked by others implementing
it.
DataStreamPeer: Remove obsolete stuff
DataStreamPeer: Remove per-message compression

With the new handshake, we're going to use streaming compression, which
is negotiated and initiated before the peer is instantiated.
DataStreamPeer: Use UTF-8 QByteArrays instead of QString for message headers

This affects the objectName in SyncMessage, InitRequest and InitData.
While the savings should be rather small in particular with compression
enabled, we shouldn't skip this opportunity; while introspecting all
serialized data for QStrings would be too invasive, we can easily do
it for those clearly defined message fields.
DataStreamPeer: Send QDateTime instead of QTime in heartbeat messages

This allows the lag detection to work correctly even during a day change.
DataStreamPeer: Optimize message serialization format

The legacy protocol serializes all messages as QVariant-in-a-QByteArray.
Except with compression, then it is QVariant-in-a-compressed-
QByteArray-in-a-QByteArray. While the actual messages either
comes as a QVariantList or a QVariantMap which is encapsulated
in above QVariant-in-a-mess.

In other words, this seems a bit excessive and causes unneeded overhead.

So for the DataStreamPeer, we're simplifying this. As all post-handshake messages
are structured as a QVariantList, we're now making this the on-wire format
as well. Since we need to know the message size for deserialization, we
first send the total message size as a quint32, followed by the number of items
as a quint32, followed by the QVariants. [1]

Since handshake messages are QVariantMaps, and we want to avoid over-nesting things,
we now send those as such a QVariantList as well, where the items are key-value
pairs - the key as UTF-8 string (as a QByteArray), and the value as a QVariant.

[1] This happens to be the same format as a QByteArray containing a QVariantList,
    so the code for that gets rather simple.
DataStreamPeer: Optimize the InitData message

Since an InitData message consists of the usual message header
(serialized as a QVariantList) followed by a QVariantMap, we can
do what we did in a few other places already; transform the map
into a list of key-value pairs, the keys being UTF-8 strings (as
QByteArrays) instead of QStrings, and append that list to the
rest of the message.

This is just a small optimization, but straightforward to do without
changing protocol semantics or introspecting payloads. And
since we send lots of InitData messages, saving even a few bytes
per message may be worth it.
DataStreamPeer: Optimize IrcUsersAndChannels init data

This is the only occasion where we change the actual message contents
for the DataStream protocol, as opposed to the legacy protocol.

However, it's worth it, because the init data for IrcUsers is the single
biggest offender in terms of data usage during sync, and we were wasting
lots of space by sending potentially thousands of identically-structured
QVariantMaps (one per IrcUser), each of which contains an indentical set
of key names. The same was true for IrcChannels in that same message,
although the data set tends to be smaller for that one.

We've now changed that by sending the init data for all the users and
channels as lists of attributes, which are then reassembled into individual
initData maps after receiving them. Our benchmarks show space savings
around 56%, which can amount to several megabytes in the uncompressed case,
provided you are in lots of busy channels. With compression it's less
impressive, but we can still save a few hundred kilobytes.

The legacy protocol gains a pair of translation methods for this special case,
thus there are no changes in the legacy format.
Output the chosen protocol type on connect

Just some debug messages showing which protocol has been selected.
Remove the STORED attribute from Q_PROPERTY declarations

Due to some lack of documentation reading and consequential misunderstanding
of what the STORED=false attribute means for a QProperty, we still had some
really old headers wrongly declaring those.

I'm not aware of any effect on anything that having those has, but better
to just clean those up.
Don't select the DataStream protocol by default for now

Until we have streaming compression implemented, using the DataStream
is not such a brilliant idea compared to the legacy protocol which
at least individually compresses messages. Thus, we should not select
the DataStream protocol by default.

Clients wanting to play around with the new protocol are still free to
negotiate this during handshake.