using System; using System.Collections.Generic; using System.IO; using System.Reflection; using NetworkFramework.Shared; namespace CLre_server.API.Synergy { struct SerializedCLreHandshake: ISerializedNetData { private byte major; private byte minor; private byte patch; private HandshakeFlag flags; private List modInfo; public Version Version { get => new Version(major, minor, patch); set { major = (byte)value.Major; minor = (byte)value.Minor; patch = (byte)value.Build; } } public IEnumerable Mods { get => modInfo.ToArray(); set { modInfo.Clear(); foreach (var mod in value) { modInfo.Add(mod); } } } public byte[] Serialize() { using (MemoryStream stream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(stream)) { // version writer.Write(major); writer.Write(minor); writer.Write(patch); writer.Write((uint)flags); writer.Write(modInfo.Count); foreach (string mod in modInfo) { writer.Write(mod); } return stream.ToArray(); } } } public void Deserialize(byte[] data) { using (MemoryStream stream = new MemoryStream(data)) { using (BinaryReader reader = new BinaryReader(stream)) { // version major = reader.ReadByte(); minor = reader.ReadByte(); patch = reader.ReadByte(); flags = (HandshakeFlag) reader.ReadUInt32(); int modCount = reader.ReadInt32(); modInfo = new List(modCount); for (int i = 0; i < modCount; i++) { modInfo.Add(reader.ReadString()); } } } } public bool HasFlag(HandshakeFlag f) { return (flags & f) != HandshakeFlag.None; } public void SetFlag(HandshakeFlag f) { flags |= f; } public void UnsetFlag(HandshakeFlag f) { flags &= ~f; } public static SerializedCLreHandshake Current() { Version v = Assembly.GetExecutingAssembly().GetName().Version; List mods = new List(); foreach (var plugin in IllusionInjector.PluginManager.Plugins) { mods.Add(plugin.Name); } return new SerializedCLreHandshake { major = (byte) v.Major, minor = (byte) v.Minor, patch = (byte) v.Build, flags = HandshakeFlag.Server, modInfo = mods, }; } public static SerializedCLreHandshake RequireCLre() { Version v = Assembly.GetExecutingAssembly().GetName().Version; List mods = new List(new []{Assembly.GetExecutingAssembly().GetName().Name}); return new SerializedCLreHandshake { major = (byte) v.Major, minor = (byte) v.Minor, patch = (byte) v.Build, flags = HandshakeFlag.Client | HandshakeFlag.RequireAll, modInfo = mods, }; } public static SerializedCLreHandshake Empty() { return new SerializedCLreHandshake { major = 0, minor = 0, patch = 0, modInfo = new List(), }; } public override string ToString() { return $"CLre {Version} ({modInfo.Count} mods)"; } } [Flags] enum HandshakeFlag : uint { None = 0, Client = 1, Server = 1 << 1, RequireAll = 1 << 2, OptionalAll = 1 << 3, Confirm = 1 << 4, } }