mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-14 16:51:28 +00:00
Update
Update
This commit is contained in:
8
Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta
Normal file
8
Assets/TEngine/Scripts/Editor/Helper/ProtoGenTools.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4843da953596d1546bc7ccc26fb5e3b3
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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<OpcodeInfo> msgOpcode = new List<OpcodeInfo>();
|
||||||
|
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9035b84a2db6d8142a2e10604836e302
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -1,67 +1,67 @@
|
|||||||
// using UnityEditor;
|
using UnityEditor;
|
||||||
// using UnityEngine;
|
using UnityEngine;
|
||||||
// using TEngine.Runtime;
|
using TEngine.Runtime;
|
||||||
//
|
|
||||||
// namespace TEngine.Editor
|
namespace TEngine.Editor
|
||||||
// {
|
{
|
||||||
// [CustomEditor(typeof(TEngine.Runtime.Network))]
|
[CustomEditor(typeof(TEngine.Runtime.Network))]
|
||||||
// internal sealed class NetworkComponentInspector : TEngineInspector
|
internal sealed class NetworkComponentInspector : TEngineInspector
|
||||||
// {
|
{
|
||||||
// public override void OnInspectorGUI()
|
public override void OnInspectorGUI()
|
||||||
// {
|
{
|
||||||
// base.OnInspectorGUI();
|
base.OnInspectorGUI();
|
||||||
//
|
|
||||||
// if (!EditorApplication.isPlaying)
|
if (!EditorApplication.isPlaying)
|
||||||
// {
|
{
|
||||||
// EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
EditorGUILayout.HelpBox("Available during runtime only.", MessageType.Info);
|
||||||
// return;
|
return;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// TEngine.Runtime.Network t = (TEngine.Runtime.Network)target;
|
TEngine.Runtime.Network t = (TEngine.Runtime.Network)target;
|
||||||
//
|
|
||||||
// if (IsPrefabInHierarchy(t.gameObject))
|
if (IsPrefabInHierarchy(t.gameObject))
|
||||||
// {
|
{
|
||||||
// EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
|
EditorGUILayout.LabelField("Network Channel Count", t.NetworkChannelCount.ToString());
|
||||||
//
|
|
||||||
// INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
|
INetworkChannel[] networkChannels = t.GetAllNetworkChannels();
|
||||||
// foreach (INetworkChannel networkChannel in networkChannels)
|
foreach (INetworkChannel networkChannel in networkChannels)
|
||||||
// {
|
{
|
||||||
// DrawNetworkChannel(networkChannel);
|
DrawNetworkChannel(networkChannel);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// Repaint();
|
Repaint();
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// private void OnEnable()
|
private void OnEnable()
|
||||||
// {
|
{
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// private void DrawNetworkChannel(INetworkChannel networkChannel)
|
private void DrawNetworkChannel(INetworkChannel networkChannel)
|
||||||
// {
|
{
|
||||||
// EditorGUILayout.BeginVertical("box");
|
EditorGUILayout.BeginVertical("box");
|
||||||
// {
|
{
|
||||||
// EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
|
EditorGUILayout.LabelField(networkChannel.Name, networkChannel.Connected ? "Connected" : "Disconnected");
|
||||||
// EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
|
EditorGUILayout.LabelField("Service Type", networkChannel.ServiceType.ToString());
|
||||||
// EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
|
EditorGUILayout.LabelField("Address Family", networkChannel.AddressFamily.ToString());
|
||||||
// EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
|
EditorGUILayout.LabelField("Local Address", networkChannel.Connected ? networkChannel.Socket.LocalEndPoint.ToString() : "Unavailable");
|
||||||
// EditorGUILayout.LabelField("Remote Address", networkChannel.Connected ? networkChannel.Socket.RemoteEndPoint.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("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("Receive Packet", Utility.Text.Format("{0} / {1}", networkChannel.ReceivedPacketCount.ToString(), networkChannel.ReceivedPacketCount.ToString()));
|
||||||
// EditorGUILayout.LabelField("Miss Heart Beat Count", networkChannel.MissHeartBeatCount.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")));
|
EditorGUILayout.LabelField("Heart Beat", Utility.Text.Format("{0} / {1}", networkChannel.HeartBeatElapseSeconds.ToString("F2"), networkChannel.HeartBeatInterval.ToString("F2")));
|
||||||
// EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
|
EditorGUI.BeginDisabledGroup(!networkChannel.Connected);
|
||||||
// {
|
{
|
||||||
// if (GUILayout.Button("Disconnect"))
|
if (GUILayout.Button("Disconnect"))
|
||||||
// {
|
{
|
||||||
// networkChannel.Close();
|
networkChannel.Close();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
// }
|
}
|
||||||
// EditorGUILayout.EndVertical();
|
EditorGUILayout.EndVertical();
|
||||||
//
|
|
||||||
// EditorGUILayout.Separator();
|
EditorGUILayout.Separator();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
@@ -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("<b>Network Information</b>");
|
||||||
|
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("<b>Network Channel: {0} ({1})</b>", 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 499fb65f1b784d4c912050bf3c1b54d3
|
||||||
|
timeCreated: 1661930992
|
@@ -189,7 +189,7 @@ namespace TEngine.Runtime
|
|||||||
private RuntimeMemoryInformationWindow<ScriptableObject> m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow<ScriptableObject>();
|
private RuntimeMemoryInformationWindow<ScriptableObject> m_RuntimeMemoryScriptableObjectInformationWindow = new RuntimeMemoryInformationWindow<ScriptableObject>();
|
||||||
|
|
||||||
private MemoryPoolInformationWindow m_MemoryPoolInformationWindow = new MemoryPoolInformationWindow();
|
private MemoryPoolInformationWindow m_MemoryPoolInformationWindow = new MemoryPoolInformationWindow();
|
||||||
// private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow();
|
private NetworkInformationWindow m_NetworkInformationWindow = new NetworkInformationWindow();
|
||||||
|
|
||||||
private SettingsWindow m_SettingsWindow = new SettingsWindow();
|
private SettingsWindow m_SettingsWindow = new SettingsWindow();
|
||||||
#endregion
|
#endregion
|
||||||
@@ -229,7 +229,7 @@ namespace TEngine.Runtime
|
|||||||
RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow);
|
RegisterDebuggerWindow("Profiler/Memory/ScriptableObject", m_RuntimeMemoryScriptableObjectInformationWindow);
|
||||||
|
|
||||||
RegisterDebuggerWindow("Profiler/Memory Pool", m_MemoryPoolInformationWindow);
|
RegisterDebuggerWindow("Profiler/Memory Pool", m_MemoryPoolInformationWindow);
|
||||||
// RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow);
|
RegisterDebuggerWindow("Profiler/Network", m_NetworkInformationWindow);
|
||||||
|
|
||||||
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
|
RegisterDebuggerWindow("Other/Settings", m_SettingsWindow);
|
||||||
|
|
||||||
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 38e14d7bbaa74254198afb9c1df69a30
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b9fbba9291a686a4485a94f19febffd1
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,23 @@
|
|||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络地址类型。
|
||||||
|
/// </summary>
|
||||||
|
public enum AddressFamily : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 未知。
|
||||||
|
/// </summary>
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IP 版本 4。
|
||||||
|
/// </summary>
|
||||||
|
IPv4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IP 版本 6。
|
||||||
|
/// </summary>
|
||||||
|
IPv6
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6f0c907c7aeb4bd2a19ff78ad8e8b668
|
||||||
|
timeCreated: 1661772419
|
@@ -0,0 +1,144 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络频道接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface INetworkChannel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道名称。
|
||||||
|
/// </summary>
|
||||||
|
string Name
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道所使用的 Socket。
|
||||||
|
/// </summary>
|
||||||
|
Socket Socket
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取是否已连接。
|
||||||
|
/// </summary>
|
||||||
|
bool Connected
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
ServiceType ServiceType
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络地址类型。
|
||||||
|
/// </summary>
|
||||||
|
AddressFamily AddressFamily
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取要发送的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
int SendPacketCount
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取累计发送的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
int SentPacketCount
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取累计已接收的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
int ReceivedPacketCount
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置当收到消息包时是否重置心跳流逝时间。
|
||||||
|
/// </summary>
|
||||||
|
bool ResetHeartBeatElapseSecondsWhenReceivePacket
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取丢失心跳的次数。
|
||||||
|
/// </summary>
|
||||||
|
int MissHeartBeatCount
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置心跳间隔时长,以秒为单位。
|
||||||
|
/// </summary>
|
||||||
|
float HeartBeatInterval
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取心跳等待时长,以秒为单位。
|
||||||
|
/// </summary>
|
||||||
|
float HeartBeatElapseSeconds
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册网络消息包处理函数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actionId"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
void RegisterHandler(int actionId, CsMsgDelegate msgDelegate);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
void Connect(IPAddress ipAddress, int port);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
|
void Connect(IPAddress ipAddress, int port, object userData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭网络频道。
|
||||||
|
/// </summary>
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向远程主机发送消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">消息包类型。</typeparam>
|
||||||
|
/// <param name="packet">要发送的消息包。</param>
|
||||||
|
void Send<T>(T packet) where T : Packet;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c66ee24862094df49e089d63f7481285
|
||||||
|
timeCreated: 1661771701
|
@@ -0,0 +1,66 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络频道辅助器接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface INetworkChannelHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取消息包头长度。
|
||||||
|
/// </summary>
|
||||||
|
int PacketHeaderLength
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道辅助器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="networkChannel">网络频道。</param>
|
||||||
|
void Initialize(INetworkChannel networkChannel);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭并清理网络频道辅助器。
|
||||||
|
/// </summary>
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 准备进行连接。
|
||||||
|
/// </summary>
|
||||||
|
void PrepareForConnecting();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送心跳消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>是否发送心跳消息包成功。</returns>
|
||||||
|
bool SendHeartBeat();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">消息包类型。</typeparam>
|
||||||
|
/// <param name="packet">要序列化的消息包。</param>
|
||||||
|
/// <param name="destination">要序列化的目标流。</param>
|
||||||
|
/// <returns>是否序列化成功。</returns>
|
||||||
|
bool Serialize<T>(T packet, Stream destination) where T : Packet;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化消息包头。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">要反序列化的来源流。</param>
|
||||||
|
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||||
|
/// <returns>反序列化后的消息包头。</returns>
|
||||||
|
IPacketHeader DeserializePacketHeader(Stream source, out object customErrorData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packetHeader">消息包头。</param>
|
||||||
|
/// <param name="source">要反序列化的来源流。</param>
|
||||||
|
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||||
|
/// <returns>反序列化后的消息包。</returns>
|
||||||
|
Packet DeserializePacket(IPacketHeader packetHeader, Stream source, out object customErrorData);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aeff0f53fdd54bd489d6a6141e79dca0
|
||||||
|
timeCreated: 1661771934
|
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络管理器接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface INetworkManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道数量。
|
||||||
|
/// </summary>
|
||||||
|
int NetworkChannelCount
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络连接成功事件。
|
||||||
|
/// </summary>
|
||||||
|
event Action<INetworkChannel, object> NetworkConnected;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络连接关闭事件。
|
||||||
|
/// </summary>
|
||||||
|
event Action<INetworkChannel> NetworkClosed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络心跳包丢失事件。
|
||||||
|
/// </summary>
|
||||||
|
event Action<INetworkChannel, int> NetworkMissHeartBeat;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络错误事件。
|
||||||
|
/// </summary>
|
||||||
|
event Action<INetworkChannel, NetworkErrorCode, string> NetworkError;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户自定义网络错误事件。
|
||||||
|
/// </summary>
|
||||||
|
event Action<INetworkChannel, object> NetworkCustomError;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否存在网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否存在网络频道。</returns>
|
||||||
|
bool HasNetworkChannel(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>要获取的网络频道。</returns>
|
||||||
|
INetworkChannel GetNetworkChannel(string name);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有网络频道。</returns>
|
||||||
|
INetworkChannel[] GetAllNetworkChannels();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">所有网络频道。</param>
|
||||||
|
void GetAllNetworkChannels(List<INetworkChannel> results);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="serviceType">网络服务类型。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
/// <returns>要创建的网络频道。</returns>
|
||||||
|
INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否销毁网络频道成功。</returns>
|
||||||
|
bool DestroyNetworkChannel(string name);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aa9566de56cd4b579631a1725b89174e
|
||||||
|
timeCreated: 1661775465
|
@@ -0,0 +1,16 @@
|
|||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络消息包头接口。
|
||||||
|
/// </summary>
|
||||||
|
public interface IPacketHeader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络消息包长度。
|
||||||
|
/// </summary>
|
||||||
|
int PacketLength
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1a61d331daf74fe48bffbb083f016cb5
|
||||||
|
timeCreated: 1661771898
|
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 007c9ae2d35f4d6181f53cf3e5738884
|
||||||
|
timeCreated: 1661930441
|
157
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs
Normal file
157
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Network.cs
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络组件。
|
||||||
|
/// </summary>
|
||||||
|
[DisallowMultipleComponent]
|
||||||
|
[AddComponentMenu("TEngine/Network")]
|
||||||
|
public class Network : UnitySingleton<Network>
|
||||||
|
{
|
||||||
|
private INetworkManager m_NetworkManager = null;
|
||||||
|
|
||||||
|
public NetworkManager NetworkManager
|
||||||
|
{
|
||||||
|
private set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道数量。
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否存在网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否存在网络频道。</returns>
|
||||||
|
public bool HasNetworkChannel(string name)
|
||||||
|
{
|
||||||
|
return m_NetworkManager.HasNetworkChannel(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>要获取的网络频道。</returns>
|
||||||
|
public INetworkChannel GetNetworkChannel(string name)
|
||||||
|
{
|
||||||
|
return m_NetworkManager.GetNetworkChannel(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有网络频道。</returns>
|
||||||
|
public INetworkChannel[] GetAllNetworkChannels()
|
||||||
|
{
|
||||||
|
return m_NetworkManager.GetAllNetworkChannels();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">所有网络频道。</param>
|
||||||
|
public void GetAllNetworkChannels(List<INetworkChannel> results)
|
||||||
|
{
|
||||||
|
m_NetworkManager.GetAllNetworkChannels(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="serviceType">网络服务类型。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
/// <returns>要创建的网络频道。</returns>
|
||||||
|
public INetworkChannel CreateNetworkChannel(string name, ServiceType serviceType, INetworkChannelHelper networkChannelHelper)
|
||||||
|
{
|
||||||
|
return m_NetworkManager.CreateNetworkChannel(name, serviceType, networkChannelHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否销毁网络频道成功。</returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1dd2b00e963a5b54db7aae1b87628982
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,53 @@
|
|||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络错误码。
|
||||||
|
/// </summary>
|
||||||
|
public enum NetworkErrorCode : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 未知错误。
|
||||||
|
/// </summary>
|
||||||
|
Unknown = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 地址族错误。
|
||||||
|
/// </summary>
|
||||||
|
AddressFamilyError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Socket 错误。
|
||||||
|
/// </summary>
|
||||||
|
SocketError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接错误。
|
||||||
|
/// </summary>
|
||||||
|
ConnectError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送错误。
|
||||||
|
/// </summary>
|
||||||
|
SendError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收错误。
|
||||||
|
/// </summary>
|
||||||
|
ReceiveError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化错误。
|
||||||
|
/// </summary>
|
||||||
|
SerializeError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化消息包头错误。
|
||||||
|
/// </summary>
|
||||||
|
DeserializePacketHeaderError,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化消息包错误。
|
||||||
|
/// </summary>
|
||||||
|
DeserializePacketError
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 86fe9208ee30402ab1fcdc8cdcff1d89
|
||||||
|
timeCreated: 1661771970
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 07167c4e7b24c2148acdfe52fbe0c817
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e1beec3505229bd418c252c142a01152
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络频道基类。
|
||||||
|
/// </summary>
|
||||||
|
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<Packet> 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<NetworkChannelBase, object> NetworkChannelConnected;
|
||||||
|
public Action<NetworkChannelBase> NetworkChannelClosed;
|
||||||
|
public Action<NetworkChannelBase, int> NetworkChannelMissHeartBeat;
|
||||||
|
public Action<NetworkChannelBase, NetworkErrorCode, SocketError, string> NetworkChannelError;
|
||||||
|
public Action<NetworkChannelBase, object> NetworkChannelCustomError;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 委托注册队列
|
||||||
|
/// </summary>
|
||||||
|
protected Dictionary<int, List<CsMsgDelegate>> m_MapCmdHandle = new Dictionary<int, List<CsMsgDelegate>>();
|
||||||
|
/// <summary>
|
||||||
|
/// 委托缓存堆栈
|
||||||
|
/// </summary>
|
||||||
|
protected Queue<List<CsMsgDelegate>> m_CachelistHandle = new Queue<List<CsMsgDelegate>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 消息包缓存堆栈
|
||||||
|
/// </summary>
|
||||||
|
protected Queue<MainPack> m_QueuepPacks = new Queue<MainPack>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道基类的新实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
public NetworkChannelBase(string name, INetworkChannelHelper networkChannelHelper)
|
||||||
|
{
|
||||||
|
m_Name = name ?? string.Empty;
|
||||||
|
m_SendPacketPool = new Queue<Packet>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道名称。
|
||||||
|
/// </summary>
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道所使用的 Socket。
|
||||||
|
/// </summary>
|
||||||
|
public Socket Socket
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_Socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取是否已连接。
|
||||||
|
/// </summary>
|
||||||
|
public bool Connected
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_Socket != null)
|
||||||
|
{
|
||||||
|
return m_Socket.Connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
public abstract ServiceType ServiceType
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络地址类型。
|
||||||
|
/// </summary>
|
||||||
|
public AddressFamily AddressFamily
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_AddressFamily;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取要发送的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
public int SendPacketCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_SendPacketPool.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取累计发送的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
public int SentPacketCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_SentPacketCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取累计已接收的消息包数量。
|
||||||
|
/// </summary>
|
||||||
|
public int ReceivedPacketCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_ReceivedPacketCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置当收到消息包时是否重置心跳流逝时间。
|
||||||
|
/// </summary>
|
||||||
|
public bool ResetHeartBeatElapseSecondsWhenReceivePacket
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_ResetHeartBeatElapseSecondsWhenReceivePacket;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_ResetHeartBeatElapseSecondsWhenReceivePacket = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取丢失心跳的次数。
|
||||||
|
/// </summary>
|
||||||
|
public int MissHeartBeatCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_HeartBeatState.MissHeartBeatCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取或设置心跳间隔时长,以秒为单位。
|
||||||
|
/// </summary>
|
||||||
|
public float HeartBeatInterval
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_HeartBeatInterval;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_HeartBeatInterval = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取心跳等待时长,以秒为单位。
|
||||||
|
/// </summary>
|
||||||
|
public float HeartBeatElapseSeconds
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_HeartBeatState.HeartBeatElapseSeconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络频道轮询。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||||
|
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭网络频道。
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Shutdown()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
m_NetworkChannelHelper.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 注册网络消息包处理函数。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actionId"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
/// <exception cref="Exception"></exception>
|
||||||
|
public void RegisterHandler(int actionId, CsMsgDelegate msgDelegate)
|
||||||
|
{
|
||||||
|
if (msgDelegate == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Packet handler is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
if (!m_MapCmdHandle.TryGetValue(actionId, out listHandle))
|
||||||
|
{
|
||||||
|
listHandle = new List<CsMsgDelegate>();
|
||||||
|
m_MapCmdHandle[actionId] = listHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listHandle != null)
|
||||||
|
{
|
||||||
|
if (!listHandle.Contains(msgDelegate))
|
||||||
|
{
|
||||||
|
listHandle.Add(msgDelegate);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning("-------------repeat RegCmdHandle ActionCode:{0}-----------", (ActionCode)actionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移除消息处理函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actionId"></param>
|
||||||
|
/// <param name="msgDelegate"></param>
|
||||||
|
public void RmvHandler(int actionId, CsMsgDelegate msgDelegate)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
if (!m_MapCmdHandle.TryGetValue(actionId, out listHandle))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listHandle != null)
|
||||||
|
{
|
||||||
|
listHandle.Remove(msgDelegate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
public void Connect(IPAddress ipAddress, int port)
|
||||||
|
{
|
||||||
|
Connect(ipAddress, port, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭连接并释放所有相关资源。
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 向远程主机发送消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">消息包类型。</typeparam>
|
||||||
|
/// <param name="packet">要发送的消息包。</param>
|
||||||
|
public void Send<T>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放资源。
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 释放资源。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">释放资源标记。</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络消息回调,非主线程
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pack"></param>
|
||||||
|
public void HandleResponse(MainPack pack)
|
||||||
|
{
|
||||||
|
lock (m_CachelistHandle)
|
||||||
|
{
|
||||||
|
List<CsMsgDelegate> listHandle;
|
||||||
|
|
||||||
|
if (m_MapCmdHandle.TryGetValue((int)pack.actioncode, out listHandle))
|
||||||
|
{
|
||||||
|
m_CachelistHandle.Enqueue(listHandle);
|
||||||
|
|
||||||
|
m_QueuepPacks.Enqueue(pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 主线程从消息包缓存堆栈/委托缓存堆栈中出列
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d124c3d2afc7006459e261c8d510711c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4a8a0b968c7b38442ae9bbf523e6f234
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 01a1e8d0d67bac34a9d5ea40a96bb0eb
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,340 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络管理器。
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class NetworkManager : INetworkManager
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, NetworkChannelBase> m_NetworkChannels;
|
||||||
|
|
||||||
|
private Action<INetworkChannel, object> m_NetworkConnectedEventHandler;
|
||||||
|
private Action<INetworkChannel> m_NetworkClosedEventHandler;
|
||||||
|
private Action<INetworkChannel, int> m_NetworkMissHeartBeatEventHandler;
|
||||||
|
private Action<INetworkChannel, NetworkErrorCode, string> m_NetworkErrorEventHandler;
|
||||||
|
private Action<INetworkChannel, object> m_NetworkCustomErrorEventHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络管理器的新实例。
|
||||||
|
/// </summary>
|
||||||
|
public NetworkManager()
|
||||||
|
{
|
||||||
|
m_NetworkChannels = new Dictionary<string, NetworkChannelBase>(StringComparer.Ordinal);
|
||||||
|
m_NetworkConnectedEventHandler = null;
|
||||||
|
m_NetworkClosedEventHandler = null;
|
||||||
|
m_NetworkMissHeartBeatEventHandler = null;
|
||||||
|
m_NetworkErrorEventHandler = null;
|
||||||
|
m_NetworkCustomErrorEventHandler = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道数量。
|
||||||
|
/// </summary>
|
||||||
|
public int NetworkChannelCount
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_NetworkChannels.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络连接成功事件。
|
||||||
|
/// </summary>
|
||||||
|
public event Action<INetworkChannel, object> NetworkConnected
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
m_NetworkConnectedEventHandler += value;
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
m_NetworkConnectedEventHandler -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络连接关闭事件。
|
||||||
|
/// </summary>
|
||||||
|
public event Action<INetworkChannel> NetworkClosed
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
m_NetworkClosedEventHandler += value;
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
m_NetworkClosedEventHandler -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络心跳包丢失事件。
|
||||||
|
/// </summary>
|
||||||
|
public event Action<INetworkChannel, int> NetworkMissHeartBeat
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
m_NetworkMissHeartBeatEventHandler += value;
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
m_NetworkMissHeartBeatEventHandler -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络错误事件。
|
||||||
|
/// </summary>
|
||||||
|
public event Action<INetworkChannel, NetworkErrorCode, string> NetworkError
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
m_NetworkErrorEventHandler += value;
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
m_NetworkErrorEventHandler -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户自定义网络错误事件。
|
||||||
|
/// </summary>
|
||||||
|
public event Action<INetworkChannel, object> NetworkCustomError
|
||||||
|
{
|
||||||
|
add
|
||||||
|
{
|
||||||
|
m_NetworkCustomErrorEventHandler += value;
|
||||||
|
}
|
||||||
|
remove
|
||||||
|
{
|
||||||
|
m_NetworkCustomErrorEventHandler -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 网络管理器轮询。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
|
||||||
|
/// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
|
||||||
|
public void Update(float elapseSeconds, float realElapseSeconds)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||||
|
{
|
||||||
|
networkChannel.Value.Update(elapseSeconds, realElapseSeconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭并清理网络管理器。
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, NetworkChannelBase> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查是否存在网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否存在网络频道。</returns>
|
||||||
|
public bool HasNetworkChannel(string name)
|
||||||
|
{
|
||||||
|
return m_NetworkChannels.ContainsKey(name ?? string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>要获取的网络频道。</returns>
|
||||||
|
public INetworkChannel GetNetworkChannel(string name)
|
||||||
|
{
|
||||||
|
NetworkChannelBase networkChannel = null;
|
||||||
|
if (m_NetworkChannels.TryGetValue(name ?? string.Empty, out networkChannel))
|
||||||
|
{
|
||||||
|
return networkChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有网络频道。</returns>
|
||||||
|
public INetworkChannel[] GetAllNetworkChannels()
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
INetworkChannel[] results = new INetworkChannel[m_NetworkChannels.Count];
|
||||||
|
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||||
|
{
|
||||||
|
results[index++] = networkChannel.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="results">所有网络频道。</param>
|
||||||
|
public void GetAllNetworkChannels(List<INetworkChannel> results)
|
||||||
|
{
|
||||||
|
if (results == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Results is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
results.Clear();
|
||||||
|
foreach (KeyValuePair<string, NetworkChannelBase> networkChannel in m_NetworkChannels)
|
||||||
|
{
|
||||||
|
results.Add(networkChannel.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="serviceType">网络服务类型。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
/// <returns>要创建的网络频道。</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 销毁网络频道。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <returns>是否销毁网络频道成功。</returns>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4ea28106108b496bb4b66fd8aa528797
|
||||||
|
timeCreated: 1661772444
|
10
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs
Normal file
10
Assets/TEngine/Scripts/Runtime/Core/NetWork/Core/Packet.cs
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络消息包基类。
|
||||||
|
/// </summary>
|
||||||
|
public abstract class Packet:IMemory
|
||||||
|
{
|
||||||
|
public abstract void Clear();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4d54f03c4aed4afbab3b4fc45def97c5
|
||||||
|
timeCreated: 1661771739
|
@@ -0,0 +1,28 @@
|
|||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
public enum ServiceType : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// TCP 网络服务。
|
||||||
|
/// </summary>
|
||||||
|
Tcp = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用同步接收的 TCP 网络服务。
|
||||||
|
/// </summary>
|
||||||
|
TcpWithSyncReceive,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Udp 网络服务。
|
||||||
|
/// </summary>
|
||||||
|
Udp,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Kcp 网络服务。
|
||||||
|
/// </summary>
|
||||||
|
Kcp,
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 11929818b1dbde74ba521dc2c5d03f49
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Helper.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9de71dee8e9fb74469064a1e1cf7a77b
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using ProtoBuf;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
[Serializable, ProtoContract(Name = @"CSPacketHeader")]
|
||||||
|
public sealed class CSPacketHeader : PacketHeaderBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 383e04755715b054f9e57b1ab1d322af
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取消息包头长度。
|
||||||
|
/// </summary>
|
||||||
|
public int PacketHeaderLength => sizeof(int);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道辅助器。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="networkChannel">网络频道。</param>
|
||||||
|
public void Initialize(INetworkChannel networkChannel)
|
||||||
|
{
|
||||||
|
m_NetworkChannel = networkChannel;
|
||||||
|
|
||||||
|
GameEventMgr.Instance.AddEventListener<INetworkChannel,object>(NetWorkEventId.NetworkConnectedEvent,OnNetworkConnected);
|
||||||
|
GameEventMgr.Instance.AddEventListener<INetworkChannel>(NetWorkEventId.NetworkClosedEvent,OnNetworkClosed);
|
||||||
|
GameEventMgr.Instance.AddEventListener<INetworkChannel,int>(NetWorkEventId.NetworkMissHeartBeatEvent,OnNetworkMissHeartBeat);
|
||||||
|
GameEventMgr.Instance.AddEventListener<INetworkChannel,NetworkErrorCode,string>(NetWorkEventId.NetworkErrorEvent,OnNetworkError);
|
||||||
|
GameEventMgr.Instance.AddEventListener<INetworkChannel,object>(NetWorkEventId.NetworkCustomErrorEvent,OnNetworkCustomError);
|
||||||
|
|
||||||
|
m_NetworkChannel.RegisterHandler((int)ActionCode.HeartBeat,HandleHeartBeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleHeartBeat(MainPack mainPack)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 准备进行连接。
|
||||||
|
/// </summary>
|
||||||
|
public void PrepareForConnecting()
|
||||||
|
{
|
||||||
|
m_NetworkChannel.Socket.ReceiveBufferSize = 1024 * 64;
|
||||||
|
m_NetworkChannel.Socket.SendBufferSize = 1024 * 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发送心跳消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>是否发送心跳消息包成功。</returns>
|
||||||
|
public bool SendHeartBeat()
|
||||||
|
{
|
||||||
|
m_NetworkChannel.Send(CSHeartBeatHandler.AllocHeartBeatPack());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">消息包类型。</typeparam>
|
||||||
|
/// <param name="packet">要序列化的消息包。</param>
|
||||||
|
/// <param name="destination">要序列化的目标流。</param>
|
||||||
|
/// <returns>是否序列化成功。</returns>
|
||||||
|
public bool Serialize<T>(T packet, Stream destination) where T : Packet
|
||||||
|
{
|
||||||
|
m_CachedStream.SetLength(m_CachedStream.Capacity); // 此行防止 Array.Copy 的数据无法写入
|
||||||
|
m_CachedStream.Position = 0L;
|
||||||
|
|
||||||
|
CSPacketHeader packetHeader = MemoryPool.Acquire<CSPacketHeader>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化消息包。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packetHeader">消息包头。</param>
|
||||||
|
/// <param name="source">要反序列化的来源流。</param>
|
||||||
|
/// <param name="customErrorData">用户自定义错误数据。</param>
|
||||||
|
/// <returns>反序列化后的消息包。</returns>
|
||||||
|
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<CSPacketHeader>(), typeof(CSPacketHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 关闭并清理网络频道辅助器。
|
||||||
|
/// </summary>
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
GameEventMgr.Instance.RemoveEventListener<INetworkChannel,object>(NetWorkEventId.NetworkConnectedEvent,OnNetworkConnected);
|
||||||
|
GameEventMgr.Instance.RemoveEventListener<INetworkChannel>(NetWorkEventId.NetworkClosedEvent,OnNetworkClosed);
|
||||||
|
GameEventMgr.Instance.RemoveEventListener<INetworkChannel,int>(NetWorkEventId.NetworkMissHeartBeatEvent,OnNetworkMissHeartBeat);
|
||||||
|
GameEventMgr.Instance.RemoveEventListener<INetworkChannel,NetworkErrorCode,string>(NetWorkEventId.NetworkErrorEvent,OnNetworkError);
|
||||||
|
GameEventMgr.Instance.RemoveEventListener<INetworkChannel,object>(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
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 02d761e658b2dcd4ea9ebff4ce324968
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0396e29af93d424fb252e3cf5a948fa6
|
||||||
|
timeCreated: 1661850708
|
@@ -0,0 +1,28 @@
|
|||||||
|
using TEngineProto;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 心跳Handler
|
||||||
|
/// </summary>
|
||||||
|
public class CSHeartBeatHandler
|
||||||
|
{
|
||||||
|
public static MainPack AllocHeartBeatPack()
|
||||||
|
{
|
||||||
|
var mainPack = MemoryPool.Acquire<MainPack>();
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 553b96ca58c647d39802bed84a356608
|
||||||
|
timeCreated: 1661850718
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 279045bf4ec72144aa03880102a04057
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,49 @@
|
|||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
public class ProtoUtils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 序列化 MainPack -> byte[]
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="mainPack"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static byte[] Serialize<T>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 反序列化
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="buffer"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T DeSerialize<T>(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ab82c8abf14856489102fe60cc78926
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Proto.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9bb2521a45da9104489c2f22445d39fb
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9a93b14384cc75e47b78cb84e7cfb9c1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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> roompack = new List<RoomPack>();
|
||||||
|
|
||||||
|
[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> playerpack = new List<PlayerPack>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cbec49a00bdc11543a0608119cf63810
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Tcp.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bcf0e9cef581b5441ad604bfc2f771c4
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,281 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
public sealed partial class NetworkManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// TCP 网络频道。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class TcpNetworkChannel : NetworkChannelBase
|
||||||
|
{
|
||||||
|
private readonly AsyncCallback m_ConnectCallback;
|
||||||
|
private readonly AsyncCallback m_SendCallback;
|
||||||
|
private readonly AsyncCallback m_ReceiveCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道的新实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
public TcpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||||
|
: base(name, networkChannelHelper)
|
||||||
|
{
|
||||||
|
m_ConnectCallback = ConnectCallback;
|
||||||
|
m_SendCallback = SendCallback;
|
||||||
|
m_ReceiveCallback = ReceiveCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
public override ServiceType ServiceType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ServiceType.Tcp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2df585ebfe0562642b66664dbf0feaaf
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,257 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace TEngine.Runtime
|
||||||
|
{
|
||||||
|
public sealed partial class NetworkManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用同步接收的 TCP 网络频道。
|
||||||
|
/// </summary>
|
||||||
|
private sealed class TcpWithSyncReceiveNetworkChannel : NetworkChannelBase
|
||||||
|
{
|
||||||
|
private readonly AsyncCallback m_ConnectCallback;
|
||||||
|
private readonly AsyncCallback m_SendCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道的新实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
public TcpWithSyncReceiveNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||||
|
: base(name, networkChannelHelper)
|
||||||
|
{
|
||||||
|
m_ConnectCallback = ConnectCallback;
|
||||||
|
m_SendCallback = SendCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
public override ServiceType ServiceType
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ServiceType.TcpWithSyncReceive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 19723c1417631894d90eef482924d87d
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta
Normal file
8
Assets/TEngine/Scripts/Runtime/Core/NetWork/Udp.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 181b125a26149ad4bbc6f270738f37ce
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取网络服务类型。
|
||||||
|
/// </summary>
|
||||||
|
public override ServiceType ServiceType => ServiceType.Udp;
|
||||||
|
|
||||||
|
|
||||||
|
private readonly AsyncCallback m_ConnectCallback;
|
||||||
|
private readonly AsyncCallback m_SendCallback;
|
||||||
|
private readonly AsyncCallback m_ReceiveCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化网络频道的新实例。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">网络频道名称。</param>
|
||||||
|
/// <param name="networkChannelHelper">网络频道辅助器。</param>
|
||||||
|
public UdpNetworkChannel(string name, INetworkChannelHelper networkChannelHelper)
|
||||||
|
: base(name, networkChannelHelper)
|
||||||
|
{
|
||||||
|
m_ConnectCallback = ConnectCallback;
|
||||||
|
m_SendCallback = SendCallback;
|
||||||
|
m_ReceiveCallback = ReceiveCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 连接到远程主机。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ipAddress">远程主机的 IP 地址。</param>
|
||||||
|
/// <param name="port">远程主机的端口号。</param>
|
||||||
|
/// <param name="userData">用户自定义数据。</param>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 17b9e06584f10da45a8a3ca27fd5e654
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
BIN
Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.xlsx
Normal file
BIN
Assets/TEngine/Tools~/Localize/ExcelConfig/Localization.xlsx
Normal file
Binary file not shown.
83
Assets/TEngine/Tools~/Protobuf/Proto/TEngineProto.proto
Normal file
83
Assets/TEngine/Tools~/Protobuf/Proto/TEngineProto.proto
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
package TEngineProto;
|
||||||
|
|
||||||
|
enum RequestCode
|
||||||
|
{
|
||||||
|
RequestNone = 0;
|
||||||
|
Heart = 1; //心跳
|
||||||
|
User = 2; //用户
|
||||||
|
Room = 3; //房间
|
||||||
|
Game = 4; //游戏
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ActionCode
|
||||||
|
{
|
||||||
|
ActionNone = 0;
|
||||||
|
HeartBeat = 1; //心跳
|
||||||
|
Register = 1000; //注册
|
||||||
|
Login = 1001; //登录
|
||||||
|
CreateRoom = 1002; //创建房间
|
||||||
|
FindRoom = 1003; //查找房间
|
||||||
|
GetPlayers = 1004; //获取玩家列表
|
||||||
|
JoinRoom = 1005; //加入房间
|
||||||
|
ExitRoom = 1006; //离开房间
|
||||||
|
Chat = 2000; //聊天
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ReturnCode
|
||||||
|
{
|
||||||
|
ReturnNone = 0;
|
||||||
|
Success = 1; //成功
|
||||||
|
Fail = 2; //失败
|
||||||
|
MsgTimeOut = 3; //消息超时
|
||||||
|
}
|
||||||
|
|
||||||
|
message MainPack
|
||||||
|
{
|
||||||
|
RequestCode requestcode = 1;
|
||||||
|
ActionCode actioncode = 2;
|
||||||
|
ReturnCode returncode = 3;
|
||||||
|
LoginPack loginPack = 4;
|
||||||
|
string extstr = 5;
|
||||||
|
repeated RoomPack roompack = 6; //房间包,repeated加上为list
|
||||||
|
PlayerPack playerpack = 7;
|
||||||
|
long HeatEchoTime = 8; //心跳包回包时间
|
||||||
|
}
|
||||||
|
|
||||||
|
message LoginPack
|
||||||
|
{
|
||||||
|
string username = 1; //用户名
|
||||||
|
string password = 2; //密码
|
||||||
|
}
|
||||||
|
|
||||||
|
message RoomPack
|
||||||
|
{
|
||||||
|
string roomname = 1; //房间名
|
||||||
|
int32 maxnum = 2; //房间最大人数
|
||||||
|
int32 curnum = 3; //房间当前人数
|
||||||
|
int32 roomID = 6;
|
||||||
|
repeated PlayerPack playerpack = 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PlayerPack
|
||||||
|
{
|
||||||
|
string playerName = 1; //玩家名称
|
||||||
|
string playerID = 2; //玩家ID
|
||||||
|
int32 hp = 3; //玩家血量
|
||||||
|
PosPack posPack = 4; //位置信息
|
||||||
|
}
|
||||||
|
|
||||||
|
message PosPack
|
||||||
|
{
|
||||||
|
float PosX = 1;
|
||||||
|
float PosY = 2;
|
||||||
|
float PosZ = 3;
|
||||||
|
float RotaX = 4;
|
||||||
|
float RotaY = 5;
|
||||||
|
float RotaZ = 6;
|
||||||
|
int32 Animation = 8;
|
||||||
|
int32 Direction = 9;
|
||||||
|
float MoveX = 10;
|
||||||
|
float MoveY = 11;
|
||||||
|
float MoveZ = 12;
|
||||||
|
}
|
8
Assets/TEngine/Tools~/Protobuf/Proto/msg.proto
Normal file
8
Assets/TEngine/Tools~/Protobuf/Proto/msg.proto
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package msg;
|
||||||
|
|
||||||
|
message Msg {
|
||||||
|
string msgId = 1;
|
||||||
|
bytes msgContent = 2;
|
||||||
|
}
|
180
Assets/TEngine/Tools~/Protobuf/Proto_CSharp/TEngineProto.cs
Normal file
180
Assets/TEngine/Tools~/Protobuf/Proto_CSharp/TEngineProto.cs
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
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> roompack = new List<RoomPack>();
|
||||||
|
|
||||||
|
[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> playerpack = new List<PlayerPack>();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
19
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat
Normal file
19
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/gen_all.bat
Normal file
@@ -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
|
Binary file not shown.
@@ -0,0 +1,829 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>protobuf-net.Reflection</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CodeGenerator">
|
||||||
|
<summary>
|
||||||
|
Abstract root for a general purpose code-generator
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CodeGenerator.Name">
|
||||||
|
<summary>
|
||||||
|
The logical name of this code generator
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeGenerator.ToString">
|
||||||
|
<summary>
|
||||||
|
Get a string representation of the instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeGenerator.Generate(Google.Protobuf.Reflection.FileDescriptorSet,ProtoBuf.Reflection.NameNormalizer)">
|
||||||
|
<summary>
|
||||||
|
Execute the code generator against a FileDescriptorSet, yielding a sequence of files
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeGenerator.Generate(Google.Protobuf.Reflection.FileDescriptorSet,ProtoBuf.Reflection.NameNormalizer,System.Collections.Generic.Dictionary{System.String,System.String})">
|
||||||
|
<summary>
|
||||||
|
Execute the code generator against a FileDescriptorSet, yielding a sequence of files
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeGenerator.Compile(ProtoBuf.Reflection.CodeFile)">
|
||||||
|
<summary>
|
||||||
|
Eexecute this code generator against a code file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeGenerator.Compile(ProtoBuf.Reflection.CodeFile[])">
|
||||||
|
<summary>
|
||||||
|
Eexecute this code generator against a set of code file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CommonCodeGenerator">
|
||||||
|
<summary>
|
||||||
|
Abstract base class for a code generator that uses a visitor pattern
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetAccess(Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Obtain the access of an item, accounting for the model's hierarchy
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetLanguageVersion(Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Get the language version for this language from a schema
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetAccess(Google.Protobuf.Reflection.DescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Obtain the access of an item, accounting for the model's hierarchy
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetAccess(Google.Protobuf.Reflection.FieldDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Obtain the access of an item, accounting for the model's hierarchy
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetAccess(Google.Protobuf.Reflection.EnumDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Obtain the access of an item, accounting for the model's hierarchy
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GetAccess(ProtoBuf.Reflection.Access)">
|
||||||
|
<summary>
|
||||||
|
Get the textual name of a given access level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.Indent">
|
||||||
|
<summary>
|
||||||
|
The indentation used by this code generator
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.DefaultFileExtension">
|
||||||
|
<summary>
|
||||||
|
The file extension of the files generatred by this generator
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.IsCaseSensitive">
|
||||||
|
<summary>
|
||||||
|
Should case-sensitivity be used when computing conflicts?
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.Escape(System.String)">
|
||||||
|
<summary>
|
||||||
|
Handle keyword escaping in the language of this code generator
|
||||||
|
</summary>
|
||||||
|
<param name="identifier"></param>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.Generate(Google.Protobuf.Reflection.FileDescriptorSet,ProtoBuf.Reflection.NameNormalizer,System.Collections.Generic.Dictionary{System.String,System.String})">
|
||||||
|
<summary>
|
||||||
|
Execute the code generator against a FileDescriptorSet, yielding a sequence of files
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteFile(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Emits the code for a file in a descriptor-set
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteExtension(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing an extension field
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code preceeding a set of extension fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following a set of extension fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code preceeding a set of extension fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following a set of extension fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteService(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.ServiceDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing a service
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteServiceFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.ServiceDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following a set of service methods
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteServiceMethod(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.MethodDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing a service method
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteServiceHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.ServiceDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following preceeding a set of service methods
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.ShouldOmitMessage(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Check whether a particular message should be suppressed - for example because it represents a map
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteMessage(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing a message type
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteConstructorFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code terminating a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteInitField(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub[])">
|
||||||
|
<summary>
|
||||||
|
Emit code initializing field values inside a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteContructorHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code beginning a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
<returns>true if a constructor is required</returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteField(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub[])">
|
||||||
|
<summary>
|
||||||
|
Emit code representing a message field
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteMessageFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following a set of message fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteMessageHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code preceeding a set of message fields
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteEnum(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing an enum type
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteOneOf(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing 'oneof' elements as an enum discriminator
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code preceeding a set of enum values
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumValueDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code representing an enum value
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code following a set of enum values
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteFileHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code at the start of a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteFileFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code at the end of a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteOneOfEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the start of an enum declaration for 'oneof' groups, including the 0/None element
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteOneOfEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit a field-based entry for a 'oneof' groups's enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteOneOfEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the end of an enum declaration for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.WriteOneOfDiscriminator(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the discriminator accessor for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:ProtoBuf.Reflection.CommonCodeGenerator.OneOfEnumSuffixEnum">
|
||||||
|
<summary>
|
||||||
|
Convention-based suffix for 'oneof' enums
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="F:ProtoBuf.Reflection.CommonCodeGenerator.OneOfEnumSuffixDiscriminator">
|
||||||
|
<summary>
|
||||||
|
Convention-based suffix for 'oneof' discriminators
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext">
|
||||||
|
<summary>
|
||||||
|
Represents the state of a code-generation invocation
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.File">
|
||||||
|
<summary>
|
||||||
|
The file being processed
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.IndentToken">
|
||||||
|
<summary>
|
||||||
|
The token to use for indentation
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.IndentLevel">
|
||||||
|
<summary>
|
||||||
|
The current indent level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.NameNormalizer">
|
||||||
|
<summary>
|
||||||
|
The mechanism to use for name normalization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.Output">
|
||||||
|
<summary>
|
||||||
|
The output for this code generation
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.Syntax">
|
||||||
|
<summary>
|
||||||
|
The effective syntax of this code-generation cycle, defaulting to "proto2" if not explicity specified
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.OneOfEnums">
|
||||||
|
<summary>
|
||||||
|
Whether to emit enums and discriminators for oneof groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.#ctor(ProtoBuf.Reflection.CommonCodeGenerator,Google.Protobuf.Reflection.FileDescriptorProto,ProtoBuf.Reflection.NameNormalizer,System.IO.TextWriter,System.String,System.Collections.Generic.Dictionary{System.String,System.String})">
|
||||||
|
<summary>
|
||||||
|
Create a new GeneratorContext instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.GetCustomOption(System.String)">
|
||||||
|
<summary>
|
||||||
|
Gets the value of an OPTION/VALUE pair provided to the system
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.EmitRequiredDefaults">
|
||||||
|
<summary>
|
||||||
|
Should default value initializers be emitted even for required values?
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.LanguageVersion">
|
||||||
|
<summary>
|
||||||
|
The specified language version (null if not specified)
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.WriteLine">
|
||||||
|
<summary>
|
||||||
|
Ends the current line
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.WriteLine(System.String)">
|
||||||
|
<summary>
|
||||||
|
Appends a value and ends the current line
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.Write(System.String)">
|
||||||
|
<summary>
|
||||||
|
Appends a value to the current line
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.Indent">
|
||||||
|
<summary>
|
||||||
|
Increases the indentation level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.Outdent">
|
||||||
|
<summary>
|
||||||
|
Decreases the indentation level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext.TryFind``1(System.String)">
|
||||||
|
<summary>
|
||||||
|
Try to find a descriptor of the type specified by T with the given full name
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub">
|
||||||
|
<summary>
|
||||||
|
Represents the union summary of a one-of declaration
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub.OneOf">
|
||||||
|
<summary>
|
||||||
|
The underlying descriptor
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub.Index">
|
||||||
|
<summary>
|
||||||
|
The effective index of this stub
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CSharpCodeGenerator">
|
||||||
|
<summary>
|
||||||
|
A code generator that writes C#
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CSharpCodeGenerator.Default">
|
||||||
|
<summary>
|
||||||
|
Reusable code-generator instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.#ctor">
|
||||||
|
<summary>
|
||||||
|
Create a new CSharpCodeGenerator instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CSharpCodeGenerator.Name">
|
||||||
|
<summary>
|
||||||
|
Returns the language name
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CSharpCodeGenerator.DefaultFileExtension">
|
||||||
|
<summary>
|
||||||
|
Returns the default file extension
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.Escape(System.String)">
|
||||||
|
<summary>
|
||||||
|
Escapes language keywords
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.GetLanguageVersion(Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Get the language version for this language from a schema
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteFileHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteFileFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start an enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End an enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumValueDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Write an enum value
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteMessageFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End a message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteMessageHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start a message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.GetAccess(ProtoBuf.Reflection.Access)">
|
||||||
|
<summary>
|
||||||
|
Get the language specific keyword representing an access level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteContructorHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code beginning a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
<returns>true if a constructor is required</returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteConstructorFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit code terminating a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteInitField(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub[])">
|
||||||
|
<summary>
|
||||||
|
Emit code initializing field values inside a constructor, if one is required
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteField(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub[])">
|
||||||
|
<summary>
|
||||||
|
Write a field
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Starts an extgensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Ends an extgensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Starts an extensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Ends an extensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteExtension(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Write an extension
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteOneOfEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the start of an enum declaration for 'oneof' groups, including the 0/None element
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteOneOfEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the end of an enum declaration for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteOneOfEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit a field-based entry for a 'oneof' groups's enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CSharpCodeGenerator.WriteOneOfDiscriminator(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the discriminator accessor for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.NameNormalizer">
|
||||||
|
<summary>
|
||||||
|
Provides general purpose name suggestions
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.NullNormalizer.Pluralize(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a name with idiomatic pluralization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.DefaultNormalizer.Pluralize(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a name with idiomatic pluralization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.AutoCapitalize(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a name with idiomatic name capitalization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.AutoPluralize(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a name with idiomatic pluralization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.NameNormalizer.Default">
|
||||||
|
<summary>
|
||||||
|
Name normalizer with default protobuf-net behaviour, using .NET idioms
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.NameNormalizer.Null">
|
||||||
|
<summary>
|
||||||
|
Name normalizer that passes through all identifiers without any changes
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.Pluralize(System.String)">
|
||||||
|
<summary>
|
||||||
|
Suggest a name with idiomatic pluralization
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.OneofDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.DescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.EnumDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.EnumValueDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.FieldDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Suggest a normalized identifier
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.BuildConflicts(Google.Protobuf.Reflection.DescriptorProto,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Obtain a set of all names defined for a message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.NameNormalizer.GetName(Google.Protobuf.Reflection.DescriptorProto,System.String,System.String,System.Boolean)">
|
||||||
|
<summary>
|
||||||
|
Get the preferred name for an element
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CodeFile">
|
||||||
|
<summary>
|
||||||
|
Describes a generated file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeFile.ToString">
|
||||||
|
<summary>
|
||||||
|
Get a string representation of this instance
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.CodeFile.#ctor(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
Create a new CodeFile instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CodeFile.Name">
|
||||||
|
<summary>
|
||||||
|
The name (including path if necessary) of this file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CodeFile.Text">
|
||||||
|
<summary>
|
||||||
|
The contents of this file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.CompilerResult">
|
||||||
|
<summary>
|
||||||
|
Represents the overall result of a compilation process
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CompilerResult.Errors">
|
||||||
|
<summary>
|
||||||
|
The errors from this execution
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.CompilerResult.Files">
|
||||||
|
<summary>
|
||||||
|
The output files from this execution
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.Reflection.Error">
|
||||||
|
<summary>
|
||||||
|
Describes an error that occurred during processing
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.Error.Parse(System.String,System.String)">
|
||||||
|
<summary>
|
||||||
|
Parse an error from a PROTOC error message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.Reflection.Error.ToString">
|
||||||
|
<summary>
|
||||||
|
Get a text representation of this instance
|
||||||
|
</summary>
|
||||||
|
<returns></returns>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.IsWarning">
|
||||||
|
<summary>
|
||||||
|
True if this instance represents a non-fatal warning
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.IsError">
|
||||||
|
<summary>
|
||||||
|
True if this instance represents a fatal error
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.File">
|
||||||
|
<summary>
|
||||||
|
The file in which this error was identified
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.Text">
|
||||||
|
<summary>
|
||||||
|
The source text relating to this error
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.Message">
|
||||||
|
<summary>
|
||||||
|
The error message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.LineContents">
|
||||||
|
<summary>
|
||||||
|
The entire line contents in the source in which this error was located
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.LineNumber">
|
||||||
|
<summary>
|
||||||
|
The line number in which this error was located
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.Reflection.Error.ColumnNumber">
|
||||||
|
<summary>
|
||||||
|
The column number in which this error was located
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="T:ProtoBuf.VBCodeGenerator">
|
||||||
|
<summary>
|
||||||
|
A code generator that writes VB
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.VBCodeGenerator.Default">
|
||||||
|
<summary>
|
||||||
|
Reusable code-generator instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.VBCodeGenerator.IsCaseSensitive">
|
||||||
|
<summary>
|
||||||
|
Should case-sensitivity be used when computing conflicts?
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.#ctor">
|
||||||
|
<summary>
|
||||||
|
Create a new VBCodeGenerator instance
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.VBCodeGenerator.Name">
|
||||||
|
<summary>
|
||||||
|
Returns the language name
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.GetLanguageVersion(Google.Protobuf.Reflection.FileDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Get the language version for this language from a schema
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:ProtoBuf.VBCodeGenerator.DefaultFileExtension">
|
||||||
|
<summary>
|
||||||
|
Returns the default file extension
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.Escape(System.String)">
|
||||||
|
<summary>
|
||||||
|
Escapes language keywords
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteFileHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteFileFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End a file
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start an enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End an enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.EnumValueDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Write an enum value
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteOneOfDiscriminator(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the discriminator accessor for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteOneOfEnumFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the end of an enum declaration for 'oneof' groups
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteOneOfEnumHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.OneofDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit the start of an enum declaration for 'oneof' groups, including the 0/None element
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteOneOfEnumValue(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Emit a field-based entry for a 'oneof' groups's enum
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteMessageFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
End a message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteMessageHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Start a message
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.GetAccess(ProtoBuf.Reflection.Access)">
|
||||||
|
<summary>
|
||||||
|
Get the language specific keyword representing an access level
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteField(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto,System.Object@,ProtoBuf.Reflection.CommonCodeGenerator.OneOfStub[])">
|
||||||
|
<summary>
|
||||||
|
Write a field
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Starts an extgensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FileDescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Ends an extgensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteExtensionsHeader(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Starts an extensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteExtensionsFooter(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.DescriptorProto,System.Object@)">
|
||||||
|
<summary>
|
||||||
|
Ends an extensions block
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:ProtoBuf.VBCodeGenerator.WriteExtension(ProtoBuf.Reflection.CommonCodeGenerator.GeneratorContext,Google.Protobuf.Reflection.FieldDescriptorProto)">
|
||||||
|
<summary>
|
||||||
|
Write an extension
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Google.Protobuf.Reflection.FileDescriptorSet.AllowNameOnlyImport">
|
||||||
|
<summary>
|
||||||
|
When processing Foo/Bar/Some.proto, should Foo/Bar be treated as an implicit import location?
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="P:Google.Protobuf.Reflection.FileDescriptorSet.DefaultPackage">
|
||||||
|
<summary>
|
||||||
|
Default package to use when none is specified; can use #FILE# and #DIR# tokens
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Binary file not shown.
3550
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.xml
Normal file
3550
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protobuf-net.xml
Normal file
File diff suppressed because it is too large
Load Diff
BIN
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.exe
Normal file
BIN
Assets/TEngine/Tools~/Protobuf/ProtobufGenCsharp/protogen.exe
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<doc>
|
||||||
|
<assembly>
|
||||||
|
<name>protogen</name>
|
||||||
|
</assembly>
|
||||||
|
<members>
|
||||||
|
</members>
|
||||||
|
</doc>
|
Reference in New Issue
Block a user