@@ -51,8 +51,10 @@ public class IgnoranceTransport : TransportLayer
5151 private Address serverAddress ;
5252 private Peer clientPeer ;
5353
54- private Dictionary < int , Peer > knownPeerConnections ; // Known connections dictonary since ENET is a little weird.
55- private int serverConnectionCount = 1 ; // Used by our dictionary to map ENET Peers to connections. Start at 1 just to be safe.
54+ private Dictionary < int , Peer > knownConnIDToPeers ; // Known connections dictonary since ENET is a little weird.
55+ private Dictionary < Peer , int > knownPeersToConnIDs ; // Vice versa.
56+
57+ private int serverConnectionCount = 1 ; // Used by our dictionary to map ENET Peers to connections. Start at 1 just to be safe, connection 0 will be localClient.
5658
5759 // This section defines what classic UNET channels refer to.
5860 private readonly PacketFlags [ ] packetSendMethods =
@@ -75,15 +77,17 @@ public class IgnoranceTransport : TransportLayer
7577 // -- INITIALIZATION -- //
7678 public IgnoranceTransport ( )
7779 {
78- Debug . LogFormat ( "EXPERIMENTAL Ignorance build {0} for Mirror 2018 ready! Report bugs and donate coffee at https://github.com/SoftwareGuy/Ignorance." , TransportVersion ) ;
80+ Debug . LogFormat ( "EXPERIMENTAL Ignorance Transport v {0} for Mirror 2018 ready! Report bugs and donate coffee at https://github.com/SoftwareGuy/Ignorance." , TransportVersion ) ;
7981 }
8082
8183 // -- CLIENT WORLD -- //
82- public virtual bool ClientConnected ( ) {
84+ public virtual bool ClientConnected ( )
85+ {
8386 return clientPeer . IsSet && clientPeer . State == PeerState . Connected ;
8487 }
8588
86- public virtual void ClientConnect ( string address , int port ) {
89+ public virtual void ClientConnect ( string address , int port )
90+ {
8791 // Fire up ENET-C#'s backend.
8892 if ( ! libraryInitialized )
8993 {
@@ -108,21 +112,25 @@ public virtual void ClientConnect(string address, int port) {
108112 ClientReceiveLoop ( client ) ;
109113 }
110114
111- private async void ClientReceiveLoop ( Host clientHost ) {
115+ private async void ClientReceiveLoop ( Host clientHost )
116+ {
112117 try
113118 {
114119 while ( true )
115120 {
121+ if ( ! clientHost . IsSet ) break ;
122+
123+ Event incomingEvent ;
116124 // Get the next message from the client peer object.
117- clientHost . Service ( 0 , out Event incomingEvent ) ;
125+ clientHost . Service ( 0 , out incomingEvent ) ;
118126 switch ( incomingEvent . Type )
119127 {
120128 case EventType . Connect :
121- // TODO: Emit a message when this happens.
122-
129+ Debug . LogFormat ( "Ignorance Transport: Successfully connected to peer located at {0}" , incomingEvent . Peer . IP ) ;
123130 OnClientConnect ? . Invoke ( ) ;
124131 break ;
125132 case EventType . Disconnect :
133+ // Nothing to do here, break the loop.
126134 return ;
127135 case EventType . Timeout :
128136 throw new TimeoutException ( "Ignorance Transport: Our peer connection timed out." ) ;
@@ -131,24 +139,29 @@ private async void ClientReceiveLoop(Host clientHost) {
131139 await Await . NextUpdate ( ) ;
132140 break ;
133141 case EventType . Receive :
134- // Got data .
142+ // Data coming in .
135143 byte [ ] data = new byte [ incomingEvent . Packet . Length ] ;
136144 incomingEvent . Packet . CopyTo ( data ) ;
137145 incomingEvent . Packet . Dispose ( ) ;
138146 OnClientData ? . Invoke ( data ) ;
139147 break ;
140148 }
141149 }
142- } catch ( Exception exception ) {
150+ }
151+ catch ( Exception exception )
152+ {
143153 // Something went wrong - just like Windows 10.
144154 OnClientError ? . Invoke ( exception ) ;
145- } finally {
155+ }
156+ finally
157+ {
146158 // We disconnected, got fed an error message or we got a Disconnect.
147159 OnClientDisconnect ? . Invoke ( ) ;
148160 }
149161 }
150162
151- public virtual void ClientSend ( int channelId , byte [ ] data ) {
163+ public virtual void ClientSend ( int channelId , byte [ ] data )
164+ {
152165 Packet mailingPigeon = default ( Packet ) ;
153166 bool sendingPacketWasSuccessful ; // really needed?
154167
@@ -167,18 +180,21 @@ public virtual void ClientSend(int channelId, byte[] data) {
167180 mailingPigeon . Create ( data , packetSendMethods [ channelId ] ) ;
168181 // probably should get the bool result from this again
169182 sendingPacketWasSuccessful = clientPeer . Send ( 0 , ref mailingPigeon ) ;
170-
183+ if ( ! sendingPacketWasSuccessful ) Debug . LogWarning ( "Ignorance Transport: Packet sending apparently wasn't successful." ) ;
184+
171185 return ;
172186 }
173187
174- public virtual void ClientDisconnect ( ) {
188+ public virtual void ClientDisconnect ( )
189+ {
175190 if ( clientPeer . IsSet ) clientPeer . DisconnectNow ( 0 ) ;
176191 if ( client != null ) client . Dispose ( ) ;
177192 client = null ;
178193 }
179194
180195 // -- SERVER WORLD -- //
181- public virtual bool ServerActive ( ) {
196+ public virtual bool ServerActive ( )
197+ {
182198 if ( ! libraryInitialized ) return false ;
183199
184200 if ( server != null ) return server . IsSet ;
@@ -198,7 +214,9 @@ public virtual void ServerStart(string address, int port, int maxConnections)
198214 // Initialize our references.
199215 server = new Host ( ) ;
200216 serverAddress = new Address ( ) ;
201- knownPeerConnections = new Dictionary < int , Peer > ( ) ;
217+
218+ knownConnIDToPeers = new Dictionary < int , Peer > ( ) ;
219+ knownPeersToConnIDs = new Dictionary < Peer , int > ( ) ;
202220
203221 // Bind if we have an address specified.
204222 if ( ! string . IsNullOrEmpty ( address ) )
@@ -221,83 +239,87 @@ private async void ServerReceiveLoop(Host server)
221239 {
222240 try
223241 {
224- while ( true ) {
225- server . Service ( 0 , out Event incomingEvent ) ;
242+ while ( true )
243+ {
244+ if ( ! server . IsSet ) break ;
245+
246+ Event incomingEvent ;
247+ server . Service ( 0 , out incomingEvent ) ;
226248
227249 switch ( incomingEvent . Type )
228250 {
229251 case EventType . Connect :
230- // TODO: Emit a message when this happens.
252+ Debug . LogFormat ( "Ignorance Transport: New connection from {0}" , incomingEvent . Peer . IP ) ;
231253
232254 // New client connected, let's set them up.
233255 int newClientConnectionId = serverConnectionCount ;
234256 // Increment our next server connection counter.
235257 serverConnectionCount ++ ;
236- // Map them in our dictionary.
237- knownPeerConnections . Add ( newClientConnectionId , incomingEvent . Peer ) ;
258+ // Map them in our dictionaries
259+ knownPeersToConnIDs . Add ( incomingEvent . Peer , newClientConnectionId ) ;
260+ knownConnIDToPeers . Add ( newClientConnectionId , incomingEvent . Peer ) ;
238261 // Invoke the async callback.
239262 OnServerConnect ? . Invoke ( newClientConnectionId ) ;
240263 break ;
241264 case EventType . Receive :
242265 // Got data.
243- byte [ ] data = new byte [ incomingEvent . Packet . Length ] ;
244-
245- // Come up with a better way of doing this, Coburn...
246- foreach ( KeyValuePair < int , Peer > entry in knownPeerConnections )
266+ // Only process that data if the peer is known.
267+ if ( knownPeersToConnIDs . ContainsKey ( incomingEvent . Peer ) )
247268 {
248- if ( entry . Value . ID == incomingEvent . Peer . ID )
249- {
250- incomingEvent . Packet . CopyTo ( data ) ;
251- incomingEvent . Packet . Dispose ( ) ;
252- OnServerData ? . Invoke ( entry . Key , data ) ;
253-
254- // No need to keep going through the list. Halt.
255- break ;
256- }
269+ byte [ ] data = new byte [ incomingEvent . Packet . Length ] ;
270+
271+ incomingEvent . Packet . CopyTo ( data ) ;
272+ incomingEvent . Packet . Dispose ( ) ;
273+ OnServerData ? . Invoke ( knownPeersToConnIDs [ incomingEvent . Peer ] , data ) ;
257274 }
275+
258276 break ;
259277 case EventType . Disconnect :
260- case EventType . Timeout :
261- // TODO: Emit a message when this happens.
262- // Look them up. Not the easiest way of doing this, though.
263-
264- foreach ( KeyValuePair < int , Peer > entry in knownPeerConnections )
278+ Debug . LogFormat ( "Ignorance Transport: Acknowledging disconnection on connection ID {0} " , knownPeersToConnIDs [ incomingEvent . Peer ] ) ;
279+ if ( knownPeersToConnIDs . ContainsKey ( incomingEvent . Peer ) )
265280 {
266- if ( entry . Value . ID == incomingEvent . Peer . ID )
267- {
268- int disconnectedConnectionId = entry . Key ;
269- OnServerDisconnect ? . Invoke ( disconnectedConnectionId ) ;
270- knownPeerConnections . Remove ( entry . Key ) ;
271- break ;
272- }
281+ OnServerDisconnect ? . Invoke ( knownPeersToConnIDs [ incomingEvent . Peer ] ) ;
282+ PeerDisconnectedInternal ( incomingEvent . Peer ) ;
273283 }
274284 break ;
285+ case EventType . Timeout :
286+ OnServerError ? . Invoke ( knownPeersToConnIDs [ incomingEvent . Peer ] , new TimeoutException ( "Ignorance Transport: Timeout occurred on connection " + knownPeersToConnIDs [ incomingEvent . Peer ] ) ) ;
287+ OnServerDisconnect ? . Invoke ( knownPeersToConnIDs [ incomingEvent . Peer ] ) ;
288+ PeerDisconnectedInternal ( incomingEvent . Peer ) ;
289+ break ;
275290 case EventType . None :
276291 // Nothing is happening, so we need to wait until the next frame.
277292 await Await . NextUpdate ( ) ;
278293 break ;
279294 }
280- }
295+ }
281296 }
282297 catch ( Exception exception )
283298 {
284- // What would go here??
285299 Debug . LogFormat ( "Server exception caught: {0}" , exception . ToString ( ) ) ;
300+ OnServerError ? . Invoke ( - 1 , exception ) ;
286301 }
287302 finally
288303 {
289- // What would go here??
290- Debug . Log ( "FIXME: I dunno what to do here" ) ;
304+ Debug . Log ( "Ignorance Transport: Server receive loop finished." ) ;
291305 }
292306 }
293307
308+ private void PeerDisconnectedInternal ( Peer peer )
309+ {
310+ // Clean up dictionaries.
311+ if ( knownConnIDToPeers . ContainsKey ( knownPeersToConnIDs [ peer ] ) ) knownConnIDToPeers . Remove ( knownPeersToConnIDs [ peer ] ) ;
312+ if ( knownPeersToConnIDs . ContainsKey ( peer ) ) knownPeersToConnIDs . Remove ( peer ) ;
313+ }
314+
294315 public virtual void ServerStartWebsockets ( string address , int port , int maxConnections )
295316 {
296317 Debug . LogError ( "Ignorance Transport does not support Websockets. Aborting..." ) ;
297318 return ;
298319 }
299320
300- public virtual void ServerSend ( int connectionId , int channelId , byte [ ] data ) {
321+ public virtual void ServerSend ( int connectionId , int channelId , byte [ ] data )
322+ {
301323 Packet mailingPigeon = default ( Packet ) ;
302324 bool wasTransmissionSuccessful ;
303325
@@ -307,44 +329,49 @@ public virtual void ServerSend(int connectionId, int channelId, byte[] data) {
307329 return ;
308330 }
309331
310- if ( knownPeerConnections . ContainsKey ( connectionId ) ) {
311- Peer target = knownPeerConnections [ connectionId ] ;
332+ if ( knownConnIDToPeers . ContainsKey ( connectionId ) )
333+ {
334+ Peer target = knownConnIDToPeers [ connectionId ] ;
312335 mailingPigeon . Create ( data , packetSendMethods [ channelId ] ) ;
313336
314337 wasTransmissionSuccessful = target . Send ( 0 , ref mailingPigeon ) ;
338+ if ( ! wasTransmissionSuccessful ) Debug . LogWarning ( "Ignorance Transport: Server-side packet sending apparently wasn't successful." ) ;
315339 return ;
316340 }
317341 }
318342
319343 public virtual bool ServerDisconnect ( int connectionId )
320344 {
321- if ( knownPeerConnections . ContainsKey ( connectionId ) ) {
322- knownPeerConnections [ connectionId ] . Disconnect ( 0 ) ;
345+ if ( knownConnIDToPeers . ContainsKey ( connectionId ) )
346+ {
347+ knownConnIDToPeers [ connectionId ] . Disconnect ( 0 ) ;
323348 return true ;
324349 }
325350
326351 return false ;
327352 }
328353
329- public virtual bool GetConnectionInfo ( int connectionId , out string address ) {
354+ public virtual bool GetConnectionInfo ( int connectionId , out string address )
355+ {
330356 address = "(invalid)" ;
331357
332- if ( knownPeerConnections . ContainsKey ( connectionId ) )
358+ if ( knownConnIDToPeers . ContainsKey ( connectionId ) )
333359 {
334- address = knownPeerConnections [ connectionId ] . IP ;
360+ address = knownConnIDToPeers [ connectionId ] . IP ;
335361 return true ;
336362 }
337363
338364 return false ;
339365 }
340366
341- public virtual void ServerStop ( ) {
342- foreach ( KeyValuePair < int , Peer > entry in knownPeerConnections )
343- {
344- entry . Value . DisconnectNow ( 0 ) ;
345- }
367+ public virtual void ServerStop ( )
368+ {
369+ foreach ( KeyValuePair < int , Peer > entry in knownConnIDToPeers ) entry . Value . DisconnectNow ( 0 ) ;
346370
347371 // Don't forget to dispose stuff.
372+ knownConnIDToPeers = new Dictionary < int , Peer > ( ) ;
373+ knownPeersToConnIDs = new Dictionary < Peer , int > ( ) ;
374+
348375 if ( server != null ) server . Dispose ( ) ;
349376 server = null ;
350377 }
@@ -446,7 +473,7 @@ public void EnableCompressionOnServer()
446473 /// </summary>
447474 public void EnableCompressionOnClient ( )
448475 {
449- if ( client != null && client . IsSet )
476+ if ( client != null && client . IsSet )
450477 {
451478 client . EnableCompression ( ) ;
452479 }
@@ -551,4 +578,4 @@ public void EnableParanoidLogging(bool enable)
551578 verboseLoggingEnabled = enable ;
552579 }
553580 }
554- }
581+ }
0 commit comments