LocalClient.cs
5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#if ENABLE_UNET
using System.Collections.Generic;
#pragma warning disable 618
namespace UnityEngine.Networking
{
sealed class LocalClient : NetworkClient
{
const int k_InitialFreeMessagePoolSize = 64;
struct InternalMsg
{
internal byte[] buffer;
internal int channelId;
}
List<InternalMsg> m_InternalMsgs = new List<InternalMsg>();
List<InternalMsg> m_InternalMsgs2 = new List<InternalMsg>();
Stack<InternalMsg> m_FreeMessages;
NetworkServer m_LocalServer;
bool m_Connected;
NetworkMessage s_InternalMessage = new NetworkMessage();
public override void Disconnect()
{
ClientScene.HandleClientDisconnect(m_Connection);
if (m_Connected)
{
PostInternalMessage(MsgType.Disconnect);
m_Connected = false;
}
m_AsyncConnect = ConnectState.Disconnected;
m_LocalServer.RemoveLocalClient(m_Connection);
}
internal void InternalConnectLocalServer(bool generateConnectMsg)
{
if (m_FreeMessages == null)
{
m_FreeMessages = new Stack<InternalMsg>();
for (int i = 0; i < k_InitialFreeMessagePoolSize; i++)
{
InternalMsg msg = new InternalMsg();
m_FreeMessages.Push(msg);
}
}
m_LocalServer = NetworkServer.instance;
m_Connection = new ULocalConnectionToServer(m_LocalServer);
SetHandlers(m_Connection);
m_Connection.connectionId = m_LocalServer.AddLocalClient(this);
m_AsyncConnect = ConnectState.Connected;
SetActive(true);
RegisterSystemHandlers(true);
if (generateConnectMsg)
{
PostInternalMessage(MsgType.Connect);
}
m_Connected = true;
}
internal override void Update()
{
ProcessInternalMessages();
}
// Called by the server to set the LocalClient's LocalPlayer object during NetworkServer.AddPlayer()
internal void AddLocalPlayer(PlayerController localPlayer)
{
if (LogFilter.logDev) Debug.Log("Local client AddLocalPlayer " + localPlayer.gameObject.name + " conn=" + m_Connection.connectionId);
m_Connection.isReady = true;
m_Connection.SetPlayerController(localPlayer);
var uv = localPlayer.unetView;
if (uv != null)
{
ClientScene.SetLocalObject(uv.netId, localPlayer.gameObject);
uv.SetConnectionToServer(m_Connection);
}
// there is no SystemOwnerMessage for local client. add to ClientScene here instead
ClientScene.InternalAddPlayer(uv, localPlayer.playerControllerId);
}
private void PostInternalMessage(byte[] buffer, int channelId)
{
InternalMsg msg;
if (m_FreeMessages.Count == 0)
{
msg = new InternalMsg(); // grow forever?
}
else
{
msg = m_FreeMessages.Pop();
}
msg.buffer = buffer;
msg.channelId = channelId;
m_InternalMsgs.Add(msg);
}
private void PostInternalMessage(short msgType)
{
NetworkWriter writer = new NetworkWriter();
writer.StartMessage(msgType);
writer.FinishMessage();
PostInternalMessage(writer.AsArray(), 0);
}
private void ProcessInternalMessages()
{
if (m_InternalMsgs.Count == 0)
{
return;
}
// new msgs will get put in m_InternalMsgs2
List<InternalMsg> tmp = m_InternalMsgs;
m_InternalMsgs = m_InternalMsgs2;
// iterate through existing set
for (int i = 0; i < tmp.Count; i++)
{
var msg = tmp[i];
if (s_InternalMessage.reader == null)
{
s_InternalMessage.reader = new NetworkReader(msg.buffer);
}
else
{
s_InternalMessage.reader.Replace(msg.buffer);
}
s_InternalMessage.reader.ReadInt16(); //size
s_InternalMessage.channelId = msg.channelId;
s_InternalMessage.conn = connection;
s_InternalMessage.msgType = s_InternalMessage.reader.ReadInt16();
m_Connection.InvokeHandler(s_InternalMessage);
m_FreeMessages.Push(msg);
connection.lastMessageTime = Time.time;
}
// put m_InternalMsgs back and clear it
m_InternalMsgs = tmp;
m_InternalMsgs.Clear();
// add any newly generated msgs in m_InternalMsgs2 and clear it
for (int ii = 0; ii < m_InternalMsgs2.Count; ii++)
{
m_InternalMsgs.Add(m_InternalMsgs2[ii]);
}
m_InternalMsgs2.Clear();
}
// called by the server, to bypass network
internal void InvokeHandlerOnClient(short msgType, MessageBase msg, int channelId)
{
// write the message to a local buffer
NetworkWriter writer = new NetworkWriter();
writer.StartMessage(msgType);
msg.Serialize(writer);
writer.FinishMessage();
InvokeBytesOnClient(writer.AsArray(), channelId);
}
// called by the server, to bypass network
internal void InvokeBytesOnClient(byte[] buffer, int channelId)
{
PostInternalMessage(buffer, channelId);
}
}
}
#pragma warning restore 618
#endif //ENABLE_UNET