From 789341701aef697d43b9e76422ba34e23faccf3e Mon Sep 17 00:00:00 2001 From: ALEXTANG <574809918@qq.com> Date: Wed, 31 Aug 2022 16:25:16 +0800 Subject: [PATCH] Update Update --- .../Scripts/Editor/Helper/ProtoGenTools.meta | 8 + .../Helper/ProtoGenTools/ProtoGenTools.cs | 291 ++ .../ProtoGenTools/ProtoGenTools.cs.meta | 11 + .../Editor/Inspector/NetworkInspector.cs | 134 +- ...uggerComponent.NetworkInformationWindow.cs | 61 + ...Component.NetworkInformationWindow.cs.meta | 3 + .../Base/Debugger/Imp/DebuggerComponent.cs | 4 +- .../TEngine/Scripts/Runtime/Core/NetWork.meta | 8 + .../Scripts/Runtime/Core/NetWork/Core.meta | 8 + .../Core/NetWork/Core/AddressFamily.cs | 23 + .../Core/NetWork/Core/AddressFamily.cs.meta | 3 + .../Core/NetWork/Core/INetworkChannel.cs | 144 + .../Core/NetWork/Core/INetworkChannel.cs.meta | 3 + .../NetWork/Core/INetworkChannelHelper.cs | 66 + .../Core/INetworkChannelHelper.cs.meta | 3 + .../Core/NetWork/Core/INetworkManager.cs | 87 + .../Core/NetWork/Core/INetworkManager.cs.meta | 3 + .../Core/NetWork/Core/IPacketHeader.cs | 16 + .../Core/NetWork/Core/IPacketHeader.cs.meta | 3 + .../Core/NetWork/Core/NetWorkEventId.cs | 11 + .../Core/NetWork/Core/NetWorkEventId.cs.meta | 3 + .../Runtime/Core/NetWork/Core/Network.cs | 157 + .../Runtime/Core/NetWork/Core/Network.cs.meta | 11 + .../Core/NetWork/Core/NetworkErrorCode.cs | 53 + .../NetWork/Core/NetworkErrorCode.cs.meta | 3 + .../Core/NetworkManager.ConnectState.cs | 35 + .../Core/NetworkManager.ConnectState.cs.meta | 11 + .../Core/NetworkManager.HeartBeatState.cs | 51 + .../NetworkManager.HeartBeatState.cs.meta | 11 + .../Core/NetworkManager.NetworkChannelBase.cs | 762 ++++ .../NetworkManager.NetworkChannelBase.cs.meta | 11 + .../Core/NetworkManager.ReceiveState.cs | 91 + .../Core/NetworkManager.ReceiveState.cs.meta | 11 + .../NetWork/Core/NetworkManager.SendState.cs | 60 + .../Core/NetworkManager.SendState.cs.meta | 11 + .../Core/NetWork/Core/NetworkManager.cs | 340 ++ .../Core/NetWork/Core/NetworkManager.cs.meta | 3 + .../Runtime/Core/NetWork/Core/Packet.cs | 10 + .../Runtime/Core/NetWork/Core/Packet.cs.meta | 3 + .../Runtime/Core/NetWork/Core/ServiceType.cs | 28 + .../Core/NetWork/Core/ServiceType.cs.meta | 11 + .../Scripts/Runtime/Core/NetWork/Helper.meta | 8 + .../Core/NetWork/Helper/CSPacketHeader.cs | 11 + .../NetWork/Helper/CSPacketHeader.cs.meta | 11 + .../NetWork/Helper/NetworkChannelHelper.cs | 207 + .../Helper/NetworkChannelHelper.cs.meta | 11 + .../Core/NetWork/Helper/PacketHandler.meta | 3 + .../PacketHandler/SCHeartBeatHandler.cs | 28 + .../PacketHandler/SCHeartBeatHandler.cs.meta | 3 + .../Core/NetWork/Helper/PacketHeaderBase.cs | 31 + .../NetWork/Helper/PacketHeaderBase.cs.meta | 11 + .../Runtime/Core/NetWork/Helper/ProtoUtils.cs | 49 + .../Core/NetWork/Helper/ProtoUtils.cs.meta | 11 + .../Scripts/Runtime/Core/NetWork/Proto.meta | 8 + .../Runtime/Core/NetWork/Proto/MainPackExt.cs | 14 + .../Core/NetWork/Proto/MainPackExt.cs.meta | 11 + .../Core/NetWork/Proto/TEngineProto.cs | 192 + .../Core/NetWork/Proto/TEngineProto.cs.meta | 11 + .../Scripts/Runtime/Core/NetWork/Tcp.meta | 8 + .../Tcp/NetworkManager.TcpNetworkChannel.cs | 281 ++ .../NetworkManager.TcpNetworkChannel.cs.meta | 11 + ...anager.TcpWithSyncReceiveNetworkChannel.cs | 257 ++ ...r.TcpWithSyncReceiveNetworkChannel.cs.meta | 11 + .../Scripts/Runtime/Core/NetWork/Udp.meta | 8 + .../Core/NetWork/Udp/UdpNetworkChannel.cs | 274 ++ .../NetWork/Udp/UdpNetworkChannel.cs.meta | 11 + .../Localize/ExcelConfig/Localization.json | 2 + .../Localize/ExcelConfig/Localization.xlsx | Bin 0 -> 10194 bytes .../Tools~/Protobuf/Proto/TEngineProto.proto | 83 + .../TEngine/Tools~/Protobuf/Proto/msg.proto | 8 + .../Protobuf/Proto_CSharp/TEngineProto.cs | 180 + .../Protobuf/ProtobufGenCsharp/gen_all.bat | 19 + .../protobuf-net.Reflection.dll | Bin 0 -> 293376 bytes .../protobuf-net.Reflection.xml | 829 ++++ .../ProtobufGenCsharp/protobuf-net.dll | Bin 0 -> 275456 bytes .../ProtobufGenCsharp/protobuf-net.xml | 3550 +++++++++++++++++ .../Protobuf/ProtobufGenCsharp/protogen.exe | Bin 0 -> 16384 bytes .../Protobuf/ProtobufGenCsharp/protogen.xml | 8 + 78 files changed, 8657 insertions(+), 69 deletions(-) create mode 100644 Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta create mode 100644 Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs create mode 100644 Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs create mode 100644 Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs.meta create mode 100644 Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.json create mode 100644 Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.xlsx create mode 100644 Assets/TEngine/Tools~/Protobuf/Proto/TEngineProto.proto create mode 100644 Assets/TEngine/Tools~/Protobuf/Proto/msg.proto create mode 100644 Assets/TEngine/Tools~/Protobuf/Proto_CSharp/TEngineProto.cs create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.Reflection.dll create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.Reflection.xml create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.dll create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.xml create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.exe create mode 100644 Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.xml diff --git a/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta new file mode 100644 index 00000000..2e886838 --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4843da953596d1546bc7ccc26fb5e3b3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs new file mode 100644 index 00000000..16bf9d33 --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using TEngine.Runtime; +#if UNITY_EDITOR +using UnityEditor; +#endif + +namespace TEngine.Editor +{ + internal class OpcodeInfo + { + public string Name; + public int Opcode; + } + + public static class ProtoGenTools + { +#if UNITY_EDITOR + [MenuItem("TEngine/生成Proto|Gen Proto", false, 10)] +#endif + public static void Export() + { + InnerProto2CS.Proto2CS(); + Log.Info("proto2cs succeed!"); + } + } + + public static class InnerProto2CS + { + private static string ProtoPath = UnityEngine.Application.dataPath + "\\TEngine\\Tools~\\Protobuf\\Proto\\"; + + private static string OutPutPath = + UnityEngine.Application.dataPath + "\\TEngine\\Tools~\\Protobuf\\Proto_CSharp\\"; + + private static readonly char[] splitChars = { ' ', '\t' }; + private static readonly List msgOpcode = new List(); + + public static void Proto2CS() + { + msgOpcode.Clear(); + Proto2CS("TEngineProto", "TEngineProto.proto", OutPutPath,10001,false); + } + + public static void Proto2CS(string ns, string protoName, string outputPath, int startOpcode,bool useMemoryPool = false) + { + if (!Directory.Exists(outputPath)) + { + Directory.CreateDirectory(outputPath); + } + + msgOpcode.Clear(); + string proto = Path.Combine(ProtoPath, protoName); + string csPath = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(proto) + ".cs"); + + string s = File.ReadAllText(proto); + + StringBuilder sb = new StringBuilder(); + sb.Append("using ProtoBuf;\n"); + sb.Append("using TEngine.Runtime;\n"); + sb.Append("using System.Collections.Generic;\n"); + sb.Append($"namespace {ns}\n"); + sb.Append("{\n"); + + bool isMsgStart = false; + bool isEnumStart = false; + foreach (string line in s.Split('\n')) + { + string newline = line.Trim(); + + if (newline == "") + { + continue; + } + + if (newline.StartsWith("//ResponseType")) + { + string responseType = line.Split(' ')[1].TrimEnd('\r', '\n'); + sb.AppendLine($"\t[ResponseType(nameof({responseType}))]"); + continue; + } + + if (newline.StartsWith("//")) + { + sb.Append($"{newline}\n"); + continue; + } + + if (newline.StartsWith("message")) + { + string parentClass = ""; + isMsgStart = true; + string msgName = newline.Split(splitChars, StringSplitOptions.RemoveEmptyEntries)[1]; + string[] ss = newline.Split(new[] { "//" }, StringSplitOptions.RemoveEmptyEntries); + + if (ss.Length == 2) + { + parentClass = ss[1].Trim(); + } + + msgOpcode.Add(new OpcodeInfo() { Name = msgName, Opcode = ++startOpcode }); + sb.Append($"\t[global::ProtoBuf.ProtoContract()]\n"); + if (useMemoryPool) + { + sb.Append($"\tpublic partial class {msgName}: IMemory"); + } + else + { + sb.Append($"\tpublic partial class {msgName}"); + } + if (parentClass != "") + { + sb.Append($", {parentClass}\n"); + } + else + { + sb.Append("\n"); + } + + continue; + } + + if (isMsgStart) + { + if (newline == "{") + { + sb.Append("\t{\n"); + continue; + } + + if (newline == "}") + { + isMsgStart = false; + sb.Append("\t}\n\n"); + continue; + } + + if (newline.Trim().StartsWith("//")) + { + sb.AppendLine(newline); + continue; + } + + if (newline.Trim() != "" && newline != "}") + { + if (newline.StartsWith("repeated")) + { + Repeated(sb, ns, newline); + } + else + { + Members(sb, newline, true); + } + } + } + + + if (newline.StartsWith("enum")) + { + isEnumStart = true; + string enumName = newline.Split(splitChars, StringSplitOptions.RemoveEmptyEntries)[1]; + + sb.Append($"\t[global::ProtoBuf.ProtoContract()]\n"); + sb.Append($"\tpublic enum {enumName}"); + sb.Append("\n"); + continue; + } + + if (isEnumStart) + { + if (newline == "{") + { + sb.Append("\t{\n"); + continue; + } + + if (newline == "}") + { + isEnumStart = false; + sb.Append("\t}\n\n"); + continue; + } + + if (newline.Trim().StartsWith("//")) + { + sb.AppendLine(newline); + continue; + } + + int index = newline.IndexOf(";"); + newline = newline.Remove(index); + sb.Append($"\t\t{newline},\n\n"); + } + } + + sb.Append("}\n"); + using (FileStream txt = new FileStream(csPath, FileMode.Create, FileAccess.ReadWrite)) + { + using (StreamWriter sw = new StreamWriter(txt)) + { + Log.Debug(sb.ToString()); + sw.Write(sb.ToString()); + } + } + } + + private static void Repeated(StringBuilder sb, string ns, string newline) + { + try + { + int index = newline.IndexOf(";"); + newline = newline.Remove(index); + string[] ss = newline.Split(splitChars, StringSplitOptions.RemoveEmptyEntries); + string type = ss[1]; + type = ConvertType(type); + string name = ss[2]; + int n = int.Parse(ss[4]); + + sb.Append($"\t\t[global::ProtoBuf.ProtoMember({n})]\n"); + sb.Append($"\t\tpublic List<{type}> {name} = new List<{type}>();\n\n"); + } + catch (Exception e) + { + Console.WriteLine($"{newline}\n {e}"); + } + } + + private static string ConvertType(string type) + { + string typeCs = ""; + switch (type) + { + case "int16": + typeCs = "short"; + break; + case "int32": + typeCs = "int"; + break; + case "bytes": + typeCs = "byte[]"; + break; + case "uint32": + typeCs = "uint"; + break; + case "long": + typeCs = "long"; + break; + case "int64": + typeCs = "long"; + break; + case "uint64": + typeCs = "ulong"; + break; + case "uint16": + typeCs = "ushort"; + break; + default: + typeCs = type; + break; + } + + return typeCs; + } + + private static void Members(StringBuilder sb, string newline, bool isRequired) + { + try + { + int index = newline.IndexOf(";"); + newline = newline.Remove(index); + string[] ss = newline.Split(splitChars, StringSplitOptions.RemoveEmptyEntries); + string type = ss[0]; + string name = ss[1]; + int n = int.Parse(ss[3]); + string typeCs = ConvertType(type); + + sb.Append($"\t\t[global::ProtoBuf.ProtoMember({n})]\n"); + if (string.Equals(type,"string")) + { + sb.Append($"\t\t[global::System.ComponentModel.DefaultValue(\"\")]\n"); + } + sb.Append($"\t\tpublic {typeCs} {name} {{ get; set; }}\n\n"); + } + catch (Exception e) + { + Console.WriteLine($"{newline}\n {e}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs.meta b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs.meta new file mode 100644 index 00000000..c5eda390 --- /dev/null +++ b/Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools/ProtoGenTools.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9035b84a2db6d8142a2e10604836e302 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Editor/Inspector/NetworkInspector.cs b/Assets/TEngine/Scripts/Editor/Inspector/NetworkInspector.cs index ccbc3f2d..f12eb5b3 100644 --- a/Assets/TEngine/Scripts/Editor/Inspector/NetworkInspector.cs +++ b/Assets/TEngine/Scripts/Editor/Inspector/NetworkInspector.cs @@ -1,67 +1,67 @@ -// using UnityEditor; -// using UnityEngine; -// using TEngine.Runtime; -// -// namespace TEngine.Editor -// { -// [CustomEditor(typeof(TEngine.Runtime.Network))] -// internal sealed class NetworkComponentInspector : TEngineInspector -// { -// public override void OnInspectorGUI() -// { -// base.OnInspectorGUI(); -// -// if (!EditorApplication.isPlaying) -// { -// EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); -// return; -// } -// -// TEngine.Runtime.Network t = (TEngine.Runtime.Network)target; -// -// if (IsPrefabInHierarchy(t.gameObject)) -// { -// EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString()); -// -// INetworkChannel[] networkChannels = t.GetAllNetworkChannels(); -// foreach (INetworkChannel networkChannel in networkChannels) -// { -// DrawNetworkChannel(networkChannel); -// } -// } -// -// Repaint(); -// } -// -// private void OnEnable() -// { -// } -// -// private void DrawNetworkChannel(INetworkChannel networkChannel) -// { -// EditorGUILayout.BeginVertical("box"); -// { -// EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected"); -// EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString()); -// EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString()); -// EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable"); -// EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable"); -// EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString())); -// EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivePacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString())); -// EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString()); -// EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2"))); -// EditorGUI.BeginDisabledGroup(!networkChannel.Connected); -// { -// if (GUILayout.Button("Disconnect")) -// { -// networkChannel.Close(); -// } -// } -// EditorGUI.EndDisabledGroup(); -// } -// EditorGUILayout.EndVertical(); -// -// EditorGUILayout.Separator(); -// } -// } -// } +using UnityEditor; +using UnityEngine; +using TEngine.Runtime; + +namespace TEngine.Editor +{ + [CustomEditor(typeof(TEngine.Runtime.Network))] + internal sealed class NetworkComponentInspector : TEngineInspector + { + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + if (!EditorApplication.isPlaying) + { + EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info); + return; + } + + TEngine.Runtime.Network t = (TEngine.Runtime.Network)target; + + if (IsPrefabInHierarchy(t.gameObject)) + { + EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString()); + + INetworkChannel[] networkChannels = t.GetAllNetworkChannels(); + foreach (INetworkChannel networkChannel in networkChannels) + { + DrawNetworkChannel(networkChannel); + } + } + + Repaint(); + } + + private void OnEnable() + { + } + + private void DrawNetworkChannel(INetworkChannel networkChannel) + { + EditorGUILayout.BeginVertical("box"); + { + EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected"); + EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString()); + EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString()); + EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable"); + EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable"); + EditorGUILayout.LabelField("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString())); + EditorGUILayout.LabelField("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivedPacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString())); + EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString()); + EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2"))); + EditorGUI.BeginDisabledGroup(!networkChannel.Connected); + { + if (GUILayout.Button("Disconnect")) + { + networkChannel.Close(); + } + } + EditorGUI.EndDisabledGroup(); + } + EditorGUILayout.EndVertical(); + + EditorGUILayout.Separator(); + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs new file mode 100644 index 00000000..fda15b77 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs @@ -0,0 +1,61 @@ +using UnityEngine; + +namespace TEngine.Runtime +{ + public sealed partial class DebuggerComponent + { + private sealed class NetworkInformationWindow : ScrollableDebuggerWindowBase + { + private Network m_NetworkComponent = null; + + public override void Initialize(params object[] args) + { + m_NetworkComponent = Network.Instance; + if (m_NetworkComponent == null) + { + Log.Fatal("Network component is invalid."); + return; + } + } + + protected override void OnDrawScrollableWindow() + { + GUILayout.Label("Network Information"); + GUILayout.BeginVertical("box"); + { + DrawItem("Network Channel Count", m_NetworkComponent.NetworkChannelCount.ToString()); + } + GUILayout.EndVertical(); + INetworkChannel[] networkChannels = m_NetworkComponent.GetAllNetworkChannels(); + for (int i = 0; i < networkChannels.Length; i++) + { + DrawNetworkChannel(networkChannels[i]); + } + } + + private void DrawNetworkChannel(INetworkChannel networkChannel) + { + GUILayout.Label(Utility.Text.Format("Network Channel: {0} ({1})", networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected")); + GUILayout.BeginVertical("box"); + { + DrawItem("Service Type", networkChannel.ServiceType.ToString()); + DrawItem("Address Family", networkChannel.AddressFamily.ToString()); + DrawItem("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable"); + DrawItem("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.ToString() : "Unavailable"); + DrawItem("Send Packet", Utility.Text.Format("{0} / {1}", networkChannel.SendPacketCount.ToString(), networkChannel.SentPacketCount.ToString())); + DrawItem("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivedPacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString())); + DrawItem("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.ToString()); + DrawItem("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2"))); + if (networkChannel.Connected) + { + if (GUILayout.Button("Disconnect", GUILayout.Height(30f))) + { + networkChannel.Close(); + } + } + } + GUILayout.EndVertical(); + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs.meta new file mode 100644 index 00000000..1d902b54 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.NetworkInformationWindow.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 499fb65f1b784d4c912050bf3c1b54d3 +timeCreated: 1661930992 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.cs b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.cs index aea0798e..bfa8d29b 100644 --- a/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.cs +++ b/Assets/TEngine/Scripts/Runtime/Core/Base/Debugger/Imp/DebuggerComponent.cs @@ -189,7 +189,7 @@ namespace TEngine.Runtime private RuntimeMemoryInformationWindow m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow(); private MemoryPoolInformationWindow m_MemoryPoolInformationWindow = new MemoryPoolInformationWindow(); - // private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow(); + private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow(); private SettingsWindow m_SettingsWindow = new SettingsWindow(); #endregion @@ -229,7 +229,7 @@ namespace TEngine.Runtime RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow); RegisterDebuggerWindow("Profiler/Memory Pool", m_MemoryPoolInformationWindow); - // RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow); + RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow); RegisterDebuggerWindow("Other/Settings", m_SettingsWindow); diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork.meta new file mode 100644 index 00000000..4283a259 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 38e14d7bbaa74254198afb9c1df69a30 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta new file mode 100644 index 00000000..d0b4ddd1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b9fbba9291a686a4485a94f19febffd1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs new file mode 100644 index 00000000..fdc3f8fb --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs @@ -0,0 +1,23 @@ +namespace TEngine.Runtime +{ + /// + /// 网络地址类型。 + /// + public enum AddressFamily : byte + { + /// + /// 未知。 + /// + Unknown = 0, + + /// + /// IP 版本 4。 + /// + IPv4, + + /// + /// IP 版本 6。 + /// + IPv6 + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs.meta new file mode 100644 index 00000000..54d65ab7 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/AddressFamily.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6f0c907c7aeb4bd2a19ff78ad8e8b668 +timeCreated: 1661772419 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs new file mode 100644 index 00000000..783aa2e5 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs @@ -0,0 +1,144 @@ +using System; +using System.Net; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + /// + /// 网络频道接口。 + /// + public interface INetworkChannel + { + /// + /// 获取网络频道名称。 + /// + string Name + { + get; + } + + /// + /// 获取网络频道所使用的 Socket。 + /// + Socket Socket + { + get; + } + + /// + /// 获取是否已连接。 + /// + bool Connected + { + get; + } + + /// + /// 获取网络服务类型。 + /// + ServiceType ServiceType + { + get; + } + + /// + /// 获取网络地址类型。 + /// + AddressFamily AddressFamily + { + get; + } + + /// + /// 获取要发送的消息包数量。 + /// + int SendPacketCount + { + get; + } + + /// + /// 获取累计发送的消息包数量。 + /// + int SentPacketCount + { + get; + } + + /// + /// 获取累计已接收的消息包数量。 + /// + int ReceivedPacketCount + { + get; + } + + /// + /// 获取或设置当收到消息包时是否重置心跳流逝时间。 + /// + bool ResetHeartBeatElapseSecondsWhenReceivePacket + { + get; + set; + } + + /// + /// 获取丢失心跳的次数。 + /// + int MissHeartBeatCount + { + get; + } + + /// + /// 获取或设置心跳间隔时长,以秒为单位。 + /// + float HeartBeatInterval + { + get; + set; + } + + /// + /// 获取心跳等待时长,以秒为单位。 + /// + float HeartBeatElapseSeconds + { + get; + } + + /// + /// 注册网络消息包处理函数。 + /// + /// + /// + void RegisterHandler(int actionId, CsMsgDelegate msgDelegate); + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + void Connect(IPAddress ipAddress, int port); + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + void Connect(IPAddress ipAddress, int port, object userData); + + /// + /// 关闭网络频道。 + /// + void Close(); + + /// + /// 向远程主机发送消息包。 + /// + /// 消息包类型。 + /// 要发送的消息包。 + void Send(T packet) where T : Packet; + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs.meta new file mode 100644 index 00000000..474bacd3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannel.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c66ee24862094df49e089d63f7481285 +timeCreated: 1661771701 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs new file mode 100644 index 00000000..40c855e5 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs @@ -0,0 +1,66 @@ +using System.IO; + +namespace TEngine.Runtime +{ + /// + /// 网络频道辅助器接口。 + /// + public interface INetworkChannelHelper + { + /// + /// 获取消息包头长度。 + /// + int PacketHeaderLength + { + get; + } + + /// + /// 初始化网络频道辅助器。 + /// + /// 网络频道。 + void Initialize(INetworkChannel networkChannel); + + /// + /// 关闭并清理网络频道辅助器。 + /// + void Shutdown(); + + /// + /// 准备进行连接。 + /// + void PrepareForConnecting(); + + /// + /// 发送心跳消息包。 + /// + /// 是否发送心跳消息包成功。 + bool SendHeartBeat(); + + /// + /// 序列化消息包。 + /// + /// 消息包类型。 + /// 要序列化的消息包。 + /// 要序列化的目标流。 + /// 是否序列化成功。 + bool Serialize(T packet, Stream destination) where T : Packet; + + /// + /// 反序列化消息包头。 + /// + /// 要反序列化的来源流。 + /// 用户自定义错误数据。 + /// 反序列化后的消息包头。 + IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData); + + /// + /// 反序列化消息包。 + /// + /// 消息包头。 + /// 要反序列化的来源流。 + /// 用户自定义错误数据。 + /// 反序列化后的消息包。 + Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs.meta new file mode 100644 index 00000000..495fc074 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkChannelHelper.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aeff0f53fdd54bd489d6a6141e79dca0 +timeCreated: 1661771934 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs new file mode 100644 index 00000000..b3ab01b2 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + /// + /// 网络管理器接口。 + /// + public interface INetworkManager + { + /// + /// 获取网络频道数量。 + /// + int NetworkChannelCount + { + get; + } + + /// + /// 网络连接成功事件。 + /// + event Action NetworkConnected; + + /// + /// 网络连接关闭事件。 + /// + event Action NetworkClosed; + + /// + /// 网络心跳包丢失事件。 + /// + event Action NetworkMissHeartBeat; + + /// + /// 网络错误事件。 + /// + event Action NetworkError; + + /// + /// 用户自定义网络错误事件。 + /// + event Action NetworkCustomError; + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + bool HasNetworkChannel(string name); + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + INetworkChannel GetNetworkChannel(string name); + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + INetworkChannel[] GetAllNetworkChannels(); + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + void GetAllNetworkChannels(List results); + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper); + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + bool DestroyNetworkChannel(string name); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs.meta new file mode 100644 index 00000000..b8132e5a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/INetworkManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aa9566de56cd4b579631a1725b89174e +timeCreated: 1661775465 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs new file mode 100644 index 00000000..48877019 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs @@ -0,0 +1,16 @@ +namespace TEngine.Runtime +{ + /// + /// 网络消息包头接口。 + /// + public interface IPacketHeader + { + /// + /// 获取网络消息包长度。 + /// + int PacketLength + { + get; + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs.meta new file mode 100644 index 00000000..888bf894 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/IPacketHeader.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1a61d331daf74fe48bffbb083f016cb5 +timeCreated: 1661771898 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs new file mode 100644 index 00000000..2a165c7a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs @@ -0,0 +1,11 @@ +namespace TEngine.Runtime +{ + public static class NetWorkEventId + { + public static int NetworkConnectedEvent = StringId.StringToHash("NetWorkEventId.NetworkConnectedEvent"); + public static int NetworkClosedEvent = StringId.StringToHash("NetWorkEventId.NetworkClosedEvent"); + public static int NetworkMissHeartBeatEvent = StringId.StringToHash("NetWorkEventId.NetworkMissHeartBeatEvent"); + public static int NetworkErrorEvent = StringId.StringToHash("NetWorkEventId.NetworkErrorEvent"); + public static int NetworkCustomErrorEvent = StringId.StringToHash("NetWorkEventId.NetworkCustomErrorEvent"); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs.meta new file mode 100644 index 00000000..a1e3f651 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetWorkEventId.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 007c9ae2d35f4d6181f53cf3e5738884 +timeCreated: 1661930441 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs new file mode 100644 index 00000000..b156d585 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace TEngine.Runtime +{ + /// + /// 网络组件。 + /// + [DisallowMultipleComponent] + [AddComponentMenu("TEngine/Network")] + public class Network : UnitySingleton + { + private INetworkManager m_NetworkManager = null; + + public NetworkManager NetworkManager + { + private set; + get; + } + + /// + /// 获取网络频道数量。 + /// + public int NetworkChannelCount + { + get + { + if (m_NetworkManager == null) + { + return 0; + } + return m_NetworkManager.NetworkChannelCount; + } + } + + protected override void OnLoad() + { + base.OnLoad(); + m_NetworkManager = new NetworkManager(); + NetworkManager = m_NetworkManager as NetworkManager; + if (m_NetworkManager == null) + { + Log.Fatal("Network manager is invalid."); + return; + } + + m_NetworkManager.NetworkConnected += OnNetworkConnected; + m_NetworkManager.NetworkClosed += OnNetworkClosed; + m_NetworkManager.NetworkMissHeartBeat += OnNetworkMissHeartBeat; + m_NetworkManager.NetworkError += OnNetworkError; + m_NetworkManager.NetworkCustomError += OnNetworkCustomError; + } + + private void Update() + { + if (m_NetworkManager != null) + { + NetworkManager.Update(Time.deltaTime, Time.unscaledDeltaTime);; + } + } + + protected override void OnDestroy() + { + base.OnDestroy(); + if (NetworkManager != null) + { + NetworkManager.Shutdown(); + } + } + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + public bool HasNetworkChannel(string name) + { + return m_NetworkManager.HasNetworkChannel(name); + } + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + public INetworkChannel GetNetworkChannel(string name) + { + return m_NetworkManager.GetNetworkChannel(name); + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public INetworkChannel[] GetAllNetworkChannels() + { + return m_NetworkManager.GetAllNetworkChannels(); + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public void GetAllNetworkChannels(List results) + { + m_NetworkManager.GetAllNetworkChannels(results); + } + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper) + { + return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper); + } + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + public bool DestroyNetworkChannel(string name) + { + return m_NetworkManager.DestroyNetworkChannel(name); + } + + private void OnNetworkConnected(INetworkChannel channel, object obj) + { + GameEventMgr.Instance.Send(NetWorkEventId.NetworkConnectedEvent,channel, obj); + } + + private void OnNetworkClosed(INetworkChannel channel) + { + GameEventMgr.Instance.Send(NetWorkEventId.NetworkClosedEvent,channel); + } + + private void OnNetworkMissHeartBeat(INetworkChannel channel, int missCount) + { + GameEventMgr.Instance.Send(NetWorkEventId.NetworkMissHeartBeatEvent,channel,missCount); + } + + private void OnNetworkError(INetworkChannel channel, NetworkErrorCode errorCode, string message) + { + GameEventMgr.Instance.Send(NetWorkEventId.NetworkErrorEvent,channel,errorCode,message); + } + + private void OnNetworkCustomError(INetworkChannel channel,object message) + { + GameEventMgr.Instance.Send(NetWorkEventId.NetworkCustomErrorEvent,channel,message); + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs.meta new file mode 100644 index 00000000..1760a35a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1dd2b00e963a5b54db7aae1b87628982 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs new file mode 100644 index 00000000..2ceade3c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs @@ -0,0 +1,53 @@ +namespace TEngine.Runtime +{ + /// + /// 网络错误码。 + /// + public enum NetworkErrorCode : byte + { + /// + /// 未知错误。 + /// + Unknown = 0, + + /// + /// 地址族错误。 + /// + AddressFamilyError, + + /// + /// Socket 错误。 + /// + SocketError, + + /// + /// 连接错误。 + /// + ConnectError, + + /// + /// 发送错误。 + /// + SendError, + + /// + /// 接收错误。 + /// + ReceiveError, + + /// + /// 序列化错误。 + /// + SerializeError, + + /// + /// 反序列化消息包头错误。 + /// + DeserializePacketHeaderError, + + /// + /// 反序列化消息包错误。 + /// + DeserializePacketError + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs.meta new file mode 100644 index 00000000..35a0f13b --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkErrorCode.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 86fe9208ee30402ab1fcdc8cdcff1d89 +timeCreated: 1661771970 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs new file mode 100644 index 00000000..3bd4b7f6 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs @@ -0,0 +1,35 @@ +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + private sealed class ConnectState + { + private readonly Socket m_Socket; + private readonly object m_UserData; + + public ConnectState(Socket socket, object userData) + { + m_Socket = socket; + m_UserData = userData; + } + + public Socket Socket + { + get + { + return m_Socket; + } + } + + public object UserData + { + get + { + return m_UserData; + } + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs.meta new file mode 100644 index 00000000..ccd0558f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ConnectState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 07167c4e7b24c2148acdfe52fbe0c817 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs new file mode 100644 index 00000000..5220221e --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs @@ -0,0 +1,51 @@ +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + private sealed class HeartBeatState + { + private float m_HeartBeatElapseSeconds; + private int m_MissHeartBeatCount; + + public HeartBeatState() + { + m_HeartBeatElapseSeconds = 0f; + m_MissHeartBeatCount = 0; + } + + public float HeartBeatElapseSeconds + { + get + { + return m_HeartBeatElapseSeconds; + } + set + { + m_HeartBeatElapseSeconds = value; + } + } + + public int MissHeartBeatCount + { + get + { + return m_MissHeartBeatCount; + } + set + { + m_MissHeartBeatCount = value; + } + } + + public void Reset(bool resetHeartBeatElapseSeconds) + { + if (resetHeartBeatElapseSeconds) + { + m_HeartBeatElapseSeconds = 0f; + } + + m_MissHeartBeatCount = 0; + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs.meta new file mode 100644 index 00000000..1ba94069 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.HeartBeatState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1beec3505229bd418c252c142a01152 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs new file mode 100644 index 00000000..4c9ee08e --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs @@ -0,0 +1,762 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using TEngineProto; + +namespace TEngine.Runtime +{ + public delegate void CsMsgDelegate(MainPack mainPack); + + public sealed partial class NetworkManager + { + /// + /// 网络频道基类。 + /// + private abstract class NetworkChannelBase : INetworkChannel, IDisposable + { + private const float DefaultHeartBeatInterval = 30f; + private const int MAX_MSG_HANDLE = 256; + + private readonly string m_Name; + protected readonly Queue m_SendPacketPool; + protected readonly INetworkChannelHelper m_NetworkChannelHelper; + protected AddressFamily m_AddressFamily; + protected bool m_ResetHeartBeatElapseSecondsWhenReceivePacket; + protected float m_HeartBeatInterval; + protected Socket m_Socket; + protected readonly SendState m_SendState; + protected readonly ReceiveState m_ReceiveState; + protected readonly HeartBeatState m_HeartBeatState; + protected int m_SentPacketCount; + protected int m_ReceivedPacketCount; + protected bool m_Active; + private bool m_Disposed; + + public Action NetworkChannelConnected; + public Action NetworkChannelClosed; + public Action NetworkChannelMissHeartBeat; + public Action NetworkChannelError; + public Action NetworkChannelCustomError; + + /// + /// 委托注册队列 + /// + protected Dictionary> m_MapCmdHandle = new Dictionary>(); + /// + /// 委托缓存堆栈 + /// + protected Queue> m_CachelistHandle = new Queue>(); + + /// + /// 消息包缓存堆栈 + /// + protected Queue m_QueuepPacks = new Queue(); + + /// + /// 初始化网络频道基类的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public NetworkChannelBase(string name, INetworkChannelHelper networkChannelHelper) + { + m_Name = name ?? string.Empty; + m_SendPacketPool = new Queue(); + m_NetworkChannelHelper = networkChannelHelper; + m_AddressFamily = AddressFamily.Unknown; + m_ResetHeartBeatElapseSecondsWhenReceivePacket = false; + m_HeartBeatInterval = DefaultHeartBeatInterval; + m_Socket = null; + m_SendState = new SendState(); + m_ReceiveState = new ReceiveState(); + m_HeartBeatState = new HeartBeatState(); + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + m_Active = false; + m_Disposed = false; + + NetworkChannelConnected = null; + NetworkChannelClosed = null; + NetworkChannelMissHeartBeat = null; + NetworkChannelError = null; + NetworkChannelCustomError = null; + + networkChannelHelper.Initialize(this); + } + + /// + /// 获取网络频道名称。 + /// + public string Name + { + get + { + return m_Name; + } + } + + /// + /// 获取网络频道所使用的 Socket。 + /// + public Socket Socket + { + get + { + return m_Socket; + } + } + + /// + /// 获取是否已连接。 + /// + public bool Connected + { + get + { + if (m_Socket != null) + { + return m_Socket.Connected; + } + + return false; + } + } + + /// + /// 获取网络服务类型。 + /// + public abstract ServiceType ServiceType + { + get; + } + + /// + /// 获取网络地址类型。 + /// + public AddressFamily AddressFamily + { + get + { + return m_AddressFamily; + } + } + + /// + /// 获取要发送的消息包数量。 + /// + public int SendPacketCount + { + get + { + return m_SendPacketPool.Count; + } + } + + /// + /// 获取累计发送的消息包数量。 + /// + public int SentPacketCount + { + get + { + return m_SentPacketCount; + } + } + + /// + /// 获取累计已接收的消息包数量。 + /// + public int ReceivedPacketCount + { + get + { + return m_ReceivedPacketCount; + } + } + + /// + /// 获取或设置当收到消息包时是否重置心跳流逝时间。 + /// + public bool ResetHeartBeatElapseSecondsWhenReceivePacket + { + get + { + return m_ResetHeartBeatElapseSecondsWhenReceivePacket; + } + set + { + m_ResetHeartBeatElapseSecondsWhenReceivePacket = value; + } + } + + /// + /// 获取丢失心跳的次数。 + /// + public int MissHeartBeatCount + { + get + { + return m_HeartBeatState.MissHeartBeatCount; + } + } + + /// + /// 获取或设置心跳间隔时长,以秒为单位。 + /// + public float HeartBeatInterval + { + get + { + return m_HeartBeatInterval; + } + set + { + m_HeartBeatInterval = value; + } + } + + /// + /// 获取心跳等待时长,以秒为单位。 + /// + public float HeartBeatElapseSeconds + { + get + { + return m_HeartBeatState.HeartBeatElapseSeconds; + } + } + + /// + /// 网络频道轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public virtual void Update(float elapseSeconds, float realElapseSeconds) + { + if (m_Socket == null || !m_Active) + { + return; + } + + HandleCsMsgOnUpdate(); + CheckCsMsgTimeOut(); + ProcessSend(); + ProcessReceive(); + if (m_Socket == null || !m_Active) + { + return; + } + + if (m_HeartBeatInterval > 0f) + { + bool sendHeartBeat = false; + int missHeartBeatCount = 0; + lock (m_HeartBeatState) + { + if (m_Socket == null || !m_Active) + { + return; + } + + m_HeartBeatState.HeartBeatElapseSeconds += realElapseSeconds; + if (m_HeartBeatState.HeartBeatElapseSeconds >= m_HeartBeatInterval) + { + sendHeartBeat = true; + missHeartBeatCount = m_HeartBeatState.MissHeartBeatCount; + m_HeartBeatState.HeartBeatElapseSeconds = 0f; + m_HeartBeatState.MissHeartBeatCount++; + } + } + + if (sendHeartBeat && m_NetworkChannelHelper.SendHeartBeat()) + { + if (missHeartBeatCount > 0 && NetworkChannelMissHeartBeat != null) + { + NetworkChannelMissHeartBeat(this, missHeartBeatCount); + } + } + } + } + + /// + /// 关闭网络频道。 + /// + public virtual void Shutdown() + { + Close(); + m_NetworkChannelHelper.Shutdown(); + } + + /// + /// 注册网络消息包处理函数。 + /// + /// + /// + /// + public void RegisterHandler(int actionId, CsMsgDelegate msgDelegate) + { + if (msgDelegate == null) + { + throw new Exception("Packet handler is invalid."); + } + + List listHandle; + if (!m_MapCmdHandle.TryGetValue(actionId, out listHandle)) + { + listHandle = new List(); + m_MapCmdHandle[actionId] = listHandle; + } + + if (listHandle != null) + { + if (!listHandle.Contains(msgDelegate)) + { + listHandle.Add(msgDelegate); + } + else + { + Log.Warning("-------------repeat RegCmdHandle ActionCode:{0}-----------", (ActionCode)actionId); + } + } + } + + /// + /// 移除消息处理函数 + /// + /// + /// + public void RmvHandler(int actionId, CsMsgDelegate msgDelegate) + { + List listHandle; + if (!m_MapCmdHandle.TryGetValue(actionId, out listHandle)) + { + return; + } + + if (listHandle != null) + { + listHandle.Remove(msgDelegate); + } + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + public void Connect(IPAddress ipAddress, int port) + { + Connect(ipAddress, port, null); + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public virtual void Connect(IPAddress ipAddress, int port, object userData) + { + if (m_Socket != null) + { + Close(); + m_Socket = null; + } + + switch (ipAddress.AddressFamily) + { + case System.Net.Sockets.AddressFamily.InterNetwork: + m_AddressFamily = AddressFamily.IPv4; + break; + + case System.Net.Sockets.AddressFamily.InterNetworkV6: + m_AddressFamily = AddressFamily.IPv6; + break; + + default: + string errorMessage = Utility.Text.Format("Not supported address family '{0}'.", ipAddress.AddressFamily); + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.AddressFamilyError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + m_SendState.Reset(); + m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength); + } + + /// + /// 关闭连接并释放所有相关资源。 + /// + public void Close() + { + lock (this) + { + if (m_Socket == null) + { + return; + } + + m_Active = false; + + try + { + m_Socket.Shutdown(SocketShutdown.Both); + } + catch + { + } + finally + { + m_Socket.Close(); + m_Socket = null; + + if (NetworkChannelClosed != null) + { + NetworkChannelClosed(this); + } + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + } + } + + /// + /// 向远程主机发送消息包。 + /// + /// 消息包类型。 + /// 要发送的消息包。 + public void Send(T packet) where T : Packet + { + if (m_Socket == null) + { + string errorMessage = "You must connect first."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + if (!m_Active) + { + string errorMessage = "Socket is not active."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + if (packet == null) + { + string errorMessage = "Packet is invalid."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SendError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + lock (m_SendPacketPool) + { + m_SendPacketPool.Enqueue(packet); + } + } + + /// + /// 释放资源。 + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// 释放资源。 + /// + /// 释放资源标记。 + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + Close(); + m_SendState.Dispose(); + m_ReceiveState.Dispose(); + } + + m_Disposed = true; + } + + protected virtual bool ProcessSend() + { + if (m_SendState.Stream.Length > 0 || m_SendPacketPool.Count <= 0) + { + return false; + } + + while (m_SendPacketPool.Count > 0) + { + Packet packet = null; + lock (m_SendPacketPool) + { + packet = m_SendPacketPool.Dequeue(); + } + + bool serializeResult = false; + try + { + serializeResult = m_NetworkChannelHelper.Serialize(packet, m_SendState.Stream); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SerializeError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + if (!serializeResult) + { + string errorMessage = "Serialized packet failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SerializeError, SocketError.Success, errorMessage); + return false; + } + + throw new Exception(errorMessage); + } + } + + m_SendState.Stream.Position = 0L; + return true; + } + + protected virtual void ProcessReceive() + { + } + + protected virtual bool ProcessPacketHeader() + { + try + { + object customErrorData = null; + IPacketHeader packetHeader = m_NetworkChannelHelper.DeserializePacketHeader(m_ReceiveState.Stream, out customErrorData); + + if (customErrorData != null && NetworkChannelCustomError != null) + { + NetworkChannelCustomError(this, customErrorData); + } + + if (packetHeader == null) + { + string errorMessage = "Packet header is invalid."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, SocketError.Success, errorMessage); + return false; + } + + throw new Exception(errorMessage); + } + + m_ReceiveState.PrepareForPacket(packetHeader); + if (packetHeader.PacketLength <= 0) + { + bool processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + return processSuccess; + } + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.DeserializePacketHeaderError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + return true; + } + + protected virtual bool ProcessPacket() + { + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(m_ResetHeartBeatElapseSecondsWhenReceivePacket); + } + + try + { + object customErrorData = null; + Packet packet = m_NetworkChannelHelper.DeserializePacket(m_ReceiveState.PacketHeader, m_ReceiveState.Stream, out customErrorData); + + if (customErrorData != null && NetworkChannelCustomError != null) + { + NetworkChannelCustomError(this, customErrorData); + } + + if (packet != null) + { + HandleResponse(packet as MainPack); + } + + m_ReceiveState.PrepareForPacketHeader(m_NetworkChannelHelper.PacketHeaderLength); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.DeserializePacketError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + + return true; + } + + /// + /// 网络消息回调,非主线程 + /// + /// + public void HandleResponse(MainPack pack) + { + lock (m_CachelistHandle) + { + List listHandle; + + if (m_MapCmdHandle.TryGetValue((int)pack.actioncode, out listHandle)) + { + m_CachelistHandle.Enqueue(listHandle); + + m_QueuepPacks.Enqueue(pack); + } + } + } + + /// + /// 主线程从消息包缓存堆栈/委托缓存堆栈中出列 + /// + private void HandleCsMsgOnUpdate() + { + if (m_CachelistHandle.Count <= 0 || m_QueuepPacks.Count <= 0) + { + return; + } + try + { + foreach (CsMsgDelegate handle in m_CachelistHandle.Dequeue()) + { + var pack = m_QueuepPacks.Peek(); + + if (pack != null) + { + handle(pack); + + UInt32 hashIndex = (uint)pack.actioncode % MAX_MSG_HANDLE; + + RmvCheckCsMsg((int)hashIndex); + } + } + m_QueuepPacks.Dequeue(); + } + catch (Exception e) + { + TLogger.LogError(e.Message); + } + } + + #region 超时检测 + private const int CHECK_TIMEOUT_PERFRAME = 10; + UInt32 m_dwLastCheckIndex = 0; + CsMsgDelegate[] m_aMsgHandles = new CsMsgDelegate[MAX_MSG_HANDLE]; + float[] m_fMsgRegTime = new float[MAX_MSG_HANDLE]; + private float m_timeout = 15; + private readonly MainPack _timeOutPack = new MainPack { returncode = ReturnCode.MsgTimeOut }; + public void RmvCheckCsMsg(int index) + { + m_aMsgHandles[index] = null; + m_fMsgRegTime[index] = 0; + } + private void RegTimeOutHandle(uint actionCode, CsMsgDelegate resHandler) + { + uint hashIndex = actionCode % MAX_MSG_HANDLE; + if (m_aMsgHandles[hashIndex] != null) + { + //NotifyTimeout(m_aMsgHandles[hashIndex]); + RmvCheckCsMsg((int)hashIndex); + } + m_aMsgHandles[hashIndex] = resHandler; + m_fMsgRegTime[hashIndex] = UnityEngine.Time.time; + } + + protected void NotifyTimeout(CsMsgDelegate msgHandler) + { + msgHandler(_timeOutPack); + } + + private void CheckCsMsgTimeOut() + { + float nowTime = UnityEngine.Time.time; + for (int i = 0; i < CHECK_TIMEOUT_PERFRAME; i++) + { + m_dwLastCheckIndex = (m_dwLastCheckIndex + 1) % MAX_MSG_HANDLE; + if (m_aMsgHandles[m_dwLastCheckIndex] != null) + { + if (m_fMsgRegTime[m_dwLastCheckIndex] + m_timeout < nowTime) + { + TLogger.LogError("msg timeout, resCmdID[{0}]", m_aMsgHandles[m_dwLastCheckIndex]); + + NotifyTimeout(m_aMsgHandles[m_dwLastCheckIndex]); + + RmvCheckCsMsg((int)m_dwLastCheckIndex); + } + } + } + } + + #endregion + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs.meta new file mode 100644 index 00000000..a096d5c6 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.NetworkChannelBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d124c3d2afc7006459e261c8d510711c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs new file mode 100644 index 00000000..478b492b --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs @@ -0,0 +1,91 @@ +using System; +using System.IO; + +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + private sealed class ReceiveState : IDisposable + { + private const int DefaultBufferLength = 1024 * 64; + private MemoryStream m_Stream; + private IPacketHeader m_PacketHeader; + private bool m_Disposed; + + public ReceiveState() + { + m_Stream = new MemoryStream(DefaultBufferLength); + m_PacketHeader = null; + m_Disposed = false; + } + + public MemoryStream Stream + { + get + { + return m_Stream; + } + } + + public IPacketHeader PacketHeader + { + get + { + return m_PacketHeader; + } + } + + public void PrepareForPacketHeader(int packetHeaderLength) + { + Reset(packetHeaderLength, null); + } + + public void PrepareForPacket(IPacketHeader packetHeader) + { + if (packetHeader == null) + { + throw new Exception("Packet header is invalid."); + } + + Reset(packetHeader.PacketLength, packetHeader); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_Stream != null) + { + m_Stream.Dispose(); + m_Stream = null; + } + } + + m_Disposed = true; + } + + private void Reset(int targetLength, IPacketHeader packetHeader) + { + if (targetLength < 0) + { + throw new Exception("Target length is invalid."); + } + + m_Stream.Position = 0L; + m_Stream.SetLength(targetLength); + m_PacketHeader = packetHeader; + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs.meta new file mode 100644 index 00000000..5d6a2077 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.ReceiveState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a8a0b968c7b38442ae9bbf523e6f234 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs new file mode 100644 index 00000000..9a573301 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs @@ -0,0 +1,60 @@ +using System; +using System.IO; + +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + private sealed class SendState : IDisposable + { + private const int DefaultBufferLength = 1024 * 64; + private MemoryStream m_Stream; + private bool m_Disposed; + + public SendState() + { + m_Stream = new MemoryStream(DefaultBufferLength); + m_Disposed = false; + } + + public MemoryStream Stream + { + get + { + return m_Stream; + } + } + + public void Reset() + { + m_Stream.Position = 0L; + m_Stream.SetLength(0L); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (m_Disposed) + { + return; + } + + if (disposing) + { + if (m_Stream != null) + { + m_Stream.Dispose(); + m_Stream = null; + } + } + + m_Disposed = true; + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs.meta new file mode 100644 index 00000000..1ee0277c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.SendState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 01a1e8d0d67bac34a9d5ea40a96bb0eb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs new file mode 100644 index 00000000..426ca1c6 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs @@ -0,0 +1,340 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + /// + /// 网络管理器。 + /// + public sealed partial class NetworkManager : INetworkManager + { + private readonly Dictionary m_NetworkChannels; + + private Action m_NetworkConnectedEventHandler; + private Action m_NetworkClosedEventHandler; + private Action m_NetworkMissHeartBeatEventHandler; + private Action m_NetworkErrorEventHandler; + private Action m_NetworkCustomErrorEventHandler; + + /// + /// 初始化网络管理器的新实例。 + /// + public NetworkManager() + { + m_NetworkChannels = new Dictionary(StringComparer.Ordinal); + m_NetworkConnectedEventHandler = null; + m_NetworkClosedEventHandler = null; + m_NetworkMissHeartBeatEventHandler = null; + m_NetworkErrorEventHandler = null; + m_NetworkCustomErrorEventHandler = null; + } + + /// + /// 获取网络频道数量。 + /// + public int NetworkChannelCount + { + get + { + return m_NetworkChannels.Count; + } + } + + /// + /// 网络连接成功事件。 + /// + public event Action NetworkConnected + { + add + { + m_NetworkConnectedEventHandler += value; + } + remove + { + m_NetworkConnectedEventHandler -= value; + } + } + + /// + /// 网络连接关闭事件。 + /// + public event Action NetworkClosed + { + add + { + m_NetworkClosedEventHandler += value; + } + remove + { + m_NetworkClosedEventHandler -= value; + } + } + + /// + /// 网络心跳包丢失事件。 + /// + public event Action NetworkMissHeartBeat + { + add + { + m_NetworkMissHeartBeatEventHandler += value; + } + remove + { + m_NetworkMissHeartBeatEventHandler -= value; + } + } + + /// + /// 网络错误事件。 + /// + public event Action NetworkError + { + add + { + m_NetworkErrorEventHandler += value; + } + remove + { + m_NetworkErrorEventHandler -= value; + } + } + + /// + /// 用户自定义网络错误事件。 + /// + public event Action NetworkCustomError + { + add + { + m_NetworkCustomErrorEventHandler += value; + } + remove + { + m_NetworkCustomErrorEventHandler -= value; + } + } + + /// + /// 网络管理器轮询。 + /// + /// 逻辑流逝时间,以秒为单位。 + /// 真实流逝时间,以秒为单位。 + public void Update(float elapseSeconds, float realElapseSeconds) + { + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + networkChannel.Value.Update(elapseSeconds, realElapseSeconds); + } + } + + /// + /// 关闭并清理网络管理器。 + /// + public void Shutdown() + { + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + NetworkChannelBase networkChannelBase = networkChannel.Value; + networkChannelBase.NetworkChannelConnected -= OnNetworkChannelConnected; + networkChannelBase.NetworkChannelClosed -= OnNetworkChannelClosed; + networkChannelBase.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat; + networkChannelBase.NetworkChannelError -= OnNetworkChannelError; + networkChannelBase.NetworkChannelCustomError -= OnNetworkChannelCustomError; + networkChannelBase.Shutdown(); + } + + m_NetworkChannels.Clear(); + } + + /// + /// 检查是否存在网络频道。 + /// + /// 网络频道名称。 + /// 是否存在网络频道。 + public bool HasNetworkChannel(string name) + { + return m_NetworkChannels.ContainsKey(name ?? string.Empty); + } + + /// + /// 获取网络频道。 + /// + /// 网络频道名称。 + /// 要获取的网络频道。 + public INetworkChannel GetNetworkChannel(string name) + { + NetworkChannelBase networkChannel = null; + if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel)) + { + return networkChannel; + } + + return null; + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public INetworkChannel[] GetAllNetworkChannels() + { + int index = 0; + INetworkChannel[] results = new INetworkChannel[m_NetworkChannels.Count]; + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + results[index++] = networkChannel.Value; + } + + return results; + } + + /// + /// 获取所有网络频道。 + /// + /// 所有网络频道。 + public void GetAllNetworkChannels(List results) + { + if (results == null) + { + throw new Exception("Results is invalid."); + } + + results.Clear(); + foreach (KeyValuePair networkChannel in m_NetworkChannels) + { + results.Add(networkChannel.Value); + } + } + + /// + /// 创建网络频道。 + /// + /// 网络频道名称。 + /// 网络服务类型。 + /// 网络频道辅助器。 + /// 要创建的网络频道。 + public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper) + { + if (networkChannelHelper == null) + { + throw new Exception("Network channel helper is invalid."); + } + + if (networkChannelHelper.PacketHeaderLength < 0) + { + throw new Exception("Packet header length is invalid."); + } + + if (HasNetworkChannel(name)) + { + throw new Exception(Utility.Text.Format("Already exist network channel '{0}'.", name ?? string.Empty)); + } + + NetworkChannelBase networkChannel = null; + switch (serviceType) + { + case ServiceType.Tcp: + networkChannel = new TcpNetworkChannel(name, networkChannelHelper); + break; + + case ServiceType.TcpWithSyncReceive: + networkChannel = new TcpWithSyncReceiveNetworkChannel(name, networkChannelHelper); + break; + + case ServiceType.Udp: + networkChannel = new UdpNetworkChannel(name, networkChannelHelper); + break; + + default: + throw new Exception(Utility.Text.Format("Not supported service type '{0}'.", serviceType)); + } + + networkChannel.NetworkChannelConnected += OnNetworkChannelConnected; + networkChannel.NetworkChannelClosed += OnNetworkChannelClosed; + networkChannel.NetworkChannelMissHeartBeat += OnNetworkChannelMissHeartBeat; + networkChannel.NetworkChannelError += OnNetworkChannelError; + networkChannel.NetworkChannelCustomError += OnNetworkChannelCustomError; + m_NetworkChannels.Add(name, networkChannel); + return networkChannel; + } + + /// + /// 销毁网络频道。 + /// + /// 网络频道名称。 + /// 是否销毁网络频道成功。 + public bool DestroyNetworkChannel(string name) + { + NetworkChannelBase networkChannel = null; + if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel)) + { + networkChannel.NetworkChannelConnected -= OnNetworkChannelConnected; + networkChannel.NetworkChannelClosed -= OnNetworkChannelClosed; + networkChannel.NetworkChannelMissHeartBeat -= OnNetworkChannelMissHeartBeat; + networkChannel.NetworkChannelError -= OnNetworkChannelError; + networkChannel.NetworkChannelCustomError -= OnNetworkChannelCustomError; + networkChannel.Shutdown(); + return m_NetworkChannels.Remove(name); + } + + return false; + } + + private void OnNetworkChannelConnected(NetworkChannelBase networkChannel, object userData) + { + if (m_NetworkConnectedEventHandler != null) + { + lock (m_NetworkConnectedEventHandler) + { + m_NetworkConnectedEventHandler(networkChannel,userData); + } + } + } + + private void OnNetworkChannelClosed(NetworkChannelBase networkChannel) + { + if (m_NetworkClosedEventHandler != null) + { + lock (m_NetworkClosedEventHandler) + { + m_NetworkClosedEventHandler(networkChannel); + } + } + } + + private void OnNetworkChannelMissHeartBeat(NetworkChannelBase networkChannel, int missHeartBeatCount) + { + if (m_NetworkMissHeartBeatEventHandler != null) + { + lock (m_NetworkMissHeartBeatEventHandler) + { + m_NetworkMissHeartBeatEventHandler(networkChannel,missHeartBeatCount); + } + } + } + + private void OnNetworkChannelError(NetworkChannelBase networkChannel, NetworkErrorCode errorCode, SocketError socketErrorCode, string errorMessage) + { + if (m_NetworkErrorEventHandler != null) + { + lock (m_NetworkErrorEventHandler) + { + m_NetworkErrorEventHandler(networkChannel,errorCode,errorMessage); + } + } + } + + private void OnNetworkChannelCustomError(NetworkChannelBase networkChannel, object customErrorData) + { + if (m_NetworkCustomErrorEventHandler != null) + { + lock (m_NetworkCustomErrorEventHandler) + { + m_NetworkCustomErrorEventHandler(networkChannel,customErrorData); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs.meta new file mode 100644 index 00000000..97a987d3 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/NetworkManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4ea28106108b496bb4b66fd8aa528797 +timeCreated: 1661772444 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs new file mode 100644 index 00000000..73ab0c3a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs @@ -0,0 +1,10 @@ +namespace TEngine.Runtime +{ + /// + /// 网络消息包基类。 + /// + public abstract class Packet:IMemory + { + public abstract void Clear(); + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs.meta new file mode 100644 index 00000000..8435f3b5 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4d54f03c4aed4afbab3b4fc45def97c5 +timeCreated: 1661771739 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs new file mode 100644 index 00000000..bca19f41 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs @@ -0,0 +1,28 @@ +namespace TEngine.Runtime +{ + /// + /// 网络服务类型。 + /// + public enum ServiceType : byte + { + /// + /// TCP 网络服务。 + /// + Tcp = 0, + + /// + /// 使用同步接收的 TCP 网络服务。 + /// + TcpWithSyncReceive, + + /// + /// Udp 网络服务。 + /// + Udp, + + /// + /// Kcp 网络服务。 + /// + Kcp, + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs.meta new file mode 100644 index 00000000..04b3f41a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/ServiceType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 11929818b1dbde74ba521dc2c5d03f49 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta new file mode 100644 index 00000000..2410227b --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9de71dee8e9fb74469064a1e1cf7a77b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs new file mode 100644 index 00000000..2e92199e --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs @@ -0,0 +1,11 @@ +using System; +using ProtoBuf; + +namespace TEngine.Runtime +{ + [Serializable, ProtoContract(Name = @"CSPacketHeader")] + public sealed class CSPacketHeader : PacketHeaderBase + { + + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs.meta new file mode 100644 index 00000000..00eff30f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/CSPacketHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 383e04755715b054f9e57b1ab1d322af +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs new file mode 100644 index 00000000..708f7029 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs @@ -0,0 +1,207 @@ +using System; +using System.IO; +using ProtoBuf; +using ProtoBuf.Meta; +using TEngineProto; + +namespace TEngine.Runtime +{ + public class NetworkChannelHelper : INetworkChannelHelper + { + private readonly MemoryStream m_CachedStream = new MemoryStream(1024 * 8); + private INetworkChannel m_NetworkChannel = null; + + /// + /// 获取消息包头长度。 + /// + public int PacketHeaderLength => sizeof(int); + + /// + /// 初始化网络频道辅助器。 + /// + /// 网络频道。 + public void Initialize(INetworkChannel networkChannel) + { + m_NetworkChannel = networkChannel; + + GameEventMgr.Instance.AddEventListener(NetWorkEventId.NetworkConnectedEvent,OnNetworkConnected); + GameEventMgr.Instance.AddEventListener(NetWorkEventId.NetworkClosedEvent,OnNetworkClosed); + GameEventMgr.Instance.AddEventListener(NetWorkEventId.NetworkMissHeartBeatEvent,OnNetworkMissHeartBeat); + GameEventMgr.Instance.AddEventListener(NetWorkEventId.NetworkErrorEvent,OnNetworkError); + GameEventMgr.Instance.AddEventListener(NetWorkEventId.NetworkCustomErrorEvent,OnNetworkCustomError); + + m_NetworkChannel.RegisterHandler((int)ActionCode.HeartBeat,HandleHeartBeat); + } + + private void HandleHeartBeat(MainPack mainPack) + { + + } + + /// + /// 准备进行连接。 + /// + public void PrepareForConnecting() + { + m_NetworkChannel.Socket.ReceiveBufferSize = 1024 * 64; + m_NetworkChannel.Socket.SendBufferSize = 1024 * 64; + } + + /// + /// 发送心跳消息包。 + /// + /// 是否发送心跳消息包成功。 + public bool SendHeartBeat() + { + m_NetworkChannel.Send(CSHeartBeatHandler.AllocHeartBeatPack()); + return true; + } + + /// + /// 序列化消息包。 + /// + /// 消息包类型。 + /// 要序列化的消息包。 + /// 要序列化的目标流。 + /// 是否序列化成功。 + public bool Serialize(T packet, Stream destination) where T : Packet + { + m_CachedStream.SetLength(m_CachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入 + m_CachedStream.Position = 0L; + + CSPacketHeader packetHeader = MemoryPool.Acquire(); + Serializer.Serialize(m_CachedStream, packetHeader); + MemoryPool.Release(packetHeader); + + Serializer.SerializeWithLengthPrefix(m_CachedStream, packet, PrefixStyle.Fixed32); + MemoryPool.Release((IMemory)packet); + + m_CachedStream.WriteTo(destination); + return true; + } + + /// + /// 反序列化消息包。 + /// + /// 消息包头。 + /// 要反序列化的来源流。 + /// 用户自定义错误数据。 + /// 反序列化后的消息包。 + public Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData) + { + // 注意:此函数并不在主线程调用! + customErrorData = null; + + CSPacketHeader csPacketHeader = packetHeader as CSPacketHeader; + if (csPacketHeader == null) + { + Log.Warning("Packet header is invalid."); + return null; + } + + Packet packet = null; + if (csPacketHeader.IsValid) + { + Type packetType = typeof(MainPack); + if (packetType != null) + { + packet = (Packet)RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, MemoryPool.Acquire(packetType), packetType, PrefixStyle.Fixed32, 0); + } + else + { + Log.Warning("Can not deserialize packet for packet id '{0}'.", csPacketHeader.Id.ToString()); + } + } + else + { + Log.Warning("Packet header is invalid."); + } + + MemoryPool.Release(csPacketHeader); + return packet; + } + + public IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData) + { + // 注意:此函数并不在主线程调用! + customErrorData = null; + return (IPacketHeader)RuntimeTypeModel.Default.Deserialize(source, MemoryPool.Acquire(), typeof(CSPacketHeader)); + } + + /// + /// 关闭并清理网络频道辅助器。 + /// + public void Shutdown() + { + GameEventMgr.Instance.RemoveEventListener(NetWorkEventId.NetworkConnectedEvent,OnNetworkConnected); + GameEventMgr.Instance.RemoveEventListener(NetWorkEventId.NetworkClosedEvent,OnNetworkClosed); + GameEventMgr.Instance.RemoveEventListener(NetWorkEventId.NetworkMissHeartBeatEvent,OnNetworkMissHeartBeat); + GameEventMgr.Instance.RemoveEventListener(NetWorkEventId.NetworkErrorEvent,OnNetworkError); + GameEventMgr.Instance.RemoveEventListener(NetWorkEventId.NetworkCustomErrorEvent,OnNetworkCustomError); + m_NetworkChannel = null; + } + + #region Handle + private void OnNetworkConnected(INetworkChannel channel,object userData) + { + if (channel != m_NetworkChannel) + { + return; + } + + if (channel.Socket == null) + { + return; + } + Log.Info("Network channel '{0}' connected, local address '{1}', remote address '{2}'.", channel.Name, channel.Socket.LocalEndPoint.ToString(), channel.Socket.RemoteEndPoint.ToString()); + } + + private void OnNetworkClosed(INetworkChannel channel) + { + if (channel != m_NetworkChannel) + { + return; + } + Log.Warning("Network channel '{0}' closed.", channel.Name); + } + + private void OnNetworkMissHeartBeat(INetworkChannel channel,int missCount) + { + if (channel != m_NetworkChannel) + { + return; + } + + Log.Warning("Network channel '{0}' miss heart beat '{1}' times.", channel.Name, missCount.ToString()); + + if (missCount < 2) + { + return; + } + channel.Close(); + } + + private void OnNetworkError(INetworkChannel channel,NetworkErrorCode errorCode,string errorMessage) + { + if (channel != m_NetworkChannel) + { + return; + } + + Log.Fatal("Network channel '{0}' error, error code is '{1}', error message is '{2}'.", channel.Name, errorCode.ToString(), errorMessage); + + channel.Close(); + } + + private void OnNetworkCustomError(INetworkChannel channel,object customErrorData) + { + if (channel != m_NetworkChannel) + { + return; + } + + Log.Fatal("Network channel '{0}' error, error code is '{1}', error message is '{2}'.", channel.Name, customErrorData.ToString()); + } + #endregion + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs.meta new file mode 100644 index 00000000..0a65b0f1 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/NetworkChannelHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 02d761e658b2dcd4ea9ebff4ce324968 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler.meta new file mode 100644 index 00000000..9c57d0f7 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0396e29af93d424fb252e3cf5a948fa6 +timeCreated: 1661850708 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs new file mode 100644 index 00000000..e96afb6f --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs @@ -0,0 +1,28 @@ +using TEngineProto; + +namespace TEngine.Runtime +{ + /// + /// 心跳Handler + /// + public class CSHeartBeatHandler + { + public static MainPack AllocHeartBeatPack() + { + var mainPack = MemoryPool.Acquire(); + mainPack.actioncode = ActionCode.HeartBeat; + mainPack.requestcode = RequestCode.Heart; + return mainPack; + } + + public static void Handler(MainPack mainPack) + { + if (mainPack == null) + { + Log.Fatal("Receive CSHeartBeat Failed !!!"); + return; + } + Log.Info("Receive packet '{0}'.", mainPack.ToString()); + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs.meta new file mode 100644 index 00000000..571942fb --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHandler/SCHeartBeatHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 553b96ca58c647d39802bed84a356608 +timeCreated: 1661850718 \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs new file mode 100644 index 00000000..e99d169c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs @@ -0,0 +1,31 @@ +namespace TEngine.Runtime +{ + public abstract class PacketHeaderBase : IPacketHeader, IMemory + { + public int Id + { + get; + set; + } + + public int PacketLength + { + get; + set; + } + + public bool IsValid + { + get + { + return Id > 0 && PacketLength >= 0; + } + } + + public void Clear() + { + Id = 0; + PacketLength = 0; + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs.meta new file mode 100644 index 00000000..d280b59c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/PacketHeaderBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 279045bf4ec72144aa03880102a04057 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs new file mode 100644 index 00000000..d21d6413 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs @@ -0,0 +1,49 @@ +using System.IO; + +namespace TEngine.Runtime +{ + public class ProtoUtils + { + /// + /// 序列化 MainPack -> byte[] + /// + /// + /// + /// + public static byte[] Serialize(T mainPack) where T : class + { + try + { + using (var stream = new System.IO.MemoryStream()) + { + ProtoBuf.Serializer.Serialize(stream, mainPack); + return stream.ToArray(); + } + } + catch (IOException ex) + { + Log.Error($"[Serialize] Error:{ex.Message}, {ex.Data["StackTrace"]}"); + return null; + } + } + + /// + /// 反序列化 + /// + /// + /// + /// + public static T DeSerialize(byte[] buffer) where T : class + { + try + { + return ProtoBuf.Serializer.Deserialize(typeof(T), new System.IO.MemoryStream(buffer)) as T; + } + catch (IOException ex) + { + Log.Error(($"[DeSerialize] Error:{ex.Message}, {ex.Data["StackTrace"]}")); + return null; + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs.meta new file mode 100644 index 00000000..ebbdc4f6 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper/ProtoUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2ab82c8abf14856489102fe60cc78926 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta new file mode 100644 index 00000000..f36a9046 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9bb2521a45da9104489c2f22445d39fb +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs new file mode 100644 index 00000000..b9149a92 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs @@ -0,0 +1,14 @@ +using TEngine.Runtime; + +namespace TEngineProto +{ + public partial class MainPack:Packet + { + public override void Clear() + { + requestcode = RequestCode.RequestNone; + actioncode = ActionCode.ActionNone; + returncode = ReturnCode.ReturnNone; + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs.meta new file mode 100644 index 00000000..6a02f710 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/MainPackExt.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9a93b14384cc75e47b78cb84e7cfb9c1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs new file mode 100644 index 00000000..9e973732 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs @@ -0,0 +1,192 @@ +using ProtoBuf; +using TEngine.Runtime; +using System.Collections.Generic; +namespace TEngineProto +{ + [global::ProtoBuf.ProtoContract()] + public enum RequestCode + { + RequestNone = 0, + + Heart = 1, + + User = 2, + + Room = 3, + + Game = 4, + + } + + [global::ProtoBuf.ProtoContract()] + public enum ActionCode + { + ActionNone = 0, + + HeartBeat = 1, + + Register = 1000, + + Login = 1001, + + CreateRoom = 1002, + + FindRoom = 1003, + + GetPlayers = 1004, + + JoinRoom = 1005, + + ExitRoom = 1006, + + Chat = 2000, + + } + + [global::ProtoBuf.ProtoContract()] + public enum ReturnCode + { + ReturnNone = 0, + + Success = 1, + + Fail = 2, + + MsgTimeOut = 3, + + } + + [global::ProtoBuf.ProtoContract()] + public partial class MainPack + { + [global::ProtoBuf.ProtoMember(1)] + public RequestCode requestcode { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + public ActionCode actioncode { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public ReturnCode returncode { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public LoginPack loginPack { get; set; } + + [global::ProtoBuf.ProtoMember(5)] + [global::System.ComponentModel.DefaultValue("")] + public string extstr { get; set; } + + [global::ProtoBuf.ProtoMember(6)] + public List roompack = new List(); + + [global::ProtoBuf.ProtoMember(7)] + public PlayerPack playerpack { get; set; } + + [global::ProtoBuf.ProtoMember(8)] + public long HeatEchoTime { get; set; } + } + + [global::ProtoBuf.ProtoContract()] + public partial class LoginPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string username { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + [global::System.ComponentModel.DefaultValue("")] + public string password { get; set; } + + } + + [global::ProtoBuf.ProtoContract()] + public partial class RoomPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string roomname { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + public int maxnum { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public int curnum { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public int state { get; set; } + + [global::ProtoBuf.ProtoMember(6)] + public int roomID { get; set; } + + [global::ProtoBuf.ProtoMember(9)] + public int visable { get; set; } + + [global::ProtoBuf.ProtoMember(10)] + public int usePassword { get; set; } + + [global::ProtoBuf.ProtoMember(11)] + [global::System.ComponentModel.DefaultValue("")] + public string password { get; set; } + + [global::ProtoBuf.ProtoMember(12)] + public List playerpack = new List(); + + } + + [global::ProtoBuf.ProtoContract()] + public partial class PlayerPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string playerName { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + [global::System.ComponentModel.DefaultValue("")] + public string playerID { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public int hp { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public PosPack posPack { get; set; } + + } + + [global::ProtoBuf.ProtoContract()] + public partial class PosPack + { + [global::ProtoBuf.ProtoMember(1)] + public float PosX { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + public float PosY { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public float PosZ { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public float RotaX { get; set; } + + [global::ProtoBuf.ProtoMember(5)] + public float RotaY { get; set; } + + [global::ProtoBuf.ProtoMember(6)] + public float RotaZ { get; set; } + + [global::ProtoBuf.ProtoMember(8)] + public int Animation { get; set; } + + [global::ProtoBuf.ProtoMember(9)] + public int Direction { get; set; } + + [global::ProtoBuf.ProtoMember(10)] + public float MoveX { get; set; } + + [global::ProtoBuf.ProtoMember(11)] + public float MoveY { get; set; } + + [global::ProtoBuf.ProtoMember(12)] + public float MoveZ { get; set; } + + } + +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs.meta new file mode 100644 index 00000000..bf365d9c --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto/TEngineProto.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbec49a00bdc11543a0608119cf63810 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta new file mode 100644 index 00000000..a5c3cd91 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bcf0e9cef581b5441ad604bfc2f771c4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs new file mode 100644 index 00000000..20ca88f0 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs @@ -0,0 +1,281 @@ +using System; +using System.Net; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + /// + /// TCP 网络频道。 + /// + private sealed class TcpNetworkChannel : NetworkChannelBase + { + private readonly AsyncCallback m_ConnectCallback; + private readonly AsyncCallback m_SendCallback; + private readonly AsyncCallback m_ReceiveCallback; + + /// + /// 初始化网络频道的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public TcpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper) + : base(name, networkChannelHelper) + { + m_ConnectCallback = ConnectCallback; + m_SendCallback = SendCallback; + m_ReceiveCallback = ReceiveCallback; + } + + /// + /// 获取网络服务类型。 + /// + public override ServiceType ServiceType + { + get + { + return ServiceType.Tcp; + } + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public override void Connect(IPAddress ipAddress, int port, object userData) + { + base.Connect(ipAddress, port, userData); + m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + if (m_Socket == null) + { + string errorMessage = "Initialize network channel failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + m_NetworkChannelHelper.PrepareForConnecting(); + ConnectAsync(ipAddress, port, userData); + } + + protected override bool ProcessSend() + { + if (base.ProcessSend()) + { + SendAsync(); + return true; + } + + return false; + } + + private void ConnectAsync(IPAddress ipAddress, int port, object userData) + { + try + { + m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData)); + } + catch (Exception exception) + { + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ConnectCallback(IAsyncResult ar) + { + ConnectState socketUserData = (ConnectState)ar.AsyncState; + try + { + socketUserData.Socket.EndConnect(ar); + } + catch (ObjectDisposedException) + { + return; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + + if (NetworkChannelConnected != null) + { + NetworkChannelConnected(this, socketUserData.UserData); + } + + m_Active = true; + ReceiveAsync(); + } + + private void SendAsync() + { + try + { + m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void SendCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesSent = 0; + try + { + bytesSent = socket.EndSend(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SendState.Stream.Position += bytesSent; + if (m_SendState.Stream.Position < m_SendState.Stream.Length) + { + SendAsync(); + return; + } + + m_SentPacketCount++; + m_SendState.Reset(); + } + + private void ReceiveAsync() + { + try + { + m_Socket.BeginReceive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None, m_ReceiveCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ReceiveCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesReceived = 0; + try + { + bytesReceived = socket.EndReceive(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + if (bytesReceived <= 0) + { + Close(); + return; + } + + m_ReceiveState.Stream.Position += bytesReceived; + if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length) + { + ReceiveAsync(); + return; + } + + m_ReceiveState.Stream.Position = 0L; + + bool processSuccess = false; + if (m_ReceiveState.PacketHeader != null) + { + processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + } + else + { + processSuccess = ProcessPacketHeader(); + } + + if (processSuccess) + { + ReceiveAsync(); + return; + } + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs.meta new file mode 100644 index 00000000..0b1fbb8a --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpNetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2df585ebfe0562642b66664dbf0feaaf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs new file mode 100644 index 00000000..86550d5e --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs @@ -0,0 +1,257 @@ +using System; +using System.Net; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + public sealed partial class NetworkManager + { + /// + /// 使用同步接收的 TCP 网络频道。 + /// + private sealed class TcpWithSyncReceiveNetworkChannel : NetworkChannelBase + { + private readonly AsyncCallback m_ConnectCallback; + private readonly AsyncCallback m_SendCallback; + + /// + /// 初始化网络频道的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public TcpWithSyncReceiveNetworkChannel(string name, INetworkChannelHelper networkChannelHelper) + : base(name, networkChannelHelper) + { + m_ConnectCallback = ConnectCallback; + m_SendCallback = SendCallback; + } + + /// + /// 获取网络服务类型。 + /// + public override ServiceType ServiceType + { + get + { + return ServiceType.TcpWithSyncReceive; + } + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public override void Connect(IPAddress ipAddress, int port, object userData) + { + base.Connect(ipAddress, port, userData); + m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + if (m_Socket == null) + { + string errorMessage = "Initialize network channel failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + m_NetworkChannelHelper.PrepareForConnecting(); + ConnectAsync(ipAddress, port, userData); + } + + protected override bool ProcessSend() + { + if (base.ProcessSend()) + { + SendAsync(); + return true; + } + + return false; + } + + protected override void ProcessReceive() + { + base.ProcessReceive(); + while (m_Socket.Available > 0) + { + if (!ReceiveSync()) + { + break; + } + } + } + + private void ConnectAsync(IPAddress ipAddress, int port, object userData) + { + try + { + m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData)); + } + catch (Exception exception) + { + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ConnectCallback(IAsyncResult ar) + { + ConnectState socketUserData = (ConnectState)ar.AsyncState; + try + { + socketUserData.Socket.EndConnect(ar); + } + catch (ObjectDisposedException) + { + return; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + + if (NetworkChannelConnected != null) + { + NetworkChannelConnected(this, socketUserData.UserData); + } + + m_Active = true; + } + + private void SendAsync() + { + try + { + m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void SendCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesSent = 0; + try + { + bytesSent = socket.EndSend(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SendState.Stream.Position += bytesSent; + if (m_SendState.Stream.Position < m_SendState.Stream.Length) + { + SendAsync(); + return; + } + + m_SentPacketCount++; + m_SendState.Reset(); + } + + private bool ReceiveSync() + { + try + { + int bytesReceived = m_Socket.Receive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None); + if (bytesReceived <= 0) + { + Close(); + return false; + } + + m_ReceiveState.Stream.Position += bytesReceived; + if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length) + { + return false; + } + + m_ReceiveState.Stream.Position = 0L; + + bool processSuccess = false; + if (m_ReceiveState.PacketHeader != null) + { + processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + } + else + { + processSuccess = ProcessPacketHeader(); + } + + return processSuccess; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return false; + } + + throw; + } + } + } + } +} diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta new file mode 100644 index 00000000..84d39b9d --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp/NetworkManager.TcpWithSyncReceiveNetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 19723c1417631894d90eef482924d87d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta new file mode 100644 index 00000000..74f97f87 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 181b125a26149ad4bbc6f270738f37ce +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs new file mode 100644 index 00000000..f33fb428 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs @@ -0,0 +1,274 @@ +using System; +using System.Net; +using System.Net.Sockets; + +namespace TEngine.Runtime +{ + + public sealed partial class NetworkManager + { + private sealed class UdpNetworkChannel : NetworkChannelBase + { + /// + /// 获取网络服务类型。 + /// + public override ServiceType ServiceType => ServiceType.Udp; + + + private readonly AsyncCallback m_ConnectCallback; + private readonly AsyncCallback m_SendCallback; + private readonly AsyncCallback m_ReceiveCallback; + + /// + /// 初始化网络频道的新实例。 + /// + /// 网络频道名称。 + /// 网络频道辅助器。 + public UdpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper) + : base(name, networkChannelHelper) + { + m_ConnectCallback = ConnectCallback; + m_SendCallback = SendCallback; + m_ReceiveCallback = ReceiveCallback; + } + + /// + /// 连接到远程主机。 + /// + /// 远程主机的 IP 地址。 + /// 远程主机的端口号。 + /// 用户自定义数据。 + public override void Connect(IPAddress ipAddress, int port, object userData) + { + base.Connect(ipAddress, port, userData); + m_Socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Udp); + if (m_Socket == null) + { + string errorMessage = "Initialize network channel failure."; + if (NetworkChannelError != null) + { + NetworkChannelError(this, NetworkErrorCode.SocketError, SocketError.Success, errorMessage); + return; + } + + throw new Exception(errorMessage); + } + + m_NetworkChannelHelper.PrepareForConnecting(); + ConnectAsync(ipAddress, port, userData); + } + + protected override bool ProcessSend() + { + if (base.ProcessSend()) + { + SendAsync(); + return true; + } + + return false; + } + + private void ConnectAsync(IPAddress ipAddress, int port, object userData) + { + try + { + m_Socket.BeginConnect(ipAddress, port, m_ConnectCallback, new ConnectState(m_Socket, userData)); + } + catch (Exception exception) + { + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ConnectCallback(IAsyncResult ar) + { + ConnectState socketUserData = (ConnectState)ar.AsyncState; + try + { + socketUserData.Socket.EndConnect(ar); + } + catch (ObjectDisposedException) + { + return; + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ConnectError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SentPacketCount = 0; + m_ReceivedPacketCount = 0; + + lock (m_SendPacketPool) + { + m_SendPacketPool.Clear(); + } + + lock (m_HeartBeatState) + { + m_HeartBeatState.Reset(true); + } + + if (NetworkChannelConnected != null) + { + NetworkChannelConnected(this, socketUserData.UserData); + } + + m_Active = true; + ReceiveAsync(); + } + + private void SendAsync() + { + try + { + m_Socket.BeginSend(m_SendState.Stream.GetBuffer(), (int)m_SendState.Stream.Position, (int)(m_SendState.Stream.Length - m_SendState.Stream.Position), SocketFlags.None, m_SendCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void SendCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesSent = 0; + try + { + bytesSent = socket.EndSend(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.SendError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + m_SendState.Stream.Position += bytesSent; + if (m_SendState.Stream.Position < m_SendState.Stream.Length) + { + SendAsync(); + return; + } + + m_SentPacketCount++; + m_SendState.Reset(); + } + + private void ReceiveAsync() + { + try + { + m_Socket.BeginReceive(m_ReceiveState.Stream.GetBuffer(), (int)m_ReceiveState.Stream.Position, (int)(m_ReceiveState.Stream.Length - m_ReceiveState.Stream.Position), SocketFlags.None, m_ReceiveCallback, m_Socket); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + } + + private void ReceiveCallback(IAsyncResult ar) + { + Socket socket = (Socket)ar.AsyncState; + if (!socket.Connected) + { + return; + } + + int bytesReceived = 0; + try + { + bytesReceived = socket.EndReceive(ar); + } + catch (Exception exception) + { + m_Active = false; + if (NetworkChannelError != null) + { + SocketException socketException = exception as SocketException; + NetworkChannelError(this, NetworkErrorCode.ReceiveError, socketException != null ? socketException.SocketErrorCode : SocketError.Success, exception.ToString()); + return; + } + + throw; + } + + if (bytesReceived <= 0) + { + Close(); + return; + } + + m_ReceiveState.Stream.Position += bytesReceived; + if (m_ReceiveState.Stream.Position < m_ReceiveState.Stream.Length) + { + ReceiveAsync(); + return; + } + + m_ReceiveState.Stream.Position = 0L; + + bool processSuccess = false; + if (m_ReceiveState.PacketHeader != null) + { + processSuccess = ProcessPacket(); + m_ReceivedPacketCount++; + } + else + { + processSuccess = ProcessPacketHeader(); + } + + if (processSuccess) + { + ReceiveAsync(); + return; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs.meta b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs.meta new file mode 100644 index 00000000..8430dd16 --- /dev/null +++ b/Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp/UdpNetworkChannel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 17b9e06584f10da45a8a3ca27fd5e654 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.json b/Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.json new file mode 100644 index 00000000..7a73a41b --- /dev/null +++ b/Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.xlsx b/Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..feaf36f10729d48425788834caa073ce49b54190 GIT binary patch literal 10194 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 q{|N1m#sBH8|1LfW%^v roompack = new List(); + + [global::ProtoBuf.ProtoMember(7)] + public PlayerPack playerpack { get; set; } + + [global::ProtoBuf.ProtoMember(8)] + public long HeatEchoTime { get; set; } + + } + + [global::ProtoBuf.ProtoContract()] + public partial class LoginPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string username { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + [global::System.ComponentModel.DefaultValue("")] + public string password { get; set; } + + } + + [global::ProtoBuf.ProtoContract()] + public partial class RoomPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string roomname { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + public int maxnum { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public int curnum { get; set; } + + [global::ProtoBuf.ProtoMember(6)] + public int roomID { get; set; } + + [global::ProtoBuf.ProtoMember(12)] + public List playerpack = new List(); + + } + + [global::ProtoBuf.ProtoContract()] + public partial class PlayerPack + { + [global::ProtoBuf.ProtoMember(1)] + [global::System.ComponentModel.DefaultValue("")] + public string playerName { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + [global::System.ComponentModel.DefaultValue("")] + public string playerID { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public int hp { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public PosPack posPack { get; set; } + + } + + [global::ProtoBuf.ProtoContract()] + public partial class PosPack + { + [global::ProtoBuf.ProtoMember(1)] + public float PosX { get; set; } + + [global::ProtoBuf.ProtoMember(2)] + public float PosY { get; set; } + + [global::ProtoBuf.ProtoMember(3)] + public float PosZ { get; set; } + + [global::ProtoBuf.ProtoMember(4)] + public float RotaX { get; set; } + + [global::ProtoBuf.ProtoMember(5)] + public float RotaY { get; set; } + + [global::ProtoBuf.ProtoMember(6)] + public float RotaZ { get; set; } + + [global::ProtoBuf.ProtoMember(8)] + public int Animation { get; set; } + + [global::ProtoBuf.ProtoMember(9)] + public int Direction { get; set; } + + [global::ProtoBuf.ProtoMember(10)] + public float MoveX { get; set; } + + [global::ProtoBuf.ProtoMember(11)] + public float MoveY { get; set; } + + [global::ProtoBuf.ProtoMember(12)] + public float MoveZ { get; set; } + + } + +} diff --git a/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat b/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat new file mode 100644 index 00000000..166a37c4 --- /dev/null +++ b/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat @@ -0,0 +1,19 @@ +@echo off +setlocal enabledelayedexpansion +::Proto文件路径 +set SOURCE_PATH=..\Proto + +::C#文件生成路径 +set TARGET_PATH=..\Proto_CSharp + +::删除之前创建的文件 +del %TARGET_PATH%\*.cs /f /s /q + +echo ------------------------------------------------------------- + +for /R %SOURCE_PATH% %%f in (*.proto) do ( + set "FILE_PATH=%%~nxf" + echo handle file: !FILE_PATH! + protogen --proto_path=%SOURCE_PATH% --csharp_out=%TARGET_PATH% !FILE_PATH! +) +pause \ No newline at end of file diff --git a/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.Reflection.dll b/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.Reflection.dll new file mode 100644 index 0000000000000000000000000000000000000000..1bcc729edd806f8a15a8c4b2ef97ff90bf0c5053 GIT binary patch literal 293376 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 + + + protobuf-net.Reflection + + + + + Abstract root for a general purpose code-generator + + + + + The logical name of this code generator + + + + + Get a string representation of the instance + + + + + Execute the code generator against a FileDescriptorSet, yielding a sequence of files + + + + + Execute the code generator against a FileDescriptorSet, yielding a sequence of files + + + + + Eexecute this code generator against a code file + + + + + Eexecute this code generator against a set of code file + + + + + Abstract base class for a code generator that uses a visitor pattern + + + + + Obtain the access of an item, accounting for the model's hierarchy + + + + + Get the language version for this language from a schema + + + + + Obtain the access of an item, accounting for the model's hierarchy + + + + + Obtain the access of an item, accounting for the model's hierarchy + + + + + Obtain the access of an item, accounting for the model's hierarchy + + + + + Get the textual name of a given access level + + + + + The indentation used by this code generator + + + + + The file extension of the files generatred by this generator + + + + + Should case-sensitivity be used when computing conflicts? + + + + + Handle keyword escaping in the language of this code generator + + + + + + + Execute the code generator against a FileDescriptorSet, yielding a sequence of files + + + + + Emits the code for a file in a descriptor-set + + + + + Emit code representing an extension field + + + + + Emit code preceeding a set of extension fields + + + + + Emit code following a set of extension fields + + + + + Emit code preceeding a set of extension fields + + + + + Emit code following a set of extension fields + + + + + Emit code representing a service + + + + + Emit code following a set of service methods + + + + + Emit code representing a service method + + + + + Emit code following preceeding a set of service methods + + + + + Check whether a particular message should be suppressed - for example because it represents a map + + + + + Emit code representing a message type + + + + + Emit code terminating a constructor, if one is required + + + + + Emit code initializing field values inside a constructor, if one is required + + + + + Emit code beginning a constructor, if one is required + + true if a constructor is required + + + + Emit code representing a message field + + + + + Emit code following a set of message fields + + + + + Emit code preceeding a set of message fields + + + + + Emit code representing an enum type + + + + + Emit code representing 'oneof' elements as an enum discriminator + + + + + Emit code preceeding a set of enum values + + + + + Emit code representing an enum value + + + + + Emit code following a set of enum values + + + + + Emit code at the start of a file + + + + + Emit code at the end of a file + + + + + Emit the start of an enum declaration for 'oneof' groups, including the 0/None element + + + + + Emit a field-based entry for a 'oneof' groups's enum + + + + + Emit the end of an enum declaration for 'oneof' groups + + + + + Emit the discriminator accessor for 'oneof' groups + + + + + Convention-based suffix for 'oneof' enums + + + + + Convention-based suffix for 'oneof' discriminators + + + + + Represents the state of a code-generation invocation + + + + + The file being processed + + + + + The token to use for indentation + + + + + The current indent level + + + + + The mechanism to use for name normalization + + + + + The output for this code generation + + + + + The effective syntax of this code-generation cycle, defaulting to "proto2" if not explicity specified + + + + + Whether to emit enums and discriminators for oneof groups + + + + + Create a new GeneratorContext instance + + + + + Gets the value of an OPTION/VALUE pair provided to the system + + + + + Should default value initializers be emitted even for required values? + + + + + The specified language version (null if not specified) + + + + + Ends the current line + + + + + Appends a value and ends the current line + + + + + Appends a value to the current line + + + + + Increases the indentation level + + + + + Decreases the indentation level + + + + + Try to find a descriptor of the type specified by T with the given full name + + + + + Represents the union summary of a one-of declaration + + + + + The underlying descriptor + + + + + The effective index of this stub + + + + + A code generator that writes C# + + + + + Reusable code-generator instance + + + + + Create a new CSharpCodeGenerator instance + + + + + Returns the language name + + + + + Returns the default file extension + + + + + Escapes language keywords + + + + + Get the language version for this language from a schema + + + + + Start a file + + + + + End a file + + + + + Start an enum + + + + + End an enum + + + + + Write an enum value + + + + + End a message + + + + + Start a message + + + + + Get the language specific keyword representing an access level + + + + + Emit code beginning a constructor, if one is required + + true if a constructor is required + + + + Emit code terminating a constructor, if one is required + + + + + Emit code initializing field values inside a constructor, if one is required + + + + + Write a field + + + + + Starts an extgensions block + + + + + Ends an extgensions block + + + + + Starts an extensions block + + + + + Ends an extensions block + + + + + Write an extension + + + + + Emit the start of an enum declaration for 'oneof' groups, including the 0/None element + + + + + Emit the end of an enum declaration for 'oneof' groups + + + + + Emit a field-based entry for a 'oneof' groups's enum + + + + + Emit the discriminator accessor for 'oneof' groups + + + + + Provides general purpose name suggestions + + + + + Suggest a name with idiomatic pluralization + + + + + Suggest a name with idiomatic pluralization + + + + + Suggest a name with idiomatic name capitalization + + + + + Suggest a name with idiomatic pluralization + + + + + Name normalizer with default protobuf-net behaviour, using .NET idioms + + + + + Name normalizer that passes through all identifiers without any changes + + + + + Suggest a normalized identifier + + + + + Suggest a name with idiomatic pluralization + + + + + Suggest a normalized identifier + + + + + Suggest a normalized identifier + + + + + Suggest a normalized identifier + + + + + Suggest a normalized identifier + + + + + Suggest a normalized identifier + + + + + Suggest a normalized identifier + + + + + Obtain a set of all names defined for a message + + + + + Get the preferred name for an element + + + + + Describes a generated file + + + + + Get a string representation of this instance + + + + + + Create a new CodeFile instance + + + + + The name (including path if necessary) of this file + + + + + The contents of this file + + + + + Represents the overall result of a compilation process + + + + + The errors from this execution + + + + + The output files from this execution + + + + + Describes an error that occurred during processing + + + + + Parse an error from a PROTOC error message + + + + + Get a text representation of this instance + + + + + + True if this instance represents a non-fatal warning + + + + + True if this instance represents a fatal error + + + + + The file in which this error was identified + + + + + The source text relating to this error + + + + + The error message + + + + + The entire line contents in the source in which this error was located + + + + + The line number in which this error was located + + + + + The column number in which this error was located + + + + + A code generator that writes VB + + + + + Reusable code-generator instance + + + + + Should case-sensitivity be used when computing conflicts? + + + + + Create a new VBCodeGenerator instance + + + + + Returns the language name + + + + + Get the language version for this language from a schema + + + + + Returns the default file extension + + + + + Escapes language keywords + + + + + Start a file + + + + + End a file + + + + + Start an enum + + + + + End an enum + + + + + Write an enum value + + + + + Emit the discriminator accessor for 'oneof' groups + + + + + Emit the end of an enum declaration for 'oneof' groups + + + + + Emit the start of an enum declaration for 'oneof' groups, including the 0/None element + + + + + Emit a field-based entry for a 'oneof' groups's enum + + + + + End a message + + + + + Start a message + + + + + Get the language specific keyword representing an access level + + + + + Write a field + + + + + Starts an extgensions block + + + + + Ends an extgensions block + + + + + Starts an extensions block + + + + + Ends an extensions block + + + + + Write an extension + + + + + When processing Foo/Bar/Some.proto, should Foo/Bar be treated as an implicit import location? + + + + + Default package to use when none is specified; can use #FILE# and #DIR# tokens + + + + diff --git a/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.dll b/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.dll new file mode 100644 index 0000000000000000000000000000000000000000..3562db520d0802b5ed28f4c461d8e23425029f63 GIT binary patch literal 275456 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�Z*W|_rbBE_HI*lf0cdv!uog0F1825B7K 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 + + + protobuf-net + + + +

+ Provides support for common .NET types that do not have a direct representation + in protobuf, using the definitions from bcl.proto + + + + + Creates a new instance of the specified type, bypassing the constructor. + + The type to create + The new instance + If the platform does not support constructor-skipping + + + + The default value for dates that are following google.protobuf.Timestamp semantics + + + + + Writes a TimeSpan to a protobuf stream using protobuf-net's own representation, bcl.TimeSpan + + + + + Parses a TimeSpan from a protobuf stream using protobuf-net's own representation, bcl.TimeSpan + + + + + Parses a TimeSpan from a protobuf stream using the standardized format, google.protobuf.Duration + + + + + Writes a TimeSpan to a protobuf stream using the standardized format, google.protobuf.Duration + + + + + Parses a DateTime from a protobuf stream using the standardized format, google.protobuf.Timestamp + + + + + Writes a DateTime to a protobuf stream using the standardized format, google.protobuf.Timestamp + + + + + Parses a DateTime from a protobuf stream + + + + + Writes a DateTime to a protobuf stream, excluding the Kind + + + + + Writes a DateTime to a protobuf stream, including the Kind + + + + + Parses a decimal from a protobuf stream + + + + + Writes a decimal to a protobuf stream + + + + + Writes a Guid to a protobuf stream + + + + + Parses a Guid from a protobuf stream + + + + + Optional behaviours that introduce .NET-specific functionality + + + + + No special behaviour + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + If false, the constructor for the type is bypassed during deserialization, meaning any field initializers + or other initialization code is skipped. + + + + + Should the object index be reserved, rather than creating an object promptly + + + + + Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. + + + + + Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. + + + + + Provides a simple buffer-based implementation of an extension object. + + + + + https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element + + + + Specifies a method on the root-contract in an hierarchy to be invoked before serialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked after serialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked before deserialization. + + + Specifies a method on the root-contract in an hierarchy to be invoked after deserialization. + + + + Pushes a null reference onto the stack. Note that this should only + be used to return a null (or set a variable to null); for null-tests + use BranchIfTrue / BranchIfFalse. + + + + + Creates a new "using" block (equivalent) around a variable; + the variable must exist, and note that (unlike in C#) it is + the variables *final* value that gets disposed. If you need + *original* disposal, copy your variable first. + + It is the callers responsibility to ensure that the variable's + scope fully-encapsulates the "using"; if not, the variable + may be re-used (and thus re-assigned) unexpectedly. + + + + + Sub-format to use when serializing/deserializing data + + + + + Uses the default encoding for the data-type. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that zigzag variant encoding will be used. This means that values + with small magnitude (regardless of sign) take a small amount + of space to encode. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that two's-complement variant encoding will be used. + This means that any -ve number will take 10 bytes (even for 32-bit), + so should only be used for compatibility. + + + + + When applied to signed integer-based data (including Decimal), this + indicates that a fixed amount of space will be used. + + + + + When applied to a sub-message, indicates that the value should be treated + as group-delimited. + + + + + When applied to members of types such as DateTime or TimeSpan, specifies + that the "well known" standardized representation should be use; DateTime uses Timestamp, + + + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Guid + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Guid + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int64 + + + The value typed as UInt64 + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Double + + + The value typed as DateTime + + + The value typed as TimeSpan + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + Represent multiple types as a union; this is used as part of OneOf - + note that it is the caller's responsbility to only read/write the value as the same type + + + The value typed as Int32 + + + The value typed as UInt32 + + + The value typed as Boolean + + + The value typed as Single + + + The value typed as Object + + + Indicates whether the specified discriminator is assigned + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Create a new discriminated union value + + + Reset a value if the specified discriminator is assigned + + + The discriminator value + + + + Simple base class for supporting unexpected fields allowing + for loss-less round-tips/merge, even if the data is not understod. + The additional fields are (by default) stored in-memory in a buffer. + + As an example of an alternative implementation, you might + choose to use the file system (temporary files) as the back-end, tracking + only the paths [such an object would ideally be IDisposable and use + a finalizer to ensure that the files are removed]. + + + + + Retrieves the extension object for the current + instance, optionally creating it if it does not already exist. + + Should a new extension object be + created if it does not already exist? + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Provides a simple, default implementation for extension support, + optionally creating it if it does not already exist. Designed to be called by + classes implementing . + + Should a new extension object be + created if it does not already exist? + The extension field to check (and possibly update). + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The type of the value to append. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The data-type of the field. + The data-format to use when encoding the value. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned is the composed value after merging any duplicated content; if the + value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The effective value of the field, or the default value if not found. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned is the composed value after merging any duplicated content; if the + value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + The effective value of the field, or the default value if not found. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + Allow tags that are present as part of the definition; for example, to query unknown enum values. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + An enumerator that yields each occurrence of the field. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + An enumerator that yields each occurrence of the field. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + The value returned (in "value") is the composed value after merging any duplicated content; + if the value is "repeated" (a list), then use GetValues instead. + + The data-type of the field. + The model to use for configuration. + The effective value of the field, or the default value if not found. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + Allow tags that are present as part of the definition; for example, to query unknown enum values. + True if data for the field was present, false otherwise. + + + + Queries an extensible object for an additional (unexpected) data-field for the instance. + Each occurrence of the field is yielded separately, making this usage suitable for "repeated" + (list) fields. + + The extended data is processed lazily as the enumerator is iterated. + The model to use for configuration. + The data-type of the field. + The extensible object to obtain the value from. + The field identifier; the tag should not be defined as a known data-field for the instance. + The data-format to use when decoding the value. + An enumerator that yields each occurrence of the field. + + + + Appends the value as an additional (unexpected) data-field for the instance. + Note that for non-repeated sub-objects, this equates to a merge operation; + for repeated sub-objects this adds a new instance to the set; for simple + values the new value supercedes the old value. + + Note that appending a value does not remove the old value from + the stream; avoid repeatedly appending values for the same field. + The model to use for configuration. + The data-format to use when encoding the value. + The extensible object to append the value to. + The field identifier; the tag should not be defined as a known data-field for the instance. + The value to append. + + + + This class acts as an internal wrapper allowing us to do a dynamic + methodinfo invoke; an't put into Serializer as don't want on public + API; can't put into Serializer<T> since we need to invoke + across classes + + + + + All this does is call GetExtendedValuesTyped with the correct type for "instance"; + this ensures that we don't get issues with subclasses declaring conflicting types - + the caller must respect the fields defined for the type they pass in. + + + + + All this does is call GetExtendedValuesTyped with the correct type for "instance"; + this ensures that we don't get issues with subclasses declaring conflicting types - + the caller must respect the fields defined for the type they pass in. + + + + + Not all frameworks are created equal (fx1.1 vs fx2.0, + micro-framework, compact-framework, + silverlight, etc). This class simply wraps up a few things that would + otherwise make the real code unnecessarily messy, providing fallback + implementations if necessary. + + + + + Intended to be a direct map to regular TypeCode, but: + - with missing types + - existing on WinRT + + + + + Indicates that the implementing type has support for protocol-buffer + extensions. + + Can be implemented by deriving from Extensible. + + + + Retrieves the extension object for the current + instance, optionally creating it if it does not already exist. + + Should a new extension object be + created if it does not already exist? + The extension object if it exists (or was created), or null + if the extension object does not exist or is not available. + The createIfMissing argument is false during serialization, + and true during deserialization upon encountering unexpected fields. + + + + Provides addition capability for supporting unexpected fields during + protocol-buffer serialization/deserialization. This allows for loss-less + round-trip/merge, even when the data is not fully understood. + + + + + Requests a stream into which any unexpected fields can be persisted. + + A new stream suitable for storing data. + + + + Indicates that all unexpected fields have now been stored. The + implementing class is responsible for closing the stream. If + "commit" is not true the data may be discarded. + + The stream originally obtained by BeginAppend. + True if the append operation completed successfully. + + + + Requests a stream of the unexpected fields previously stored. + + A prepared stream of the unexpected fields. + + + + Indicates that all unexpected fields have now been read. The + implementing class is responsible for closing the stream. + + The stream originally obtained by BeginQuery. + + + + Requests the length of the raw binary stream; this is used + when serializing sub-entities to indicate the expected size. + + The length of the binary stream representing unexpected data. + + + + Provides the ability to remove all existing extension data + + + + + Remove all existing extension data + + + + + Specifies the method used to infer field tags for members of the type + under consideration. Tags are deduced using the invariant alphabetic + sequence of the members' names; this makes implicit field tags very brittle, + and susceptible to changes such as field names (normally an isolated + change). + + + + + No members are serialized implicitly; all members require a suitable + attribute such as [ProtoMember]. This is the recmomended mode for + most scenarios. + + + + + Public properties and fields are eligible for implicit serialization; + this treats the public API as a contract. Ordering beings from ImplicitFirstTag. + + + + + Public and non-public fields are eligible for implicit serialization; + this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag. + + + + + Represents the set of serialization callbacks to be used when serializing/deserializing a type. + + + + Called before serializing an instance + + + Called before deserializing an instance + + + Called after serializing an instance + + + Called after deserializing an instance + + + + True if any callback is set, else False + + + + + Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined + + + + + Get the name of the type being represented + + + + + Gets the base-type for this type + + + + + When used to compile a model, should public serialization/deserialzation methods + be included for this type? + + + + + Should this type be treated as a reference by default? + + + + + Adds a known sub-type to the inheritance model + + + + + Adds a known sub-type to the inheritance model + + + + + Indicates whether the current type has defined callbacks + + + + + Indicates whether the current type has defined subtypes + + + + + Returns the set of callbacks defined for this type + + + + + Assigns the callbacks to use during serialiation/deserialization. + + The method (or null) called before serialization begins. + The method (or null) called when serialization is complete. + The method (or null) called before deserialization begins (or when a new instance is created during deserialization). + The method (or null) called when deserialization is complete. + The set of callbacks. + + + + Assigns the callbacks to use during serialiation/deserialization. + + The name of the method (or null) called before serialization begins. + The name of the method (or null) called when serialization is complete. + The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization). + The name of the method (or null) called when deserialization is complete. + The set of callbacks. + + + + Gets or sets the name of this contract. + + + + + Designate a factory-method to use to create instances of this type + + + + + Designate a factory-method to use to create instances of this type + + + + + Throws an exception if the type has been made immutable + + + + + The runtime type that the meta-type represents + + + + + Adds a member (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API. + This is otherwise identical to Add. + + + + + Gets or sets whether the type should use a parameterless constructor (the default), + or whether the type should skip the constructor completely. This option is not supported + on compact-framework. + + + + + The concrete type to create when a new instance of this type is needed; this may be useful when dealing + with dynamic proxies, or with interface-based APIs + + + + + Adds a member (by name) to the MetaType + + + + + Performs serialization of this type via a surrogate; all + other serialization options are ignored and handled + by the surrogate's configuration. + + + + + Adds a set of members (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType + + + + + Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists + + + + + Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API. + This is otherwise identical to Add. + + + + + Returns the ValueMember that matchs a given field number, or null if not found + + + + + Returns the ValueMember that matchs a given member (property/field), or null if not found + + + + + Returns the ValueMember instances associated with this type + + + + + Returns the SubType instances associated with this type + + + + + Compiles the serializer for this type; this is *not* a full + standalone compile, but can significantly boost performance + while allowing additional types to be added. + + An in-place compile can access non-public types / members + + + + Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather + than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. + + + + + Gets or sets a value indicating that this type should NOT be treated as a list, even if it has + familiar list-like characteristics (enumerable, add, etc) + + + + + Indicates whether this type should always be treated as a "group" (rather than a string-prefixed sub-message) + + + + + Indiate the variant of the protobuf .proto DSL syntax to use + + + + + https://developers.google.com/protocol-buffers/docs/proto + + + + + https://developers.google.com/protocol-buffers/docs/proto3 + + + + + Provides protobuf serialization support for a number of types that can be defined at runtime + + + + + Global default that + enables/disables automatic tag generation based on the existing name / order + of the defined members. See + for usage and important warning / explanation. + You must set the global default before attempting to serialize/deserialize any + impacted type. + + + + + Global default that determines whether types are considered serializable + if they have [DataContract] / [XmlType]. With this enabled, ONLY + types marked as [ProtoContract] are added automatically. + + + + + Global switch that enables or disables the implicit + handling of "zero defaults"; meanning: if no other default is specified, + it assumes bools always default to false, integers to zero, etc. + + If this is disabled, no such assumptions are made and only *explicit* + default values are processed. This is enabled by default to + preserve similar logic to v1. + + + + + Global switch that determines whether types with a .ToString() and a Parse(string) + should be serialized as strings. + + + + + Global switch that determines whether DateTime serialization should include the Kind of the date/time. + + + + + Global switch that determines whether a single instance of the same string should be used during deserialization. + + Note this does not use the global .NET string interner + + + + Should the Kind be included on date/time values? + + + + + The default model, used to support ProtoBuf.Serializer + + + + + Returns a sequence of the Type instances that can be + processed by this model. + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + The .proto syntax to use + + + + Obtains the MetaType associated with a given Type for the current model, + allowing additional configuration. + + + + + Adds support for an additional type in this model, optionally + applying inbuilt patterns. If the type is already known to the + model, the existing type is returned **without** applying + any additional behaviour. + + Inbuilt patterns include: + [ProtoContract]/[ProtoMember(n)] + [DataContract]/[DataMember(Order=n)] + [XmlType]/[XmlElement(Order=n)] + [On{Des|S}erializ{ing|ed}] + ShouldSerialize*/*Specified + + The type to be supported + Whether to apply the inbuilt configuration patterns (via attributes etc), or + just add the type with no additional configuration (the type must then be manually configured). + The MetaType representing this type, allowing + further configuration. + + + + Should serializers be compiled on demand? It may be useful + to disable this for debugging purposes. + + + + + Should support for unexpected types be added automatically? + If false, an exception is thrown when unexpected types + are encountered. + + + + + Verifies that the model is still open to changes; if not, an exception is thrown + + + + + Prevents further changes to this model + + + + + Provides the key that represents a given type in the current model. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + Represents the type (including inheritance) to consider. + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + Represents the type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Compiles the serializers individually; this is *not* a full + standalone compile, but can significantly boost performance + while allowing additional types to be added. + + An in-place compile can access non-public types / members + + + + Fully compiles the current model into a static-compiled model instance + + A full compilation is restricted to accessing public types / members + An instance of the newly created compiled type-model + + + + Represents configuration options for compiling a model to + a standalone assembly. + + + + + Import framework options from an existing type + + + + + The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly + + + + + The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly + + + + + The name of the TypeModel class to create + + + + + The path for the new dll + + + + + The runtime version for the generated assembly + + + + + The runtime version for the generated assembly + + + + + The acecssibility of the generated serializer + + + + + Type accessibility + + + + + Available to all callers + + + + + Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)] + + + + + Fully compiles the current model into a static-compiled serialization dll + (the serialization dll still requires protobuf-net for support services). + + A full compilation is restricted to accessing public types / members + The name of the TypeModel class to create + The path for the new dll + An instance of the newly created compiled type-model + + + + Fully compiles the current model into a static-compiled serialization dll + (the serialization dll still requires protobuf-net for support services). + + A full compilation is restricted to accessing public types / members + An instance of the newly created compiled type-model + + + + The amount of time to wait if there are concurrent metadata access operations + + + + + If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating + what caused the problem; this is only raised if the lock-owning code successfully completes. + + + + + Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory. + + + + + Contains the stack-trace of the owning code when a lock-contention scenario is detected + + + + + The stack-trace of the code that owned the lock when a lock-contention scenario occurred + + + + + Event-type that is raised when a lock-contention scenario is detected + + + + + Represents an inherited type in a type hierarchy. + + + + + The field-number that is used to encapsulate the data (as a nested + message) for the derived dype. + + + + + The sub-type to be considered. + + + + + Creates a new SubType instance. + + The field-number that is used to encapsulate the data (as a nested + message) for the derived dype. + The sub-type to be considered. + Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default. + + + + Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could + be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names). + + + + + The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName. + + + + + The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type. + + + + + Delegate type used to perform type-formatting functions; the sender originates as the type-model. + + + + + Provides protobuf serialization support for a number of types + + + + + Should the Kind be included on date/time values? + + + + + Resolve a System.Type to the compiler-specific type + + + + + Resolve a System.Type to the compiler-specific type + + + + + This is the more "complete" version of Serialize, which handles single instances of mapped types. + The value is written as a complete field, including field-header and (for sub-objects) a + length-prefix + In addition to that, this provides support for: + - basic values; individual int / string / Guid / etc + - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType + + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied writer. + + The existing instance to be serialized (cannot be null). + The destination writer to write to. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Used to resolve types on a per-field basis. + Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). + The type of object to deserialize (can be null if "resolver" is specified). + The sequence of deserialized objects. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). + The type of object to deserialize (can be null if "resolver" is specified). + The sequence of deserialized objects. + Additional information about this serialization operation. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignores for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume (or -1 to read to the end of the stream). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The number of bytes to consume (or -1 to read to the end of the stream). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + Additional information about this serialization operation. + + + + Applies a protocol-buffer reader to an existing instance (which may be null). + + The type (including inheritance) to consider. + The existing instance to be modified (can be null). + The reader to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + This is the more "complete" version of Deserialize, which handles single instances of mapped types. + The value is read as a complete field, including field-header and (for sub-objects) a + length-prefix..kmc + + In addition to that, this provides support for: + - basic values; individual int / string / Guid / etc + - IList sets of any type handled by TryDeserializeAuxiliaryType + + + + + Creates a new runtime model, to which the caller + can add support for a range of types. A model + can be used "as is", or can be compiled for + optimal performance. + + + + + Applies common proxy scenarios, resolving the actual type to consider + + + + + Indicates whether the supplied type is explicitly modelled by the model + + + + + Provides the key that represents a given type in the current model. + The type is also normalized for proxies at the same time. + + + + + Advertise that a type's key can have changed + + + + + Provides the key that represents a given type in the current model. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + Represents the type (including inheritance) to consider. + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Applies a protocol-buffer stream to an existing instance (which may be null). + + Represents the type (including inheritance) to consider. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Indicates the type of callback to be used + + + + + Invoked before an object is serialized + + + + + Invoked after an object is serialized + + + + + Invoked before an object is deserialized (or when a new instance is created) + + + + + Invoked after an object is deserialized + + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Indicates that while an inheritance tree exists, the exact type encountered was not + specified in that hierarchy and cannot be processed. + + + + + Indicates that the given type was not expected, and cannot be processed. + + + + + Indicates that the given type cannot be constructed; it may still be possible to + deserialize into existing instances. + + + + + Returns true if the type supplied is either a recognised contract type, + or a *list* of a recognised contract type. + + Note that primitives always return false, even though the engine + will, if forced, try to serialize such + True if this type is recognised as a serializable entity, else false + + + + Returns true if the type supplied is a basic type with inbuilt handling, + a recognised contract type, or a *list* of a basic / contract type. + + + + + Returns true if the type supplied is a basic type with inbuilt handling, + or a *list* of a basic type with inbuilt handling + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for, or null to generate a .proto that represents the entire model + The .proto definition as a string + The .proto syntax to use for the operation + + + + Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting + are provided on a single API as it is essential that both are mapped identically at all times. + + + + + Creates a new IFormatter that uses protocol-buffer [de]serialization. + + A new IFormatter to be used during [de]serialization. + The type of object to be [de]deserialized by the formatter. + + + + Represents a member (property/field) that is mapped to a protobuf field + + + + + The number that identifies this member in a protobuf stream + + + + + Gets the member (field/property) which this member relates to. + + + + + Gets the backing member (field/property) which this member relates to + + + + + Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList) + + + + + The underlying type of the member + + + + + For abstract types (IList etc), the type of concrete object to create (if required) + + + + + The type the defines the member + + + + + The default value of the item (members with this value will not be serialized) + + + + + Creates a new ValueMember instance + + + + + Creates a new ValueMember instance + + + + + Specifies the rules used to process the field; this is used to determine the most appropriate + wite-type, but also to describe subtypes within that wire-type (such as SignedVariant) + + + + + Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32" + is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that + when serializing the defined type is always used. + + + + + Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values). + This option only applies to list/array data of primitive types (int, double, etc). + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Indicates whether this field is mandatory. + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + Indicates that the member should be treated as a protobuf Map + + + + + Specifies the data-format that should be used for the key, when IsMap is enabled + + + + + Specifies the data-format that should be used for the value, when IsMap is enabled + + + + + Specifies methods for working with optional data members. + + Provides a method (null for none) to query whether this member should + be serialized; it must be of the form "bool {Method}()". The member is only serialized if the + method returns true. + Provides a method (null for none) to indicate that a member was + deserialized; it must be of the form "void {Method}(bool)", and will be called with "true" + when data is found. + + + + Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used + when inferring a schema). + + + + + Should lists have extended support for null values? Note this makes the serialization less efficient. + + + + + Specifies the type of prefix that should be applied to messages. + + + + + No length prefix is applied to the data; the data is terminated only be the end of the stream. + + + + + A base-128 length prefix is applied to the data (efficient for short messages). + + + + + A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility). + + + + + A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility). + + + + + Indicates that a type is defined for protocol-buffer serialization. + + + + + Gets or sets the defined name of the type. + + + + + Gets or sets the fist offset to use with implicit field tags; + only uesd if ImplicitFields is set. + + + + + If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored. + + + + + If specified, do NOT treat this type as a list, even if it looks like one. + + + + + Gets or sets the mechanism used to automatically infer field tags + for members. This option should be used in advanced scenarios only. + Please review the important notes against the ImplicitFields enumeration. + + + + + Enables/disables automatic tag generation based on the existing name / order + of the defined members. This option is not used for members marked + with ProtoMemberAttribute, as intended to provide compatibility with + WCF serialization. WARNING: when adding new fields you must take + care to increase the Order for new elements, otherwise data corruption + may occur. + + If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName. + + + + Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed. + + + + + Specifies an offset to apply to [DataMember(Order=...)] markers; + this is useful when working with mex-generated classes that have + a different origin (usually 1 vs 0) than the original data-contract. + + This value is added to the Order of each member. + + + + + If true, the constructor for the type is bypassed during deserialization, meaning any field initializers + or other initialization code is skipped. + + + + + Should this type be treated as a reference by default? Please also see the implications of this, + as recorded on ProtoMemberAttribute.AsReference + + + + + Indicates whether this type should always be treated as a "group" (rather than a string-prefixed sub-message) + + + + + Applies only to enums (not to DTO classes themselves); gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather + than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. + + + + + Allows to define a surrogate type used for serialization/deserialization purpose. + + + + + Has a EnumPassthru value been explicitly set? + + + + + Indicates that a static member should be considered the same as though + were an implicit / explicit conversion operator; in particular, this + is useful for conversions that operator syntax does not allow, such as + to/from interface types. + + + + + Used to define protocol-buffer specific behavior for + enumerated values. + + + + + Gets or sets the specific value to use for this enum during serialization. + + + + + Indicates whether this instance has a customised value mapping + + true if a specific value is set + + + + Gets or sets the defined name of the enum, as used in .proto + (this name is not used during serialization). + + + + + Indicates an error during serialization/deserialization of a proto stream. + + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + Creates a new ProtoException instance. + + + + Indicates that a member should be excluded from serialization; this + is only normally used when using implict fields. + + + + + Indicates that a member should be excluded from serialization; this + is only normally used when using implict fields. This allows + ProtoIgnoreAttribute usage + even for partial classes where the individual members are not + under direct control. + + + + + Creates a new ProtoPartialIgnoreAttribute instance. + + Specifies the member to be ignored. + + + + The name of the member to be ignored. + + + + + Indicates the known-types to support for an individual + message. This serializes each level in the hierarchy as + a nested message to retain wire-compatibility with + other protocol-buffer implementations. + + + + + Creates a new instance of the ProtoIncludeAttribute. + + The unique index (within the type) that will identify this data. + The additional type to serialize/deserialize. + + + + Creates a new instance of the ProtoIncludeAttribute. + + The unique index (within the type) that will identify this data. + The additional type to serialize/deserialize. + + + + Gets the unique index (within the type) that will identify this data. + + + + + Gets the additional type to serialize/deserialize. + + + + + Gets the additional type to serialize/deserialize. + + + + + Specifies whether the inherited sype's sub-message should be + written with a length-prefix (default), or with group markers. + + + + + Controls the formatting of elements in a dictionary, and indicates that + "map" rules should be used: duplicates *replace* earlier values, rather + than throwing an exception + + + + + Describes the data-format used to store the key + + + + + Describes the data-format used to store the value + + + + + Disables "map" handling; dictionaries will use ".Add(key,value)" instead of "[key] = value", + which means duplicate keys will cause an exception (instead of retaining the final value); if + a proto schema is emitted, it will be produced using "repeated" instead of "map" + + + + + Declares a member to be used in protocol-buffer serialization, using + the given Tag. A DataFormat may be used to optimise the serialization + format (for instance, using zigzag encoding for negative numbers, or + fixed-length encoding for large values. + + + + + Compare with another ProtoMemberAttribute for sorting purposes + + + + + Compare with another ProtoMemberAttribute for sorting purposes + + + + + Creates a new ProtoMemberAttribute instance. + + Specifies the unique tag used to identify this member within the type. + + + + Gets or sets the original name defined in the .proto; not used + during serialization. + + + + + Gets or sets the data-format to be used when encoding this value. + + + + + Gets the unique tag used to identify this member within the type. + + + + + Gets or sets a value indicating whether this member is mandatory. + + + + + Gets a value indicating whether this member is packed. + This option only applies to list/array data of primitive types (int, double, etc). + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Enables full object-tracking/full-graph support. + + + + + Embeds the type information into the stream, allowing usage with types not known in advance. + + + + + Gets or sets a value indicating whether this member is packed (lists/arrays). + + + + + Additional (optional) settings that control serialization of members + + + + + Default; no additional options + + + + + Indicates that repeated elements should use packed (length-prefixed) encoding + + + + + Indicates that the given item is required + + + + + Enables full object-tracking/full-graph support + + + + + Embeds the type information into the stream, allowing usage with types not known in advance + + + + + Indicates whether this field should *repace* existing values (the default is false, meaning *append*). + This option only applies to list/array data. + + + + + Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used + + + + + Declares a member to be used in protocol-buffer serialization, using + the given Tag and MemberName. This allows ProtoMemberAttribute usage + even for partial classes where the individual members are not + under direct control. + A DataFormat may be used to optimise the serialization + format (for instance, using zigzag encoding for negative numbers, or + fixed-length encoding for large values. + + + + + Creates a new ProtoMemberAttribute instance. + + Specifies the unique tag used to identify this member within the type. + Specifies the member to be serialized. + + + + The name of the member to be serialized. + + + + + A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call + ReadFieldHeader and (after matching the field) an appropriate Read* method. + + + + + Gets the number of the field being processed. + + + + + Indicates the underlying proto serialization format on the wire. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + + + + Gets / sets a flag indicating whether strings should be checked for repetition; if + true, any repeated UTF-8 byte sequence will result in the same String instance, rather + than a second instance of the same string. Enabled by default. Note that this uses + a custom interner - the system-wide string interner is not used. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Addition information about this deserialization operation. + + + + + Releases resources used by the reader, but importantly does not Dispose the + underlying stream; in many typical use-cases the stream is used for different + processes, so it is assumed that the consumer will Dispose their stream separately. + + + + + Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Returns the position of the current reader (note that this is not necessarily the same as the position + in the underlying stream, if multiple readers are used on the same stream) + + + + + Returns the position of the current reader (note that this is not necessarily the same as the position + in the underlying stream, if multiple readers are used on the same stream) + + + + + Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Reads a string from the stream (using UTF8); supported wire-types: String + + + + + Throws an exception indication that the given value cannot be mapped to an enum. + + + + + Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64 + + + + + Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between) + parsing the message in accordance with the model associated with the reader + + + + + Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup + marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader + should return zero) + + + + + Begins consuming a nested message in the stream; supported wire-types: StartGroup, String + + The token returned must be help and used when callining EndSubItem + + + + Reads a field header from the stream, setting the wire-type and retuning the field number. If no + more fields are available, then 0 is returned. This methods respects sub-messages. + + + + + Looks ahead to see whether the next field in the stream is what we expect + (typically; what we've just finished reading - for example ot read successive list items) + + + + + Get the TypeModel associated with this reader + + + + + Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example, + a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made. + + + + + Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example, + SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown. + + + + + Discards the data for the current field. + + + + + Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64 + + + + + Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + + Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + + Reads a little-endian encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a big-endian encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a varint encoded integer. An exception is thrown if the data is not all available. + + + + + Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available. + + + + + Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available. + + + + + Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available. + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + + Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length + reader to be created. + + + + The number of bytes consumed; 0 if no data available + + + + Copies the current field into the instance as extension data + + + + + Indicates whether the reader still has data remaining in the current sub-item, + additionally setting the wire-type for the next field if there is more data. + This is used when decoding packed data. + + + + + Utility method, not intended for public use; this helps maintain the root object is complex scenarios + + + + + Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String + + + + + Merge two objects using the details from the current reader; this is used to change the type + of objects when an inheritance relationship is discovered later than usual during deserilazation. + + + + + Creates a new reader against a stream + + The source stream + The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects + Additional context about this serialization operation + The number of bytes to read, or -1 to read until the end of the stream + + + + Represents an output stream for writing protobuf data. + + Why is the API backwards (static methods with writer arguments)? + See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html + + + + + Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). + + The object to write. + The key that uniquely identifies the type within the model. + The destination. + + + + Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the + caller is asserting that this relationship is non-recursive; no recursion check will be + performed. + + The object to write. + The key that uniquely identifies the type within the model. + The destination. + + + + Writes a field-header, indicating the format of the next data we plan to write. + + + + + Writes a byte-array to the stream; supported wire-types: String + + + + + Writes a byte-array to the stream; supported wire-types: String + + + + + Indicates the start of a nested record. + + The instance to write. + The destination. + A token representing the state of the stream; this token is given to EndSubItem. + + + + Indicates the end of a nested record. + + The token obtained from StartubItem. + The destination. + + + + Creates a new writer against a stream + + The destination stream + The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects + Additional context about this serialization operation + + + + Creates a new writer against a stream + + The destination stream + The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects + Additional context about this serialization operation + + + + Addition information about this serialization operation. + + + + + Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed + by this operation. + + + + + Get the TypeModel associated with this writer + + + + + Writes any buffered data (if possible) to the underlying stream. + + The writer to flush + It is not always possible to fully flush, since some sequences + may require values to be back-filled into the byte-stream. + + + + Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a string to the stream; supported wire-types: String + + + + + Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant + + + + + Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 + + + + + Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 + + + + + Throws an exception indicating that the given enum cannot be mapped to a serialized value. + + + + + Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 + + + + + Copies any extension data stored for the instance to the underlying stream + + + + + Used for packed encoding; indicates that the next field should be skipped rather than + a field header written. Note that the field number must match, else an exception is thrown + when the attempt is made to write the (incorrect) field. The wire-type is taken from the + subsequent call to WriteFieldHeader. Only primitive types can be packed. + + + + + Used for packed encoding; explicitly reset the packed field marker; this is not required + if using StartSubItem/EndSubItem + + + + + Used for packed encoding; writes the length prefix using fixed sizes rather than using + buffering. Only valid for fixed-32 and fixed-64 encoding. + + + + + Specifies a known root object to use during reference-tracked serialization + + + + + Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String + + + + + Additional information about a serialization operation + + + + + Gets or sets a user-defined object containing additional information about this serialization/deserialization operation. + + + + + A default SerializationContext, with minimal information. + + + + + Gets or sets the source or destination of the transmitted data. + + + + + Convert a SerializationContext to a StreamingContext + + + + + Convert a StreamingContext to a SerializationContext + + + + + Provides protocol-buffer serialization capability for concrete, attributed types. This + is a *default* model, but custom serializer models are also supported. + + + Protocol-buffer serialization is a compact binary format, designed to take + advantage of sparse data and knowledge of specific data types; it is also + extensible, allowing a type to be deserialized / merged even if some data is + not recognised. + + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for + The .proto definition as a string + + + + Suggest a .proto definition for the given type + + The type to generate a .proto definition for + The .proto definition as a string + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Applies a protocol-buffer stream to an existing instance. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Serializes a given instance and deserializes it as a different type; + this can be used to translate between wire-compatible objects (where + two .NET types represent the same data), or to promote/demote a type + through an inheritance hierarchy. + + No assumption of compatibility is made between the types. + The type of the object being copied. + The type of the new object to be created. + The existing instance to use as a template. + A new instane of type TNewType, with the data from TOldType. + + + + Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination SerializationInfo to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination SerializationInfo to write to. + Additional information about this serialization operation. + + + + Writes a protocol-buffer representation of the given instance to the supplied XmlWriter. + + The type being serialized. + The existing instance to be serialized (cannot be null). + The destination XmlWriter to write to. + + + + Applies a protocol-buffer from an XmlReader to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The XmlReader containing the data to apply to the instance (cannot be null). + + + + Applies a protocol-buffer from a SerializationInfo to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The SerializationInfo containing the data to apply to the instance (cannot be null). + + + + Applies a protocol-buffer from a SerializationInfo to an existing instance. + + The type being merged. + The existing instance to be modified (cannot be null). + The SerializationInfo containing the data to apply to the instance (cannot be null). + Additional information about this serialization operation. + + + + Precompiles the serializer for a given type. + + + + + Creates a new IFormatter that uses protocol-buffer [de]serialization. + + The type of object to be [de]deserialized by the formatter. + A new IFormatter to be used during [de]serialization. + + + + Reads a sequence of consecutive length-prefixed items from a stream, using + either base-128 or fixed-length prefixes. Base-128 prefixes with a tag + are directly comparable to serializing multiple items in succession + (use the tag to emulate the implicit behavior + when serializing a list/array). When a tag is + specified, any records with different tags are silently omitted. The + tag is ignored. The tag is ignored for fixed-length prefixes. + + The type of object to deserialize. + The binary stream containing the serialized records. + The prefix style used in the data. + The tag of records to return (if non-positive, then no tag is + expected and all records are returned). + The sequence of deserialized objects. + + + + Creates a new instance from a protocol-buffer stream that has a length-prefix + on data (to assist with network IO). + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + How to encode the length prefix. + A new, initialized instance. + + + + Creates a new instance from a protocol-buffer stream that has a length-prefix + on data (to assist with network IO). + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + How to encode the length prefix. + The expected tag of the item (only used with base-128 prefix style). + A new, initialized instance. + + + + Applies a protocol-buffer stream to an existing instance, using length-prefixed + data - useful with network IO. + + The type being merged. + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The type being serialized. + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + Indicates the number of bytes expected for the next message. + The stream containing the data to investigate for a length. + The algorithm used to encode the length. + The length of the message, if it could be identified. + True if a length could be obtained, false otherwise. + + + Indicates the number of bytes expected for the next message. + The buffer containing the data to investigate for a length. + The offset of the first byte to read from the buffer. + The number of bytes to read from the buffer. + The algorithm used to encode the length. + The length of the message, if it could be identified. + True if a length could be obtained, false otherwise. + + + + The field number that is used as a default when serializing/deserializing a list of objects. + The data is treated as repeated message with field number 1. + + + + + Provides non-generic access to the default serializer. + + + + + Create a deep clone of the supplied instance; any sub-items are also cloned. + + + + + Writes a protocol-buffer representation of the given instance to the supplied stream. + + The existing instance to be serialized (cannot be null). + The destination stream to write to. + + + + Creates a new instance from a protocol-buffer stream + + The type to be created. + The binary stream to apply to the new instance (cannot be null). + A new, initialized instance. + + + Applies a protocol-buffer stream to an existing instance. + The existing instance to be modified (cannot be null). + The binary stream to apply to the instance (cannot be null). + The updated instance + + + + Writes a protocol-buffer representation of the given instance to the supplied stream, + with a length-prefix. This is useful for socket programming, + as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back + from an ongoing stream. + + The existing instance to be serialized (cannot be null). + How to encode the length prefix. + The destination stream to write to. + The tag used as a prefix to each record (only used with base-128 style prefixes). + + + + Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed + data - useful with network IO. + + The existing instance to be modified (can be null). + The binary stream to apply to the instance (cannot be null). + How to encode the length prefix. + Used to resolve types on a per-field basis. + The updated instance; this may be different to the instance argument if + either the original instance was null, or the stream defines a known sub-type of the + original instance. + + + + Indicates whether the supplied type is explicitly modelled by the model + + + + + Precompiles the serializer for a given type. + + + + + Global switches that change the behavior of protobuf-net + + + + + + + + + + Maps a field-number to a type + + + + + Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization + operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense + of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers). + + + + + The type that this serializer is intended to work for. + + + + + Perform the steps necessary to serialize this data. + + The value to be serialized. + The writer entity that is accumulating the output data. + + + + Perform the steps necessary to deserialize this data. + + The current value, if appropriate. + The reader providing the input data. + The updated / replacement value. + + + + Indicates whether a Read operation replaces the existing value, or + extends the value. If false, the "value" parameter to Read is + discarded, and should be passed in as null. + + + + + Now all Read operations return a value (although most do); if false no + value should be expected. + + + + Emit the IL necessary to perform the given actions + to serialize this data. + + Details and utilities for the method being generated. + The source of the data to work against; + If the value is only needed once, then LoadValue is sufficient. If + the value is needed multiple times, then note that a "null" + means "the top of the stack", in which case you should create your + own copy - GetLocalWithValue. + + + + Emit the IL necessary to perform the given actions to deserialize this data. + + Details and utilities for the method being generated. + For nested values, the instance holding the values; note + that this is not always provided - a null means not supplied. Since this is always + a variable or argument, it is not necessary to consume this value. + + + + Uses protocol buffer serialization on the specified operation; note that this + must be enabled on both the client and server. + + + + + Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. + + + + + + Creates a new ProtoBehaviorExtension instance. + + + + + Gets the type of behavior. + + + + + Creates a behavior extension based on the current configuration settings. + + The behavior extension. + + + + Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. + + Add the following to the server and client app.config in the system.serviceModel section: + + + + + + + + + + + + + + Configure your endpoints to have a behaviorConfiguration as follows: + + + + + + + + + + + + + Describes a WCF operation behaviour that can perform protobuf serialization + + + + + Create a new ProtoOperationBehavior instance + + + + + The type-model that should be used with this behaviour + + + + + Creates a protobuf serializer if possible (falling back to the default WCF serializer) + + + + + An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[]) + + + + + Attempt to create a new serializer for the given model and type + + A new serializer instance if the type is recognised by the model; null otherwise + + + + Creates a new serializer for the given model and type + + + + + Ends an object in the output + + + + + Begins an object in the output + + + + + Writes the body of an object in the output + + + + + Indicates whether this is the start of an object we are prepared to handle + + + + + Reads the body of an object + + + + + Used to hold particulars relating to nested objects. This is opaque to the caller - simply + give back the token you are given at the end of an object. + + + + + Indicates the encoding used to represent an individual value in a protobuf stream + + + + + Represents an error condition + + + + + Base-128 variant-length encoding + + + + + Fixed-length 8-byte encoding + + + + + Length-variant-prefixed encoding + + + + + Indicates the start of a group + + + + + Indicates the end of a group + + + + + Fixed-length 4-byte encoding + 10 + + + + This is not a formal wire-type in the "protocol buffers" spec, but + denotes a variant integer that should be interpreted using + zig-zag semantics (so -ve numbers aren't a significant overhead) + + + + diff --git a/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.exe b/Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.exe new file mode 100644 index 0000000000000000000000000000000000000000..c875ab45606bb552da67a4010020415a4031c935 GIT binary patch literal 16384 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 + + + protogen + + + +