using System;
using MessagePack;
namespace GameCult.Networking
{
///
/// Serializes and deserializes the explicit modern CultNet schema-v0 message family.
///
public static class CultNetSchemaMessageSerialization
{
///
/// Gets the serializer options used for CultNet schema-v0 messages.
///
public static readonly MessagePackSerializerOptions Options =
MessagePackSerializerOptions.Standard.WithSecurity(MessagePackSecurity.UntrustedData);
///
/// Serializes a typed CultNet schema message.
///
public static byte[] Serialize(T message) where T : ICultNetSchemaMessage
{
if (message == null) throw new ArgumentNullException(nameof(message));
return MessagePackSerializer.Serialize(message, Options);
}
///
/// Deserializes a typed CultNet schema message.
///
public static T Deserialize(byte[] payload) where T : ICultNetSchemaMessage
{
if (payload == null) throw new ArgumentNullException(nameof(payload));
return MessagePackSerializer.Deserialize(payload, Options);
}
///
/// Deserializes a CultNet schema message by inspecting its schema version.
///
public static ICultNetSchemaMessage Deserialize(byte[] payload)
{
if (payload == null) throw new ArgumentNullException(nameof(payload));
var header = MessagePackSerializer.Deserialize(payload, Options);
if (header == null || string.IsNullOrWhiteSpace(header.SchemaVersion))
{
throw new MessagePackSerializationException("CultNet schema-v0 payload is missing schemaVersion.");
}
return header.SchemaVersion switch
{
CultNetSchemaVersions.Hello => Deserialize(payload),
CultNetSchemaVersions.Login => Deserialize(payload),
CultNetSchemaVersions.Register => Deserialize(payload),
CultNetSchemaVersions.Verify => Deserialize(payload),
CultNetSchemaVersions.LoginSuccess => Deserialize(payload),
CultNetSchemaVersions.Error => Deserialize(payload),
CultNetSchemaVersions.SampleChangeName => Deserialize(payload),
CultNetSchemaVersions.SampleChat => Deserialize(payload),
CultNetSchemaVersions.OperationRequest => Deserialize(payload),
CultNetSchemaVersions.OperationResponse => Deserialize(payload),
CultNetSchemaVersions.DocumentDelete => Deserialize(payload),
CultNetSchemaVersions.DocumentPutRaw => Deserialize(payload),
CultNetSchemaVersions.SnapshotRequest => Deserialize(payload),
CultNetSchemaVersions.SnapshotResponseRaw => Deserialize(payload),
CultNetSchemaVersions.DatabaseSubscribe => Deserialize(payload),
CultNetSchemaVersions.DatabaseUnsubscribe => Deserialize(payload),
CultNetSchemaVersions.DatabaseChangeRaw => Deserialize(payload),
CultNetSchemaVersions.ShardCatalogRequest => Deserialize(payload),
CultNetSchemaVersions.ShardCatalogResponse => Deserialize(payload),
CultNetSchemaVersions.ShardLogRequest => Deserialize(payload),
CultNetSchemaVersions.ShardLogResponse => Deserialize(payload),
CultNetSchemaVersions.SimulationObservation => Deserialize(payload),
CultNetSchemaVersions.SimulationConsensusCandidate => Deserialize(payload),
CultNetSchemaVersions.VerseCatalogRequest => Deserialize(payload),
CultNetSchemaVersions.VerseCatalogResponse => Deserialize(payload),
CultNetSchemaVersions.PeerExchangeRequest => Deserialize(payload),
CultNetSchemaVersions.PeerExchangeResponse => Deserialize(payload),
CultNetSchemaVersions.SchemaCatalogRequest => Deserialize(payload),
CultNetSchemaVersions.SchemaCatalogResponse => Deserialize(payload),
_ => throw new MessagePackSerializationException(
$"Unsupported CultNet schema-v0 message \"{header.SchemaVersion}\".")
};
}
[MessagePackObject(AllowPrivate = true)]
internal sealed class CultNetSchemaHeader
{
[Key("schemaVersion")] public string SchemaVersion { get; set; } = string.Empty;
}
}
}